Added support for embedding reserved words and symbols.
Implemented .include logic.
1 parent bed81f8 commit 2d835bab7e3704b023ebabad9f1b1a55583a2903
@tundra tundra authored on 11 Mar 2004
Showing 1 changed file
View
217
tconfpy.py
 
# 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
 
###########
# 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
###########
 
 
#----------------------------------------------------------#
# 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
 
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 #
#----------------------------------------------------------#
 
 
##########
# Debug Messages
##########
 
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"
 
 
###########
# Prompts
###########
 
 
###########
# Warning Messages
###########
 
wWARNING = "WARNING"
 
 
#--------------------------- Code Begins Here ---------------------------------#
 
#----------------------------------------------------------#
# 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)
 
# Something went wrong
except:
 
if DEBUG:
DebugMsg(dNUMLINES %(LineNum, cfgfile))
DebugMsg(dNUMLINES %(cfgfile, TotalLines))
 
ErrorMsg(eCONFOPEN % cfgfile)
return (SymTable, ErrMsgs, WarnMsgs, DebugMsgs, not PARSEOK)
 
##########
 
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()
 
##########
# Parse A Line
##########
 
def ParseLine(line, cfgfile):
 
global IgnoreCase, LineNum, MsgList, ParseOptions, SymTable
def ParseLine(line, cfgfile, linenum):
 
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'