Reorganized code to use a common symbol name validation routine.
Wrote logic to explicitly check for illegal first character in symbol names.
Wrote logic to check symbol names for illegal characters throughout.
1 parent 0536f86 commit 1d97334228cab16b97cd5be39de74b06c10de8d5
@tundra tundra authored on 14 Apr 2004
Showing 1 changed file
View
174
tconfpy.py
 
# Program Information
 
PROGNAME = "tconfpy"
RCSID = "$Id: tconfpy.py,v 1.170 2004/04/14 02:26:08 tundra Exp $"
RCSID = "$Id: tconfpy.py,v 1.171 2004/04/14 20:53:25 tundra Exp $"
VERSION = RCSID.split()[2]
 
# Copyright Information
 
PREDEFINTRO + "PLATFORM" : sysplat,
PREDEFINTRO + "PYTHONVERSION" : platform.python_version()
}
 
 
# Symbols Illegal As First Character Of Variable/Namespace Name
 
IllegalStart = (ENVIRO)
 
# Symbols Illegal Anywhere In A Variable/Namespace Name
 
IllegalChars = (DELIML, DELIMR, COMMENT)
 
 
# Regular Expressions
 
reVARWHITE = r".*\s+.*" # Look for embedded whitespace
reVARREF = r"\%s.+?\%s" % (DELIML, DELIMR) # Variable reference
##########
# Debug Literals And Messages
##########
 
# Literals
# Debug Literals
 
dDEBUG = "DEBUG"
dLINEIGNORE = "Line Ignored"
 
dBLANKLINE = "Parsed To Blank Line. %s" % dLINEIGNORE
dNOTINCLUDE = "Current Conditional Block False. %s" % dLINEIGNORE
 
# Messages
# Debug Messages
 
Messages["dLINEIGNORE"] = FILENUM + " '%s'" + PTR + "%s\n"
Messages["dNAMESPACE"] = FILENUM + "Setting Current Namespace To: '%s'"
Messages["dNUMLINES"] = "Processing File '%s' Resulted In %d Total Lines Parsed"
###########
# Error Literals And Messages
###########
 
# Literals
# Error Literals
 
eERROR = "ERROR"
 
eBADDEFAULT = "Type Of Default Value Does Not Agree With Type Declared"
eNOTDESCRIPT = "Invalid Descriptor Type"
eNOVARREF = "Must Have At Least One Variable Reference"
eSTARTUP = "<Program Starting>"
 
# Messages
# Error Messages
 
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["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)
Messages["eIFEXTRATXT"] = FILENUM + "Extra Text On Line. '%s' Only Accepts Variable References As Arguments"
Messages["eNAMESPACEILLEGAL"] = FILENUM + "'%s' Is An Illegal Namespace. Begins With '%s' Symbol"
Messages["eNAMESPACENEW"] = FILENUM + "New Namespace Creation Not Permitted. Current Namespace Unchanged: '%s'"
Messages["eNOTLEGALVAL"] = FILENUM + "'%s' Not Found In List Of Legal Values For Variable '%s'"
Messages["eSTRINGLONG"] = FILENUM + "Right-Hand-Side Too Long. '%s' Must Be No More Than %s Characters Long"
Messages["eSTRINGSHORT"] = FILENUM + "Right-Hand-Side Too Short. '%s' Must Be At Least %s Characters Long"
Messages["eSYMBADCHAR"] = FILENUM + "Symbol '%s' Contains Illegal Character '%s'"
Messages["eSYMBADSTART"] = FILENUM + "Symbol '%s' Begins With An Illegal Character"
Messages["eSYMNAMESPC"] = FILENUM + "Symbol Names May Not Contain Whitespace"
Messages["eSYMNONAME"] = FILENUM + "Symbol Name Evaluates To Null String. Not Permitted"
Messages["eTYPEBAD"] = FILENUM + "Type Mismatch. '%s' Must Be Assigned Values Of Type %s Only"
Messages["eVALLARGE"] = FILENUM + "%s Is Larger Than The Maximum Allowed, %s, For Variable '%s'"
Messages["eVALSMALL"] = FILENUM + "%s Is Smaller Than The Minimum Allowed, %s, For Variable '%s'"
Messages["eVARNAMESPC"] = FILENUM + "Variable Names May Not Contain Whitespace"
Messages["eVARHASDELIM"] = FILENUM + "Variable Names May Not Include The '%s' Or '%s' Characters" % (DELIML, DELIMR)
Messages["eVARILLEGAL"] = FILENUM + "'%s' Is An Illegal Variable Name Here. Begins With '%s' Symbol"
Messages["eVARNEW"] = FILENUM + "New Variable Creation Not Permitted"
Messages["eVARNONAME"] = FILENUM + "Variable Name Evaluates To Null String. Not Permitted"
Messages["eVARREADONLY"] = FILENUM + "Variable '%s' Is Read-Only. Cannot Change Its Value"
Messages["eVARREFNEST"] = FILENUM + "Nested Variable References Are Not Permitted"
Messages["eVARUNDEF"] = FILENUM + "Attempt To Reference Undefined Variable '%s'"
 
###########
# Warning Literals And Messages
###########
 
# Literals
# Warning Literals
 
wWARNING = "WARNING"
 
# Messages
# Warning Messages
 
Messages["wENDLITEXTRA"] = FILENUM + "'%s' Statement Without Preceding '%s'. Statement Ignored" % (ENDLITERAL, LITERAL)
Messages["wENDLITMISS"] = FILENUM + "Missing '%s' Statement. All lines treated literally to end-of-file" % ENDLITERAL
Messages["wLITEXTRA"] = FILENUM + "Already In A Literal Block. '%s' Statement Ignored" % LITERAL
for var in VarRef.findall(line):
 
sym = var[1:-1] # Strip delimiters
 
# Do some preliminary tests to validate variable names
# Make sure there is no whitespace in the variable reference
 
if VarWhite.match(sym):
ErrorMsg("eVARNAMESPC", (cfgfile, linenum))
ref_ok = False
 
# Look for evidence of attempts to nest variable references
 
if sym.count(DELIML) or sym.count(DELIMR):
ErrorMsg("eVARREFNEST", (cfgfile, linenum))
ref_ok = False
# Make sure symbol name is properly formed
 
ref_ok = ValidateSymbolName(sym, cfgfile, linenum)
# If Preliminary tests found errors - quit now
if not ref_ok:
# Flag attempts to create new namespaces if this is disabled
if not ALLOWNEWNS and ns != SymTable[NAMESPACE].Value and ns not in SymTable[NAMESPACE].LegalVals:
ErrorMsg("eNAMESPACENEW", (cfgfile, linenum, SymTable[NAMESPACE].Value))
# Make sure the namespace does not start with the ENVIRO introducer
 
elif ns and ns[0] == ENVIRO:
ErrorMsg("eNAMESPACEILLEGAL", (cfgfile, linenum, ns, ENVIRO))
# Make sure the namespace is properly formed
 
elif not ValidateSymbolName(ns, cfgfile, linenum, AllowEmpty=True):
pass # Validation function issues relevant error messages
 
 
# Install the new namespace
else:
 
if DEBUG:
DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dNOTINCLUDE))
return
 
# Catch attempts to dereference without name
# Catch attempts to dereference without name anywhere in the line
 
if line.count(DELIML + DELIMR):
ErrorMsg("eVARNONAME", (cfgfile, linenum))
ErrorMsg("eSYMNONAME", (cfgfile, linenum))
 
if DEBUG:
DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
e = line.index(EQUAL)
l = line[:e].strip()
r = line[e+1:].strip()
 
# Make sure the variable name has no spaces in it
 
if VarWhite.match(l):
ErrorMsg("eVARNAMESPC", (cfgfile, linenum))
 
# Suppress attempts to set null-named variables
 
elif not l:
ErrorMsg("eVARNONAME", (cfgfile, linenum))
 
# Variables may not contain reference delimiters
 
elif l.count(DELIML) or l.count(DELIMR):
ErrorMsg("eVARHASDELIM", (cfgfile, linenum))
# Make sure symbol name is properly formed
 
if not ValidateSymbolName(l, cfgfile, linenum):
pass # Validation function issues relevant error messages
 
# Suppress any attempt to change a RO variable
# ***NOTE***
if not ALLOWNEWNS and r != SymTable[NAMESPACE].Value and r not in SymTable[NAMESPACE].LegalVals:
ErrorMsg("eNAMESPACENEW", (cfgfile, linenum, SymTable[NAMESPACE].Value))
update = False
# Make sure the new namespace does not start with the ENVIRO introducer
elif r and r[0] == ENVIRO:
ErrorMsg("eNAMESPACEILLEGAL", (cfgfile, linenum, r, ENVIRO))
update = False
# Make sure the new namespace does not start with
# an illegal character.
elif not ValidateSymbolName(r, cfgfile, linenum, AllowEmpty=True):
update = False # Validation function issues relevant error messages
 
# Install the new namespace
else:
if l == NSSEP + NAMESPACE:
# In all other cases prepend current namespace
else:
ns = SymTable[NAMESPACE].Value
 
# Top level namespace variables don't need separator
# Also, make sure the variable name does not begin with ENVIRO introducer.
# If it does, do nothing, and we'll catch the error below.
# Top level namespace variables don't need
# separator Also, make sure the variable name does
# not begin with an illegal character. If it
# does, do nothing, and we'll catch the error
# below.
if ns and l[0] != ENVIRO:
if ns and l[0] not in IllegalStart:
l = "%s%s%s" % (ns, NSSEP, l)
 
d = VarDescriptor()
 
# create the new entry
 
if l not in SymTable:
 
# Make sure the variable name does not begin with ENVIRO introducer
if l[0] == ENVIRO:
ErrorMsg("eVARILLEGAL", (cfgfile, linenum, l, ENVIRO))
# Make sure the variable name does not begin with
# an illegal character.
if l[0] in IllegalStart:
ErrorMsg("eVARILLEGAL", (cfgfile, linenum, l, l[0]))
 
# Only do this if new variable creation allowed
elif ALLOWNEWVAR:
d.Default = r
##########
 
 
# End of 'ParseLine'
 
 
#####
# Ensure Symbol Name Is Properly Formed
#####
 
def ValidateSymbolName(sym, cfgfile, linenum, AllowEmpty=False):
 
sym_ok = True
 
# Check for whitespace
 
if VarWhite.match(sym):
ErrorMsg("eSYMNAMESPC", (cfgfile, linenum))
sym_ok = False
 
 
# Check for empty symbols if they are disallowed
 
if not AllowEmpty and not sym:
ErrorMsg("eSYMNONAME", (cfgfile, linenum))
sym_ok = False
 
# Check for illegal starting symbol
 
if sym and sym[0] in IllegalStart:
ErrorMsg("eSYMBADSTART", (cfgfile, linenum, sym))
sym_ok = False
 
# Check for illegal characters in symbol name
 
for c in sym:
if c in IllegalChars:
ErrorMsg("eSYMBADCHAR", (cfgfile, linenum, sym, c))
sym_ok = False
 
# Return symbol validity
 
return sym_ok
 
# End Of 'ValidateSymbolName()'
 
 
#----------------------------------------------------------#
# List Of Public Names Available To Program Importing Us #