| |
---|
| | .SS API Overview |
---|
| | |
---|
| | .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. |
---|
| | See the section in the language reference below on \'.literal\' |
---|
| |
---|
| | |
---|
| | |
---|
| | .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 |
---|
| | |
---|
| |
---|
| | |