#!/usr/bin/env python # tconfpy.py # Copyright (c) 2003 TundraWare Inc. All Rights Reserved. # For Updates See: http://www.tundraware.com/Software/tconfpy # Program Information PROGNAME = "tconfpy" RCSID = "$Id: tconfpy.py,v 1.103 2004/03/09 23:39:33 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information CPRT = chr(169) DATE = "2003-2004" OWNER = "TundraWare Inc." RIGHTS = "All Rights Reserved" COPYRIGHT = "Copyright %s %s %s, %s." % (CPRT, DATE, OWNER, RIGHTS) PROGINFO = PROGNAME + " " + VERSION BANNER = "%s\n%s\n%s\n" % (PROGINFO, COPYRIGHT, RCSID) #----------------------------------------------------------# # Variables User Might Change # #----------------------------------------------------------# #------------------- Nothing Below Here Should Need Changing -----------------# #----------------------------------------------------------# # Public Features Of This Module # #----------------------------------------------------------# __all__ = ["ParseConfig"] #----------------------------------------------------------# # Imports # #----------------------------------------------------------# import os.path #----------------------------------------------------------# # Aliases & Redefinitions # #----------------------------------------------------------# #----------------------------------------------------------# # Constants & Literals # #----------------------------------------------------------# ########### # Constants ########### COMMENT = '#' # Comment introducer character MSGPOS = 10 # Where to start message output PARSEOK = True # Indicates successful parsing ########### # Literals ########### #----------------------------------------------------------# # Prompts, & Application Strings # #----------------------------------------------------------# ########## # Debug Messages ########## dDEBUG = "DEBUG" dNUMLINES = "Processed %d Lines In '%s'" ########### # Error Messages ########### eCONFOPEN = "Cannot Open The File '%s'" eERROR = "ERROR" ########### # Prompts ########### ########### # Warning Messages ########### 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 ---------------------------------# #----------------------------------------------------------# # Object Base Class Definitions # #----------------------------------------------------------# #----------------------------------------------------------# # Utility Function Definitions # #----------------------------------------------------------# ########## # Create A Debug Message ########## def DebugMsg(dmsg): global DebugMsgs DebugMsgs.append(mkmsg(dmsg, dDEBUG)) # End of 'DebugMsg()' ########## # Create An Error Message ########## def ErrorMsg(error): global ErrMsgs ErrMsgs.append(mkmsg(error + "!", eERROR)) # End of 'ErrorMsg()' ########## # Create A Warning Message ########## def WarningMsg(warning): global WarnMsgs WarnMsgs.append(mkmsg(warning + "!", wWARNING)) # End of 'WarningMsg()' ########## # Construct A Standard Application Message String ########## def mkmsg(msg, msgtype=""): if msgtype: msgtype += ":" pad = " " * (MSGPOS - len(msgtype)) return "%s - %s%s%s" % (PROGINFO, msgtype, pad, msg) # End of 'mkmsg()' #----------------------------------------------------------# # Entry Point On Direct Invocation # #----------------------------------------------------------# if __name__ == '__main__': print BANNER #----------------------------------------------------------# # Public API To Module # #----------------------------------------------------------# def ParseConfig(cfgfile, Options={}, IgnoreCase=False, debug=False): global DEBUG, IGNORECASE, LineNum, ParseOptions, SymTable global DebugMsgs, ErrMsgs, WarnMsgs # Initialize the globals DEBUG = debug IGNORECASE = IgnoreCase LineNum = 0 DebugMsgs = [] ErrMsgs = [] WarnMsgs = [] ParseOptions = Options SymTable = {} # Begin parsing try: ParseFile(cfgfile) # Return the parsing results if DEBUG: DebugMsg(dNUMLINES %(LineNum, cfgfile)) return (SymTable, ErrMsgs, WarnMsgs, DebugMsgs, PARSEOK) # Something went wrong except: if DEBUG: DebugMsg(dNUMLINES %(LineNum, cfgfile)) ErrorMsg(eCONFOPEN % cfgfile) return (SymTable, ErrMsgs, WarnMsgs, DebugMsgs, not PARSEOK) # End of 'ParseConfig()' #----------------------------------------------------------# # Parser Support Functions # #----------------------------------------------------------# ########## # Condition A Line - Remove Comments & Leading/Trailing Whitespace ########## def ConditionLine(line): return line.split(COMMENT)[0].strip() # End of 'ConditionLine()' ########## # Parse A File ########## def ParseFile(cfgfile): global IgnoreCase, LineNum, MsgList, ParseOptions, SymTable cf = open(cfgfile) # Successful open of config file - Begin processing it # Process and massage the configuration file for line in cf.read().splitlines(): LineNum += 1 # Parse this line ParseLine(line, cfgfile) # Close the config file cf.close() # End of 'ParseFile()' ########## # Parse A Line ########## def ParseLine(line, cfgfile): global IgnoreCase, LineNum, MsgList, ParseOptions, SymTable line = ConditionLine(line) # End of 'ParseLine'