Bump copyright date to 2019
[tor.git] / scripts / maint / annotate_ifdef_directives
blobca267a865e732d39bba12ee5cccaf54eb23b2928
1 #!/usr/bin/python
2 # Copyright (c) 2017-2019, The Tor Project, Inc.
3 # See LICENSE for licensing information
5 import re
7 LINE_OBVIOUSNESS_LIMIT = 4
9 class Problem(Exception):
10 pass
12 def uncomment(s):
13 s = re.sub(r'//.*','',s)
14 s = re.sub(r'/\*.*','',s)
15 return s.strip()
17 def translate(f_in, f_out):
18 whole_file = []
19 stack = []
20 cur_level = whole_file
21 lineno = 0
22 for line in f_in:
23 lineno += 1
24 m = re.match(r'\s*#\s*(if|ifdef|ifndef|else|endif|elif)\b\s*(.*)',
25 line)
26 if not m:
27 f_out.write(line)
28 continue
29 command,rest = m.groups()
30 if command in ("if", "ifdef", "ifndef"):
31 # The #if directive pushes us one level lower on the stack.
32 if command == 'ifdef':
33 rest = "defined(%s)"%uncomment(rest)
34 elif command == 'ifndef':
35 rest = "!defined(%s)"%uncomment(rest)
36 elif rest.endswith("\\"):
37 rest = rest[:-1]+"..."
39 rest = uncomment(rest)
41 new_level = [ (command, rest, lineno) ]
42 stack.append(cur_level)
43 cur_level = new_level
44 f_out.write(line)
45 elif command in ("else", "elif"):
46 if len(cur_level) == 0 or cur_level[-1][0] == 'else':
47 raise Problem("Unexpected #%s on %d"% (command,lineno))
48 if (len(cur_level) == 1 and command == 'else' and
49 lineno > cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT):
50 f_out.write("#else /* !(%s) */\n"%cur_level[0][1])
51 else:
52 f_out.write(line)
53 cur_level.append((command, rest, lineno))
54 else:
55 assert command == 'endif'
56 if len(stack) == 0:
57 raise Problem("Unmatched #%s on %s"% (command,lineno))
58 if lineno <= cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT:
59 f_out.write(line)
60 elif len(cur_level) == 1 or (
61 len(cur_level) == 2 and cur_level[1][0] == 'else'):
62 f_out.write("#endif /* %s */\n"%cur_level[0][1])
63 else:
64 f_out.write("#endif /* %s || ... */\n"%cur_level[0][1])
65 cur_level = stack.pop()
66 if len(stack) or cur_level != whole_file:
67 raise Problem("Missing #endif")
69 import sys,os
70 for fn in sys.argv[1:]:
71 with open(fn+"_OUT", 'w') as output_file:
72 translate(open(fn, 'r'), output_file)
73 os.rename(fn+"_OUT", fn)