symbian-qemu-0.9.1-12/python-2.6.1/Tools/scripts/h2py.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #! /usr/bin/env python
       
     2 
       
     3 # Read #define's and translate to Python code.
       
     4 # Handle #include statements.
       
     5 # Handle #define macros with one argument.
       
     6 # Anything that isn't recognized or doesn't translate into valid
       
     7 # Python is ignored.
       
     8 
       
     9 # Without filename arguments, acts as a filter.
       
    10 # If one or more filenames are given, output is written to corresponding
       
    11 # filenames in the local directory, translated to all uppercase, with
       
    12 # the extension replaced by ".py".
       
    13 
       
    14 # By passing one or more options of the form "-i regular_expression"
       
    15 # you can specify additional strings to be ignored.  This is useful
       
    16 # e.g. to ignore casts to u_long: simply specify "-i '(u_long)'".
       
    17 
       
    18 # XXX To do:
       
    19 # - turn trailing C comments into Python comments
       
    20 # - turn C Boolean operators "&& || !" into Python "and or not"
       
    21 # - what to do about #if(def)?
       
    22 # - what to do about macros with multiple parameters?
       
    23 
       
    24 import sys, re, getopt, os
       
    25 
       
    26 p_define = re.compile('^[\t ]*#[\t ]*define[\t ]+([a-zA-Z0-9_]+)[\t ]+')
       
    27 
       
    28 p_macro = re.compile(
       
    29   '^[\t ]*#[\t ]*define[\t ]+'
       
    30   '([a-zA-Z0-9_]+)\(([_a-zA-Z][_a-zA-Z0-9]*)\)[\t ]+')
       
    31 
       
    32 p_include = re.compile('^[\t ]*#[\t ]*include[\t ]+<([a-zA-Z0-9_/\.]+)')
       
    33 
       
    34 p_comment = re.compile(r'/\*([^*]+|\*+[^/])*(\*+/)?')
       
    35 p_cpp_comment = re.compile('//.*')
       
    36 
       
    37 ignores = [p_comment, p_cpp_comment]
       
    38 
       
    39 p_char = re.compile(r"'(\\.[^\\]*|[^\\])'")
       
    40 
       
    41 p_hex = re.compile(r"0x([0-9a-fA-F]+)L?")
       
    42 
       
    43 filedict = {}
       
    44 importable = {}
       
    45 
       
    46 try:
       
    47     searchdirs=os.environ['include'].split(';')
       
    48 except KeyError:
       
    49     try:
       
    50         searchdirs=os.environ['INCLUDE'].split(';')
       
    51     except KeyError:
       
    52         try:
       
    53             if  sys.platform.find("beos") == 0:
       
    54                 searchdirs=os.environ['BEINCLUDES'].split(';')
       
    55             elif sys.platform.startswith("atheos"):
       
    56                 searchdirs=os.environ['C_INCLUDE_PATH'].split(':')
       
    57             else:
       
    58                 raise KeyError
       
    59         except KeyError:
       
    60             searchdirs=['/usr/include']
       
    61 
       
    62 def main():
       
    63     global filedict
       
    64     opts, args = getopt.getopt(sys.argv[1:], 'i:')
       
    65     for o, a in opts:
       
    66         if o == '-i':
       
    67             ignores.append(re.compile(a))
       
    68     if not args:
       
    69         args = ['-']
       
    70     for filename in args:
       
    71         if filename == '-':
       
    72             sys.stdout.write('# Generated by h2py from stdin\n')
       
    73             process(sys.stdin, sys.stdout)
       
    74         else:
       
    75             fp = open(filename, 'r')
       
    76             outfile = os.path.basename(filename)
       
    77             i = outfile.rfind('.')
       
    78             if i > 0: outfile = outfile[:i]
       
    79             modname = outfile.upper()
       
    80             outfile = modname + '.py'
       
    81             outfp = open(outfile, 'w')
       
    82             outfp.write('# Generated by h2py from %s\n' % filename)
       
    83             filedict = {}
       
    84             for dir in searchdirs:
       
    85                 if filename[:len(dir)] == dir:
       
    86                     filedict[filename[len(dir)+1:]] = None  # no '/' trailing
       
    87                     importable[filename[len(dir)+1:]] = modname
       
    88                     break
       
    89             process(fp, outfp)
       
    90             outfp.close()
       
    91             fp.close()
       
    92 
       
    93 def pytify(body):
       
    94     # replace ignored patterns by spaces
       
    95     for p in ignores:
       
    96         body = p.sub(' ', body)
       
    97     # replace char literals by ord(...)
       
    98     body = p_char.sub('ord(\\0)', body)
       
    99     # Compute negative hexadecimal constants
       
   100     start = 0
       
   101     UMAX = 2*(sys.maxint+1)
       
   102     while 1:
       
   103         m = p_hex.search(body, start)
       
   104         if not m: break
       
   105         s,e = m.span()
       
   106         val = long(body[slice(*m.span(1))], 16)
       
   107         if val > sys.maxint:
       
   108             val -= UMAX
       
   109             body = body[:s] + "(" + str(val) + ")" + body[e:]
       
   110         start = s + 1
       
   111     return body
       
   112 
       
   113 def process(fp, outfp, env = {}):
       
   114     lineno = 0
       
   115     while 1:
       
   116         line = fp.readline()
       
   117         if not line: break
       
   118         lineno = lineno + 1
       
   119         match = p_define.match(line)
       
   120         if match:
       
   121             # gobble up continuation lines
       
   122             while line[-2:] == '\\\n':
       
   123                 nextline = fp.readline()
       
   124                 if not nextline: break
       
   125                 lineno = lineno + 1
       
   126                 line = line + nextline
       
   127             name = match.group(1)
       
   128             body = line[match.end():]
       
   129             body = pytify(body)
       
   130             ok = 0
       
   131             stmt = '%s = %s\n' % (name, body.strip())
       
   132             try:
       
   133                 exec stmt in env
       
   134             except:
       
   135                 sys.stderr.write('Skipping: %s' % stmt)
       
   136             else:
       
   137                 outfp.write(stmt)
       
   138         match = p_macro.match(line)
       
   139         if match:
       
   140             macro, arg = match.group(1, 2)
       
   141             body = line[match.end():]
       
   142             body = pytify(body)
       
   143             stmt = 'def %s(%s): return %s\n' % (macro, arg, body)
       
   144             try:
       
   145                 exec stmt in env
       
   146             except:
       
   147                 sys.stderr.write('Skipping: %s' % stmt)
       
   148             else:
       
   149                 outfp.write(stmt)
       
   150         match = p_include.match(line)
       
   151         if match:
       
   152             regs = match.regs
       
   153             a, b = regs[1]
       
   154             filename = line[a:b]
       
   155             if importable.has_key(filename):
       
   156                 outfp.write('from %s import *\n' % importable[filename])
       
   157             elif not filedict.has_key(filename):
       
   158                 filedict[filename] = None
       
   159                 inclfp = None
       
   160                 for dir in searchdirs:
       
   161                     try:
       
   162                         inclfp = open(dir + '/' + filename)
       
   163                         break
       
   164                     except IOError:
       
   165                         pass
       
   166                 if inclfp:
       
   167                     outfp.write(
       
   168                             '\n# Included from %s\n' % filename)
       
   169                     process(inclfp, outfp, env)
       
   170                 else:
       
   171                     sys.stderr.write('Warning - could not find file %s\n' %
       
   172                                      filename)
       
   173 
       
   174 if __name__ == '__main__':
       
   175     main()