[tor-commits] [tor/master] annotate_ifdef_directives: remove some cases of double negation

asn at torproject.org asn at torproject.org
Mon Sep 30 10:45:36 UTC 2019


commit 65e63e746120a03b54de51f1db148a7fa1aa27e2
Author: Nick Mathewson <nickm at torproject.org>
Date:   Wed Sep 18 10:59:35 2019 -0400

    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.
---
 scripts/maint/annotate_ifdef_directives | 44 +++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

diff --git a/scripts/maint/annotate_ifdef_directives b/scripts/maint/annotate_ifdef_directives
index b784ca71b..4463d8382 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))





More information about the tor-commits mailing list