|  | #!/usr/bin/env python | 
|  |  | 
|  | from __future__ import absolute_import, division, print_function | 
|  | import argparse | 
|  | import os.path as path | 
|  |  | 
|  |  | 
|  | def read_tests(f): | 
|  | basename, _ = path.splitext(path.basename(f)) | 
|  | tests = [] | 
|  | prev_pattern = None | 
|  |  | 
|  | for lineno, line in enumerate(open(f), 1): | 
|  | fields = list(filter(None, map(str.strip, line.split('\t')))) | 
|  | if not (4 <= len(fields) <= 5) \ | 
|  | or 'E' not in fields[0] or fields[0][0] == '#': | 
|  | continue | 
|  |  | 
|  | terse_opts, pat, text, sgroups = fields[0:4] | 
|  | groups = []  # groups as integer ranges | 
|  | if sgroups == 'NOMATCH': | 
|  | groups = [] | 
|  | elif ',' in sgroups: | 
|  | noparen = map(lambda s: s.strip('()'), sgroups.split(')(')) | 
|  | for g in noparen: | 
|  | s, e = map(str.strip, g.split(',')) | 
|  | groups.append([int(s), int(e)]) | 
|  | break | 
|  | else: | 
|  | # This skips tests that should result in an error. | 
|  | # There aren't many, so I think we can just capture those | 
|  | # manually. Possibly fix this in future. | 
|  | continue | 
|  |  | 
|  | opts = [] | 
|  | if text == "NULL": | 
|  | text = "" | 
|  | if pat == 'SAME': | 
|  | pat = prev_pattern | 
|  | if '$' in terse_opts: | 
|  | pat = pat.encode('utf-8').decode('unicode_escape') | 
|  | text = text.encode('utf-8').decode('unicode_escape') | 
|  | text = text.encode('unicode_escape').decode('utf-8') | 
|  | opts.append('escaped') | 
|  | else: | 
|  | opts.append('escaped') | 
|  | text = text.encode('unicode_escape').decode('utf-8') | 
|  | if 'i' in terse_opts: | 
|  | opts.append('case-insensitive') | 
|  |  | 
|  | pat = pat.encode('unicode_escape').decode('utf-8') | 
|  | pat = pat.replace('\\\\', '\\') | 
|  | tests.append({ | 
|  | 'name': '"%s%d"' % (basename, lineno), | 
|  | 'options': repr(opts), | 
|  | 'pattern': "'''%s'''" % pat, | 
|  | 'input': "'''%s'''" % text, | 
|  | 'matches': str(groups), | 
|  | }) | 
|  | prev_pattern = pat | 
|  | return tests | 
|  |  | 
|  |  | 
|  | if __name__ == '__main__': | 
|  | parser = argparse.ArgumentParser( | 
|  | description='Generate match tests from an AT&T POSIX test file.') | 
|  | aa = parser.add_argument | 
|  | aa('datfile', help='A dat AT&T POSIX test file.') | 
|  | args = parser.parse_args() | 
|  |  | 
|  | tests = read_tests(args.datfile) | 
|  | for t in tests: | 
|  | print('[[tests]]') | 
|  | for k, v in t.items(): | 
|  | print('%s = %s' % (k, v)) | 
|  | print('') |