#! /usr/bin/env python

# Read #define's and translate to Python code.
# Handle #include statements.
# Handle #define macros with one argument.
# Anything that isn't recognized or doesn't translate into valid
# Python is ignored.

# Without filename arguments, acts as a filter.
# 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 Boolean operators "&& || !" into Python "and or not"
# - what to do about #if(def)?
# - what to do about macros with multiple parameters?

import sys, re, getopt, os

p_define = re.compile('^[\t ]*#[\t ]*define[\t ]+([a-zA-Z0-9_]+)[\t ]+')

p_macro = re.compile(
  '^[\t ]*#[\t ]*define[\t ]+'
  '([a-zA-Z0-9_]+)\(([_a-zA-Z][_a-zA-Z0-9]*)\)[\t ]+')

p_include = re.compile('^[\t ]*#[\t ]*include[\t ]+<([a-zA-Z0-9_/\.]+)')

p_comment = re.compile(r'/\*([^*]+|\*+[^/])*(\*+/)?')
p_cpp_comment = re.compile('//.*')

ignores = [p_comment, p_cpp_comment]

p_char = re.compile(r"'(\\.[^\\]*|[^\\])'")

filedict = {}
importable = {}

try:
    searchdirs=os.environ['include'].splitfields(';')
except KeyError:
    try:
        searchdirs=os.environ['INCLUDE'].splitfields(';')
    except KeyError:
        try:
            if  sys.platform.find("beos") == 0:
                searchdirs=os.environ['BEINCLUDES'].splitfields(';')
            else:
                raise KeyError
        except KeyError:
            searchdirs=['/usr/include']

def main():
    global filedict
    opts, args = getopt.getopt(sys.argv[1:], 'i:')
    for o, a in opts:
        if o == '-i':
            ignores.append(re.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 = outfile.rfind('.')
            if i > 0: outfile = outfile[:i]
            modname = outfile.upper()
            outfile = modname + '.py'
            outfp = open(outfile, 'w')
            outfp.write('# Generated by h2py from %s\n' % filename)
            filedict = {}
            for dir in searchdirs:
                if filename[:len(dir)] == dir:
                    filedict[filename[len(dir)+1:]] = None  # no '/' trailing
                    importable[filename[len(dir)+1:]] = modname
                    break
            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
        match = p_define.match(line)
        if match:
            # gobble up continuation lines
            while line[-2:] == '\\\n':
                nextline = fp.readline()
                if not nextline: break
                lineno = lineno + 1
                line = line + nextline
            name = match.group(1)
            body = line[match.end():]
            # replace ignored patterns by spaces
            for p in ignores:
                body = p.sub(' ', body)
            # replace char literals by ord(...)
            body = p_char.sub('ord(\\0)', body)
            stmt = '%s = %s\n' % (name, body.strip())
            ok = 0
            try:
                exec stmt in env
            except:
                sys.stderr.write('Skipping: %s' % stmt)
            else:
                outfp.write(stmt)
        match = p_macro.match(line)
        if match:
            macro, arg = match.group(1, 2)
            body = line[match.end():]
            for p in ignores:
                body = p.sub(' ', body)
            body = p_char.sub('ord(\\0)', body)
            stmt = 'def %s(%s): return %s\n' % (macro, arg, body)
            try:
                exec stmt in env
            except:
                sys.stderr.write('Skipping: %s' % stmt)
            else:
                outfp.write(stmt)
        match = p_include.match(line)
        if match:
            regs = match.regs
            a, b = regs[1]
            filename = line[a:b]
            if importable.has_key(filename):
                outfp.write('from %s import *\n' % importable[filename])
            elif not filedict.has_key(filename):
                filedict[filename] = None
                inclfp = None
                for dir in searchdirs:
                    try:
                        inclfp = open(dir + '/' + filename)
                        break
                    except IOError:
                        pass
                if inclfp:
                    outfp.write(
                            '\n# Included from %s\n' % filename)
                    process(inclfp, outfp, env)
                else:
                    sys.stderr.write('Warning - could not find file %s' % filename)

main()
