mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 18:28:49 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			113 lines
		
	
	
	
		
			3.1 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			113 lines
		
	
	
	
		
			3.1 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
 | |
| import string
 | |
| 
 | |
| 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 = string.strip(line)
 | |
| 		if tmp[:1] != '#':
 | |
| 			if ok: fpo.write(line)
 | |
| 			continue
 | |
| 		tmp = string.strip(tmp[1:])
 | |
| 		words = string.split(tmp)
 | |
| 		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()
 | 
