# A 'tconfpy' Example Configuration File
# Copyright 2003-2005 TundraWare Inc.
# $Id: example.cfg,v 1.109 2005/01/19 23:22:12 tundra Exp $
#
# This is designed to illustrate the various features
# of the 'tconfpy' configuration language.
#
# You can play with this using the 'test-tc.py' test driver
# program. For instance:
#
# python test-tc.py debug litvars debug example.cfg
# python test-tc.py symtbl litvars debug example.cfg
#
# See the 'test-tc.py' documentation for a description of
# the various options it supports.
#
#
# Whitespace is ignored and used here for neatness.
# Everything is case-sensitive except values for booleans.
#####
# Creating And Modifing Variables
#####
foo = 123 # Creates variable 'foo' and sets its value to "123"
foo = bar # Changes the value of 'foo' to "bar"
Foo = blat # Variable names are case sensistive: New variable 'Foo' introduced here
#####
# Variable References - Getting The Value Of A Variable
#####
boing = [foo] # Creates variable 'boing' and sets its value to "bar"
#####
# Indirect variable access
#####
[foo] = baz # Creates variable 'bar' and sets its value to "baz"
#####
# Accessing Environment Variables
#####
boo = [$USER] # Creates variable 'boo' and assigns it the value
# of the environment variable 'USER'. This will
# cause an error if 'USER' is not defined.
#####
# Namespaces
#####
[NS1] # Changes namespace to 'NS1'
foo = 100 # Creates 'NS1.foo' and sets its value to "100'
NAMESPACE=NS2 # Changes namespace to 'NS2'
bar = [.NS1.foo] # Sets 'NS2.bar' to "100" - notice the escaped variable reference
NAMESPACE = # Reset namespace back to root - can also be done with [] on line by itself
#####
# Existential Conditionals
#####
# Logical AND
.ifall $USER bar # Both environment variable 'USER' and variable 'bar' must
# Exist for this to be true
ifall = True # Notice you cannot use variable 'IFALL' - it is predefined as
# an internal variable for one of the reserved words
# and is marked as Read Only
.else # If either or both did not exist - this is optional
ifall = FALSE
.endif # This is required
# Logical OR
.ifany $USER bar # Either environment variable 'USER' or variable 'bar' must
# exist for this to be true
ifany = TRUE
.else
ifany = I don't THINK so!
.endif
# Logical NOR
.ifnone $USER bar # Neither environment variable 'USER' or variable
# 'bar' may exist for this to be true
ifnone = TRUE
.else
ifnone = No Way Jose'
.endif
#####
# Comparison Conditionals
#####
# In these examples, notice that the left-hand-side of the comparison
# is a variable *reference*. We want to compare the *value* of the
# variable 'NS.2.bar' to the right-hand-side, not the name of the variable.
.if [.NS2.bar] == 100
ifequiv = yup
.endif
.if [.NS2.bar] != 1000
ifnotequiv = yup
.endif
#####
# Literal Text Processing
#####
# In this example, notice that any the variables references in the
# literal block ('[HASH]' and '[MyMsg]') only get replaced if you run
# 'test-tc.py' with the 'litvars' option.
MyMsg = Hello World!
.ifall [foo]
.literal
/* Here is some C Code - Variable Refs below replaced only
if 'litvars' option selected from test-tc.py */
[HASH]include <stdio.h>
main()
{
printf("[MyMsg]");
}
.endliteral
.endif
#####
# Type And Value Enforcement
####
# This illustrates 'tconfpy's ability to enforce type and value
# agreement. To make this work, you have to invoke 'test-tc.py' with
# the 'symtbl' argument. This will pass an initial symbol table with
# validation constraints defined for the variables used below. To see
# the permitted values and types of the variables passed when
# 'symbtbl' is used, look at the top part of the 'test-tc.py' source
# code.
# Some of these examples purposely introduce a type/value
# error to illustrate how 'tconfpy' does validation.
# Write Protection
ro1 = Something # Error: 'ro1' is a Read Only variable
# Type Enforcement
int1 = 4s # Error: 'int1' only accepts integers
# Value Enforcement
int1 = 11 # Error: Value must be one of 1, 2, or 23
# Value Enforcement For Namespace Names
# You can make this fail if you supply 'test-tc.py' the 'limitns' option
[XYZ] # Error: the 'limitns' option requires namespaces to begin with 'NS'.
# Notice that this is just a test driver feature to help you learn
# 'tconfpy'. You can place any limits you like on namespace formation
# in your own programs.
[] # But this always works because the root namespace is always legal
# Enforcing String Content
str1 = box # Fine
str1 = Bax # Also Fine
str1 = FunStuff # Error: Does not match any of the validation regular expressions
# Enforcing String Lengths
str1 = abc # This is OK
str1 = ab # Too short: must be at least 3 characters long
str1 = abcccccccccccc # Too long: must be 8 or less characters long
# Setting Booleans
# This is the one case where the right-hand-side of the assignment is
# INsensitive to case.
# Booleans can be set with: Yes/No, True/False, 1/0, and On/Off
bool1 = yEs
bool1 = 0
bool1 = yessir # Error: Unrecognized boolean value
# Testing Booleans - The HARD WAY
# No matter how you set it, the *value* of a boolean is always stored as
# 'True' or 'False'. This matters when doing Comparison Conditionals
.if [bool1] == False
bool1was = False
.else
bool1was = True
.endif
.if [bool1] == Off # Will always be false - a boolean never takes on
# the value of anything other than 'True' or 'False'
# something
.endif
# Testing Booleans - The EASY WAY
# Quick Review: If you do this, you are testing to see if a boolean
# variable *exists*:
#
# .ifall/any/none BoolVar1 BoolVar2 ....
#
# Ordinarily, [foo] returns the *value* of variable 'foo'. But in the
# case of booleans in an existential test, this construct returns the
# *logical state* of the boolean variable. So you can do things like:
bool1 = True
.ifany [bool1]
bool1was=True
.else
bool1was=False
.endif
# This only works *within existential tests* (.ifany, .ifall, .ifnone).
# Everywhere else, [BoolVar] will return one of the strings, 'True' or 'False'.
# You can also mix and match boolean state tests and regular existentials:
.ifnone [bool1] variable1 [str1] ....
# something
.endif