# A 'tconfpy' Example Configuration File # Copyright 2003-2005 TundraWare Inc. # $Id: example.cfg,v 1.108 2005/01/14 10:21:13 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