#! /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()
