diff --git a/tconfpy.py b/tconfpy.py index 46c4129..3ada51b 100755 --- a/tconfpy.py +++ b/tconfpy.py @@ -6,7 +6,7 @@ # Program Information PROGNAME = "tconfpy" -RCSID = "$Id: tconfpy.py,v 1.103 2004/03/09 23:39:33 tundra Exp $" +RCSID = "$Id: tconfpy.py,v 1.104 2004/03/12 00:38:47 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information @@ -59,16 +59,65 @@ # Constants ########### -COMMENT = '#' # Comment introducer character +# General Constants + MSGPOS = 10 # Where to start message output PARSEOK = True # Indicates successful parsing +# Reserved Symbols + +COMMENT = '#' # Comment introducer character +DELIML = '[' # Left delimiter for vbl reference +DELIMR = ']' # Right delimiter for vbl reference +DOLLAR = '$' # Used to note enviro vbl + + +# Control and conditional symbols + +INCLUDE = ".include" +ENDIF = ".endif" +IF = ".if" + +# Table of reserved symbols used by parser. User is able +# to include this in the right side of a variable definition +# via [reserved sym]. + +Reserved = {"DELIML" : DELIML, + "DELIMR" : DELIMR, + "DOLLAR" : DOLLAR, + "HASH" : COMMENT, + "INCLUDE" : INCLUDE, + "ENDIF" : ENDIF, + "IF" : IF + } + + + ########### # Literals ########### #----------------------------------------------------------# +# Global Variables & Data Structures # +#----------------------------------------------------------# + + +DEBUG = False # Control Debug output +IGNORECASE = False # Case observed by default + +DebugMsg = [] # Place to store and return debug info +ErrMsgs = [] # Place to store and return errors +WarnMsgs = [] # Place to store and return warnings + + +CondStack = [True,] # Conditional stack +SymTable = {} # Results of the parsing stored here +TotalLines = 0 # Total number of lines parsed + + + +#----------------------------------------------------------# # Prompts, & Application Strings # #----------------------------------------------------------# @@ -77,15 +126,16 @@ # Debug Messages ########## -dDEBUG = "DEBUG" -dNUMLINES = "Processed %d Lines In '%s'" +dDEBUG = "DEBUG" +dNUMLINES = "Processing '%s' Resulted In %d Total Lines Parsed" +dPARSEDLINE = "%s Line %d Parses To: %s" ########### # Error Messages ########### -eCONFOPEN = "Cannot Open The File '%s'" -eERROR = "ERROR" +eCONFOPEN = "Cannot Open The File '%s'" +eERROR = "ERROR" ########### @@ -100,26 +150,6 @@ wWARNING = "WARNING" - -#----------------------------------------------------------# -# Global Variables & Data Structures # -#----------------------------------------------------------# - - -DEBUG = False # Control Debug output -IGNORECASE = False # Case observed by default - -DebugMsg = [] # Place to store and return debug info -ErrMsgs = [] # Place to store and return errors -WarnMsgs = [] # Place to store and return warnings - - -LineNum = 0 # Keep track of the line number as we go -ParseOptions = {} # Options and settings for know variables -SymTable = {} # Results of the parsing stored here - - - #--------------------------- Code Begins Here ---------------------------------# @@ -203,32 +233,34 @@ # Public API To Module # #----------------------------------------------------------# - def ParseConfig(cfgfile, Options={}, IgnoreCase=False, debug=False): - global DEBUG, IGNORECASE, LineNum, ParseOptions, SymTable global DebugMsgs, ErrMsgs, WarnMsgs + global CondStack, DEBUG, IGNORECASE, SymTable, TotalLines # Initialize the globals DEBUG = debug IGNORECASE = IgnoreCase - LineNum = 0 + + DebugMsgs = [] ErrMsgs = [] - WarnMsgs = [] - ParseOptions = Options - SymTable = {} + WarnMsgs = [] + + CondStack = [True,] + SymTable = Options + TotalLines = 0 # Begin parsing - + try: ParseFile(cfgfile) # Return the parsing results if DEBUG: - DebugMsg(dNUMLINES %(LineNum, cfgfile)) + DebugMsg(dNUMLINES %(cfgfile, TotalLines)) return (SymTable, ErrMsgs, WarnMsgs, DebugMsgs, PARSEOK) @@ -237,7 +269,7 @@ except: if DEBUG: - DebugMsg(dNUMLINES %(LineNum, cfgfile)) + DebugMsg(dNUMLINES %(cfgfile, TotalLines)) ErrorMsg(eCONFOPEN % cfgfile) return (SymTable, ErrMsgs, WarnMsgs, DebugMsgs, not PARSEOK) @@ -269,17 +301,20 @@ def ParseFile(cfgfile): - global IgnoreCase, LineNum, MsgList, ParseOptions, SymTable + global IgnoreCase, MsgList, SymTable, TotalLines cf = open(cfgfile) # Successful open of config file - Begin processing it + linenum=0 + # Process and massage the configuration file for line in cf.read().splitlines(): - LineNum += 1 - + linenum += 1 + TotalLines += 1 + # Parse this line - ParseLine(line, cfgfile) + ParseLine(line, cfgfile, linenum) # Close the config file cf.close() @@ -291,11 +326,35 @@ # Parse A Line ########## -def ParseLine(line, cfgfile): +def ParseLine(line, cfgfile, linenum): - global IgnoreCase, LineNum, MsgList, ParseOptions, SymTable + global CondStack, MsgList, SymTable line = ConditionLine(line) + ########## + # Beginning Of Line Parser + ########## + + # Only attempt on non-blank lines + if line: + + # Substitute references to reserved symbols + + for ref in Reserved.keys(): + line = line.replace("%s%s%s" % (DELIML, ref, DELIMR), Reserved[ref]) + + # Process .include statements + + if line.startswith(INCLUDE): + ParseFile(line.split(INCLUDE)[1].strip()) + + + ########## + # End Of Line Parser + ########## + + if DEBUG: + DebugMsg(dPARSEDLINE %(cfgfile, linenum, line)) # End of 'ParseLine'