Completed logic for existential conditional and final .endif counts.
Modified variable deref logic to report reference attempts to undefined variables.
1 parent e0ea110 commit b54e4e43487f9ef4418d941601fc96420842feea
@tundra tundra authored on 14 Mar 2004
Showing 1 changed file
View
117
tconfpy.py
 
# Program Information
 
PROGNAME = "tconfpy"
RCSID = "$Id: tconfpy.py,v 1.112 2004/03/14 04:43:53 tundra Exp $"
RCSID = "$Id: tconfpy.py,v 1.113 2004/03/14 09:04:52 tundra Exp $"
VERSION = RCSID.split()[2]
 
# Copyright Information
 
FILENUM = "[File: %s Line: %s]" # Display filename and linenum
PTR = " ---> " # Textual pointer for debug output
 
 
# Reserved Symbols
# Special And Reserved Symbols
 
HASH = r'#'
COMMENT = HASH # Comment introducer character
DELIML = r'[' # Left delimiter for vbl reference
EQUAL = r'=' # Used in vbl definition
EQUIV = r"==" # Used in conditional tests
NOTEQUIV = r"!=" # Used in conditional tests
 
Reserved = ["DELIML", "DELIMR", "DOLLAR", "EQUAL", "EQUIV", "NOTEQUIV",
"HASH", "INCLUDE", "ENDIF", "IF"]
 
# Control and conditional symbols
 
INCLUDE = ".include"
ENDIF = ".endif"
IF = ".if"
 
Reserved = ["DELIML", "DELIMR", "DOLLAR", "EQUAL", "EQUIV", "NOTEQUIV",
"HASH", "INCLUDE", "ENDIF", "IF"]
 
 
# Regular Expressions
 
reVARREF = r"\%s.+?\%s" % (DELIML, DELIMR) # Variable reference
 
###########
# Literals
###########
 
 
TRUE = str(True)
FALSE = str(False)
 
 
#----------------------------------------------------------#
# Global Variables & Data Structures #
###########
 
eERROR = "ERROR"
 
eBADCOND = FILENUM + " Badly Formed Conditional Expression: '%s'"
eCONFOPEN = "Cannot Open The File '%s'"
eENDIFEXTRA = FILENUM + " " + ENDIF + " Without Matching Condition"
 
 
###########
# Prompts
###########
eENDIFEXTRA = FILENUM + " '" + ENDIF + "' Without Matching Condition"
eENDIFMISS = FILENUM + " Missing %d '" + ENDIF + "' Statement(s)"
eVARUNDEF = FILENUM + " " + "Attempt To Reference Undefined Variable '%s'"
 
 
###########
# Warning Messages
###########
 
wWARNING = "WARNING"
 
wENDIFBAD = FILENUM + " Text After " + ENDIF + " Ignored"
wTRAILING = FILENUM + " Trailing Text After '%s' Statement Ignored"
 
 
#--------------------------- Code Begins Here ---------------------------------#
 
 
# End of 'ConditionLine()'
 
 
 
##########
# Dereference Variables
##########
 
def DerefVar(line, cfgfile, linenum):
 
# Find all symbols refrences and replace w/sym table entry if present
 
ref_ok = True
for var in VarRef.findall(line):
 
sym = var[1:-1] # Strip delimiters
if sym in SymTable:
line = line.replace(var, str(SymTable[sym][SYM_VALUE]))
 
return line
# Reference to undefined variable
else:
ErrorMsg(eVARUNDEF % (cfgfile, linenum, sym))
ref_ok = False
return line, ref_ok
 
# End of 'DerefVar()'
 
 
except:
 
ErrorMsg(eCONFOPEN % cfgfile) # Record the error
 
# Make sure we had all condition blocks balanced with matching '.endif'
 
finalcond = len(CondStack)
if finalcond != 1:
ErrorMsg(eENDIFMISS % (cfgfile, linenum, finalcond-1))
 
# End of 'ParseFile()'
 
 
##########
if line.startswith(ENDIF):
 
# This should be the only thing on the line
if line != ENDIF:
WarningMsg(wENDIFBAD % (cfgfile, linenum))
WarningMsg(wTRAILING % (cfgfile, linenum, ENDIF))
 
# Remove one level of nesting
CondStack.pop()
 
 
if line.startswith(IF):
line = line.split(IF)[1].strip()
 
# Handle .if string == string form
# Handle Equality Form: ".if string == string"
if line.count(EQUIV):
pass
 
# Handle .if string != string form
# Handle Inequality Form: ".if string != string"
elif line.count(NOTEQUIV):
pass
 
# Handle .if string
# FIXXXXXXX THIS TO CHECK FOR CORRECT FORM FIRST
# Handle Existential Form: ".if string"
else:
line = DerefVar(line, cfgfile, linenum)
 
# See if all the variable references were resolved
 
if not VarRef.match(line):
CondStack.append(True)
 
# Must be in form: ".if [var]" - trailing garbage ignored
 
chk = VarRef.findall(line)
if line[0] == DELIML and len(chk) > 0:
 
# Warn if there was trailing garbage
if len(line) != len(chk[0]):
WarningMsg(wTRAILING % (cfgfile, linenum, IF + " " + chk[0]))
 
# And condition the line to only contain the variable reference
line = chk[0]
 
# Now see if the variable resolved and set state accordingly
 
line, ref_ok = DerefVar(line, cfgfile, linenum)
if ref_ok:
line = TRUE
CondStack.append(True)
else:
line = FALSE
CondStack.append(False)
 
# Bogus conditional syntax
else:
CondStack.append(False)
ErrorMsg(eBADCOND % (cfgfile, linenum, orig))
 
 
line, ref_ok = DerefVar(line, cfgfile, linenum)
 
 
##########
# Note blank lines for debug purposes
if not line:
line = dBLANKLINE
 
DebugMsg(dPARSEDLINE %(cfgfile, linenum, orig, line))
DebugMsg(dPARSEDLINE % (cfgfile, linenum, orig, line))
 
# End of 'ParseLine'