B.2   A Taste of Tcl

Tcl represents all data as ordinary text strings. As you might expect, the string-handling features of Tcl are particularly strong. However, Tcl also provides a full complement of C-like arithmetic operators to manipulate strings that represent numbers.

The examples in the following sections exhibit some of the fundamental mechanisms of the Tcl language, in order to provide some of the flavor of working in Tcl. However, this is only an introduction.

For documentation on all Tcl interfaces in Tornado (as well as on C interfaces), see the Tornado API Guide from Wind River Systems.

For the Tcl language itself, the following generally available books are helpful:

B.2.1   Tcl Variables

The Tcl set command defines variables. Its result is the current value of the variable, as shown in the following examples:

Table B-1:  Setting Tcl Variables


Tcl Expression
 
Result
 

set num 6
 
6
 
set y hello
 
hello
 
set z "hello world"
 
hello world
 
set t $z
 
hello world
 
set u "$z $y"
 
hello world hello
 
set v {$z $y}    
 
$z $y
 

The expressions above also illustrate the use of some special characters in Tcl:

SPACE
Spaces normally separate single words, or tokens, each of which is a syntactic unit in Tcl expressions.

" "
A pair of double quotes groups the enclosed string, including spaces, into a single token.

$vname
The $ character normally introduces a variable reference. A token $vname (either not surrounded by quotes, or inside double quotes) substitutes the value of the variable named vname.

{ }
Curly braces are a stronger form of quoting. They group the enclosed string into a single token, and also prevent any substitutions in that string. For example, you can get the character $ into a string by enclosing it in curly braces.

With a single argument, set gives the current value of a variable:

Table B-2:  Evaluating Tcl Variables


Tcl Expression
 
Result
 

set num
 
6
 
set z
 
hello world
 

B.2.2   Lists in Tcl

Tcl provides special facilities for manipulating lists. In Tcl, a list is just a string, with the list elements delimited by spaces, as shown in the following examples:

Table B-3:  Using Tcl Lists


Tcl Expression
 
Result
 
Description
 

llength $v
 
2
 
Length of list v.
 
lindex $u 1
 
world
 
Second element of list u.
 
set long "a b c d e f g"
 
a b c d e f g
 
Define a longer list.
 
lrange $long 2 4
 
c d e
 
Select elements 2 through 4 of list long.
 
lreplace $long 2 4 C D E
 
a b C D E f g
 
Replace elements 2 through 4 of list long.
 
set V "{c d e} f {h {i j} k}"
 
 
Define a list of lists.
 
lindex $V 1
 
f
 
Some elements of V are singletons.
 
lindex $V 0
 
c d e
 
Some elements of V are lists.
 

The last examples use curly braces to delimit list items, yielding "lists of lists." This powerful technique, especially combined with recursive command substitution (see B.2.4 Command Substitution), can provide a little of the flavor of Lisp in Tcl programs.

B.2.3   Associative Arrays

Tcl arrays are all associative arrays, using a parenthesized key to select or define a particular element of an array: arrayName(keyString). The keyString may in fact represent a number, giving the effect of ordinary indexed arrays. The following are some examples of expressions involving Tcl arrays:

Table B-4:  Using Tcl Arrays


Tcl Expression
 
Result
 
Description
 

set taskId(tNetTask)
 
0x4f300
 
Get element tNetTask of array taskId.
 
set cpuFamily(5) m68k
 
m68k
 
Define array cpuFamily and an
element keyed 5.
 
set cpuFamily(10) sparc
 
sparc
 
Define element keyed 10 of array
cpuFamily.
 
set cpuId 10
 
10
 
Define cpuId, and use it as a key to cpuFamily.
 
set cpuFamily($cpuId)
 
sparc
 

B.2.4   Command Substitution

In Tcl, you can capture the result of the command as text by enclosing the command in square brackets [ ]. The Tcl interpreter substitutes the command result in the same process that is already running, which makes this an efficient operation.

Table B-5:  Examples of Tcl Command Substitution


Tcl Expression
 
Result
 

set m [lrange $long 2 4]
 
c d e
 
set n [lindex $m 1]
 
d
 
set o [lindex [lrange $long 2 4] 1]
 
d
 
set x [lindex [lindex $V 2] 1]
 
i j
 

The last example selects from a list of lists (defined among the examples in B.2.2 Lists in Tcl). This and the previous example show that you can nest Tcl command substitutions readily. The Tcl interpreter substitutes the most deeply nested command, then continues substituting recursively until it can evaluate the outermost command.

B.2.5   Arithmetic

Tcl has an expr command to evaluate arithmetic expressions. The expr command understands numbers in decimal and hexadecimal, as in the following examples:

Table B-6:  Arithmetic in Tcl


Tcl Expression
 
Result
 

expr (2 << 2) + 3
 
11
 
expr 0xff00 & 0xf00
 
3840
 

B.2.6   I/O, Files, and Formatting

Tcl includes many commands for working with files and for formatted I/O. Tcl also has many facilities for interrogating file directories and attributes. The following examples illustrate some of the possibilities:

Table B-7:  Files and Formatting in Tcl


Tcl Expression
 
Description
 

set myfile [open myfile.out w]
 
Open a file for writing.
 
puts $myfile [format "%s %d\n" \ 
     "you are number" [expr 3+3]]
 
Format a string and write it to file.
 
close $myfile
 
Close the file.
 
file exists myfile.out
 
1
 
file writable myfile.out
 
1
 
file executable myfile.out
 
0
 
glob *.o
 
testCall.o foo.o bar.o
 

B.2.7   Procedures

Procedure definition in Tcl is straightforward, and resembles many other languages. The command proc builds a procedure from its arguments, which give the procedure name, a list of its arguments, and a sequence of statements for the procedure body. In the body, the return command specifies the result of the procedure. For example, the following defines a procedure to compute the square of a number:

proc square {i} { 
    return [expr $i * $i] 
}

If a procedure's argument list ends with the word args, the result is a procedure that can be called with any number of arguments. All trailing arguments are captured in a list $args. For example, the following procedure calculates the sum of all its arguments:

proc sum {args} { 
    set accum 0 
    foreach item $args { 
        incr accum $item 
    } 
    return $accum 
}

Defined Tcl procedures are called by name, and can be used just like any other Tcl command. The following examples illustrate some possibilities:

Table B-8:  Calling a Tcl Procedure


Tcl Expression
 
Result
 

square 4
 
16
 
square [sum 1 2 3]
 
36
 
set x "squ"
 
squ
 
set y "are"
 
are
 
$x$y 4
 
16
 

The technique illustrated by the last example--constructing a procedure name "on the fly"--is used extensively in the Tornado tools to group a set of related procedures. The effect is similar to what can be achieved with function pointers in C.

For example, in Tornado tools, events are represented in Tcl as structured strings. The first element of the string is the name of the event. Tcl scripts that handle events can search for the appropriate procedure to handle a particular event by mapping the event name to a procedure name, and calling that procedure if it exists. The following Tcl script demonstrates this approach:

proc shEventDispatch {event} {  
         set handlerProc "[lindex $event 0]_Handler" 
 
         if {[info procs $handlerProc] != ""} { 
             $handlerProc $event 
         } { 
             #event has no handler--do nothing. 
         } 
}

B.2.8   Control Structures

Tcl provides all the popular control structures: conditionals (if), loops (while, for, and foreach), case statements (switch), and explicit variable-scope control (global, upvar, and uplevel variable declarations). By using these facilities, you can even define your own control structures. While there is nothing mysterious about these facilities, more detailed descriptions are beyond the scope of this summary. For detailed information, see the books cited in the introduction to B.2 A Taste of Tcl.

B.2.9   Tcl Error Handling

Every Tcl procedure, whether built-in or script, normally returns a string. Tcl procedures may signal an error instead: in a defined procedure, this is done with the error command. This starts a process called unwinding. When a procedure signals an error, it passes to its caller a string containing information about the error. Control is passed to the calling procedure. If that procedure did not provide for this possibility by using the Tcl catch command, control is passed to its caller in turn. This recursive unwinding continues until the top level, the Tcl interpreter, is reached.

As control is passed along, any procedure can catch the error and take one of two actions: signal another error and provide error information, or work around the error and return as usual, ending the unwinding process.

At each unwinding step, the Tcl interpreter adds a description of the current execution context to the Tcl variable errorInfo. After unwinding ends, you can display errorInfo to trace error information. Another variable, errorCode, may contain diagnostic information, such as an operating system dependent error code returned by a system call.

B.2.10   Integrating Tcl and C Applications

Tcl is designed to integrate with C applications. The Tcl interpreter itself is distributed as a library, ready to link with other applications. The core of the Tcl integration strategy is to allow each application to add its own commands to the Tcl language. This is accomplished primarily through the subroutine Tcl_CreateCommand( ) in the Tcl interpreter library, which associates a new Tcl command name and a pointer to an application-specific routine. For more details, consult the Tcl books cited in the introduction to B.2 A Taste of Tcl.