mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			112 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#! /usr/bin/env python3
 | 
						|
 | 
						|
# 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 themselves (if the #if(n)def tests for one of the mentioned
 | 
						|
# names) are removed as well.
 | 
						|
 | 
						|
# Features: Arbitrary nesting of recognized and unrecognized
 | 
						|
# preprocessor 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 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 filename in args:
 | 
						|
        if filename == '-':
 | 
						|
            process(sys.stdin, sys.stdout)
 | 
						|
        else:
 | 
						|
            f = open(filename, '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)
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
    main()
 |