Added detail concerning conditional directives.
1 parent 88310a3 commit 72c0e7be52b7e80b48365b3cb27145c1977c1bc9
@tundra tundra authored on 17 Apr 2004
Showing 1 changed file
View
95
tconfpy.3
.nf
Variable Name Contains
------------- --------
 
.MACHINENAME - The name of the computer on which you are running.
.MACHINENAME - The name of the computer on which you are running.
May also include full domain name, depending on system.
 
.OSDETAILS - Detailed information about the operating system in use.
 
.OSNAME - The name of the operating system in use.
 
.OSRELEASE - The version of the operating system in use.
 
.PLATFORM - The generic type of the operating system in use.
.OSDETAILS - Detailed information about the operating system in use.
 
.OSNAME - The name of the operating system in use.
 
.OSRELEASE - The version of the operating system in use.
 
.OSTYPE - Generic type of operating system in use.
 
.PLATFORM - The generic type of the operating system in use.
 
.PYTHONVERSION - The version of Python in use.
.fi
 
Why bother? There are several reasons:
 
.IP \(bu 4
This makes it easy to break up large, complex configurations into simpler (smaller)
pieces.
pieces. This generally makes things easier to maintain.
 
.IP \(bu 4
This makes is easy to "factor" common configuration information into separate
files which can then be used by different programs as needed.
 
.IP \(bu 4
But the most common use for \'.include\' is to load a "standard" configuration for
The most common use for \'.include\' is to load a "standard" configuration for
your program. Recall that the last assignment of a variable's value "wins".
Suppose you want all the standard settings for a program, but you just want to
change one or two options. Instead of requiring each user to have the whole
set of standard settings in their own configuration file, the system administrator
can make them available as a common configuration. Each user \'.include\'s
that file and then overrides any options they like:
can make them available as a common configuration. You then \'.include\'
that file and override any options you like:
 
.nf
# Get the standard options
.include /usr/local/etc/MyAppStandardConfig.cfg
 
One last thing needs to be noted here. \*(TC does not detect
so-called "circular" inclusions. If file \'a\' \'.include\'s file
\'b\' and file \'b\' \'.include\'s file \'a\', you will have an
infinite loop of inclusion, which, uh, is a Bad Thing...
infinite loop of inclusion, which, uh ..., is a Bad Thing...
 
.SS Conditional Directives
 
One of the most powerful features of \*(TC is its "conditional
ConditionalDirective Argument(s)
more stuff
.endif
 
interesting stuff
.else
yet more stuff
 
ConditionalDirective Argument(s)
other stuff
.endif
ending stuff
.endif
.fi
 
There are no explicit limits to how deeply you can nest a configuration. However,
you must have an \'.endif\' that terminates each conditional test. Bear in mind that
\*(TC pays no attention to your indentation. It associates an \'.endif\'
.B with the last conditional it encountered.
.B with the last conditional it encountered.
That's why it's a really good idea to use some consistent indentation style so
.B you
can understand the logical structure of the conditions. It's also a
good idea to put comments throughout such conditional blocks so it's
clear what is going on.
 
There are a few general rules to keep in mind when dealing with conditionals:
 
.IP \(bu 4
There must be whitespace between the conditional directive and its
arguments (which may- or may not have whitespace in them).
 
.IP \(bu 4
As with any other kind of \*(TC statement, you may place comments
anywhere at the end of a conditional directive line or within the
conditional blocks.
 
.IP \(bu 4
Each conditional directive must have a corresponding \'.endif\'. If
you have more conditionals than \'.endif\'s or vice-versa, \*(TC will
produce an error message to that effect. It can get complicated to
keep track of this, especially with deeply nested conditionals. It is
therefore recommended that you always begin and end conditional blocks
within the same file. i.e., Don't start a conditional in one file and
then \'.include\' another file that has the terminating \'.endif\' in
it.
 
.IP \(bu 4
The \'.else\' clause is optional. However, it can only appear after
some preceding conditional directive.
 
.IP \(bu 4
As in other parts of the \*(TC language, variable names and references
in conditional directives are always relative to the currently active
namespace unless they are escaped with a leading period. Similarly,
in this context, Environment Variables, Predefined Variables,
and the NAMESPACE Variable are always relative to the root namespace,
no matter what namespace is currently active.
 
 
.SS Existential Conditional Directives
 
There are three Existential Conditionals: \'.ifall\', \'.ifany\', and \'.ifnone\'.
Each has the same syntax:
 
.nf
ExistentialDirective varname ...
included if True
included if test was True
 
.else # optional
include if False
included if test was False
.fi
.fi
 
In other words, existential conditionals require
.B one or more variable names.
In each case, the actual content of that variable is ignored. The test is merely
checking to see
.B if a variable by that name exists.
In other words, existential conditionals require one or more
.B variable names.
In each case, the actual content of that variable is ignored. The test merely
checks to see if a variable by that name
.B exists.
Nothing else may appear on an existential conditional line, except,
perhaps, a comment.
 
The three forms of existential conditional tests implement three different kinds of
.fi
 
You can also use variable references here to get the name of a varible
to test by "indirection" (as we saw in the previous section on
accessing/setting variables indirectly. This is not a recommended
accessing/setting variables indirectly0. This is not a recommended
way of doing things because it can be kind of obscure to understand,
but it is possible to do this:
 
.nf
You can also do indirection through an environment variable, but
this is
.B really
not recommended because of the obscurity it introduces into a
configuration file. Say, $TERM is set to \'vt100\':
configuration file. Say the \'TERM\' environment variable is set to
\'vt100\':
 
.nf
.ifany [$TERM]
...
.endif
.fi
 
This will test to see if a variable called \'vt100\' exists in the
symbol table. Perhaps, not the clearest possible construct!
symbol table. This is, perhaps, not the clearest possible construct!
 
.SS Comparison Conditional Directives
 
There are two Comparison Conditionals:
 
.nf
.if string1 == string2 # True if string1 and string2 are identical
.if string1 != string2 # True if stringa and string2 are different
.if string1 != string2 # True if string1 and string2 are different
.fi
 
As a general matter, you can put literal strings on both sides of such a
test, but the real value of these tests comes when you use variable