Loading scripts/maint/annotate_ifdef_directives +94 −21 Original line number Diff line number Diff line Loading @@ -2,24 +2,60 @@ # Copyright (c) 2017-2019, The Tor Project, Inc. # See LICENSE for licensing information # This script iterates over a list of C files. For each file, it looks at the # #if/#else C macros, and annotates them with comments explaining what they # match. # # For example, it replaces this: # # #ifdef HAVE_OCELOT # // 500 lines of ocelot code # #endif # # with this: # # #ifdef HAVE_OCELOT # // 500 lines of ocelot code # #endif /* defined(HAVE_OCELOT) */ # # Note that only #else and #endif lines are annotated. Existing comments # on those lines are removed. r""" This script iterates over a list of C files. For each file, it looks at the #if/#else C macros, and annotates them with comments explaining what they match. For example, it replaces this kind of input... >>> INPUT = ''' ... #ifdef HAVE_OCELOT ... C code here ... #if MIMSY == BOROGROVE ... block 1 ... block 1 ... block 1 ... block 1 ... #else ... block 2 ... block 2 ... block 2 ... block 2 ... #endif ... #endif ... ''' With this kind of output: >>> EXPECTED_OUTPUT = ''' ... #ifdef HAVE_OCELOT ... C code here ... #if MIMSY == BOROGROVE ... block 1 ... block 1 ... block 1 ... block 1 ... #else /* !(MIMSY == BOROGROVE) */ ... block 2 ... block 2 ... block 2 ... block 2 ... #endif /* MIMSY == BOROGROVE */ ... #endif /* defined(HAVE_OCELOT) */ ... ''' Here's how to use it: >>> import sys >>> if sys.version_info.major < 3: from cStringIO import StringIO >>> if sys.version_info.major >= 3: from io import StringIO >>> OUTPUT = StringIO() >>> translate(StringIO(INPUT), OUTPUT) >>> assert OUTPUT.getvalue() == EXPECTED_OUTPUT Note that only #else and #endif lines are annotated. Existing comments on those lines are removed. """ import re Loading @@ -38,6 +74,17 @@ class Problem(Exception): def close_parens_needed(expr): """Return the number of left-parentheses needed to make 'expr' balanced. >>> close_parens_needed("1+2") 0 >>> close_parens_needed("(1 + 2)") 0 >>> close_parens_needed("(1 + 2") 1 >>> close_parens_needed("(1 + (2 *") 2 >>> close_parens_needed("(1 + (2 * 3) + (4") 2 """ return expr.count("(") - expr.count(")") Loading @@ -47,6 +94,17 @@ def truncate_expression(expr, new_width): characters long. Try to return an expression with balanced parentheses. >>> truncate_expression("1+2+3", 8) '1+2+3' >>> truncate_expression("1+2+3+4+5", 8) '1+2+3...' >>> truncate_expression("(1+2+3+4)", 8) '(1+2...)' >>> truncate_expression("(1+(2+3+4))", 8) '(1+...)' >>> truncate_expression("(((((((((", 8) '((...))' """ if len(expr) <= new_width: # The expression is already short enough. Loading @@ -69,14 +127,23 @@ def truncate_expression(expr, new_width): return ellipsis def commented_line(fmt, argument, maxwidth=LINE_WIDTH): """ # (This is a raw docstring so that our doctests can use \.) r""" Return fmt%argument, for use as a commented line. If the line would be longer than maxwidth, truncate argument. be longer than maxwidth, truncate argument but try to keep its parentheses balanced. Requires that fmt%"..." will fit into maxwidth characters. Requires that fmt ends with a newline. >>> commented_line("/* %s */\n", "hello world", 32) '/* hello world */\n' >>> commented_line("/* %s */\n", "hello world", 15) '/* hello... */\n' >>> commented_line("#endif /* %s */\n", "((1+2) && defined(FOO))", 32) '#endif /* ((1+2) && defi...) */\n' """ assert fmt.endswith("\n") result = fmt % argument Loading Loading @@ -208,6 +275,12 @@ def translate(f_in, f_out): raise Problem("Missing #endif") import sys,os if sys.argv[1] == "--self-test": import doctest doctest.testmod() sys.exit(0) for fn in sys.argv[1:]: with open(fn+"_OUT", 'w') as output_file: translate(open(fn, 'r'), output_file) Loading Loading
scripts/maint/annotate_ifdef_directives +94 −21 Original line number Diff line number Diff line Loading @@ -2,24 +2,60 @@ # Copyright (c) 2017-2019, The Tor Project, Inc. # See LICENSE for licensing information # This script iterates over a list of C files. For each file, it looks at the # #if/#else C macros, and annotates them with comments explaining what they # match. # # For example, it replaces this: # # #ifdef HAVE_OCELOT # // 500 lines of ocelot code # #endif # # with this: # # #ifdef HAVE_OCELOT # // 500 lines of ocelot code # #endif /* defined(HAVE_OCELOT) */ # # Note that only #else and #endif lines are annotated. Existing comments # on those lines are removed. r""" This script iterates over a list of C files. For each file, it looks at the #if/#else C macros, and annotates them with comments explaining what they match. For example, it replaces this kind of input... >>> INPUT = ''' ... #ifdef HAVE_OCELOT ... C code here ... #if MIMSY == BOROGROVE ... block 1 ... block 1 ... block 1 ... block 1 ... #else ... block 2 ... block 2 ... block 2 ... block 2 ... #endif ... #endif ... ''' With this kind of output: >>> EXPECTED_OUTPUT = ''' ... #ifdef HAVE_OCELOT ... C code here ... #if MIMSY == BOROGROVE ... block 1 ... block 1 ... block 1 ... block 1 ... #else /* !(MIMSY == BOROGROVE) */ ... block 2 ... block 2 ... block 2 ... block 2 ... #endif /* MIMSY == BOROGROVE */ ... #endif /* defined(HAVE_OCELOT) */ ... ''' Here's how to use it: >>> import sys >>> if sys.version_info.major < 3: from cStringIO import StringIO >>> if sys.version_info.major >= 3: from io import StringIO >>> OUTPUT = StringIO() >>> translate(StringIO(INPUT), OUTPUT) >>> assert OUTPUT.getvalue() == EXPECTED_OUTPUT Note that only #else and #endif lines are annotated. Existing comments on those lines are removed. """ import re Loading @@ -38,6 +74,17 @@ class Problem(Exception): def close_parens_needed(expr): """Return the number of left-parentheses needed to make 'expr' balanced. >>> close_parens_needed("1+2") 0 >>> close_parens_needed("(1 + 2)") 0 >>> close_parens_needed("(1 + 2") 1 >>> close_parens_needed("(1 + (2 *") 2 >>> close_parens_needed("(1 + (2 * 3) + (4") 2 """ return expr.count("(") - expr.count(")") Loading @@ -47,6 +94,17 @@ def truncate_expression(expr, new_width): characters long. Try to return an expression with balanced parentheses. >>> truncate_expression("1+2+3", 8) '1+2+3' >>> truncate_expression("1+2+3+4+5", 8) '1+2+3...' >>> truncate_expression("(1+2+3+4)", 8) '(1+2...)' >>> truncate_expression("(1+(2+3+4))", 8) '(1+...)' >>> truncate_expression("(((((((((", 8) '((...))' """ if len(expr) <= new_width: # The expression is already short enough. Loading @@ -69,14 +127,23 @@ def truncate_expression(expr, new_width): return ellipsis def commented_line(fmt, argument, maxwidth=LINE_WIDTH): """ # (This is a raw docstring so that our doctests can use \.) r""" Return fmt%argument, for use as a commented line. If the line would be longer than maxwidth, truncate argument. be longer than maxwidth, truncate argument but try to keep its parentheses balanced. Requires that fmt%"..." will fit into maxwidth characters. Requires that fmt ends with a newline. >>> commented_line("/* %s */\n", "hello world", 32) '/* hello world */\n' >>> commented_line("/* %s */\n", "hello world", 15) '/* hello... */\n' >>> commented_line("#endif /* %s */\n", "((1+2) && defined(FOO))", 32) '#endif /* ((1+2) && defi...) */\n' """ assert fmt.endswith("\n") result = fmt % argument Loading Loading @@ -208,6 +275,12 @@ def translate(f_in, f_out): raise Problem("Missing #endif") import sys,os if sys.argv[1] == "--self-test": import doctest doctest.testmod() sys.exit(0) for fn in sys.argv[1:]: with open(fn+"_OUT", 'w') as output_file: translate(open(fn, 'r'), output_file) Loading