Guido van Rossum | 41ffccb | 1993-04-01 20:50:35 +0000 | [diff] [blame] | 1 | #! /usr/local/bin/python |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 2 | |
| 3 | # Read #define's from stdin and translate to Python code on stdout. |
Guido van Rossum | 01f5f62 | 1994-05-17 09:05:54 +0000 | [diff] [blame^] | 4 | # Very primitive: non-#define's are ignored, as is anything that isn't |
| 5 | # valid Python as it stands. |
Guido van Rossum | 09336f9 | 1994-05-03 14:37:30 +0000 | [diff] [blame] | 6 | # If one or more filenames are given, output is written to corresponding |
| 7 | # filenames in the local directory, translated to all uppercase, with |
| 8 | # the extension replaced by ".py". |
Guido van Rossum | 01f5f62 | 1994-05-17 09:05:54 +0000 | [diff] [blame^] | 9 | # By passing one or more options of the form "-i regular_expression" |
| 10 | # you can specify additional strings to be ignored. This is useful |
| 11 | # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'". |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 12 | |
| 13 | # XXX To do: |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 14 | # - turn trailing C comments into Python comments |
| 15 | # - turn C string quotes into Python comments |
| 16 | # - turn C Boolean operators "&& || !" into Python "and or not" |
| 17 | # - what to do about #if(def)? |
Guido van Rossum | 01f5f62 | 1994-05-17 09:05:54 +0000 | [diff] [blame^] | 18 | # - what to do about #include? |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 19 | # - what to do about macros with parameters? |
| 20 | # - reject definitions with semicolons in them |
| 21 | |
Guido van Rossum | 09336f9 | 1994-05-03 14:37:30 +0000 | [diff] [blame] | 22 | import sys, regex, string, getopt, os |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 23 | |
| 24 | p_define = regex.compile('^#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+') |
| 25 | |
Guido van Rossum | 047979e | 1992-06-05 15:13:53 +0000 | [diff] [blame] | 26 | p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?') |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 27 | |
Guido van Rossum | 01f5f62 | 1994-05-17 09:05:54 +0000 | [diff] [blame^] | 28 | ignores = [p_comment] |
| 29 | |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 30 | def main(): |
Guido van Rossum | 01f5f62 | 1994-05-17 09:05:54 +0000 | [diff] [blame^] | 31 | opts, args = getopt.getopt(sys.argv[1:], 'i:') |
| 32 | for o, a in opts: |
| 33 | if o == '-i': |
| 34 | ignores.append(regex.compile(a)) |
Guido van Rossum | 09336f9 | 1994-05-03 14:37:30 +0000 | [diff] [blame] | 35 | if not args: |
| 36 | args = ['-'] |
| 37 | for filename in args: |
| 38 | if filename == '-': |
| 39 | sys.stdout.write('# Generated by h2py from stdin\n') |
| 40 | process(sys.stdin, sys.stdout) |
| 41 | else: |
| 42 | fp = open(filename, 'r') |
| 43 | outfile = os.path.basename(filename) |
| 44 | i = string.rfind(outfile, '.') |
| 45 | if i > 0: outfile = outfile[:i] |
| 46 | outfile = string.upper(outfile) |
| 47 | outfile = outfile + '.py' |
| 48 | outfp = open(outfile, 'w') |
| 49 | outfp.write('# Generated by h2py from %s\n' % filename) |
| 50 | process(fp, outfp) |
| 51 | outfp.close() |
| 52 | fp.close() |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 53 | |
Guido van Rossum | 09336f9 | 1994-05-03 14:37:30 +0000 | [diff] [blame] | 54 | def process(fp, outfp): |
| 55 | env = {} |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 56 | lineno = 0 |
| 57 | while 1: |
| 58 | line = fp.readline() |
| 59 | if not line: break |
| 60 | lineno = lineno + 1 |
Guido van Rossum | 01f5f62 | 1994-05-17 09:05:54 +0000 | [diff] [blame^] | 61 | # gobble up continuation lines |
| 62 | while line[-2:] == '\\\n': |
| 63 | nextline = fp.readline() |
| 64 | if not nextline: break |
| 65 | lineno = lineno + 1 |
| 66 | line = line + nextline |
| 67 | n = p_define.match(line) |
| 68 | if n >= 0: |
| 69 | name = p_define.group(1) |
| 70 | body = line[n:] |
| 71 | # replace ignored patterns by spaces |
| 72 | for p in ignores: |
| 73 | while p.search(body) >= 0: |
| 74 | a, b = p.regs[0] |
| 75 | body = body[:a] + ' ' + body[b:] |
Guido van Rossum | 09336f9 | 1994-05-03 14:37:30 +0000 | [diff] [blame] | 76 | stmt = '%s = %s\n' % (name, string.strip(body)) |
| 77 | ok = 0 |
| 78 | try: |
| 79 | exec stmt in env |
| 80 | ok = 1 |
| 81 | except: |
| 82 | sys.stderr.write('Skipping: %s' % stmt) |
| 83 | if ok: |
| 84 | outfp.write(stmt) |
Guido van Rossum | 2ba9f30 | 1992-03-02 16:20:32 +0000 | [diff] [blame] | 85 | |
| 86 | main() |