aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2019-09-18 10:59:35 -0400
committerNick Mathewson <nickm@torproject.org>2019-09-26 15:52:45 -0400
commit65e63e746120a03b54de51f1db148a7fa1aa27e2 (patch)
tree975fa4a798e79ae4fabae4e14b98ba1b2c1d8018
parent16890839d35e9ac270e32934a232b45de9e8544b (diff)
downloadtor-65e63e746120a03b54de51f1db148a7fa1aa27e2.tar.gz
tor-65e63e746120a03b54de51f1db148a7fa1aa27e2.zip
annotate_ifdef_directives: remove some cases of double negation
This change should reduce the number of cases where we say "/* !(!defined(foo)) */" . This only does cases where we can use a regex to make sure that the simplification is guaranteed to be correct. Full boolean simplification would require this script to parse C, and nobody wants that.
-rwxr-xr-xscripts/maint/annotate_ifdef_directives44
1 files changed, 42 insertions, 2 deletions
diff --git a/scripts/maint/annotate_ifdef_directives b/scripts/maint/annotate_ifdef_directives
index b784ca71ba..4463d83828 100755
--- a/scripts/maint/annotate_ifdef_directives
+++ b/scripts/maint/annotate_ifdef_directives
@@ -54,6 +54,46 @@ def commented_line(fmt, argument, maxwidth=LINE_WIDTH):
assert len(result) <= maxwidth
return result
+def negate(expr):
+ """Return a negated version of expr; try to avoid double-negation.
+
+ We usually wrap expressions in parentheses and add a "!".
+ >>> negate("A && B")
+ '!(A && B)'
+
+ But if we recognize the expression as negated, we can restore it.
+ >>> negate(negate("A && B"))
+ 'A && B'
+
+ The same applies for defined(FOO).
+ >>> negate("defined(FOO)")
+ '!defined(FOO)'
+ >>> negate(negate("defined(FOO)"))
+ 'defined(FOO)'
+
+ Internal parentheses don't confuse us:
+ >>> negate("!(FOO) && !(BAR)")
+ '!(!(FOO) && !(BAR))'
+
+ """
+ expr = expr.strip()
+ # See whether we match !(...), with no intervening close-parens.
+ m = re.match(r'^!\s*\(([^\)]*)\)$', expr)
+ if m:
+ return m.group(1)
+
+
+ # See whether we match !?defined(...), with no intervening close-parens.
+ m = re.match(r'^(!?)\s*(defined\([^\)]*\))$', expr)
+ if m:
+ if m.group(1) == "!":
+ prefix = ""
+ else:
+ prefix = "!"
+ return prefix + m.group(2)
+
+ return "!(%s)" % expr
+
def uncomment(s):
"""
Remove existing trailing comments from an #else or #endif line.
@@ -108,8 +148,8 @@ def translate(f_in, f_out):
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(commented_line("#else /* !(%s) */\n",
- cur_level[0][1]))
+ f_out.write(commented_line("#else /* %s */\n",
+ negate(cur_level[0][1])))
else:
f_out.write(line)
cur_level.append((command, rest, lineno))