Skip to content
Permalink
Browse files
fixup! annotate_ifdef_directives: remove some cases of double negation
Fix our logic for removing double negation, thanks to tests added
later in the branch.
  • Loading branch information
nmathewson committed Sep 26, 2019
1 parent 0cce8c7 commit 704c23ca01e58fa8ba60c9a453475b404c5d2d0d
Showing with 31 additions and 5 deletions.
  1. +31 −5 scripts/maint/annotate_ifdef_directives
@@ -55,16 +55,42 @@ def commented_line(fmt, argument, maxwidth=LINE_WIDTH):
return result

def negate(expr):
"""Return a negated version of expr; try to avoid double-negation."""
"""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)
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)


# See whether we match !?defined(...), with no intervening close-parens.
m = re.match(r'^(!?)\s*(defined\([^\)]*\))$', expr)
if m:
return m.group(1)
if m.group(1) == "!":
prefix = ""
else:
prefix = "!"
return prefix + m.group(2)

return "!(%s)" % expr

0 comments on commit 704c23c

Please sign in to comment.