Blame test/shaping/hb_test_tools.py

Packit 874993
#!/usr/bin/env python
Packit 874993
Packit 874993
from __future__ import print_function
Packit 874993
import sys, os, re, difflib, unicodedata, errno, cgi
Packit 874993
from itertools import *
Packit 874993
Packit 874993
diff_symbols = "-+=*&^%$#@!~/"
Packit 874993
diff_colors = ['red', 'green', 'blue']
Packit 874993
Packit 874993
try:
Packit 874993
	unichr = unichr
Packit 874993
Packit 874993
	if sys.maxunicode < 0x10FFFF:
Packit 874993
		# workarounds for Python 2 "narrow" builds with UCS2-only support.
Packit 874993
Packit 874993
		_narrow_unichr = unichr
Packit 874993
Packit 874993
		def unichr(i):
Packit 874993
			"""
Packit 874993
			Return the unicode character whose Unicode code is the integer 'i'.
Packit 874993
			The valid range is 0 to 0x10FFFF inclusive.
Packit 874993
Packit 874993
			>>> _narrow_unichr(0xFFFF + 1)
Packit 874993
			Traceback (most recent call last):
Packit 874993
			  File "<stdin>", line 1, in ?
Packit 874993
			ValueError: unichr() arg not in range(0x10000) (narrow Python build)
Packit 874993
			>>> unichr(0xFFFF + 1) == u'\U00010000'
Packit 874993
			True
Packit 874993
			>>> unichr(1114111) == u'\U0010FFFF'
Packit 874993
			True
Packit 874993
			>>> unichr(0x10FFFF + 1)
Packit 874993
			Traceback (most recent call last):
Packit 874993
			  File "<stdin>", line 1, in ?
Packit 874993
			ValueError: unichr() arg not in range(0x110000)
Packit 874993
			"""
Packit 874993
			try:
Packit 874993
				return _narrow_unichr(i)
Packit 874993
			except ValueError:
Packit 874993
				try:
Packit 874993
					padded_hex_str = hex(i)[2:].zfill(8)
Packit 874993
					escape_str = "\\U" + padded_hex_str
Packit 874993
					return escape_str.decode("unicode-escape")
Packit 874993
				except UnicodeDecodeError:
Packit 874993
					raise ValueError('unichr() arg not in range(0x110000)')
Packit 874993
Packit 874993
except NameError:
Packit 874993
	unichr = chr
Packit 874993
Packit 874993
try:
Packit 874993
	unicode = unicode
Packit 874993
except NameError:
Packit 874993
	unicode = str
Packit 874993
Packit 874993
def tounicode(s, encoding='ascii', errors='strict'):
Packit 874993
	if not isinstance(s, unicode):
Packit 874993
		return s.decode(encoding, errors)
Packit 874993
	else:
Packit 874993
		return s
Packit 874993
Packit 874993
class ColorFormatter:
Packit 874993
Packit 874993
	class Null:
Packit 874993
		@staticmethod
Packit 874993
		def start_color (c): return ''
Packit 874993
		@staticmethod
Packit 874993
		def end_color (): return ''
Packit 874993
		@staticmethod
Packit 874993
		def escape (s): return s
Packit 874993
		@staticmethod
Packit 874993
		def newline (): return '\n'
Packit 874993
Packit 874993
	class ANSI:
Packit 874993
		@staticmethod
Packit 874993
		def start_color (c):
Packit 874993
			return {
Packit 874993
				'red': '\033[41;37;1m',
Packit 874993
				'green': '\033[42;37;1m',
Packit 874993
				'blue': '\033[44;37;1m',
Packit 874993
			}[c]
Packit 874993
		@staticmethod
Packit 874993
		def end_color ():
Packit 874993
			return '\033[m'
Packit 874993
		@staticmethod
Packit 874993
		def escape (s): return s
Packit 874993
		@staticmethod
Packit 874993
		def newline (): return '\n'
Packit 874993
Packit 874993
	class HTML:
Packit 874993
		@staticmethod
Packit 874993
		def start_color (c):
Packit 874993
			return '' % c
Packit 874993
		@staticmethod
Packit 874993
		def end_color ():
Packit 874993
			return ''
Packit 874993
		@staticmethod
Packit 874993
		def escape (s): return cgi.escape (s)
Packit 874993
		@staticmethod
Packit 874993
		def newline (): return '
\n'
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def Auto (argv = [], out = sys.stdout):
Packit 874993
		format = ColorFormatter.ANSI
Packit 874993
		if "--format" in argv:
Packit 874993
			argv.remove ("--format")
Packit 874993
			format = ColorFormatter.ANSI
Packit 874993
		if "--format=ansi" in argv:
Packit 874993
			argv.remove ("--format=ansi")
Packit 874993
			format = ColorFormatter.ANSI
Packit 874993
		if "--format=html" in argv:
Packit 874993
			argv.remove ("--format=html")
Packit 874993
			format = ColorFormatter.HTML
Packit 874993
		if "--no-format" in argv:
Packit 874993
			argv.remove ("--no-format")
Packit 874993
			format = ColorFormatter.Null
Packit 874993
		return format
Packit 874993
Packit 874993
Packit 874993
class DiffColorizer:
Packit 874993
Packit 874993
	diff_regex = re.compile ('([a-za-z0-9_]*)([^a-za-z0-9_]?)')
Packit 874993
Packit 874993
	def __init__ (self, formatter, colors=diff_colors, symbols=diff_symbols):
Packit 874993
		self.formatter = formatter
Packit 874993
		self.colors = colors
Packit 874993
		self.symbols = symbols
Packit 874993
Packit 874993
	def colorize_lines (self, lines):
Packit 874993
		lines = (l if l else '' for l in lines)
Packit 874993
		ss = [self.diff_regex.sub (r'\1\n\2\n', l).splitlines (True) for l in lines]
Packit 874993
		oo = ["",""]
Packit 874993
		st = [False, False]
Packit 874993
		for l in difflib.Differ().compare (*ss):
Packit 874993
			if l[0] == '?':
Packit 874993
				continue
Packit 874993
			if l[0] == ' ':
Packit 874993
				for i in range(2):
Packit 874993
					if st[i]:
Packit 874993
						oo[i] += self.formatter.end_color ()
Packit 874993
						st[i] = False
Packit 874993
				oo = [o + self.formatter.escape (l[2:]) for o in oo]
Packit 874993
				continue
Packit 874993
			if l[0] in self.symbols:
Packit 874993
				i = self.symbols.index (l[0])
Packit 874993
				if not st[i]:
Packit 874993
					oo[i] += self.formatter.start_color (self.colors[i])
Packit 874993
					st[i] = True
Packit 874993
				oo[i] += self.formatter.escape (l[2:])
Packit 874993
				continue
Packit 874993
		for i in range(2):
Packit 874993
			if st[i]:
Packit 874993
				oo[i] += self.formatter.end_color ()
Packit 874993
				st[i] = False
Packit 874993
		oo = [o.replace ('\n', '') for o in oo]
Packit 874993
		return [s1+s2+self.formatter.newline () for (s1,s2) in zip (self.symbols, oo) if s2]
Packit 874993
Packit 874993
	def colorize_diff (self, f):
Packit 874993
		lines = [None, None]
Packit 874993
		for l in f:
Packit 874993
			if l[0] not in self.symbols:
Packit 874993
				yield self.formatter.escape (l).replace ('\n', self.formatter.newline ())
Packit 874993
				continue
Packit 874993
			i = self.symbols.index (l[0])
Packit 874993
			if lines[i]:
Packit 874993
				# Flush
Packit 874993
				for line in self.colorize_lines (lines):
Packit 874993
					yield line
Packit 874993
				lines = [None, None]
Packit 874993
			lines[i] = l[1:]
Packit 874993
			if (all (lines)):
Packit 874993
				# Flush
Packit 874993
				for line in self.colorize_lines (lines):
Packit 874993
					yield line
Packit 874993
				lines = [None, None]
Packit 874993
		if (any (lines)):
Packit 874993
			# Flush
Packit 874993
			for line in self.colorize_lines (lines):
Packit 874993
				yield line
Packit 874993
Packit 874993
Packit 874993
class ZipDiffer:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def diff_files (files, symbols=diff_symbols):
Packit 874993
		files = tuple (files) # in case it's a generator, copy it
Packit 874993
		try:
Packit 874993
			for lines in izip_longest (*files):
Packit 874993
				if all (lines[0] == line for line in lines[1:]):
Packit 874993
					sys.stdout.writelines ([" ", lines[0]])
Packit 874993
					continue
Packit 874993
Packit 874993
				for i, l in enumerate (lines):
Packit 874993
					if l:
Packit 874993
						sys.stdout.writelines ([symbols[i], l])
Packit 874993
		except IOError as e:
Packit 874993
			if e.errno != errno.EPIPE:
Packit 874993
				print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr)
Packit 874993
				sys.exit (1)
Packit 874993
Packit 874993
Packit 874993
class DiffFilters:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def filter_failures (f):
Packit 874993
		for key, lines in DiffHelpers.separate_test_cases (f):
Packit 874993
			lines = list (lines)
Packit 874993
			if not DiffHelpers.test_passed (lines):
Packit 874993
				for l in lines: yield l
Packit 874993
Packit 874993
class Stat:
Packit 874993
Packit 874993
	def __init__ (self):
Packit 874993
		self.count = 0
Packit 874993
		self.freq = 0
Packit 874993
Packit 874993
	def add (self, test):
Packit 874993
		self.count += 1
Packit 874993
		self.freq += test.freq
Packit 874993
Packit 874993
class Stats:
Packit 874993
Packit 874993
	def __init__ (self):
Packit 874993
		self.passed = Stat ()
Packit 874993
		self.failed = Stat ()
Packit 874993
		self.total  = Stat ()
Packit 874993
Packit 874993
	def add (self, test):
Packit 874993
		self.total.add (test)
Packit 874993
		if test.passed:
Packit 874993
			self.passed.add (test)
Packit 874993
		else:
Packit 874993
			self.failed.add (test)
Packit 874993
Packit 874993
	def mean (self):
Packit 874993
		return float (self.passed.count) / self.total.count
Packit 874993
Packit 874993
	def variance (self):
Packit 874993
		return (float (self.passed.count) / self.total.count) * \
Packit 874993
		       (float (self.failed.count) / self.total.count)
Packit 874993
Packit 874993
	def stddev (self):
Packit 874993
		return self.variance () ** .5
Packit 874993
Packit 874993
	def zscore (self, population):
Packit 874993
		"""Calculate the standard score.
Packit 874993
		   Population is the Stats for population.
Packit 874993
		   Self is Stats for sample.
Packit 874993
		   Returns larger absolute value if sample is highly unlikely to be random.
Packit 874993
		   Anything outside of -3..+3 is very unlikely to be random.
Packit 874993
		   See: http://en.wikipedia.org/wiki/Standard_score"""
Packit 874993
Packit 874993
		return (self.mean () - population.mean ()) / population.stddev ()
Packit 874993
Packit 874993
Packit 874993
Packit 874993
Packit 874993
class DiffSinks:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def print_stat (f):
Packit 874993
		passed = 0
Packit 874993
		failed = 0
Packit 874993
		# XXX port to Stats, but that would really slow us down here
Packit 874993
		for key, lines in DiffHelpers.separate_test_cases (f):
Packit 874993
			if DiffHelpers.test_passed (lines):
Packit 874993
				passed += 1
Packit 874993
			else:
Packit 874993
				failed += 1
Packit 874993
		total = passed + failed
Packit 874993
		print ("%d out of %d tests passed.  %d failed (%g%%)" % (passed, total, failed, 100. * failed / total))
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def print_ngrams (f, ns=(1,2,3)):
Packit 874993
		gens = tuple (Ngram.generator (n) for n in ns)
Packit 874993
		allstats = Stats ()
Packit 874993
		allgrams = {}
Packit 874993
		for key, lines in DiffHelpers.separate_test_cases (f):
Packit 874993
			test = Test (lines)
Packit 874993
			allstats.add (test)
Packit 874993
Packit 874993
			for gen in gens:
Packit 874993
				for ngram in gen (test.unicodes):
Packit 874993
					if ngram not in allgrams:
Packit 874993
						allgrams[ngram] = Stats ()
Packit 874993
					allgrams[ngram].add (test)
Packit 874993
Packit 874993
		importantgrams = {}
Packit 874993
		for ngram, stats in allgrams.iteritems ():
Packit 874993
			if stats.failed.count >= 30: # for statistical reasons
Packit 874993
				importantgrams[ngram] = stats
Packit 874993
		allgrams = importantgrams
Packit 874993
		del importantgrams
Packit 874993
Packit 874993
		for ngram, stats in allgrams.iteritems ():
Packit 874993
			print ("zscore: %9f failed: %6d passed: %6d ngram: <%s>" % (stats.zscore (allstats), stats.failed.count, stats.passed.count, ','.join ("U+%04X" % u for u in ngram)))
Packit 874993
Packit 874993
Packit 874993
Packit 874993
class Test:
Packit 874993
Packit 874993
	def __init__ (self, lines):
Packit 874993
		self.freq = 1
Packit 874993
		self.passed = True
Packit 874993
		self.identifier = None
Packit 874993
		self.text = None
Packit 874993
		self.unicodes = None
Packit 874993
		self.glyphs = None
Packit 874993
		for l in lines:
Packit 874993
			symbol = l[0]
Packit 874993
			if symbol != ' ':
Packit 874993
				self.passed = False
Packit 874993
			i = 1
Packit 874993
			if ':' in l:
Packit 874993
				i = l.index (':')
Packit 874993
				if not self.identifier:
Packit 874993
					self.identifier = l[1:i]
Packit 874993
				i = i + 2 # Skip colon and space
Packit 874993
			j = -1
Packit 874993
			if l[j] == '\n':
Packit 874993
				j -= 1
Packit 874993
			brackets = l[i] + l[j]
Packit 874993
			l = l[i+1:-2]
Packit 874993
			if brackets == '()':
Packit 874993
				self.text = l
Packit 874993
			elif brackets == '<>':
Packit 874993
				self.unicodes = Unicode.parse (l)
Packit 874993
			elif brackets == '[]':
Packit 874993
				# XXX we don't handle failed tests here
Packit 874993
				self.glyphs = l
Packit 874993
Packit 874993
Packit 874993
class DiffHelpers:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def separate_test_cases (f):
Packit 874993
		'''Reads lines from f, and if the lines have identifiers, ie.
Packit 874993
		   have a colon character, groups them by identifier,
Packit 874993
		   yielding lists of all lines with the same identifier.'''
Packit 874993
Packit 874993
		def identifier (l):
Packit 874993
			if ':' in l[1:]:
Packit 874993
				return l[1:l.index (':')]
Packit 874993
			return l
Packit 874993
		return groupby (f, key=identifier)
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def test_passed (lines):
Packit 874993
		lines = list (lines)
Packit 874993
		# XXX This is a hack, but does the job for now.
Packit 874993
		if any (l.find("space+0|space+0") >= 0 for l in lines if l[0] == '+'): return True
Packit 874993
		if any (l.find("uni25CC") >= 0 for l in lines if l[0] == '+'): return True
Packit 874993
		if any (l.find("dottedcircle") >= 0 for l in lines if l[0] == '+'): return True
Packit 874993
		if any (l.find("glyph0") >= 0 for l in lines if l[0] == '+'): return True
Packit 874993
		if any (l.find("gid0") >= 0 for l in lines if l[0] == '+'): return True
Packit 874993
		if any (l.find("notdef") >= 0 for l in lines if l[0] == '+'): return True
Packit 874993
		return all (l[0] == ' ' for l in lines)
Packit 874993
Packit 874993
Packit 874993
class FilterHelpers:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def filter_printer_function (filter_callback):
Packit 874993
		def printer (f):
Packit 874993
			for line in filter_callback (f):
Packit 874993
				print (line)
Packit 874993
		return printer
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def filter_printer_function_no_newline (filter_callback):
Packit 874993
		def printer (f):
Packit 874993
			for line in filter_callback (f):
Packit 874993
				sys.stdout.writelines ([line])
Packit 874993
		return printer
Packit 874993
Packit 874993
Packit 874993
class Ngram:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def generator (n):
Packit 874993
Packit 874993
		def gen (f):
Packit 874993
			l = []
Packit 874993
			for x in f:
Packit 874993
				l.append (x)
Packit 874993
				if len (l) == n:
Packit 874993
					yield tuple (l)
Packit 874993
					l[:1] = []
Packit 874993
Packit 874993
		gen.n = n
Packit 874993
		return gen
Packit 874993
Packit 874993
Packit 874993
class UtilMains:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def process_multiple_files (callback, mnemonic = "FILE"):
Packit 874993
Packit 874993
		if "--help" in sys.argv:
Packit 874993
			print ("Usage: %s %s..." % (sys.argv[0], mnemonic))
Packit 874993
			sys.exit (1)
Packit 874993
Packit 874993
		try:
Packit 874993
			files = sys.argv[1:] if len (sys.argv) > 1 else ['-']
Packit 874993
			for s in files:
Packit 874993
				callback (FileHelpers.open_file_or_stdin (s))
Packit 874993
		except IOError as e:
Packit 874993
			if e.errno != errno.EPIPE:
Packit 874993
				print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr)
Packit 874993
				sys.exit (1)
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def process_multiple_args (callback, mnemonic):
Packit 874993
Packit 874993
		if len (sys.argv) == 1 or "--help" in sys.argv:
Packit 874993
			print ("Usage: %s %s..." % (sys.argv[0], mnemonic))
Packit 874993
			sys.exit (1)
Packit 874993
Packit 874993
		try:
Packit 874993
			for s in sys.argv[1:]:
Packit 874993
				callback (s)
Packit 874993
		except IOError as e:
Packit 874993
			if e.errno != errno.EPIPE:
Packit 874993
				print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr)
Packit 874993
				sys.exit (1)
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def filter_multiple_strings_or_stdin (callback, mnemonic, \
Packit 874993
					      separator = " ", \
Packit 874993
					      concat_separator = False):
Packit 874993
Packit 874993
		if "--help" in sys.argv:
Packit 874993
			print ("Usage:\n  %s %s...\nor:\n  %s\n\nWhen called with no arguments, input is read from standard input." \
Packit 874993
			      % (sys.argv[0], mnemonic, sys.argv[0]))
Packit 874993
			sys.exit (1)
Packit 874993
Packit 874993
		try:
Packit 874993
			if len (sys.argv) == 1:
Packit 874993
				while (1):
Packit 874993
					line = sys.stdin.readline ()
Packit 874993
					if not len (line):
Packit 874993
						break
Packit 874993
					if line[-1] == '\n':
Packit 874993
						line = line[:-1]
Packit 874993
					print (callback (line))
Packit 874993
			else:
Packit 874993
				args = sys.argv[1:]
Packit 874993
				if concat_separator != False:
Packit 874993
					args = [concat_separator.join (args)]
Packit 874993
				print (separator.join (callback (x) for x in (args)))
Packit 874993
		except IOError as e:
Packit 874993
			if e.errno != errno.EPIPE:
Packit 874993
				print ("%s: %s: %s" % (sys.argv[0], e.filename, e.strerror), file=sys.stderr)
Packit 874993
				sys.exit (1)
Packit 874993
Packit 874993
Packit 874993
class Unicode:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def decode (s):
Packit 874993
		return u','.join ("U+%04X" % ord (u) for u in tounicode (s, 'utf-8'))
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def parse (s):
Packit 874993
		s = re.sub (r"0[xX]", " ", s)
Packit 874993
		s = re.sub (r"[<+>{},;&#\\xXuUnNiI\n	]", " ", s)
Packit 874993
		return [int (x, 16) for x in s.split ()]
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def encode (s):
Packit 874993
		s = u''.join (unichr (x) for x in Unicode.parse (s))
Packit 874993
		if sys.version_info[0] == 2: s = s.encode ('utf-8')
Packit 874993
		return s
Packit 874993
Packit 874993
	shorthands = {
Packit 874993
		"ZERO WIDTH NON-JOINER": "ZWNJ",
Packit 874993
		"ZERO WIDTH JOINER": "ZWJ",
Packit 874993
		"NARROW NO-BREAK SPACE": "NNBSP",
Packit 874993
		"COMBINING GRAPHEME JOINER": "CGJ",
Packit 874993
		"LEFT-TO-RIGHT MARK": "LRM",
Packit 874993
		"RIGHT-TO-LEFT MARK": "RLM",
Packit 874993
		"LEFT-TO-RIGHT EMBEDDING": "LRE",
Packit 874993
		"RIGHT-TO-LEFT EMBEDDING": "RLE",
Packit 874993
		"POP DIRECTIONAL FORMATTING": "PDF",
Packit 874993
		"LEFT-TO-RIGHT OVERRIDE": "LRO",
Packit 874993
		"RIGHT-TO-LEFT OVERRIDE": "RLO",
Packit 874993
	}
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def pretty_name (u):
Packit 874993
		try:
Packit 874993
			s = unicodedata.name (u)
Packit 874993
		except ValueError:
Packit 874993
			return "XXX"
Packit 874993
		s = re.sub (".* LETTER ", "", s)
Packit 874993
		s = re.sub (".* VOWEL SIGN (.*)", r"\1-MATRA", s)
Packit 874993
		s = re.sub (".* SIGN ", "", s)
Packit 874993
		s = re.sub (".* COMBINING ", "", s)
Packit 874993
		if re.match (".* VIRAMA", s):
Packit 874993
			s = "HALANT"
Packit 874993
		if s in Unicode.shorthands:
Packit 874993
			s = Unicode.shorthands[s]
Packit 874993
		return s
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def pretty_names (s):
Packit 874993
		s = re.sub (r"[<+>\\uU]", " ", s)
Packit 874993
		s = re.sub (r"0[xX]", " ", s)
Packit 874993
		s = [unichr (int (x, 16)) for x in re.split ('[, \n]', s) if len (x)]
Packit 874993
		return u' + '.join (Unicode.pretty_name (x) for x in s).encode ('utf-8')
Packit 874993
Packit 874993
Packit 874993
class FileHelpers:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def open_file_or_stdin (f):
Packit 874993
		if f == '-':
Packit 874993
			return sys.stdin
Packit 874993
		return file (f)
Packit 874993
Packit 874993
Packit 874993
class Manifest:
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def read (s, strict = True):
Packit 874993
Packit 874993
		if not os.path.exists (s):
Packit 874993
			if strict:
Packit 874993
				print ("%s: %s does not exist" % (sys.argv[0], s), file=sys.stderr)
Packit 874993
				sys.exit (1)
Packit 874993
			return
Packit 874993
Packit 874993
		s = os.path.normpath (s)
Packit 874993
Packit 874993
		if os.path.isdir (s):
Packit 874993
Packit 874993
			try:
Packit 874993
				m = file (os.path.join (s, "MANIFEST"))
Packit 874993
				items = [x.strip () for x in m.readlines ()]
Packit 874993
				for f in items:
Packit 874993
					for p in Manifest.read (os.path.join (s, f)):
Packit 874993
						yield p
Packit 874993
			except IOError:
Packit 874993
				if strict:
Packit 874993
					print ("%s: %s does not exist" % (sys.argv[0], os.path.join (s, "MANIFEST")), file=sys.stderr)
Packit 874993
					sys.exit (1)
Packit 874993
				return
Packit 874993
		else:
Packit 874993
			yield s
Packit 874993
Packit 874993
	@staticmethod
Packit 874993
	def update_recursive (s):
Packit 874993
Packit 874993
		for dirpath, dirnames, filenames in os.walk (s, followlinks=True):
Packit 874993
Packit 874993
			for f in ["MANIFEST", "README", "LICENSE", "COPYING", "AUTHORS", "SOURCES", "ChangeLog"]:
Packit 874993
				if f in dirnames:
Packit 874993
					dirnames.remove (f)
Packit 874993
				if f in filenames:
Packit 874993
					filenames.remove (f)
Packit 874993
			dirnames.sort ()
Packit 874993
			filenames.sort ()
Packit 874993
			ms = os.path.join (dirpath, "MANIFEST")
Packit 874993
			print ("  GEN    %s" % ms)
Packit 874993
			m = open (ms, "w")
Packit 874993
			for f in filenames:
Packit 874993
				print (f, file=m)
Packit 874993
			for f in dirnames:
Packit 874993
				print (f, file=m)
Packit 874993
			for f in dirnames:
Packit 874993
				Manifest.update_recursive (os.path.join (dirpath, f))
Packit 874993
Packit 874993
if __name__ == '__main__':
Packit 874993
	pass