mirror of
https://github.com/python/cpython.git
synced 2024-12-01 11:15:56 +01:00
aaab30e00c
(with one small bugfix in bgen/bgen/scantools.py) This replaces string module functions with string methods for the stuff in the Tools directory. Several uses of string.letters etc. are still remaining.
113 lines
3.6 KiB
Python
Executable File
113 lines
3.6 KiB
Python
Executable File
#! /usr/bin/env python
|
|
|
|
# Selectively preprocess #ifdef / #ifndef statements.
|
|
# Usage:
|
|
# ifdef [-Dname] ... [-Uname] ... [file] ...
|
|
#
|
|
# This scans the file(s), looking for #ifdef and #ifndef preprocessor
|
|
# commands that test for one of the names mentioned in the -D and -U
|
|
# options. On standard output it writes a copy of the input file(s)
|
|
# minus those code sections that are suppressed by the selected
|
|
# combination of defined/undefined symbols. The #if(n)def/#else/#else
|
|
# lines themselfs (if the #if(n)def tests for one of the mentioned
|
|
# names) are removed as well.
|
|
|
|
# Features: Arbitrary nesting of recognized and unrecognized
|
|
# preprocesor statements works correctly. Unrecognized #if* commands
|
|
# are left in place, so it will never remove too much, only too
|
|
# little. It does accept whitespace around the '#' character.
|
|
|
|
# Restrictions: There should be no comments or other symbols on the
|
|
# #if(n)def lines. The effect of #define/#undef commands in the input
|
|
# file or in included files is not taken into account. Tests using
|
|
# #if and the defined() pseudo function are not recognized. The #elif
|
|
# command is not recognized. Improperly nesting is not detected.
|
|
# Lines that look like preprocessor commands but which are actually
|
|
# part of comments or string literals will be mistaken for
|
|
# preprocessor commands.
|
|
|
|
import sys
|
|
import regex
|
|
import getopt
|
|
|
|
defs = []
|
|
undefs = []
|
|
|
|
def main():
|
|
opts, args = getopt.getopt(sys.argv[1:], 'D:U:')
|
|
for o, a in opts:
|
|
if o == '-D':
|
|
defs.append(a)
|
|
if o == '-U':
|
|
undefs.append(a)
|
|
if not args:
|
|
args = ['-']
|
|
for file in args:
|
|
if file == '-':
|
|
process(sys.stdin, sys.stdout)
|
|
else:
|
|
f = open(file, 'r')
|
|
process(f, sys.stdout)
|
|
f.close()
|
|
|
|
def process(fpi, fpo):
|
|
keywords = ('if', 'ifdef', 'ifndef', 'else', 'endif')
|
|
ok = 1
|
|
stack = []
|
|
while 1:
|
|
line = fpi.readline()
|
|
if not line: break
|
|
while line[-2:] == '\\\n':
|
|
nextline = fpi.readline()
|
|
if not nextline: break
|
|
line = line + nextline
|
|
tmp = line.strip()
|
|
if tmp[:1] != '#':
|
|
if ok: fpo.write(line)
|
|
continue
|
|
tmp = tmp[1:].strip()
|
|
words = tmp.split()
|
|
keyword = words[0]
|
|
if keyword not in keywords:
|
|
if ok: fpo.write(line)
|
|
continue
|
|
if keyword in ('ifdef', 'ifndef') and len(words) == 2:
|
|
if keyword == 'ifdef':
|
|
ko = 1
|
|
else:
|
|
ko = 0
|
|
word = words[1]
|
|
if word in defs:
|
|
stack.append((ok, ko, word))
|
|
if not ko: ok = 0
|
|
elif word in undefs:
|
|
stack.append((ok, not ko, word))
|
|
if ko: ok = 0
|
|
else:
|
|
stack.append((ok, -1, word))
|
|
if ok: fpo.write(line)
|
|
elif keyword == 'if':
|
|
stack.append((ok, -1, ''))
|
|
if ok: fpo.write(line)
|
|
elif keyword == 'else' and stack:
|
|
s_ok, s_ko, s_word = stack[-1]
|
|
if s_ko < 0:
|
|
if ok: fpo.write(line)
|
|
else:
|
|
s_ko = not s_ko
|
|
ok = s_ok
|
|
if not s_ko: ok = 0
|
|
stack[-1] = s_ok, s_ko, s_word
|
|
elif keyword == 'endif' and stack:
|
|
s_ok, s_ko, s_word = stack[-1]
|
|
if s_ko < 0:
|
|
if ok: fpo.write(line)
|
|
del stack[-1]
|
|
ok = s_ok
|
|
else:
|
|
sys.stderr.write('Unknown keyword %s\n' % keyword)
|
|
if stack:
|
|
sys.stderr.write('stack: %s\n' % stack)
|
|
|
|
main()
|