| |
---|
| | \fCtconfpy\fP can parse configurations both in files as well as in-memory |
---|
| | lists. Whenever you see the term "file", think "a file or a set of |
---|
| | configuration statements stored in a list". |
---|
| | |
---|
| | .B ANOTHER NOTE: |
---|
| | Throughout this document we refer to "symbols" and "variables" |
---|
| | interchangeably. Strictly speaking, this is not really right. A |
---|
| | "symbol" is an entry in a symbol table representing the state of some |
---|
| | "variable" that is visible to a person writing a configuration. But |
---|
| | it's safe to assume you're smart enough to understand this subtlety |
---|
| | and know what is meant by context ;) |
---|
| | |
---|
| | .B JUST ONE LAST NOTE: |
---|
| | If you run \fCtconfpy\fP directly, it will dump version and copyright |
---|
| | information, as well as the value of the current predefined |
---|
| | System Variables: |
---|
| | |
---|
| |
---|
| | .ft C \" Courier |
---|
| | .nf |
---|
| | class SymbolTable(object): |
---|
| | def __init__(self): |
---|
| | |
---|
| | # These items are populated when the parser returns |
---|
| | |
---|
| | self.Symbols = {} |
---|
| | self.DebugMsgs = [] |
---|
| | self.ErrMsgs = [] |
---|
| | self.WarnMsgs = [] |
---|
| | self.LiteralLines = [] |
---|
| | self.TotalLines = 0 |
---|
| | self.Visited = [] |
---|
| | |
---|
| | # These items are for internal parser use only |
---|
| | # Never write an application to depend on their content |
---|
| | |
---|
| | self.Templates = Template() |
---|
| | self.ALLOWNEWVAR = True |
---|
| | self.TEMPONLY = False |
---|
| | self.LITERALVARS = False |
---|
| |
---|
| | if you wish to provide an initial symbol table. In this case, |
---|
| | only \fCSymbols\fP need be populated. |
---|
| | |
---|
| | When the parse is complete, an object of this same type is returned. |
---|
| | \fCSymbols\fP, \fCDebugMsgs\fP, \fCErrMsgs\fP, \fCWarnMsgs\fP, and |
---|
| | \fCLiteralLines\fP will be populated with the parse results as |
---|
| | appropriate. |
---|
| | \fCSymbols\fP, \fCDebugMsgs\fP, \fCErrMsgs\fP, \fCWarnMsgs\fP, |
---|
| | \fCLiteralLines\fP, \fCTotalLines\fP, and \fCVisited\fP will be |
---|
| | populated with the parse results as appropriate. The remaining |
---|
| | elements of the object are meaningless when the parser returns, and |
---|
| | applications should never make use of them. |
---|
| | |
---|
| | |
---|
| | .TP |
---|
| | .B The Variable Descriptor Object |
---|
| |
---|
| | list in sequential order, treating each entry as a configuration line. |
---|
| | This allows you to use \fCtconfpy\fP for parsing either configuration files or |
---|
| | in-memory configurations. If you pass anything other than a string |
---|
| | or list here, \fCtconfpy\fP will produce an error. |
---|
| | |
---|
| | If you do pass the API an in-memory list, \fCtconfpy\fP treats each |
---|
| | entry as a line in a configuration "file". However, this means that |
---|
| | each element of the list must be a |
---|
| | .B string. |
---|
| | The parser checks this first and only processes entries in the list |
---|
| | that are strings. Entries of any other type produce an error and are |
---|
| | ignored. |
---|
| | |
---|
| | |
---|
| | .TP |
---|
| | .B CallingProgram (Default: \fC\fCtconfpy\fP + Version Number\fP) |
---|
| |
---|
| | this: |
---|
| | |
---|
| | .ft C \" Courier |
---|
| | .nf |
---|
| | |
---|
| | from tconfpy import * |
---|
| | |
---|
| | # Create an empty symbol table |
---|
| | MySymTable = SymbolTable() |
---|
| |
---|
| | |
---|
| | # Repeat this process for all variables, then call the parser |
---|
| | |
---|
| | retval = ParseConfig("MyConfigFile", InitialSymTable=MySymTable) |
---|
| | |
---|
| | .fi |
---|
| | .ft \" revert |
---|
| | |
---|
| | |
---|
| |
---|
| | |
---|
| | .ft C \" Courier |
---|
| | .nf |
---|
| | retval = ParseConfig("myconfigfile", AllowNewVars=False) |
---|
| | .fi |
---|
| | .ft \" revert |
---|
| | |
---|
| | This means that the configuration file can "reference" |
---|
| | any predefined variables, and even change their values |
---|
| | (if they are Writeable), but it cannot create |
---|
| | w.fi |
---|
| | .ft \" revert |
---|
| | |
---|
| | This means that the configuration file can "reference" any predefined |
---|
| | variables, and even change their values (if they are Writeable), but |
---|
| | it cannot create |
---|
| | .B new |
---|
| | variables. |
---|
| | |
---|
| | This feature is primarily intended for use when you pass an initial |
---|
| |
---|
| | example: |
---|
| | |
---|
| | .ft C \" Courier |
---|
| | .nf |
---|
| | |
---|
| | inter1 = Really, really, really, really, long argument #1 |
---|
| | inter2 = Really, really, really, really, long argument #2 |
---|
| | |
---|
| | realvar = command [inter1] [inter2] |
---|
| |
---|
| | .B exact same thing |
---|
| | as a predefined variable you might pass in the initial symbol |
---|
| | table. In other words, it is a Python dictionary entry where the |
---|
| | key is the variable name and the entry is in \fCVarDescriptor\fP |
---|
| | format. |
---|
| | |
---|
| | The only difference is that a templated variable does not come into |
---|
| | existence in the main symbol table until a variable by that |
---|
| | format. The big difference here is that normal variables are stored |
---|
| | in the symbol table in a \fCSymbolTable\fP container object. But |
---|
| | templated variables are stored in a \fCTemplate\fP container object. |
---|
| | (See |
---|
| | .B Core Objects |
---|
| | above for the details.) |
---|
| | |
---|
| | Templated variables are thus defined (by the calling program) just |
---|
| | like you would any other variable - but stored in a different place: |
---|
| | |
---|
| | .ft C \" Courier |
---|
| | .nf |
---|
| | from tconfpy import * |
---|
| | |
---|
| | # Create an empty template table |
---|
| | MyTemplates = Template() |
---|
| | |
---|
| | # Create descriptor for new variable |
---|
| | MyTemplateVarDes = VarDescriptor() |
---|
| | |
---|
| | # Code to fiddle with descriptor contents goes here |
---|
| | MyTemplateVarDes.Type = TYPE_INT |
---|
| | |
---|
| | ... and so forth |
---|
| | |
---|
| | # Now load the variable into the symbol table |
---|
| | MyTemplates.Symbols["MyTemplateName"] = MyTemplateVarDes |
---|
| | |
---|
| | # Now pass the Templates to the parser |
---|
| | retval = ParseConfig("myfile", Templates=MyTemplates) |
---|
| | .fi |
---|
| | .ft \" revert |
---|
| | |
---|
| | .B NOTE: |
---|
| | You may optionally pass either an initial symbol table or a template |
---|
| | table or both to the parser when you call it. That is, the initial |
---|
| | set of symbols is disjoint from any templates you've defined. |
---|
| | |
---|
| | Semantically, the only difference between "regular" and templated |
---|
| | variables, is that a templated variable does not come into existence |
---|
| | (i.e. Become an entry) in the main symbol table until a variable by |
---|
| | that |
---|
| | .B name |
---|
| | is encountered in the configuration file. Then the variable is |
---|
| | created using the template as its entry in the main symbol table. |
---|
| | |
---|
| |
---|
| | If there is a template with a matching name, see if the value the |
---|
| | user wants to assign to that variable passes all the type/validation |
---|
| | rules. If so, load the variable into the symbol table and set its |
---|
| | value as requested, |
---|
| | .B using the \fCVarDescriptor\fP object from the template. |
---|
| | .B using the |
---|
| | \fCVarDescriptor\fP |
---|
| | .B object from the template. |
---|
| | (This ensures that future attempts to change the variable's value will |
---|
| | also be type/validation checked.) |
---|
| | |
---|
| | If the assignment fails the validation tests, issue an appropriate |
---|
| |
---|
| | which means you can create new variables even when no template |
---|
| | for them exists. |
---|
| | |
---|
| | .P |
---|
| | A few subtleties of templating variables are worth noting here: |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | The same template is used over and over again to create a |
---|
| | new variable of the same name |
---|
| | .B in different namespaces. |
---|
| | For example, suppose you've defined a template with the name, |
---|
| | \fCAccountNumber\fP: |
---|
| | |
---|
| | .ft C \" Courier |
---|
| | .nf |
---|
| | [ComputerSupplier] |
---|
| | AccountNumber = 1234-5 |
---|
| | |
---|
| | [Lawyer] |
---|
| | AccountNumber = 3456-3 |
---|
| | .fi |
---|
| | .ft \" revert |
---|
| | |
---|
| | This would create two separate variables in the symbol table, based |
---|
| | on the same template: \fCComputerSupplier.AccountNumber\fP and |
---|
| | \fCLawyer.AccountNumber\fP. |
---|
| | |
---|
| | This works because \fCtconfpy\fP checks the so-called "canonical" name |
---|
| | of a variable when it is being created (the part of the name without |
---|
| | the namespace information) to see if a template exists for it. For |
---|
| | this reason, |
---|
| | .B a template name must never contain a namespace. |
---|
| | If you attempt to create templates with names like \fCFoo.Templatename\fP, |
---|
| | the parser will reject it and produce an error. |
---|
| | |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | Notice that for variables actually in the symbol table, |
---|
| | \fCVarDescriptor.Value\fP holds the current value for the variable. |
---|
| | However, this field is meaningless in a template. The template is |
---|
| | only used when creating a new variable |
---|
| | .B to be added the normal symbol table. |
---|
| | The value field of the template's variable descriptor is never |
---|
| | used for anything - it is never read nor is it ever set. |
---|
| | |
---|
| | .IP \(bu 4 |
---|
| | By definition, a templated variable does not actually exist (in the |
---|
| | symbol table) until you assign it some value in the configuration |
---|
| | file. This means that even if you mark the variable as Read Only |
---|
| | in its template, you are able to set it one time - to actually |
---|
| | create it. Thereafter, the variable exists in the symbol table |
---|
| | with it's \fCWriteable\fP attribute set to \fCFalse\fP and future |
---|
| | changes to the variable are prevented |
---|
| | |
---|
| | .P |
---|
| | In summary, Variable Templates give you a way to place |
---|
| | restrictions on variable type and content |
---|
| | .B in the event that the variable actually comes into existence. |
---|
| | They also give you a way to define such restrictions for an |
---|
| |
---|
| | .B retval.DebugMsgs |
---|
| | |
---|
| | A Python list containing detailed debug information for each line |
---|
| | parsed as well as some brief summary information about the parse. |
---|
| | \fCretval.Debug\fP defaults to an empty list and is only populated if you |
---|
| | \fCretval.DebugMsgs\fP defaults to an empty list and is only populated if you |
---|
| | set \fCDebug=True\fP in the API call that initiated the parse (as in the |
---|
| | example above). |
---|
| | |
---|
| | |
---|
| |
---|
| | .TP |
---|
| | .B retval.WarnMsgs |
---|
| | A Python list containing warning messages. These describe minor |
---|
| | problems not fatal to the parse process, but that you really ought to |
---|
| | clean up in the configuration file. |
---|
| | clean up in the configuration file. It is possible to create a configuration |
---|
| | that produces no errors but does produce warnings, for example. It is |
---|
| | almost always the case that this configuration is not being handled |
---|
| | the way you intended. As a general matter of good practice, apply |
---|
| | "belt and suspenders" rules in your applications, and demand that |
---|
| | a configration be free of both errors and warnings before proceding. |
---|
| | |
---|
| | |
---|
| | .TP |
---|
| | .B retval.LiteralLines |
---|
| |
---|
| | .fi |
---|
| | .ft \" revert |
---|
| | |
---|
| | .SH DOCUMENT REVISION INFORMATION |
---|
| | $Id: tconfpy.3,v 1.156 2005/01/20 00:07:38 tundra Exp $ |
---|
| | |
---|
| | $Id: tconfpy.3,v 1.157 2005/01/20 08:18:32 tundra Exp $ |
---|
| | |
---|
| | |