| 
									
										
										
										
											1996-11-27 19:52:01 +00:00
										 |  |  | #! /usr/bin/env python | 
					
						
							| 
									
										
										
										
											1994-05-09 14:52:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | # 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: | 
					
						
							| 
									
										
										
										
											1998-10-08 15:24:48 +00:00
										 |  |  | 				stack.append((ok, ko, word)) | 
					
						
							| 
									
										
										
										
											1994-05-09 14:52:41 +00:00
										 |  |  | 				if not ko: ok = 0 | 
					
						
							|  |  |  | 			elif word in undefs: | 
					
						
							| 
									
										
										
										
											1998-10-08 15:24:48 +00:00
										 |  |  | 				stack.append((ok, not ko, word)) | 
					
						
							| 
									
										
										
										
											1994-05-09 14:52:41 +00:00
										 |  |  | 				if ko: ok = 0 | 
					
						
							|  |  |  | 			else: | 
					
						
							| 
									
										
										
										
											1998-10-08 15:24:48 +00:00
										 |  |  | 				stack.append((ok, -1, word)) | 
					
						
							| 
									
										
										
										
											1994-05-09 14:52:41 +00:00
										 |  |  | 				if ok: fpo.write(line) | 
					
						
							|  |  |  | 		elif keyword == 'if': | 
					
						
							| 
									
										
										
										
											1998-10-08 15:24:48 +00:00
										 |  |  | 			stack.append((ok, -1, '')) | 
					
						
							| 
									
										
										
										
											1994-05-09 14:52:41 +00:00
										 |  |  | 			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() |