| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 | 
							- #!/usr/bin/python
 
- # Copyright (c) 2017, The Tor Project, Inc.
 
- # See LICENSE for licensing information
 
- import re
 
- LINE_OBVIOUSNESS_LIMIT = 4
 
- class Problem(Exception):
 
-     pass
 
- def uncomment(s):
 
-     s = re.sub(r'//.*','',s)
 
-     s = re.sub(r'/\*.*','',s)
 
-     return s.strip()
 
- def translate(f_in, f_out):
 
-     whole_file = []
 
-     stack = []
 
-     cur_level = whole_file
 
-     lineno = 0
 
-     for line in f_in:
 
-         lineno += 1
 
-         m = re.match(r'\s*#\s*(if|ifdef|ifndef|else|endif|elif)\b\s*(.*)',
 
-                      line)
 
-         if not m:
 
-             f_out.write(line)
 
-             continue
 
-         command,rest = m.groups()
 
-         if command in ("if", "ifdef", "ifndef"):
 
-             # The #if directive pushes us one level lower on the stack.
 
-             if command == 'ifdef':
 
-                 rest = "defined(%s)"%uncomment(rest)
 
-             elif command == 'ifndef':
 
-                 rest = "!defined(%s)"%uncomment(rest)
 
-             elif rest.endswith("\\"):
 
-                 rest = rest[:-1]+"..."
 
-             rest = uncomment(rest)
 
-             new_level = [ (command, rest, lineno) ]
 
-             stack.append(cur_level)
 
-             cur_level = new_level
 
-             f_out.write(line)
 
-         elif command in ("else", "elif"):
 
-             if len(cur_level) == 0 or cur_level[-1][0] == 'else':
 
-                 raise Problem("Unexpected #%s on %d"% (command,lineno))
 
-             if (len(cur_level) == 1 and command == 'else' and
 
-                 lineno > cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT):
 
-                 f_out.write("#else /* !(%s) */\n"%cur_level[0][1])
 
-             else:
 
-                 f_out.write(line)
 
-             cur_level.append((command, rest, lineno))
 
-         else:
 
-             assert command == 'endif'
 
-             if len(stack) == 0:
 
-                 raise Problem("Unmatched #%s on %s"% (command,lineno))
 
-             if lineno <= cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT:
 
-                 f_out.write(line)
 
-             elif len(cur_level) == 1 or (
 
-                     len(cur_level) == 2 and cur_level[1][0] == 'else'):
 
-                 f_out.write("#endif /* %s */\n"%cur_level[0][1])
 
-             else:
 
-                 f_out.write("#endif /* %s || ... */\n"%cur_level[0][1])
 
-             cur_level = stack.pop()
 
-     if len(stack) or cur_level != whole_file:
 
-         raise Problem("Missing #endif")
 
- import sys,os
 
- for fn in sys.argv[1:]:
 
-     with open(fn+"_OUT", 'w') as output_file:
 
-         translate(open(fn, 'r'), output_file)
 
-     os.rename(fn+"_OUT", fn)
 
 
  |