| |
---|
| | # Program Information |
---|
| | |
---|
| | PROGNAME = "tren.py" |
---|
| | PROGENV = PROGNAME.split(".py")[0].upper() |
---|
| | RCSID = "$Id: tren.py,v 1.109 2010/01/25 23:23:30 tundra Exp $" |
---|
| | RCSID = "$Id: tren.py,v 1.110 2010/01/26 01:15:08 tundra Exp $" |
---|
| | VERSION = RCSID.split()[2] |
---|
| | |
---|
| | # Copyright Information |
---|
| | |
---|
| |
---|
| | EXT = "Ext" # Rename target is extension |
---|
| | EXTDELIM = "." # Extension delimeter |
---|
| | INCL = "-I" # Include file command line option |
---|
| | NAM = "Nam" # Rename target is name |
---|
| | SEPARATOR = "-" *70 |
---|
| | |
---|
| | |
---|
| | #----------------------------------------------------------# |
---|
| | # Prompts, & Application Strings # |
---|
| |
---|
| | ##### |
---|
| | |
---|
| | DEBUGFLAG = "-d" |
---|
| | dCMDLINE = "Command Line" |
---|
| | dCURSTATE = "Current State Of Program Options" |
---|
| | dDEBUG = "DEBUG" |
---|
| | dINCLUDING = "Including file '%s'" |
---|
| | dPAIR = "Option/Target Pair" |
---|
| | dPROGENV = "$" + PROGENV |
---|
| | dRESOLVEDOPTS = "Resolved Command Line" |
---|
| | |
---|
| |
---|
| | |
---|
| | # Program toggle and option defaults |
---|
| | |
---|
| | DEBUG = False # Debugging off |
---|
| | CASE = True # Search is case-sensitive |
---|
| | CASESENSITIVE = True # Search is case-sensitive |
---|
| | ERRORCONTINUE = False # Do not continue after error |
---|
| | EXTDELIM = EXTDELIM # Extension Delimiter |
---|
| | FORCERENAM = False # Do not rename if target already exists |
---|
| | GLOBAL = False # Only rename first instance of old string |
---|
| |
---|
| | |
---|
| | |
---|
| | # Global data structures |
---|
| | |
---|
| | COMMANDLINES = [] # Stores "options... targets" from command line |
---|
| | |
---|
| | |
---|
| | |
---|
| | #--------------------------- Code Begins Here ---------------------------------# |
---|
| | |
---|
| | |
---|
| |
---|
| | ##### |
---|
| | |
---|
| | def DumpState(): |
---|
| | |
---|
| | DebugMsg(dCURSTATE) |
---|
| | DebugMsg(SEPARATOR) |
---|
| | |
---|
| | # Names of all the state variables we want dumped |
---|
| | state = [ |
---|
| | "DEBUG", |
---|
| | "CASE", |
---|
| | "CASESENSITIVE", |
---|
| | "ERRORCONTINUE", |
---|
| | "EXTDELIM", |
---|
| | "FORCERENAM", |
---|
| | "GLOBAL", |
---|
| |
---|
| | |
---|
| | for k in state: |
---|
| | DebugMsg(ColumnPad([k, eval(k)])) |
---|
| | |
---|
| | DebugMsg(SEPARATOR + "\n") |
---|
| | |
---|
| | # End of 'DumpState()' |
---|
| | |
---|
| | |
---|
| | ##### |
---|
| |
---|
| | def PrintStdout(msg, trailing="\n"): |
---|
| | sys.stdout.write(msg + trailing) |
---|
| | |
---|
| | # End of 'PrintStdout' |
---|
| | |
---|
| | |
---|
| | ##### |
---|
| | # Process Include Files On The Command Line |
---|
| | ##### |
---|
| | |
---|
| | def ProcessIncludes(OPTIONS): |
---|
| | |
---|
| | # Resolve include file references allowing for nested includes. |
---|
| | # This has to be done here separate from the command line options so |
---|
| | # that getopt() processing below will "see" the included statements. |
---|
| | |
---|
| | NUMINCLUDES = 0 |
---|
| | while " ". join(OPTIONS).find(INCL) > -1: |
---|
| | |
---|
| | # Get the index of the next include to process. |
---|
| | # It cannot be the last item because this means the filename |
---|
| | # to include is missing. |
---|
| | |
---|
| | i = OPTIONS.index(INCL) |
---|
| | if i == len(OPTIONS)-1: |
---|
| | ErrorMsg(eBADARG % eBADINCL) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | file = OPTIONS[i+1] ; lhs = OPTIONS[:i] ; rhs = OPTIONS[i+2:] |
---|
| | |
---|
| | # Keep track of- and limit the number of includes allowed |
---|
| | # This is an easy way to stop circular (infinite) includes. |
---|
| | |
---|
| | NUMINCLUDES += 1 |
---|
| | if NUMINCLUDES >= MAXINCLUDES: |
---|
| | ErrorMsg(eTOOMANYINC) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | # Replace insert option on the command line with that file's contents. |
---|
| | # Handle comments within lines. |
---|
| | |
---|
| | try: |
---|
| | n = [] |
---|
| | f = open(file) |
---|
| | for l in f.readlines(): |
---|
| | l = l.split(COMMENT)[0] |
---|
| | n += l.split() |
---|
| | f.close() |
---|
| | |
---|
| | if DEBUG: |
---|
| | DebugMsg(dINCLUDING % file) |
---|
| | |
---|
| | OPTIONS = lhs + n + rhs |
---|
| | |
---|
| | except IOError as e: |
---|
| | ErrorMsg(eFILEOPEN % (file, e.args[1])) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | return OPTIONS |
---|
| | |
---|
| | # End of 'ProcessIncludes()' |
---|
| | |
---|
| | |
---|
| | ##### |
---|
| | # Break The Command Line Into Separate "Option... Target..." Pairs |
---|
| | ##### |
---|
| | |
---|
| | def ProcessOptTgtPair(OPTIONS): |
---|
| | |
---|
| | DOINGOPTS = True |
---|
| | commandlines = [] |
---|
| | cmd = [] |
---|
| | |
---|
| | while OPTIONS: |
---|
| | |
---|
| | i = OPTIONS[0] |
---|
| | OPTIONS = OPTIONS[1:] |
---|
| | |
---|
| | # Process options |
---|
| | if i.startswith("-"): |
---|
| | if DOINGOPTS: |
---|
| | cmd.append(i) |
---|
| | |
---|
| | # Starting a new "options... targets ..." pair |
---|
| | else: |
---|
| | commandlines.append(cmd) |
---|
| | cmd = [] |
---|
| | DOINGOPTS = True |
---|
| | cmd.append(i) |
---|
| | |
---|
| | # Process targets |
---|
| | else: |
---|
| | DOINGOPTS = False |
---|
| | cmd.append(i) |
---|
| | |
---|
| | |
---|
| | if cmd: |
---|
| | commandlines.append(cmd) |
---|
| | |
---|
| | return commandlines |
---|
| | |
---|
| | # End of 'ProcessOptTgtPair()' |
---|
| | |
---|
| | |
---|
| | ##### |
---|
| | # Print Usage Information |
---|
| |
---|
| | envopt = os.getenv(PROGENV) |
---|
| | if envopt: |
---|
| | OPTIONS = envopt.split() + OPTIONS |
---|
| | |
---|
| | # Resolve include file references allowing for nested includes. |
---|
| | # This has to be done here separate from the command line options so |
---|
| | # that getopt() processing below will "see" the included statements. |
---|
| | |
---|
| | NUMINCLUDES = 0 |
---|
| | while " ". join(OPTIONS).find(INCL) > -1: |
---|
| | |
---|
| | # Get the index of the next include to process. |
---|
| | # It cannot be the last item because this means the filename |
---|
| | # to include is missing. |
---|
| | |
---|
| | i = OPTIONS.index(INCL) |
---|
| | if i == len(OPTIONS)-1: |
---|
| | ErrorMsg(eBADARG % eBADINCL) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | file = OPTIONS[i+1] ; lhs = OPTIONS[:i] ; rhs = OPTIONS[i+2:] |
---|
| | |
---|
| | # Keep track of- and limit the number of includes allowed |
---|
| | # This is an easy way to stop circular (infinite) includes. |
---|
| | |
---|
| | NUMINCLUDES += 1 |
---|
| | if NUMINCLUDES >= MAXINCLUDES: |
---|
| | ErrorMsg(eTOOMANYINC) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | # Replace insert option on the command line with that file's contents. |
---|
| | # Handle comments within lines. |
---|
| | |
---|
| | try: |
---|
| | n = [] |
---|
| | f = open(file) |
---|
| | for l in f.readlines(): |
---|
| | l = l.split(COMMENT)[0] |
---|
| | n += l.split() |
---|
| | f.close() |
---|
| | |
---|
| | OPTIONS = lhs + n + rhs |
---|
| | |
---|
| | except IOError as e: |
---|
| | ErrorMsg(eFILEOPEN % (file, e.args[1])) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | # We also need to detect a request for debugging now |
---|
| | # so we don't have to wait for getopt to parse it |
---|
| | # to begin seeing debugging output |
---|
| | |
---|
| | # Check for debug manually to see if we want |
---|
| | # debug info about includes |
---|
| | |
---|
| | if DEBUGFLAG in OPTIONS: |
---|
| | DEBUG = True |
---|
| | while DEBUGFLAG in OPTIONS: |
---|
| | OPTIONS.remove(DEBUGFLAG) |
---|
| | |
---|
| | # Deal with include files |
---|
| | |
---|
| | OPTIONS = ProcessIncludes(OPTIONS) |
---|
| | |
---|
| | # Check for debug manually again before we process the options |
---|
| | # to get debug info on command line expansion |
---|
| | |
---|
| | if DEBUGFLAG in OPTIONS: |
---|
| | DEBUG = True |
---|
| | |
---|
| | # Break command line into "option ... targets ..." pairs. |
---|
| | |
---|
| | options = OPTIONS # Save for later |
---|
| | DOINGOPTS = True |
---|
| | cmd = [] |
---|
| | |
---|
| | while OPTIONS: |
---|
| | |
---|
| | i = OPTIONS[0] |
---|
| | OPTIONS = OPTIONS[1:] |
---|
| | |
---|
| | # Process options |
---|
| | if i.startswith("-"): |
---|
| | if DOINGOPTS: |
---|
| | cmd.append(i) |
---|
| | |
---|
| | # Starting a new "options... targets ..." pair |
---|
| | else: |
---|
| | COMMANDLINES.append(cmd) |
---|
| | cmd = [] |
---|
| | DOINGOPTS = True |
---|
| | cmd.append(i) |
---|
| | |
---|
| | # Process targets |
---|
| | else: |
---|
| | DOINGOPTS = False |
---|
| | cmd.append(i) |
---|
| | |
---|
| | |
---|
| | if cmd: |
---|
| | COMMANDLINES.append(cmd) |
---|
| | |
---|
| | |
---|
| | pairs = ProcessOptTgtPair(OPTIONS) |
---|
| | |
---|
| | if DEBUG: |
---|
| | |
---|
| | # Dump what we know about the command line |
---|
| | |
---|
| | DebugMsg(ColumnPad([dCMDLINE, sys.argv])) |
---|
| | DebugMsg(ColumnPad([dPROGENV, os.getenv("TREN")])) |
---|
| | DebugMsg(ColumnPad([dRESOLVEDOPTS, options])) |
---|
| | DebugMsg(ColumnPad([dRESOLVEDOPTS, OPTIONS])) |
---|
| | |
---|
| | |
---|
| | # Now process the command line in "opts... targets" pairs |
---|
| | |
---|
| | for commandline in COMMANDLINES: |
---|
| | for commandline in pairs: |
---|
| | |
---|
| | if DEBUG: |
---|
| | DebugMsg(ColumnPad([dPAIR, " ".join(commandline)])) |
---|
| | |
---|
| | try: |
---|
| | opts, args = getopt.getopt(commandline, '1abbCcEefghl:qr:tvXx]') |
---|
| | opts, args = getopt.getopt(commandline, '1abbCcdEefghl:qr:tvXx]') |
---|
| | except getopt.GetoptError as e: |
---|
| | ErrorMsg(eBADARG % e.args[0]) |
---|
| | sys.exit(1) |
---|
| | |
---|
| |
---|
| | TARGET = ALL |
---|
| | if opt == "-b": |
---|
| | TARGET = NAM |
---|
| | if opt == "-C": |
---|
| | CASE = True |
---|
| | CASESENSITIVE = True |
---|
| | if opt == "-c": |
---|
| | CASE = False |
---|
| | CASESENSITIVE = False |
---|
| | if opt == "-d": |
---|
| | DumpState() |
---|
| | if opt == "-E": |
---|
| | ERRORCONTINUE = True |
---|
| | if opt == "-e": |
---|
| | TARGET = EXT |
---|
| |
---|
| | |