Browse Source

Merge branch 'annotate_ifdefs'

Nick Mathewson 6 years ago
parent
commit
5d06bbc66f
1 changed files with 74 additions and 0 deletions
  1. 74 0
      scripts/maint/annotate_ifdef_directives

+ 74 - 0
scripts/maint/annotate_ifdef_directives

@@ -0,0 +1,74 @@
+#!/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)
+