diff --git a/tconfpy.3 b/tconfpy.3 index b672736..b282fcd 100644 --- a/tconfpy.3 +++ b/tconfpy.3 @@ -157,19 +157,26 @@ .nf -.B ParseConfig(cfgfile, InitialSymTbl={}, Debug=False, LiteralVars=False) +.B ParseConfig(cfgfile, InitialSymTbl={}, AllowNewVars=True, Debug=False, LiteralVars=False) where: .B cfgfile The the name of a file containing configuration information + .B InitialSymTbl A pre-populated symbol table. Defaults to an empty symbol table. As described below, this must contain valid \'VarDescriptor\' entries for each symbol in the table. + +.B AllowNewVars + Allow the user to create new variables in the configuration + file. Defaults to True. + .B Debug Defaults to False. If set to True, \*(TC will provide detailed debugging information about each line processed when it returns. + .B LiteralVars Defaults to False. If set to True this option Enables variable substitutions within \'.literal\' blocks of a configuration file. @@ -251,6 +258,120 @@ .SS Passing An Initial Symbol Table +The simplest way to parse a configuration file is just to call +the parser with the name of that file: + + +.nf +retval = ParseConfig("myconfigfile") +.fi + +Assuming your configuration file is valid, \'ParseConfig()\' will +return a symbol table populated with all the variables defined in the +file and their associated values. This symbol table will have +.B only +the symbols defined in that file (plus a few built-in and pre-defined +symbols needed internally by \*(TC). + +However, the API provides a way for you to pass a "primed" symbol +table to the parser that contains pre-defined symbols/values of +your own choosing. Why on earth would you want to do this? There +are a number of reasons: + +.nf +1) You may wish to write a configuration file which somehow depends + on a pre-defined variable which only the calling program can know: + + .if [APPVERSION] == 1.0 + # Set configuration for older application releases + .else + # Set configuration for newer releases + .endif + + In this example, only the calling application can know its own + version, so it sets the variable APPVERSION in a symbol table + which is passed to \'ParseConfig()\'. + +2) You may wish to "protect" certain variable names be creating + them ahead of time and marking them as "Read Only". This is + useful when you want a variable to be available for use + within a configuration file, but you do not want users to + be able to change its value. In this case, the variable can + be referenced in a string substitution or conditional test, + but cannot be changed. + +3) You may want to place limits on what values can be assigned to + a particular variable. By default, all variables newly defined + within a configuration file are defined to be strings of any + length, with no restrictions on their content. By pre-defining a + variable, you can specify its type (integer, string, boolean, or + complex), a list of possible legal values, a range of legal values, + min/max string length, or a set of regular expressions for string + variables - one of which must match. In other words, you can have + \*(TC "validate" what values the user assigns to particular + variables. This substantially simplifies your application because + no invalid variable value will ever be returned from the parser. + +.fi + + + + +When you pass an initial symbol table to the parser, \*(TC does +some basic validation that the table contents properly conform +to the \'VarDescriptor\' format and generates error messages if +it finds problems. However, the program does +.B not +check your specifications to see if they make sense. For instance +if you define an integer with a minimum value of 100 and a maximum +value of 50, \*(TC cheerfully accepts these limits even they they +are impossible. You'll just be unable to do anything with that +variable - any attempt to change its value will cause an error +to be recorded. Similarly, if you put a value in \'LegalVals\' that +is outside the range of \'Min\' to \'Max\', \*(TC will accept +it quietly. + +.SS The \'AllowNewVars\' Option + +By default, \*(TC lets the user define any new variables they +wish in a configuration file, merely by placing a line in the +file in this form: + +.nf + Varname = Value +.fi + +However, you can disable this capability by calling the parser like +this: + +.nf + retval = ParseConfig("myconfigfile", AllowNewVars=False) +.fi + +This means that the configuration file can "reference" +any pre-defined variables, and even change their values +(if they are not Read-Only), but it cannot create +.B new +variables. This is primarily intended for use when you +pass an initial symbol table to the parser and you do not want +any other variables defined by the user. Why? To prevent them +from making spelling errors. For example, you can define the +variable name "MyEmail" and they will get an error if they +accidentally try to do something like "myemail = x@y.com". + + +.SS How \*(TC Processes Errors + +As a general matter, when \*(TC encounters an error in the +configuration file currently being parsed, it does two things. First, +it adds a descriptive error message into the list of errors returned +to the calling program (see the next section). Secondly, in many +cases, noteably during conditional processing, it sets the parser +state so the block in which the error occurred is logically False. +This does not happen in every case, however. If you are having +problems with errors, enable the Debugging features of the package and +look at the debug output. It provides detailed information about what +caused the error and why. .SS \*(TC Return Values