ยปCore Development>Code coverage>Tools/scripts/ifdef.py

Python code coverage for Tools/scripts/ifdef.py

#countcontent
1n/a#! /usr/bin/env python3
2n/a
3n/a# Selectively preprocess #ifdef / #ifndef statements.
4n/a# Usage:
5n/a# ifdef [-Dname] ... [-Uname] ... [file] ...
6n/a#
7n/a# This scans the file(s), looking for #ifdef and #ifndef preprocessor
8n/a# commands that test for one of the names mentioned in the -D and -U
9n/a# options. On standard output it writes a copy of the input file(s)
10n/a# minus those code sections that are suppressed by the selected
11n/a# combination of defined/undefined symbols. The #if(n)def/#else/#else
12n/a# lines themselves (if the #if(n)def tests for one of the mentioned
13n/a# names) are removed as well.
14n/a
15n/a# Features: Arbitrary nesting of recognized and unrecognized
16n/a# preprocessor statements works correctly. Unrecognized #if* commands
17n/a# are left in place, so it will never remove too much, only too
18n/a# little. It does accept whitespace around the '#' character.
19n/a
20n/a# Restrictions: There should be no comments or other symbols on the
21n/a# #if(n)def lines. The effect of #define/#undef commands in the input
22n/a# file or in included files is not taken into account. Tests using
23n/a# #if and the defined() pseudo function are not recognized. The #elif
24n/a# command is not recognized. Improperly nesting is not detected.
25n/a# Lines that look like preprocessor commands but which are actually
26n/a# part of comments or string literals will be mistaken for
27n/a# preprocessor commands.
28n/a
29n/aimport sys
30n/aimport getopt
31n/a
32n/adefs = []
33n/aundefs = []
34n/a
35n/adef main():
36n/a opts, args = getopt.getopt(sys.argv[1:], 'D:U:')
37n/a for o, a in opts:
38n/a if o == '-D':
39n/a defs.append(a)
40n/a if o == '-U':
41n/a undefs.append(a)
42n/a if not args:
43n/a args = ['-']
44n/a for filename in args:
45n/a if filename == '-':
46n/a process(sys.stdin, sys.stdout)
47n/a else:
48n/a f = open(filename, 'r')
49n/a process(f, sys.stdout)
50n/a f.close()
51n/a
52n/adef process(fpi, fpo):
53n/a keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif')
54n/a ok = 1
55n/a stack = []
56n/a while 1:
57n/a line = fpi.readline()
58n/a if not line: break
59n/a while line[-2:] == '\\\n':
60n/a nextline = fpi.readline()
61n/a if not nextline: break
62n/a line = line + nextline
63n/a tmp = line.strip()
64n/a if tmp[:1] != '#':
65n/a if ok: fpo.write(line)
66n/a continue
67n/a tmp = tmp[1:].strip()
68n/a words = tmp.split()
69n/a keyword = words[0]
70n/a if keyword not in keywords:
71n/a if ok: fpo.write(line)
72n/a continue
73n/a if keyword in ('ifdef', 'ifndef') and len(words) == 2:
74n/a if keyword == 'ifdef':
75n/a ko = 1
76n/a else:
77n/a ko = 0
78n/a word = words[1]
79n/a if word in defs:
80n/a stack.append((ok, ko, word))
81n/a if not ko: ok = 0
82n/a elif word in undefs:
83n/a stack.append((ok, not ko, word))
84n/a if ko: ok = 0
85n/a else:
86n/a stack.append((ok, -1, word))
87n/a if ok: fpo.write(line)
88n/a elif keyword == 'if':
89n/a stack.append((ok, -1, ''))
90n/a if ok: fpo.write(line)
91n/a elif keyword == 'else' and stack:
92n/a s_ok, s_ko, s_word = stack[-1]
93n/a if s_ko < 0:
94n/a if ok: fpo.write(line)
95n/a else:
96n/a s_ko = not s_ko
97n/a ok = s_ok
98n/a if not s_ko: ok = 0
99n/a stack[-1] = s_ok, s_ko, s_word
100n/a elif keyword == 'endif' and stack:
101n/a s_ok, s_ko, s_word = stack[-1]
102n/a if s_ko < 0:
103n/a if ok: fpo.write(line)
104n/a del stack[-1]
105n/a ok = s_ok
106n/a else:
107n/a sys.stderr.write('Unknown keyword %s\n' % keyword)
108n/a if stack:
109n/a sys.stderr.write('stack: %s\n' % stack)
110n/a
111n/aif __name__ == '__main__':
112n/a main()