Added sections on API options.
Fleshed out most of section on passing symbol tables.
Added AllowNewVars option description.
Added short explanation of error handling.
1 parent 02028a7 commit deac4ee46fb4f96b4d453f01989ed27ce4b7acde
@tundra tundra authored on 6 Apr 2004
Showing 1 changed file
View
123
tconfpy.3
.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