summaryrefslogtreecommitdiff
path: root/Tools/scripts/h2py.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1994-10-03 16:45:35 +0000
committerGuido van Rossum <guido@python.org>1994-10-03 16:45:35 +0000
commitcb2863d4ae921dc94f5a18d8f2aa584f4acb69ab (patch)
tree19c3dd058dd44ef809abd5903a4775740ade54ba /Tools/scripts/h2py.py
parent77332c005cb032452bfd8bf09b0177a5e1c519ad (diff)
downloadcpython-cb2863d4ae921dc94f5a18d8f2aa584f4acb69ab.tar.gz
Get rid of freeze (now its own directory).
Added some new demos. Fixed a few others.
Diffstat (limited to 'Tools/scripts/h2py.py')
-rwxr-xr-xTools/scripts/h2py.py80
1 files changed, 58 insertions, 22 deletions
diff --git a/Tools/scripts/h2py.py b/Tools/scripts/h2py.py
index 3d7a8516c8..db0dbd826a 100755
--- a/Tools/scripts/h2py.py
+++ b/Tools/scripts/h2py.py
@@ -1,32 +1,43 @@
#! /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.
+# 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 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
+# - what to do about macros with multiple parameters?
-import sys, regex, string, getopt, os
+import sys, regex, regsub, string, getopt, os
p_define = regex.compile('^#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)[\t ]+')
+p_macro = regex.compile(
+ '^#[\t ]*define[\t ]+\([a-zA-Z0-9_]+\)(\([_a-zA-Z][_a-zA-Z0-9]*\))[\t ]+')
+
+p_include = regex.compile('^#[\t ]*include[\t ]+<\([a-zA-Z0-9_/\.]+\)')
+
p_comment = regex.compile('/\*\([^*]+\|\*+[^/]\)*\(\*+/\)?')
ignores = [p_comment]
+p_char = regex.compile("'\(\\\\.[^\\\\]*\|[^\\\\]\)'")
+
+filedict = {}
+
def main():
opts, args = getopt.getopt(sys.argv[1:], 'i:')
for o, a in opts:
@@ -47,40 +58,65 @@ def main():
outfile = outfile + '.py'
outfp = open(outfile, 'w')
outfp.write('# Generated by h2py from %s\n' % filename)
+ filedict = {}
+ if filename[:13] == '/usr/include/':
+ filedict[filename[13:]] = None
process(fp, outfp)
outfp.close()
fp.close()
-def process(fp, outfp):
- env = {}
+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:
+ # gobble up continuation lines
+ while line[-2:] == '\\\n':
+ nextline = fp.readline()
+ if not nextline: break
+ lineno = lineno + 1
+ line = line + nextline
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:]
+ body = regsub.gsub(p, ' ', body)
+ # replace char literals by ord(...)
+ body = regsub.gsub(p_char, 'ord(\\0)', body)
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:
+ else:
outfp.write(stmt)
-
+ n =p_macro.match(line)
+ if n >= 0:
+ macro, arg = p_macro.group(1, 2)
+ body = line[n:]
+ for p in ignores:
+ body = regsub.gsub(p, ' ', body)
+ body = regsub.gsub(p_char, '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)
+ if p_include.match(line) >= 0:
+ regs = p_include.regs
+ a, b = regs[1]
+ filename = line[a:b]
+ if not filedict.has_key(filename):
+ filedict[filename] = None
+ outfp.write(
+ '\n# Included from %s\n' % filename)
+ inclfp = open('/usr/include/' + filename, 'r')
+ process(inclfp, outfp, env)
main()
+