Restructured the error/warning/debug message reporting logic
to report message type along with the detail.
Generally cleaned up various message types.
1 parent 728c730 commit d2b7ad2d4acf0de455940cebf0aa0eea645911ee
@tundra tundra authored on 16 Mar 2004
Showing 1 changed file
View
225
tconfpy.py
 
# Program Information
 
PROGNAME = "tconfpy"
RCSID = "$Id: tconfpy.py,v 1.118 2004/03/16 03:18:19 tundra Exp $"
RCSID = "$Id: tconfpy.py,v 1.119 2004/03/16 10:35:47 tundra Exp $"
VERSION = RCSID.split()[2]
 
# Copyright Information
 
###########
 
# Formatting Constants
 
MSGPOS = 10 # Where to start message output
MSGPROMPT = "%s>"
FILENUM = "[File: %s Line: %s]" # Display filename and linenum
PTR = " ---> " # Textual pointer for debug output
 
 
None
]
 
##########
# Error, Warning, And Debug Message Strings Stored In A Global Dictionary
##########
 
Messages = {}
 
 
#----------------------------------------------------------#
# Prompts, & Application Strings #
#----------------------------------------------------------#
 
 
##########
# Debug Messages
##########
 
 
##########
# Debug Literals And Messages
##########
 
# Literals
 
dDEBUG = "DEBUG"
 
dBLANKLINE = "Parsed To Blank Line - Ignored"
dLINEIGNORE = FILENUM + " '%s' " + PTR + "%s\n"
dNOTINCLUDE = "Current Conditional Block False: Line Not Included"
dNUMLINES = "Processing File '%s' Resulted In %d Total Lines Parsed"
dPARSEDLINE = FILENUM + " '%s'" + PTR + "'%s'\n"
 
###########
# Error Messages
###########
 
# Messages
 
Messages["dLINEIGNORE"] = FILENUM + " '%s' " + PTR + "%s\n"
Messages["dNUMLINES"] = "Processing File '%s' Resulted In %d Total Lines Parsed"
Messages["dPARSEDLINE"] = FILENUM + " '%s'" + PTR + "'%s'\n"
 
 
###########
# Error Literals And Messages
###########
 
# Literals
 
eERROR = "ERROR"
eSYNTAX = "Incorrect '%s' Syntax"
 
eBADEXPR = FILENUM + " Bad Expression - %s: '%s'"
eCONFOPEN = "Cannot Open The File '%s'"
eENDIFEXTRA = FILENUM + " '" + ENDIF + "' Without Matching Condition"
eENDIFBAD = eSYNTAX % ENDIF
eENDIFMISS = FILENUM + " Missing %d '" + ENDIF + "' Statement(s)"
eIFBAD = eSYNTAX % IF
eINCLBAD = eSYNTAX % INCLUDE
eNOVARREF = "Must Have At Least One Variable Reference"
eVARUNDEF = FILENUM + " " + "Attempt To Reference Undefined Variable '%s'"
 
 
###########
# Warning Messages
###########
 
# Messages
 
Messages["eBADCOND"] = FILENUM + " Bad Directive - %s %s"
Messages["eCONFOPEN"] = "Cannot Open The File '%s'"
Messages["eENDIFEXTRA"] = FILENUM + " '" + ENDIF + "' Without Matching Condition"
Messages["eENDIFMISS"] = FILENUM + " Missing %d '" + ENDIF + "' Statement(s)"
Messages["eVARUNDEF"] = FILENUM + " " + "Attempt To Reference Undefined Variable '%s'"
 
 
###########
# Warning Literals And Messages
###########
 
# Literals
 
wWARNING = "WARNING"
 
wEXTRATEXT = FILENUM + " '%s' Statements Only Process Variables. Extra Text Ignored"
wTRAILING = FILENUM + " Trailing Text After '%s' Statement Ignored"
# Messages
 
Messages["wEXTRATEXT"] = FILENUM + " '%s' Statements Only Process Variables. Extra Text Ignored"
Messages["wTRAILING"] = FILENUM + " Trailing Text After '%s' Statement Ignored"
 
 
# Determine Length Of Longest Message Type
# Needed for formatting later
 
MAXMSG = 0
for msg in Messages:
l = len(msg)
if l > MAXMSG:
MAXMSG = l
 
 
#--------------------------- Code Begins Here ---------------------------------#
 
##########
# Create A Debug Message
##########
 
def DebugMsg(dmsg):
def DebugMsg(dmsg, args):
 
global DebugMsgs
DebugMsgs.append(mkmsg(dmsg, dDEBUG))
DebugMsgs.append(mkmsg(Messages[dmsg] % args, dmsg))
 
# End of 'DebugMsg()'
 
 
##########
# Create An Error Message
##########
 
def ErrorMsg(error):
def ErrorMsg(error, args):
 
global ErrMsgs
ErrMsgs.append(mkmsg(error + "!", eERROR))
ErrMsgs.append(mkmsg(Messages[error] % args + "!", error))
 
# End of 'ErrorMsg()'
 
 
##########
# Create A Warning Message
##########
 
def WarningMsg(warning):
def WarningMsg(warning, args):
 
global WarnMsgs
WarnMsgs.append(mkmsg(warning + "!", wWARNING))
WarnMsgs.append(mkmsg(Messages[warning] % args + "!", warning))
 
# 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)
def mkmsg(msg, msgtype):
 
pad = " " * (MAXMSG - len(msgtype) + 2)
 
return "%s %s%s%s" % (PROGINFO, MSGPROMPT % msgtype, pad, msg)
 
 
# End of 'mkmsg()'
 
 
# Return the parsing results
 
if DEBUG:
DebugMsg(dNUMLINES %(cfgfile, TotalLines))
DebugMsg("dNUMLINES", (cfgfile, TotalLines))
return (SymTable, ErrMsgs, WarnMsgs, DebugMsgs)
 
 
# Attempts to reference undefined variables are legitimate
# in this case and ought not to generate an error message.
 
if reporterr:
ErrorMsg(eVARUNDEF % (cfgfile, linenum, sym))
ErrorMsg("eVARUNDEF", (cfgfile, linenum, sym))
 
ref_ok = False
 
return line, ref_ok
 
# File open failed for some reason
except:
 
ErrorMsg(eCONFOPEN % cfgfile) # Record the error
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))
ErrorMsg("eENDIFMISS", (cfgfile, linenum, finalcond-1))
 
# End of 'ParseFile()'
 
 
if line.startswith(ENDIF):
 
# Check for space after conditional
if line.split()[0] != ENDIF:
ErrorMsg(eBADEXPR % (cfgfile, linenum, eENDIFBAD, orig))
ErrorMsg("eBADCOND", (cfgfile, linenum, eENDIFBAD, "'%s'" % orig))
 
# This should be the only thing on the line
elif line != ENDIF:
WarningMsg(wTRAILING % (cfgfile, linenum, ENDIF))
WarningMsg("wTRAILING", (cfgfile, linenum, ENDIF))
 
# Remove one level of nesting
CondStack.pop()
 
# Error, if there are more .endifs than conditionals
if not CondStack:
ErrorMsg(eENDIFEXTRA % (cfgfile, linenum))
ErrorMsg("eENDIFEXTRA", (cfgfile, linenum))
CondStack.append(False) # Inhibit further parsing
 
#####
# Check State Of Parser
#####
 
 
if not CondStack[-1]:
if DEBUG:
DebugMsg(dLINEIGNORE % (cfgfile, linenum, orig, dNOTINCLUDE))
DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dNOTINCLUDE))
return
 
#####
# .include Processing
if line.startswith(INCLUDE):
 
# Make sure a space follows the directive
if line.split()[0] != INCLUDE:
ErrorMsg(eBADEXPR % (cfgfile, linenum, eINCLBAD, orig))
ErrorMsg("eBADCOND", (cfgfile, linenum, eINCLBAD, "'%s'" % orig))
 
else:
ParseFile(line.split(INCLUDE)[1].strip())
 
 
# There must be at least one var reference in the condition
 
vars = VarRef.findall(line)
if len(vars) > 0:
 
# Only variable references are significant - warn on other text.
 
# Strip out variable references and see if anything
# other than whitespace is left.
plain = line
 
# Only variable references are significant - warn on other text.
 
# Strip out variable references and see if anything
# other than whitespace is left.
 
plain = line
if vars:
for v in vars:
plain=plain.replace(v, "")
 
if len(plain.strip()):
WarningMsg(wEXTRATEXT % (cfgfile, linenum, IFTYPE))
if len(plain.strip()):
WarningMsg("wEXTRATEXT", (cfgfile, linenum, IFTYPE))
 
if vars:
 
# Go see how many references actually resolve
resolved = 0
resolved += 1
 
# And set state accordingly
 
state = sTRUE
state = True
if IFTYPE == IFALL and len(vars) != resolved:
state = sFALSE
state = False
 
if IFTYPE == IFANY and not resolved:
state = sFALSE
state = False
 
if IFTYPE == IFNONE and resolved:
state = sFALSE
state = False
 
CondStack.append(state)
line = state
 
# Bogus conditional syntax
 
# Now reflect this in the parsed line
line = sTRUE
if not state:
line = sFALSE
 
# Bogus conditional syntax - no variable refs found
else:
ErrorMsg(eBADEXPR % (cfgfile, linenum, eNOVARREF, orig))
ErrorMsg("eBADCOND", (cfgfile, linenum, "'%s'" % orig, eNOVARREF))
 
#####
# (In)Equality Conditionals
#####
elif line.count(NOTEQUIV):
pass
 
#####
# Line Started With IF, But Was Not In Any Knwon IF Form
# Line Started With IF, But Was Not In Any Known IF Form
#####
 
else:
ErrorMsg(eBADEXPR % (cfgfile, linenum, eIFBAD, orig))
ErrorMsg("eBADCOND", (cfgfile, linenum, eIFBAD, "'%s'" % orig))
 
#####
# Handle New Variable Declaration/Assignment
##########
# End Of Line Parser
##########
 
 
##########
# Write Fully Parsed Line To Debug Log If Requested
##########
 
if DEBUG:
 
# Note blank lines for debug purposes
if not line:
DebugMsg(dLINEIGNORE % (cfgfile, linenum, orig, dBLANKLINE))
DebugMsg("dLINEIGNORE", (cfgfile, linenum, orig, dBLANKLINE))
 
# All non-blank lines noted here
else:
DebugMsg(dPARSEDLINE % (cfgfile, linenum, orig, line))
DebugMsg("dPARSEDLINE", (cfgfile, linenum, orig, line))
 
 
 
# End of 'ParseLine'