| |
---|
| | |
---|
| | PROGNAME = "tren.py" |
---|
| | BASENAME = PROGNAME.split(".py")[0] |
---|
| | PROGENV = BASENAME.upper() |
---|
| | RCSID = "$Id: tren.py,v 1.144 2010/02/05 05:42:45 tundra Exp $" |
---|
| | RCSID = "$Id: tren.py,v 1.145 2010/02/05 18:05:53 tundra Exp $" |
---|
| | VERSION = RCSID.split()[2] |
---|
| | |
---|
| | # Copyright Information |
---|
| | |
---|
| |
---|
| | DEFLEN = 75 # Default output line length |
---|
| | DEFSEP = "=" # Default rename command separator: old=new |
---|
| | ESC = "\\" # Escape character |
---|
| | EXT = "Ext" # Rename target is extension |
---|
| | INCL = "-I" # Include file command line option |
---|
| | INCL = "I" # Include file command line option |
---|
| | NAM = "Nam" # Rename target is name |
---|
| | OPTINTRO = "-" # Option introducer |
---|
| | |
---|
| | # Internal program state literals |
---|
| | |
---|
| | DEBUG = "DEBUG" |
---|
| |
---|
| | # Error Messages |
---|
| | ##### |
---|
| | |
---|
| | eBADARG = "Invalid command line: %s!" |
---|
| | eBADINCL = "option %s requires argument" % INCL |
---|
| | eBADINCL = "option -%s requires argument" % INCL |
---|
| | eBADNEWOLD = "Bad -r argument '%s'! Requires exactly one new, old string separator (Default: " + DEFSEP + ")" |
---|
| | eBADLEN = "Bad line length '%s'!" |
---|
| | eERROR = "ERROR" |
---|
| | eFILEOPEN = "Cannot open file '%s': %s!" |
---|
| |
---|
| | ##### |
---|
| | |
---|
| | 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. |
---|
| | """ 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. |
---|
| | |
---|
| | This is a bit tricky because we have to handle every possible |
---|
| | legal command line syntax for option specification: |
---|
| | |
---|
| | -I filename |
---|
| | -Ifilename |
---|
| | -....I filename |
---|
| | -....Ifilename |
---|
| | """ |
---|
| | |
---|
| | NUMINCLUDES = 0 |
---|
| | while " ". join(OPTIONS).find(INCL) > -1: |
---|
| | FoundNewInclude = True |
---|
| | |
---|
| | while FoundNewInclude: |
---|
| | |
---|
| | FoundNewInclude = False |
---|
| | i = 0 |
---|
| | while i < len(OPTIONS): |
---|
| | |
---|
| | # Detect all possible command line include constructs, |
---|
| | # isolating the requested filename and replaciing its |
---|
| | # contents at that position in the command line. |
---|
| | |
---|
| | field = OPTIONS[i] |
---|
| | if field.startswith(OPTINTRO) and (field.find(INCL) > -1): |
---|
| | |
---|
| | FoundNewInclude = True |
---|
| | lhs, rhs = field.split(INCL) |
---|
| | |
---|
| | if lhs == OPTINTRO: |
---|
| | lhs = "" |
---|
| | |
---|
| | if rhs == "": |
---|
| | |
---|
| | if i < len(OPTIONS)-1: |
---|
| | |
---|
| | inclfile = OPTIONS[i+1] |
---|
| | OPTIONS = OPTIONS[:i+1] + OPTIONS[i+2:] |
---|
| | |
---|
| | # We have an include without a filename at the end |
---|
| | # of the command line which is bogus. |
---|
| | else: |
---|
| | ErrorMsg(eBADARG % eBADINCL) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | |
---|
| | else: |
---|
| | inclfile = rhs |
---|
| | |
---|
| | # Before actually doing the include, make sure we've |
---|
| | # not exceeded the limit. This is here mostly to make |
---|
| | # sure we stop recursive/circular includes. |
---|
| | |
---|
| | NUMINCLUDES += 1 |
---|
| | if NUMINCLUDES > MAXINCLUDES: |
---|
| | ErrorMsg(eTOOMANYINC) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | # Read the included file, stripping out comments |
---|
| | |
---|
| | try: |
---|
| | n = [] |
---|
| | f = open(inclfile) |
---|
| | for line in f.readlines(): |
---|
| | line = line.split(COMMENT)[0] |
---|
| | n += line.split() |
---|
| | f.close() |
---|
| | |
---|
| | # 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) |
---|
| | |
---|
| | # You can't end a command line with the include option and no argument |
---|
| | |
---|
| | if i == len(OPTIONS)-1: |
---|
| | ErrorMsg(eBADARG % eBADINCL) |
---|
| | sys.exit(1) |
---|
| | # Keep track of the filenames being included |
---|
| | |
---|
| | # Handle the case where the user does- and does not separate |
---|
| | # the option and the filename with a space since both |
---|
| | # forms are legal command line syntax |
---|
| | |
---|
| | # The use included the space |
---|
| | if OPTIONS[i] == INCL: |
---|
| | file = OPTIONS[i+1] ; lhs = OPTIONS[:i] ; rhs = OPTIONS[i+2:] |
---|
| | |
---|
| | # The the option and filename are not space separated |
---|
| | else: |
---|
| | file = OPTIONS[i].replace(INCL,"") ; lhs = OPTIONS[:i] ; rhs = OPTIONS[i+1:] |
---|
| | |
---|
| | # 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() |
---|
| | |
---|
| | # Keep track of the filenames being included |
---|
| | |
---|
| | IncludedFiles.append(os.path.abspath(file)) |
---|
| | |
---|
| | OPTIONS = lhs + n + rhs |
---|
| | |
---|
| | except IOError as e: |
---|
| | ErrorMsg(eFILEOPEN % (file, e.args[1])) |
---|
| | sys.exit(1) |
---|
| | IncludedFiles.append(os.path.abspath(inclfile)) |
---|
| | |
---|
| | # Insert content of included file at current |
---|
| | # command line position |
---|
| | |
---|
| | # A non-null left hand side means that there were |
---|
| | # options before the include we need to preserve |
---|
| | |
---|
| | if lhs: |
---|
| | n = [lhs] + n |
---|
| | |
---|
| | OPTIONS = OPTIONS[:i] + n + OPTIONS[i+1:] |
---|
| | |
---|
| | except IOError as e: |
---|
| | ErrorMsg(eFILEOPEN % (inclfile, e.args[1])) |
---|
| | sys.exit(1) |
---|
| | |
---|
| | i += 1 |
---|
| | |
---|
| | return OPTIONS |
---|
| | |
---|
| | # End of 'ProcessIncludes()' |
---|
| |
---|
| | |