Broke out symbol table validation feature into ValidateSymbolTable().
Both passed symbol and template tables are now checked for validity.
Initial value for each passed symbol is checked for valid type.
Template names are checked to make sure they do not contain namespace separators.
1 parent c0a10c2 commit 0cdaa9ce88b0c87dfc895503bb038f6a487776ab
@tundra tundra authored on 19 Jan 2005
Showing 1 changed file
View
218
tconfpy.py
 
# Program Information
 
PROGNAME = "tconfpy"
RCSID = "$Id: tconfpy.py,v 2.106 2005/01/19 10:03:33 tundra Exp $"
RCSID = "$Id: tconfpy.py,v 2.107 2005/01/19 11:08:24 tundra Exp $"
VERSION = RCSID.split()[2]
 
# Copyright Information
 
 
eBADDEFAULT = "Type Of Default Value Does Not Agree With Type Declared"
eBADLEGALVAL = "Type Of One Or More LegalVals Does Not Agree With Type Declared"
eBADMINMAX = "Type Of Min Or Max Value Not Appropriate For"
eBADVARREF = "Attempt To Get Value Of Non-Existent Variable"
eBADTEMPLNAME = "Template Name Not Canonical"
eBADVALTYP = "Initial Value Has Wrong Type"
eBADVARREF = "Attempt To Get Value Of Non-Existent Variable"
eIFBAD = "'%s' Or '%s' Missing" % (EQUIV, NOTEQUIV)
eINITSYMTBL = "InitialSymTable"
eLEGALVALLIST = "The LegalVal Attribute Is Wrong Type (Must Be A List)"
eNOTDESCRIPT = "Invalid Descriptor Type"
eNOVARS = "This Conditional Requires At Least One Variable Name To Test"
eSTARTUP = "<Program Starting>"
eTEMPLATES = "Templates"
 
# Error Messages
 
Messages["eAPIPARAMBAD"] = "API Error: %s For Variable '%s' In '%s' Passed To The API"
Messages["eBADCOND"] = FILENUM + "Bad '%s' Directive. %s"
Messages["eBADREGEX"] = FILENUM + "Bad Regular Expression, '%s', In Legal Values List For Variable '%s'"
Messages["eBADSYNTAX"] = FILENUM + "Syntax Error. Statement Not In Known Form"
Messages["eCONFIGTYPE"] = "Don't Know How To Process Configurations Of Type '%s'"
Messages["eCONFOPEN"] = FILENUM + "Cannot Open The File '%s'"
Messages["eDESCRIPTBAD"] = "API Error: %s For Variable '%s'"
Messages["eELSENOIF"] = FILENUM + "'%s' Without Preceding '%s' Form" % (ELSE, IF)
Messages["eENDIFEXTRA"] = FILENUM + "'" + ENDIF + "' Without Matching Condition"
Messages["eENDIFMISS"] = FILENUM + "Missing %d" + " '%s' " % ENDIF + " Statement(s)"
Messages["eEQUIVEXTRA"] = FILENUM + "Only a single '%s' Or '%s' Operator Permitted" % (EQUIV, NOTEQUIV)
Debug=False):
 
global SymTable
# Create a new symbol table
SymTable = SymbolTable()
 
# Set the name of the calling program for output messages
mkmsg.proginfo = CallingProgram
 
# Validate the passed symbol table
symtblok = ValidateSymbolTable(InitialSymTable.Symbols, eINITSYMTBL)
 
# Validate the passed template table
templok = ValidateSymbolTable(Templates.Symbols, eTEMPLATES, istemplate=True)
 
# Both of these must be OK or we're done
 
if not (symtblok and templok):
return SymTable
 
# Everything was fine
mkmsg.proginfo = CallingProgram
else:
# Load the symbol table
for sym in InitialSymTable.Symbols:
SymTable.Symbols[sym] = InitialSymTable.Symbols[sym]
 
# Load the template table
 
for sym in Templates.Symbols:
SymTable.Templates.Symbols[sym] = Templates.Symbols[sym]
 
# Create and initialize a new symbol table
 
SymTable = SymbolTable()
 
# Initialize the globals
 
SymTable.ALLOWNEWVAR = AllowNewVars
SymTable.Templates = Templates
SymTable.LITERALVARS = LiteralVars
SymTable.INLITERAL = False
SymTable.DEBUG = Debug
 
# Load the predefines symbols
# Load the predefined symbols
 
for var in Predefined.keys():
 
d = VarDescriptor()
d.Value = Predefined[var]
d.Writeable = False
SymTable.Symbols[var] = d
 
 
 
# Add any passed symbols to the SymbolTable
 
deserror = False
for sym in InitialSymTable.Symbols:
 
des = InitialSymTable.Symbols[sym]
 
# Make sure a valid descriptor was passed for each variable
 
desok = True
 
# Make sure we got a Var Descriptor Object
 
if not isinstance(des, VarDescriptor):
desok = False
ErrorMsg("eDESCRIPTBAD", (eNOTDESCRIPT, sym))
des = VarDescriptor() # Make a fake one so the following tests don't blow up
 
# Check various entries for type agreement
 
dt = des.Type
 
# Make sure default value agrees with variable type
 
if des.Default and type(des.Default) != dt:
desok = False
ErrorMsg("eDESCRIPTBAD", (eBADDEFAULT, sym))
 
# Make sure that LegalVals is a list type
 
if type(des.LegalVals) != type([]):
desok = False
ErrorMsg("eDESCRIPTBAD", (eLEGALVALLIST, sym))
# Then check each value in the list for type agreement
else:
 
for lv in des.LegalVals:
if type(lv) != dt:
desok = False
ErrorMsg("eDESCRIPTBAD", (eBADLEGALVAL, sym))
 
# Make sure min and max limits are of the correct type
 
for mm in (des.Min, des.Max):
 
# Floats can accept Float or Int boundaries
# Ints, & Strings can accept Int boundaries
# Boundaries not relevant for Bool and Complex
# Anything else is an error
 
if mm and dt == TYPE_FLOAT and type(mm) != TYPE_FLOAT and type(mm) != TYPE_INT:
desok = False
ErrorMsg("eDESCRIPTBAD", (eBADMINMAX, sym))
 
if mm and dt in (TYPE_INT, TYPE_STRING) and type(mm) != TYPE_INT:
desok = False
ErrorMsg("eDESCRIPTBAD", (eBADMINMAX, sym))
 
# Only load the symbol table with valid entries
if desok:
SymTable.Symbols[sym] = des
 
# Indicate that a problem was encountered
else:
deserror = True
 
# If any of the passed symbols had bogus descriptor contents, we're done
 
if deserror:
return SymTable
 
 
# Symbol Table passed to API was OK, so keep going
 
 
# End Of 'ValidateSymbolName()'
 
#####
# Validate Symbol Table Content
#####
 
def ValidateSymbolTable(symtbl, name, istemplate=False):
 
errors = 0
for sym in symtbl:
 
# Template names cannot contain a namespace separator character
if istemplate and sym.count(NSSEP):
ErrorMsg("eAPIPARAMBAD", (eBADTEMPLNAME, sym, name))
errors += 1
des = symtbl[sym]
 
# Make sure a valid descriptor was passed for each variable
# Make sure we got a Var Descriptor Object
 
if not isinstance(des, VarDescriptor):
errors += 1
ErrorMsg("eAPIPARAMBAD", (eNOTDESCRIPT, sym, name))
des = VarDescriptor() # Make a fake one so the following tests don't blow up
 
# Check various entries for type agreement
 
dt = des.Type
 
# Make sure default value agrees with variable type
 
if des.Value and type(des.Value) != dt:
errors += 1
ErrorMsg("eAPIPARAMBAD", (eBADVALTYP, sym, name))
 
# Make sure default value agrees with variable type
 
if des.Default and type(des.Default) != dt:
errors += 1
ErrorMsg("eAPIPARAMBAD", (eBADDEFAULT, sym, name))
 
# Make sure that LegalVals is a list type
 
if type(des.LegalVals) != type([]):
errors += 1
ErrorMsg("eAPIPARAMBAD", (eLEGALVALLIST, sym, name))
# Then check each value in the list for type agreement
else:
 
for lv in des.LegalVals:
if type(lv) != dt:
errors += 1
ErrorMsg("eAPIPARAMBAD", (eBADLEGALVAL, sym, name))
 
# Make sure min and max limits are of the correct type
 
for mm in (des.Min, des.Max):
 
# Floats can accept Float or Int boundaries
# Ints, & Strings can accept Int boundaries
# Boundaries not relevant for Bool and Complex
# Anything else is an error
 
if mm and dt == TYPE_FLOAT and type(mm) != TYPE_FLOAT and type(mm) != TYPE_INT:
errors += 1
ErrorMsg("eAPIPARAMBAD", (eBADMINMAX, sym, name))
 
if mm and dt in (TYPE_INT, TYPE_STRING) and type(mm) != TYPE_INT:
errors += 1
ErrorMsg("eAPIPARAMBAD", (eBADMINMAX, sym, name))
 
# Return success of validation
 
symtblok = True
 
if errors:
symtblok = False
 
return symtblok
 
# End Of 'ValidateSymbolTable()'
 
 
#####
# Validate Value
#####
 
def ValidateValue(l, r, cfgfile, linenum):