| #! /usr/local/bin/python |
| |
| # Read #define's from stdin and translate to Python code on stdout. |
| # Very primitive: non-#define's are ignored, as is anything that isn't |
| # valid Python as it stands. |
| # If one or more filenames are given, output is written to corresponding |
| # filenames in the local directory, translated to all uppercase, with |
| # the extension replaced by ".py". |
| # By passing one or more options of the form "-i regular_expression" |
| # you can specify additional strings to be ignored. This is useful |
| # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'". |
| |
| # XXX To do: |
| # - turn trailing C comments into Python comments |
| # - turn C string quotes into Python comments |
| # - turn C Boolean operators "&& || !" into Python "and or not" |
| # - what to do about #if(def)? |
| # - what to do about #include? |
| # - what to do about macros with parameters? |
| # - reject definitions with semicolons in them |
| |
| import sys, regex, string, getopt, os |
| |
| p_define = regex.compile('^#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+') |
| |
| p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?') |
| |
| ignores = [p_comment] |
| |
| def main(): |
| opts, args = getopt.getopt(sys.argv[1:], 'i:') |
| for o, a in opts: |
| if o == '-i': |
| ignores.append(regex.compile(a)) |
| if not args: |
| args = ['-'] |
| for filename in args: |
| if filename == '-': |
| sys.stdout.write('# Generated by h2py from stdin\n') |
| process(sys.stdin, sys.stdout) |
| else: |
| fp = open(filename, 'r') |
| outfile = os.path.basename(filename) |
| i = string.rfind(outfile, '.') |
| if i > 0: outfile = outfile[:i] |
| outfile = string.upper(outfile) |
| outfile = outfile + '.py' |
| outfp = open(outfile, 'w') |
| outfp.write('# Generated by h2py from %s\n' % filename) |
| process(fp, outfp) |
| outfp.close() |
| fp.close() |
| |
| def process(fp, outfp): |
| env = {} |
| lineno = 0 |
| while 1: |
| line = fp.readline() |
| if not line: break |
| lineno = lineno + 1 |
| # gobble up continuation lines |
| while line[-2:] == '\\\n': |
| nextline = fp.readline() |
| if not nextline: break |
| lineno = lineno + 1 |
| line = line + nextline |
| n = p_define.match(line) |
| if n >= 0: |
| name = p_define.group(1) |
| body = line[n:] |
| # replace ignored patterns by spaces |
| for p in ignores: |
| while p.search(body) >= 0: |
| a, b = p.regs[0] |
| body = body[:a] + ' ' + body[b:] |
| stmt = '%s = %s\n' % (name, string.strip(body)) |
| ok = 0 |
| try: |
| exec stmt in env |
| ok = 1 |
| except: |
| sys.stderr.write('Skipping: %s' % stmt) |
| if ok: |
| outfp.write(stmt) |
| |
| main() |