#!/usr/bin/env python # test-tc.py - A Test Driver For The 'tconfpy' Configuration File Parser # Copyright (c) 2003-2004 TundraWare Inc. All Rights Reserved. PROGNAME = "tconfpy Test Driver" RCSID = "$Id: test-tc.py,v 1.132 2004/04/16 19:50:47 tundra Exp $" VERSION = RCSID.split()[2] # Copyright Information CPRT = chr(169) DATE = "2004" OWNER = "TundraWare Inc." RIGHTS = "All Rights Reserved" COPYRIGHT = "Copyright %s %s %s, %s." % (CPRT, DATE, OWNER, RIGHTS) PROGINFO = PROGNAME + " " + VERSION BANNER = "%s\n%s\n%s\n" % (PROGINFO, COPYRIGHT, RCSID) #---------------------------------------------------------------------------# # Imports And Other Odds-And-Ends # #---------------------------------------------------------------------------# from tconfpy import * import sys # Translation table for booleans into equivalent writeable state TF = {True:"RW", False:"RO"} #---------------------------------------------------------------------------# # Build An Initial Symbol Table # #---------------------------------------------------------------------------# # One of the options of this test driver is to initialize a test symbol # table. We build that table here in case the user requested it. # Create An Empty Symbol Table symtbl = {} # This test driver makes it easy to add pre-defined symbols of # your own choosing. The first way is like this ... # The data below is used to populate an initial symbol table. You can add or # change things here without modifying any of the following code. # Each symbol has an entry which is a list with the following items: # # Name, Value, Writeable, Type, Default, LegalVals, Min, Max # # Where 'None' appears, the init code just uses the default established # by the VarDescriptor base class. syms = [ ["int1", 1, True, TYPE_INT, 0, [1, 2, 23], None, None ], ["int2", 1, True, TYPE_INT, 0, [], 1, 30 ], ["float1", 1.0, None, TYPE_FLOAT, 0.5, [3.14, 2.73], None, None ], ["float2", 1.0, None, TYPE_FLOAT, 0.5, [], -1.2, 0.5 ], ["str1" , "stringy", None, None, None, [r'^box$', r'^Bax', r'a+bc'], 3, 8 ], ["cmplx1", 4+5j, None, TYPE_COMPLEX, 0-0j, [], None, None ], ["cmplx2", 4+5j, None, TYPE_COMPLEX, 0-0j, [1-1j, 1+1j], None, None ], ["bool1", True, None, TYPE_BOOL, None, None, None, None ], ["ro1", "ReadVar", False, None, None, None, None, None ], ] # Another way to add pre-defined symbols is to explicitly load # them into the symbol table. The example below does this as # well as demonstrating how to use inheritance to create # your own types derviced from the tconfpy variable descriptor # base class. # Here's a way to inherit the base symbol definition from # the module and then derive a new object type for your # own convenience # Note the use of 'super()' here to run each constructor in # the inheritance tree only once. class mycmplx(VarDescriptor): def __init__(self): super(mycmplx, self).__init__() self.Value = 2-2j self.Default = 39-4j self.Type = TYPE_COMPLEX # Instantiate some of these mc1 = mycmplx() mc2 = mycmplx() mc2.Value = 8-3.14159j mc2.Writeable = False # And stuff them into the symbol table symtbl["MyComplex1"] = mc1 symtbl["MyComplex2"] = mc2 #---------------------------------------------------------------------------# # Nothing Else Should Need Changing Below Here #---------------------------------------------------------------------------# # Fill in the symbol table with stuff defined in the table above for sym in syms: # Create and init the descriptor des = VarDescriptor() pos = 1 for attr in ("Value", "Writeable", "Type", "Default", "LegalVals", "Min", "Max"): val = sym[pos] if val != None: exec("des." + attr + "=val") pos += 1 symtbl[sym[0]] = des #---------------------------------------------------------------------------# # Utility And Support Functions # #---------------------------------------------------------------------------# ########## # Format and return contents of a symbol table entry ########## def dumpsymbol(val, d): retval = str(val) + " " * (18 - len(val)) for v, p in ((d.Value, 20), (TF[d.Writeable], 2), (str(d.Type).split()[1][1:-2], 7), (d.Default, 8), (d.LegalVals, 8), (d.Min, 8), (d.Max, 8)): retval += str(v) + (p - len(str(v)) + 2) * ' ' return retval # End of 'dumpsymbol()' ########## # Routine to dump returned values ########## def dumpreturn(name, data, isdict=False): print name print len(name) * '=' + '\n' items = data if isdict: items = data.keys() items.sort() for val in items: if isdict: print dumpsymbol(val, data[val]) else: print val print '\n' # End of 'dumpreturn()' #---------------------------------------------------------------------------# ########## # Beginning of test driver ########## files = 1 # Make sure we got legit arguments if len(sys.argv) < 2: print BANNER print "Usage: test-tc.py [symtbl] [nonewvar] [limitns] [litvars] [debug] file file ..." sys.exit(1) # Process all the requested configuration files, # dumping the what tconfpy returns for each one. ALLOWVAR = True DEBUG = False LIMITNS = False LITVARS = False ST = False for fn in sys.argv[files:]: # Handle inline options if fn == "symtbl": ST = True elif fn == "nonewvar": ALLOWVAR = False elif fn == "limitns": LIMITNS = True elif fn == "litvars": LITVARS = True elif fn == "debug": DEBUG = True # Everything else presumed to be a configuration file else: # The default is no pre-defined symbols st = {} if ST: st = symtbl if LIMITNS: # Limit the number of namespaces the user can use des = VarDescriptor() des.Value = "NS0" # This is the initial namespace des.LegalVals = [r"^NS.*", ] des.Min = 3 des.Max = 8 st["NAMESPACE"] = des retval = ParseConfig(fn, InitialSymTable=st, AllowNewVars=ALLOWVAR, LiteralVars=LITVARS, Debug=DEBUG ) if retval.Errors: print "Errors Were Found In '%s'!" % fn else: print "No Errors Found In '%s'!" % fn print # Format and display the results dumpreturn("SYMBOL TABLE", retval.SymTable, isdict=True) dumpreturn("ERRORS", retval.Errors) dumpreturn("WARNINGS", retval.Warnings) if DEBUG: dumpreturn("DEBUG", retval.Debug) dumpreturn("LITERAL LINES", retval.Literals)