#!/usr/bin/env python3
#--------------------------------------------------------------------
#
# preproc.py
#
# General purpose macro preprocessor
#
#--------------------------------------------------------------------
# Usage:
#
#	preproc.py input_file [output_file] [-D<variable> ...]
#
# Where <variable> may be a keyword or a key=value pair
#
# Syntax:  Basically like cpp.  However, this preprocessor handles
# only a limited set of keywords, so it does not otherwise mangle
# the file in the belief that it must be C code.  Handling of boolean
# relations is important, so these are thoroughly defined (see below)
#
#	#if defined(<variable>) [...]
#	#ifdef <variable>
#	#ifndef <variable>
#	#elseif <variable>
#	#else
#	#endif
#
#	#define <variable> [...]
#	#define <variable>(<parameters>) [...]
#	#undef <variable>
#
#	#include <filename>
#
# <variable> may be
#	<keyword>
#	<keyword>=<value>
#
#	<keyword> without '=' is effectively the same as <keyword>=1
#	Lack of a keyword is equivalent to <keyword>=0, in a conditional.
#
# Boolean operators (in order of precedence):
#	!	NOT
#	&&	AND
#	||	OR	
#
# Comments:
#       Most comments (C-like or Tcl-like) are output as-is.  A
#	line beginning with "###" is treated as a preprocessor
#	comment and is not copied to the output.
#
# Examples;
#	#if defined(X) || defined(Y)
#	#else
#	#if defined(Z)
#	#endif
#--------------------------------------------------------------------

import os
import re
import sys

def solve_statement(condition):

    defrex = re.compile('defined[ \t]*\(([^\)]+)\)')
    orrex = re.compile('(.+)\|\|(.+)')
    andrex = re.compile('(.+)&&(.+)')
    notrex = re.compile('!([^&\|]+)')
    parenrex = re.compile('\(([^\)]+)\)')
    leadspacerex = re.compile('^[ \t]+(.*)')
    endspacerex = re.compile('(.*)[ \t]+$')

    matchfound = True
    while matchfound:
        matchfound = False

        # Search for defined(K) (K must be a single keyword)
        # If the keyword was defined, then it should have been replaced by 1
        lmatch = defrex.search(condition)
        if lmatch:
            key = lmatch.group(1)
            if key == 1 or key == '1' or key == True:
                repl = 1
            else:
                repl = 0

            condition = defrex.sub(str(repl), condition)
            matchfound = True

        # Search for (X) recursively
        lmatch = parenrex.search(condition)
        if lmatch:
            repl = solve_statement(lmatch.group(1))
            condition = parenrex.sub(str(repl), condition)
            matchfound = True

        # Search for !X recursively
        lmatch = notrex.search(condition)
        if lmatch:
            only = solve_statement(lmatch.group(1))
            if only == '1':
                repl = '0'
            else:
                repl = '1'
            condition = notrex.sub(str(repl), condition)
            matchfound = True

        # Search for A&&B recursively
        lmatch = andrex.search(condition)
        if lmatch:
            first = solve_statement(lmatch.group(1))
            second = solve_statement(lmatch.group(2))
            if first == '1' and second == '1':
                repl = '1'
            else:
                repl = '0'
            condition = andrex.sub(str(repl), condition)
            matchfound = True

        # Search for A||B recursively
        lmatch = orrex.search(condition)
        if lmatch:
            first = solve_statement(lmatch.group(1))
            second = solve_statement(lmatch.group(2))
            if first == '1' or second == '1':
                repl = '1'
            else:
                repl = '0'
            condition = orrex.sub(str(repl), condition)
            matchfound = True
 
    # Remove whitespace
    lmatch = leadspacerex.match(condition)
    if lmatch:
        condition = lmatch.group(1)
    lmatch = endspacerex.match(condition)
    if lmatch:
        condition = lmatch.group(1)
    
    return condition

def solve_condition(condition, keys, defines, keyrex):
    # Do definition replacement on the conditional
    for keyword in keys:
        condition = keyrex[keyword].sub(defines[keyword], condition)

    value = solve_statement(condition)
    if value == '1':
        return 1
    else:
        return 0

def sortkeys(keys):
    newkeys = []
    for i in range(0, len(keys)):
        keyword = keys[i]
        found = False
        for j in range(0, len(newkeys)):
            inword = newkeys[j]
            if inword in keyword:
                # Insert keyword before inword
                newkeys.insert(j, keyword)
                found = True
                break
        if not found:
            newkeys.append(keyword)
    return newkeys

def runpp(keys, keyrex, defines, ccomm, incdirs, inputfile, ofile):

    includerex = re.compile('^[ \t]*#include[ \t]+"*([^ \t\n\r"]+)')
    definerex = re.compile('^[ \t]*#define[ \t]+([^ \t]+)[ \t]+(.+)')
    paramrex = re.compile('^([^\(]+)\(([^\)]+)\)')
    defrex = re.compile('^[ \t]*#define[ \t]+([^ \t\n\r]+)')
    undefrex = re.compile('^[ \t]*#undef[ \t]+([^ \t\n\r]+)')
    ifdefrex = re.compile('^[ \t]*#ifdef[ \t]+(.+)')
    ifndefrex = re.compile('^[ \t]*#ifndef[ \t]+(.+)')
    ifrex = re.compile('^[ \t]*#if[ \t]+(.+)')
    elseifrex = re.compile('^[ \t]*#elseif[ \t]+(.+)')
    elserex = re.compile('^[ \t]*#else')
    endifrex = re.compile('^[ \t]*#endif')
    commentrex = re.compile('^###[^#]*$')
    ccstartrex = re.compile('/\*')		# C-style comment start
    ccendrex = re.compile('\*/')		# C-style comment end
    contrex = re.compile('.*\\\\$')		# Backslash continuation line

    badifrex = re.compile('^[ \t]*#if[ \t]*.*')
    badelserex = re.compile('^[ \t]*#else[ \t]*.*')

    # This code is not designed to operate on huge files.  Neither is it designed to be
    # efficient.

    # ifblock state:
    # -1 : not in an if/else block
    #  0 : no condition satisfied yet
    #  1 : condition satisfied
    #  2 : condition was handled, waiting for endif

    ifile = False
    try:
        ifile = open(inputfile, 'r')
    except FileNotFoundError:
        for dir in incdirs:
            try:
                ifile = open(dir + '/' + inputfile, 'r')
            except FileNotFoundError:
                pass
            else:
                break

    if not ifile:
        print("Error:  Cannot open file " + inputfile + " for reading.\n", file=sys.stderr)
        return

    ccblock = -1
    ifblock = -1
    ifstack = []
    lineno = 0

    filetext = ifile.readlines()
    lastline = []

    for line in filetext:
        lineno += 1

        # C-style comments override everything else
        if ccomm:
            if ccblock == -1:
                pmatch = ccstartrex.search(line)
                if pmatch:
                    ematch = ccendrex.search(line[pmatch.end(0):])
                    if ematch:
                        line = line[0:pmatch.start(0)] + line[pmatch.end(0) + ematch.end(0):]
                    else:
                        line = line[0:pmatch.start(0)]
                        ccblock = 1
            elif ccblock == 1:
                ematch = ccendrex.search(line)
                if ematch:
                    line = line[ematch.end(0)+2:]
                    ccblock = -1
                else:
                    continue

        # Handle continuation detected in previous line
        if lastline:
            # Note:  Apparently there is a character retained after the backslash,
            # so strip the last two characters from the line.
            line = lastline[0:-2] + line
            lastline = []

        # Continuation lines have the next highest priority.  However, this
        # script will attempt to keep continuation lines in the body of the
        # text and only collapse lines where continuation lines occur in
        # a preprocessor statement.

        cmatch = contrex.match(line)

        # Ignore lines beginning with "###"
        pmatch = commentrex.match(line)
        if pmatch:
            continue

        # Handle ifdef
        pmatch = ifdefrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            if ifblock != -1:
                ifstack.append(ifblock)
                
            if ifblock == 1 or ifblock == -1:
                condition = pmatch.group(1)
                ifblock = solve_condition(condition, keys, defines, keyrex)
            else:
                ifblock = 2
            continue

        # Handle ifndef
        pmatch = ifndefrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            if ifblock != -1:
                ifstack.append(ifblock)
                
            if ifblock == 1 or ifblock == -1:
                condition = pmatch.group(1)
                ifblock = solve_condition(condition, keys, defines, keyrex)
                ifblock = 1 if ifblock == 0 else 0
            else:
                ifblock = 2
            continue

        # Handle if
        pmatch = ifrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            if ifblock != -1:
                ifstack.append(ifblock)

            if ifblock == 1 or ifblock == -1:
                condition = pmatch.group(1)
                ifblock = solve_condition(condition, keys, defines, keyrex)
            else:
                ifblock = 2
            continue

        # Handle elseif
        pmatch = elseifrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            if ifblock == -1:
               print("Error: #elseif without preceding #if at line " + str(lineno) + ".", file=sys.stderr)
               ifblock = 0

            if ifblock == 1:
                ifblock = 2
            elif ifblock != 2:
                condition = pmatch.group(1)
                ifblock = solve_condition(condition, keys, defines, keyrex)
            continue

        # Handle else
        pmatch = elserex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            if ifblock == -1:
               print("Error: #else without preceding #if at line " + str(lineno) + ".", file=sys.stderr)
               ifblock = 0

            if ifblock == 1:
                ifblock = 2
            elif ifblock == 0:
                ifblock = 1
            continue

        # Handle endif
        pmatch = endifrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            if ifblock == -1:
                print("Error:  #endif outside of #if block at line " + str(lineno) + " (ignored)", file=sys.stderr)
            elif ifstack:
                ifblock = ifstack.pop()
            else:
                ifblock = -1
            continue
                 
        # Check for 'if' or 'else' that were not properly formed
        pmatch = badifrex.match(line)
        if pmatch:
            print("Error:  Badly formed #if statement at line " + str(lineno) + " (ignored)", file=sys.stderr)
            if ifblock != -1:
                ifstack.append(ifblock)

            if ifblock == 1 or ifblock == -1:
                ifblock = 0
            else:
                ifblock = 2
            continue

        pmatch = badelserex.match(line)
        if pmatch:
            print("Error:  Badly formed #else statement at line " + str(lineno) + " (ignored)", file=sys.stderr)
            ifblock = 2
            continue

        # Ignore all lines that are not satisfied by a conditional
        if ifblock == 0 or ifblock == 2:
            continue

        # Handle include.  Note that this code does not expect or
        # handle 'if' blocks that cross file boundaries.
        pmatch = includerex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            inclfile = pmatch.group(1)
            runpp(keys, keyrex, defines, ccomm, incdirs, inclfile, ofile)
            continue

        # Handle define (with value)
        pmatch = definerex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            condition = pmatch.group(1)

            # Additional handling of definition w/parameters: #define X(a,b,c) ..."
            rmatch = paramrex.match(condition) 
            if rmatch:
                # 'condition' as a key into keyrex only needs to be unique.
                # Use the definition word without everything in parentheses
                condition = rmatch.group(1)

                # 'pcondition' is the actual search regexp and must capture all
                # the parameters individually for substitution

                parameters = rmatch.group(2).split(',')

                # Generate the regexp string to match comma-separate values
                # Note that this is based on the cpp preprocessor, which
                # apparently allows commas in arguments if surrounded by
                # parentheses;  e.g., "def(a, b, (c1,c2))".  This is NOT
                # handled.

                pcondition = condition + '\('
                for param in parameters[0:-1]:
                    pcondition += '(.*),'
                pcondition += '(.*)\)'

                # Generate the substitution string with group substitutions
                pvalue = pmatch.group(2)
                idx = 1
                for param in parameters:
                    pvalue = pvalue.replace(param, '\g<' + str(idx) + '>')
                    idx = idx + 1

                defines[condition] = pvalue
                keyrex[condition] = re.compile(pcondition)
            else:
                parameters = []
                value = pmatch.group(2)
                # Note:  Need to check for infinite recursion here, but it's tricky.
                defines[condition] = value
                keyrex[condition] = re.compile(condition)

            if condition not in keys:
                # Parameterized keys go to the front of the list
                if parameters:
                    keys.insert(0, condition)
                else:
                    keys.append(condition)
                keys = sortkeys(keys)
            continue

        # Handle define (simple case, no value)
        pmatch = defrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            condition = pmatch.group(1)
            defines[condition] = '1'
            keyrex[condition] = re.compile(condition)
            if condition not in keys:
                keys.append(condition)
                keys = sortkeys(keys)
            continue

        # Handle undef
        pmatch = undefrex.match(line)
        if pmatch:
            if cmatch:
                lastline = line
                continue
            condition = pmatch.group(1)
            if condition in keys:
                defines.pop(condition)
                keyrex.pop(condition)
                keys.remove(condition)
            continue

        # Now do definition replacement on what's left (if anything)
        # This must be done repeatedly from the top until there are no
        # more substitutions to make.

        while True:
            origline = line
            for keyword in keys:
                newline = keyrex[keyword].sub(defines[keyword], line)
                if newline != line:
                    line = newline
                    break
                    
            if line == origline:
                break
                
        # Output the line
        print(line, file=ofile, end='')

    if ifblock != -1 or ifstack != []:
        print("Error:  input file ended with an unterminated #if block.", file=sys.stderr)

    if ifile != sys.stdin:
        ifile.close()
    return

def printusage(progname):
    print('Usage: ' + progname + ' input_file [output_file] [-options]')
    print('   Options are:')
    print('      -help         Print this help text.')
    print('      -quiet        Stop without error if input file is not found.')
    print('      -ccomm        Remove C comments in /* ... */ delimiters.')
    print('      -D<def>       Define word <def> and set its value to 1.')
    print('      -D<def>=<val> Define word <def> and set its value to <val>.')
    print('      -I<dir>       Add <dir> to search path for input files.')
    return

if __name__ == '__main__':

   # Parse command line for options and arguments
    options = []
    arguments = []
    for item in sys.argv[1:]:
        if item.find('-', 0) == 0:
            options.append(item)
        else:
            arguments.append(item)

    if len(arguments) > 0:
        inputfile = arguments[0]
        if len(arguments) > 1:
            outputfile = arguments[1]
        else:
            outputfile = []
    else:
        printusage(sys.argv[0])
        sys.exit(0)

    defines = {}
    keyrex = {}
    keys = []
    incdirs = []
    ccomm = False
    quiet = False
    for item in options:
        result = item.split('=')
        if result[0] == '-help':
            printusage(sys.argv[0])
            sys.exit(0)
        elif result[0] == '-ccomm':
            ccomm = True
        elif result[0] == '-quiet':
            quiet = True
        elif result[0][0:2] == '-I':
            incdirs.append(result[0][2:])
        elif result[0][0:2] == '-D':
            keyword = result[0][2:]
            try:
                value = result[1]
            except:
                value = '1'
            defines[keyword] = value
            keyrex[keyword] = re.compile(keyword)
            keys.append(keyword)
            keys = sortkeys(keys)
        else:
            print('Bad option ' + item + ', options are -help, -quiet, -ccomm, -D<def> -I<dir>\n')
            sys.exit(1)

    if not os.path.isfile(inputfile):
        if not quiet:
            print("Error:  No input file " + inputfile + " found.")
        else:
            sys.exit(0)

    if outputfile:
        ofile = open(outputfile, 'w')
    else:
        ofile = sys.stdout

    if not ofile:
        print("Error:  Cannot open file " + outputfile + " for writing.")
        sys.exit(1)

    # Sort keys so that if any definition contains another definition, the
    # subset word is handled last;  otherwise the subset word will get
    # substituted, screwing up the definition names in which it occurs.

    keys = sortkeys(keys)

    runpp(keys, keyrex, defines, ccomm, incdirs, inputfile, ofile)
    if ofile != sys.stdout:
        ofile.close()

    # Set mode of outputfile to be equal to that of inputfile (if not stdout)
    if outputfile:
        statinfo = os.stat(inputfile)
        mode = statinfo.st_mode
        os.chmod(outputfile, mode)

    sys.exit(0)
