This document is a single-page version of a a multi-page document, suitable for easy printing.

Tool Command Language

This chapter is designed to provide information about the Tool Command Language, abbreviated Tcl, (the language in which Swat commands are written) so that new commands can be written and old commands modified. This chapter contains the following main sections:

  1 Using This Chapter
  2 Copyright Information
  3 Background and Description
  4 Syntax and Structure
    4.1 Basic Command Syntax
    4.2 Expressions
    4.3 Lists
    4.4 Command Results
    4.5 Procedures
    4.6 Variables
  5 Commands
    5.1 Notation
    5.2 Built-in Commands
  6 Coding
    6.1 Swat Data Structure Commands
    6.2 Examples
  7 Using a New Command
    7.1 Compilation
    7.2 Autoloading
    7.3 Explicit Loading


Tool Command Language: 1 Using This Chapter

This chapter provides the information needed to write a new Swat command in Tcl. But, new commands need only be written in certain situations. Some of the situations in which it is advantageous to write a new Swat command in Tcl are:

The existing Swat commands should take care of the bulk of debugging, but sometimes an extra command can help.


Tool Command Language: 2 Copyright Information

The following sections of this chapter fall under the copyright below: Background and Description, Syntax and Structure, and Commands.

Copyright © 1987 Regents of the University of California

Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies. The University of California makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.


Tool Command Language: 3 Background and Description

The Tool Command Language is abbreviated as Tcl and is pronounced "tickle". It was developed and written by Professor John Ousterhout at the University of California at Berkeley. Tcl is a combination of two main parts: a language and a library.

Language
The Tcl language is a textual language intended primarily for issuing commands to interactive programs such as text editors, illustrators, shells, and most importantly debuggers. It has a set syntax and is programmable, thus allowing users to create more powerful commands than the built-in command set listed in the Swat Command Reference.
Library
Tcl also includes a library which can be imbedded in an application, as it is in Swat. This library includes a parser for the Tcl language, routines to implement the Tcl built-in commands, and procedures allowing an application to extend Tcl with additional commands.

Tool Command Language: 4 Syntax and Structure

Tcl supports only one type of data: strings . All commands, all arguments to commands, all command results, and all variable values are strings. Where commands require numeric arguments or return numeric results, the arguments and results are passed as strings. Many commands expect their string arguments to have certain formats, but this interpretation is up to the individual commands. For example, arguments often contain Tcl command strings, which may get executed as part of the commands. The easiest way to understand the Tcl interpreter is to remember that everything is just an operation on a string. In many cases Tcl constructs will look similar to more structured constructs from other languages. However, the Tcl constructs are not structured at all; they are just strings of characters, and this gives them a different behavior than the structures they may look like.

Although the exact interpretation of a Tcl string depends on who is doing the interpretation, there are three common forms that strings take: commands , expressions , and lists . This section will have the following main parts:


Tool Command Language: 4.1 Syntax and Structure: Basic Command Syntax

The Tcl language has syntactic similarities to both Unix and Lisp. However, the interpretation of commands is different in Tcl than in either of those other two systems. A Tcl command string consists of one or more commands separated by newline characters. Each command consists of a collection of fields separated by white space (spaces or tabs). The first field must be the name of a command, and the additional fields, if any, are arguments that will be passed to that command. For example, the command:

var a 22

has three fields: the first, var , is the name of a Tcl command, and the last two, a and 22 , will be passed as arguments to the var command. The command name may refer to a built-in Tcl command, an application specific command, or a command procedure defined with the built-in proc command. Arguments are passed literally as text strings. Individual commands may interpret those strings in any fashion they wish. The var command, for example, will treat its first argument as the name of a variable and its second argument as a string value to assign to that variable. For other commands, arguments may be interpreted as integers, lists, file names, or Tcl commands.

Comments

If the first non-blank character in a command is # (a number sign), then everything from the # up through the next newline character is treated as comment and discarded by the parser.

Argument Grouping

Normally each argument field ends at the next white space (tabs or spaces), but curly braces ("{" and "}") may be used to group arguments in different ways. If an argument field begins with a left brace, then the argument is not terminated by white space; it ends at the matching right brace. Tcl will strip off the outermost layer of braces before passing the argument to the command. For example, in the command:

var a {b c}

the var command will receive two arguments: a and b c . The matching right brace need not be on the same line as the left brace; in this case the newline will be included in the argument field along with any other characters up to the matching right brace. In many cases an argument field to one command consists of a Tcl command string that will be executed later; braces allow complex command structures to be built up without confusion. For example, the eval command takes one argument, which is a command string; eval invokes the Tcl interpreter to execute the command string. The command:

eval {
       var a 22
       var b 33
}

will assign the value 22 to a and 33 to b .

Tcl braces act like quote characters in most other languages, in that they prevent any special interpretation of the characters between the left brace and the matching right brace.

When an argument is in braces, then command, variable, and backslash substitutions do not occur in the normal fashion; all Tcl does is to strip off the outer layer of braces and pass the contents to the command. Braces are only significant in a command field if the first character of the field is a left brace. Otherwise neither left nor right braces in the field will be treated specially (except as part of variable substitution).

Command Grouping

Normally, each command occupies one line (the command is terminated by a newline character). Thus, the string:

var a 22
var b 33

will be interpreted as two separate commands. However, brackets may be used to group commands in ways other than one-command-per-line. If the first character of a command is an open bracket, then the command is not terminated by a newline character; instead, it consists of all the characters up to the matching close bracket. Newline characters inside a bracketed command are treated as white space (they will act as argument separators for arguments that are not enclosed in braces). For example, the string:

[var a
22] [var b 33]

will have the same effect as the previous example.

Command Substitution

If an open bracket occurs in any of the fields of a command, then command substitution occurs. All of the text up to the matching close bracket is treated as a Tcl command and executed immediately. The result of that command is substituted for the bracketed text. For example, consider the command:

var a [var b]

When the var command has only a single argument, it is the name of a variable and var returns the contents of that variable. In this case, if variable b has the value test , then the command above is equivalent to the command:

var a test

Brackets can be used in more complex ways. for example, if the variable b has the value tmp and the variable c has the value val , then the command:

var a test[var b].[var c]

is equivalent to the command:

var a testtmp.val

If a field is enclosed in braces then the brackets and the characters between them are not interpreted specially; they are passed through to the argument verbatim.

Variable Substitution

The dollar sign ($) may be used as a special shorthand form for substituting variables. If $ appears in an argument that is not enclosed in braces then variable substitution will occur. The characters after the $, up to the first character that is not a number, letter, or underscore, are taken as a variable name and the string value of that variable is substituted for the name. Or, if the dollar sign is followed by an open curly brace, then the variable name consists of all the characters up to the next close curly brace. For example, if variable outfile has the value test , then the command:

var a $outfile.c

is equivalent to the command:

var a test.c

and the command:

var a abc${outfile}tmp

is equivalent to the command:

var a abctesttmp

Variable substitution does not occur in arguments that are enclosed in braces: the dollar sign and variable name are passed through to the argument verbatim.

The dollar sign abbreviation is simply a shorthand form. $a is completely equivalent to [var a] ; it is provided as a convenience to reduce typing.

Backslash Substitution

Backslashes may be used to insert non-printing characters into command fields and also to insert braces, brackets, and dollar signs into fields without them being interpreted specially as previously described. The backslash sequences understood by the Tcl interpreter are listed below. In each case, the backslash sequence is replaced by the given character.

For example, in the command:

var a \{x\[\ yz\141

the second argument to var is {x[ yza (note the <space> as part of the argument).

If a backslash is followed by something other than one of the options listed below, then the backslash is transmitted to the argument field without any special processing, and the Tcl scanner continues normal processing with the next character. For example, in the command:

var \*a \\\{test

the first argument will be \*a and the second \{test .

If an argument is enclosed in braces, then backslash sequences inside the argument are parsed but no substitution occurs. In particular, backslashed braces are not counted in locating the matching right brace that terminates the argument. for example, in the command:

var a {\{abc}

the second argument to var will be \{abc .

The backslash mechanism is not sufficient to generate any argument structure; it only covers the most common cases. To produce particularly complicated arguments it will probably be easiest to use the format command along with command substitution.


Tool Command Language: 4.2 Syntax and Structure: Expressions

The second major interpretation applied to strings in Tcl is as expressions . Several commands, such as expr , for , and if , treat some of their arguments as expressions and call the Tcl expression processor (Tcl_Expr) to evaluate them. A Tcl expression has C-like syntax and evaluates to an integer result. Expressions may contain integer values, variable names in $ notation (the variables' values must be integer strings), commands (embedded in brackets) that produce integer string results, parentheses for grouping, and operators. Numeric values, whether they are passed directly or through variable or command substitution, may be specified either in decimal (the normal case), in octal (if the first character of the value of the first character is 0 (zero)), or in hexadecimal (if the first two characters of the value are 0x). The valid operators are listed below, grouped in decreasing order of precedence.

See a C manual for more details on the results produced by each operator. All of the binary operators group left to right within the same precedence level. for example, the expression:

(4*2)<7

evaluates to zero. Evaluating the expression string:

($a+3)<[var b]

will cause the values of the variables a and b to be examined; the result will be 1 if b is greater than a by at least 3; otherwise the result will be 0.

In general it is safest to enclose an expression in braces when entering it in a command; otherwise, if the expression contains any white space then the Tcl interpreter will split it among several arguments. For example, the command:

expr $a + $b

results in three arguments being passed to expr : $a , + , and $b . In addition, if the expression is not in braces then the Tcl interpreter will perform variable and command substitution immediately (it will happen in the command parser rather than in the expression parser). In many cases the expression is being passed to a command that will evaluate the expression later (or even many times if, for example, the expression is to be used to decide when to exit a loop). usually the desired goal is to re-do the variable or command substitutions each time the expression is evaluated, rather than once and for all at the beginning. For an example of a mistake, the command:

for {var i 1} $i<=10 {var i [expr $i+1]} {body...}

is probably intended to iterate over all values of i from 1 to 10. After each iteration of the body of the loop, for will pass its second argument to the expression evaluator to see whether or not to continue processing. Unfortunately, in this case the value of i in the second argument will be substituted once and for all when the for command is parsed. If i was 0 before the for command was invoked then for 's second argument will be 0<=10 which will always evaluate to 1, even though i 's value eventually becomes greater than 10. In the above case the loop will never terminate. By placing the expression in braces, the substitution of i 's value will be delayed; it will be re-done each time the expression is evaluated, which is probably the desired result:

for {var i 1} {$i<=10} {var i [expr $i+1]} {body...}

Tool Command Language: 4.3 Syntax and Structure: Lists

The third major way that strings are interpreted in Tcl is a list . A list is just a string with a list-like structure consisting of fields separated by white space. For example, the string:

Al Sue Anne John

is a list with four elements or fields. Lists have the same basic structure as command strings, except that a newline character in a list is treated as a field separator just like a space or tab. Conventions for braces and backslashes are the same for lists as for commands. For example, the string:

a b\ c {d e {f g h}}

is a list with three elements: a , b c , and d e {f g h} . Note the space between the b and c . Whenever an element is extracted from a list, the same rules about backslashes and braces are applied as for commands. Thus in the above example when the third element is extracted from the list, the result is:

d e {f g h}

(when the field was extracted, all that happened was to strip off the outermost layer of braces). Command substitution is never made on a list (at least, not by the list-processing commands; the list can always be passed to the Tcl interpreter for evaluation).

The Tcl commands concat , foreach , index , length , list , and range allow you to build lists, extract elements from them, search them, and perform other list-related functions.


Tool Command Language: 4.4 Syntax and Structure: Command Results

Each command produces two results: a code and a string . The code indicates whether the command completed successfully or not, and the string gives additional information. The valid codes are defined as follows:

TCL_OK
This is the normal return code, and indicates that the command completed successfully. The string gives the commands's return value.
TCL_ERROR
Indicates that an error occurred; the string gives a message describing the error.
TCL_RETURN
Indicates that the return command has been invoked, and that the current procedure should return immediately. The string gives the return value that procedure should return.
TCL_BREAK
Indicates that the break command has been invoked, so the innermost loop should abort immediately. The string should always be empty.
TCL_CONTINUE
Indicates that the continue command has been invoked, so the innermost loop should go on to the next iteration. The string should always be empty.

Tcl programmers do not normally need to think about return codes, since TCL_OK is almost always returned. If anything else is returned by a command, then the Tcl interpreter immediately stops processing commands and returns to its caller. If there are several nested invocations of the Tcl interpreter in progress, then each nested command will usually return the error to its caller, until eventually the error is reported to the top-level application code. The application will then display the error message for the user.

In a few cases, some commands will handle certain "error" conditions themselves and not return them upwards. For example, the for command checks for the TCL_BREAK code; if it occurs, then for stops executing the body of the loop and returns TCL_OK to its caller. The for command also handles TCL_CONTINUE codes and the procedure interpreter handles TCL_RETURN codes. The catch command allows Tcl programs to catch errors and handle them without aborting command interpretation any further.


Tool Command Language: 4.5 Syntax and Structure: Procedures

Tcl allows one to extend the command interface by defining procedures. A Tcl procedure can be invoked just like any other Tcl command (it has a name and it receives one or more arguments). The only difference is that its body is not a piece of C code linked into the program; it is a string containing one or more other Tcl commands. See the proc command for information on how to define procedures and what happens when they are invoked.


Tool Command Language: 4.6 Syntax and Structure: Variables

Tcl allows the definition of variables and the use of their values either through $-style variable substitution, the var command, or a few other mechanisms. Variables need not be declared: a new variable will automatically be created each time a new variable name is used. Variables may be either global or local. If a variable name is used when a procedure is not being executed, then it automatically refers to a global invocation of the procedure. Local variables are deleted whenever a procedure exits. The global command may be used to request that a name refer to a global variable for the duration of the current procedure (somewhat analogous to extern in C).


Tool Command Language: 5 Commands

The Tcl library provides the following built-in commands, which will be available to any application using Tcl. In addition to these built-in commands, there may be additional commands defined in Swat, plus commands defined as Tcl procedures.


Tool Command Language: 5.1 Commands: Notation

The descriptions of the Tcl commands will follow the following notational conventions:


Tool Command Language: 5.2 Commands: Built-in Commands

The built-in Tcl commands are as follows:

bc

bc list <proc>
bc disasm <proc>
bc compile <proc>
bc fcompile <file> [<nohelp>]
bc fload <file>
bc fdisasm <file>
bc debug [1|0]

Examples:

"bc compile poof"
Compiles the body of the procedure "poof" and replaces the existing procedure with its compiled form.
"bc fcomp bptutils.tcl"
Creates the file "bptutils.tlc" that contains a stream of compiled Tcl that will do exactly what sourcing bptutils.tcl does, except the resulting procedures will be compiled Tcl, not interpreted Tcl.
"bc fload bptutils.tlc"
Loads a file containing a stream of compiled Tcl code.

The "bc" command allows you to create and examine compiled Tcl code. Compiled Tcl is not nearly as readable or changeable as interpreted Tcl code, but it's 30-50% faster.

The "list" subcommand doesn't work.

See Also: source.

break

break

Examples:

"break"
Break out of the current loop.

Breaks out of the current loop or the current nested interpreter.

See Also: continue, for.

case

case <string> [in] [<pat> <body>]+

Examples:

"[case $c in
       {[0-9]} {
       # do something with digit
   }
       default {
        # do something with non-digit
   }
  ]"
Do one of two things depending on whether the character in $c is a digit.

Perform one of a set of actions based on whether a string matches one or more patterns.

See Also: string, if.

catch

catch <command> [<varName>]

Executes a command, retaining control even if the command generates an error (which would otherwise cause execution to unwind completely).

See Also: protect.

concat

concat <arg1>+

Examples:

"concat $list1 $list2"
Merges the lists in $list1 and $list2 into a single list whose elements are the elements of the two lists.

Concatenates multiple list arguments into a single list.

See Also: list.

continue

continue

Examples:

"continue"
Return to the top of the enclosing loop.

Skips the rest of the commands in the current loop iteration, continuing at the top of the loop.

See Also: break, for.

defsubr

defsubr <name> <args> <body>

Examples:

"defsubr poof {arg1 args} {return [list $arg1 $args]}"
Defines a procedure poof that takes 1 or more arguments and merges them into a list of two elements.

This is the same as the "proc" command, except the new procedure's name may not be abbreviated when it is invoked.

error

error <message>

Examples:

"error {invalid argument}"
Generates an error, giving the not-so-helpful message "invalid argument" to the caller's caller.

See Also: return, catch.

eval

eval <body>

Examples:

"eval $mangled_command"
Evaluate the command contained in $mangled_command and return its result.

Evaluates the passed string as a command and returns the result of that evaluation.

See Also: concat, list.

expr

expr <expression> [float]

Examples:

"expr 36*25"
Multiplies 36 by 25 and returns the result.
"expr $i/6 float"
Divides the number in $i by 6 using floating- point arithmetic; the result is a real number.
"expr 7.2*10 float"
Multiplies 7.2 by 10. Note that though the answer (72) is an integer, we need to pass the "float" keyword to make sure that the expression is interpreted correctly.

Evaluates an arithmetic expression and returns its value.

file

file dirname <name>
file exists <name>
file extension <name>
file isdirectory <name>
file isfile <name>
file readable <name>
file rootname <name>
file tail <name>
file writable <name>
file match <pattern>
file newer <name1> <name2>

Examples:

"file match /pcgeos/tcl/*.tcl"
Looks for all files/directories in /pcgeos/tcl whose name ends with ".tcl".
"file isdir $path"
See if the path stored in $path refers to a directory.
"file tail $path"
Return the final component of the path stored in $path

Performs various checks and manipulations of file and directory names.

See Also: string.

for

for <start> <test> <next> <body>

Examples:

"for {var i 0} {$i < 10} {var i [expr $i+1]} {echo $i}"
Prints the numbers from 0 to 9.

This is Tcl's main looping construct. It functions similarly to the "for" in C.

See Also: foreach, break, continue.

foreach

foreach <varname> <list> <body>

Examples:

"foreach el $list {echo poof = $el}"
Prints each element of the list $list preceded by the profound words "poof = "

This is a looping construct to easily iterate over all the elements of a list.

format

format <formatString> [<arg> ]*

This command generates a formatted string in the same way as the C sprintf procedure (it uses sprintf in its implementation). <formatString> indicates how to format the result, using % fields as in sprintf , and the additional arguments, if any, provide values to be substituted into the result. All of the sprintf options are valid; see the sprintf procedure in a C manual for more details. Each <arg> must match the expected type from the % field in <formatString>; the format command converts each argument to the correct type (floating, integer, etc.) before passing it to sprintf for formatting. The only unusual conversion is for %c; in this case the argument must be a decimal string, which will then be converted to the corresponding ASCII character value. format does backslash substitution on its <formatString> argument, so backslash sequences in <formatString> will be handled correctly even if the argument is in braces. The return value from format is the formatted string.

global

global <varname>+

Examples:

"global attached"
When next the "attached" variable is fetched or set, get it from the global scope, not the local one.

Declares the given variables to be from the global scope.

See Also: var.

if

if <test> [then] <trueBody> 
(elif <test> [(then)] <trueBody>)*
[[else] <falseBody>]

Examples:

"if {$v > 3} {echo yes} {echo no}"
Prints "yes" if $v is greater than 3, else it prints "no".
"if {$v > 3} then {echo yes} else {echo no}"
Ditto.
"if {$v > 3} then {echo yes} elif {$v == 3} {echo maybe} else {echo no}"

This is Tcl's conditional, as you'd expect from its name.

See Also: expr.

index

index <value> <index> [chars]

Examples:

"index {a b c} 1"
Extracts "b" from the list.
"index {hi mom} 3 char"
Extracts "m" from the string.

"index" is used to retrieve a single element or character from a list or string.

info

info args <procname> [<pattern>]
info arglist <procname>
info body <procname>
info cmdcount
info commands [<pattern>]
info default <procname> <arg> <varname>
info globals [<pattern>]
info locals [<pattern>]
info procs [<pattern>]
info vars [<pattern>]

Examples:

"info args fmtval"
Retrieves the names of the arguments for the "fmtval" command so you know in what order to pass things.
"info body print-frame"
Retrieves the string that is the body of the "print-frame" Tcl procedure.
"info commands reg "
Retrieves a list of commands whose names contain the string "reg".

This command provides information about a number of data structures maintained by the Tcl interpreter.

See Also: proc, defcmd, defcommand, defsubr.

length

length <value> [<chars>]

Examples:

"length $args"
Returns the number of elements in the list $args
"length $str char"
Returns the number of characters in the string $str

Determines the number of characters in a string, or elements in a list.

See Also: index, range.

list

list <arg>+

Examples:

"list a b {c d e} {f {g h}}"
Returns the list "a b {c d e} {f {g h}}"

Joins any number of arguments into a single list, applying quoting braces and backslashes as necessary to form a valid Tcl list.

See Also: concat, index, range.

proc

proc <name> <args> <body>

Examples:

"proc poof {{arg1 one} args} {return [list $arg1 $args]}"
Defines a procedure poof that takes 0 or more arguments and merges them into a list of two elements. If no argument is given, the result will be the list {one {}}

Defines a new Tcl procedure that can be invoked by typing a unique abbreviation of the procedure name.

See Also: defsubr, return.

protect

protect <body> <cleanup>

Examples:

"protect {
     var s [stream open $file w]
     # do stuff with the stream
 } {

     catch {stream close $s}

 }"
Perform some random operations on a file making sure the stream gets closed, even if the user types control-C.

Allows one to ensure that clean-up for a sequence of commands will always happen, even if the user types control-C to interrupt the command.

See Also: catch.

range

range <value> <first> <last> [chars] 

Examples:

"range {a b c} 1 end"
Returns {b c} (element 1 to the end)
"range {hi mom} 3 end chars"
Returns "mom"

Extracts a range of characters from a string, or elements from a list.

See Also: index.

return

return [<value>]

Examples:

"return $val"
Returns the string in $val as the value for the current Tcl procedure.

Causes an immediate return from the current Tcl procedure, with or without a value.

See Also: error, proc, defsubr, defcommand, defcmd.

scan

scan <string> <format> [<varname1> ]*

Examples:

"scan $input {my name is %s} name"
Trims the leading string "my name is " from the string in $input and stores the rest of the string within the variable $name

"scan" parses fields from an input string, given the string and a format string that defines the various types of fields. The fields are assigned to variables within the caller's scope.

See Also: format.

source

source <fileName>

Examples:

"source coolness"
Evaluates all commands within the file "coolness.tcl" in the current directory.

Reads and evaluates commands from a file.

string

string compare<string1> <string2> [no_case]
string first<substring> <string> [no_case]
string last<substring> <string> [no_case]
string match<string> <pattern>
string subst <string> <search> <replace> [global] 

Examples:

"if {[string c [index $args 1] all] == 0}"
Do something if the 2nd element of the list in $args is the string "all".
"while {[string m [index $args 0] -*]}"
Loop while the first element of the list in $args begins with a hyphen.

Examine strings in various ways.

See Also: case.

uplevel

uplevel <level> <body>
uplevel <function> <body>

Examples:

"uplevel print-frame {var found1}"
Sets $found to 1 within the variables belonging to the nearest invocation of print-frame on the call stack.
"uplevel 0 {var foo-table}"
Retrieves the value of the global variable foo-table.
"uplevel 1 {var found 1}"
Sets $found to 1 within the scope of the procedure that called the one executing the "uplevel" command.

Provides access to the variables of another procedure for fairly specialized purposes.

See Also: global.

var

var <varname>
var (<name> <value>)+

Examples:

"echo [var poof]"
Prints the value stored in the variable "poof"
"var a b c d"
Assigns the string "b" to the variable "a", and the string "d" to the variable "c".
"var yes $no no $yes"
Exchanges the values of the "yes" and "no" variables

This is the means by which variables are defined in Tcl. Less often, it is also used to retrieve the value of a variable (usually that's done via variable substitution).

See Also: global.


Tool Command Language: 6 Coding

This section provides information about the features and commands of Tcl that are important to know when using Swat, and the features and commands of Swat that are important to know when using Tcl. These features should be kept in mind while programming in Tcl because, if used properly, they make programming, debugging, and understanding existing commands much easier.This section will contain the following parts:


Tool Command Language: 6.1 Coding: Swat Data Structure Commands

symbol, type, patient, handle, brk, cbrk, event, thread, src, cache, table

This section contains information about Swat's built-in data structures and the commands that access them. These commands examine and modify vital information about the state of GEOS while it is running under Swat.

brk

brk <addr> [<command>]
brk pset <addr> [<command>]
brk aset <addr> [<command>]
brk tset <addr> [<command>]
brk clear <break>*
brk delete <break>*
brk enable <break>*
brk disable <break>*
brk address <break>
brk list [<addr>]
brk debug [<flag>]
brk isset <addr>
brk cond <break> <condition>*
brk cmd <break> [<command>]
brk delcmd <break> [<command>]

Examples:

"brk WinOpen"
Sets the machine to stop unconditionally when any thread calls WinOpen.
"brk pset WinOpen"
Sets the machine to stop when any thread for the current patient calls WinOpen.
"brk tset WinOpen"
Sets the machine to stop when any thread for the current patient calls WinOpen, and deletes the breakpoint when the machine next stops.
"brk enable 1 3-5"
Re-enables breakpoints 1, 3, 4, and 5
"brk clear 2-"
Clears all breakpoints from number 2 onward.
"brk cond 3 cx=42"
Sets breakpoint 3 to be conditional, stopping when the machine reaches the breakpoint's address with CX being 42.
"brk cond 2 (ss:0)!=1b80h"
Sets breakpoint 2 to be conditional, stopping when the machine reaches the breakpoint's address with the word at ss:0 not being 1b80h. Note that the "ss" is the value of the ss register when the "brk cond" command is executed, not when the breakpoint is reached.

Allows you to specify that execution should stop when it reaches a particular point. These breakpoints can be conditional, and can execute an arbitrary Tcl command, which can say whether the machine is to remain stopped, or continue on its way.

cache

cache create (lru|fifo) <maxSize> [<flushProc>]
cache destroy <cache> [flush|noflush]
cache lookup <cache> <key>
cache enter <cache> <key>
cache invalone <cache> <entry>
cache invalall <cache> [flush|noflush]
cache key <cache> <entry>
cache size <cache>
cache maxsize <cache>
cache setmaxsize <cache> <maxSize>
cache getval <cache> <entry>
cache setval <cache> <entry> <value>

Examples:

"var cache [cache create lru 10]"
Creates a cache of 10 items that are flushed on a least-recently-used basis. The returned token is saved for later use.
"var entry [cache lookup $cache mom]"
Sees if an entry with the key "mom" is in the cache and saves its entry token if so.
"echo mom=[cache getval $cache $entry]"
Retrieves the value stored in the entry for "mom" and echoes it.
"cache invalone $cache $entry"
Flushes the entry just found from the cache.
"cache destroy $cache"
Destroys the cache.

The cache command, as the name implies, maintains a cache of data that is keyed by strings. When a new entry is added to an already-full cache, an existing entry is automatically flushed based on the usage message with which the cache was created: lru (last recently used) or fifo (first in, first out). If lru , the least-recently-used entry is flushed; if fifo , the oldest entry is flushed.

cbrk

cbrk <addr> <condition>*
cbrk aset <addr> <condition>*
cbrk tset <addr> <condition>*
cbrk clear <break>*
cbrk delete <break>*
cbrk enable <break>*
cbrk disable <break>*
cbrk address <break>
cbrk list [<addr>]
cbrk debug [<flag>]
cbrk isset <addr>
cbrk cond <break> <condition>*
cbrk cmd <break> [<command>]
cbrk delcmd <break> [<command>]

Examples:

"cbrk WinOpen di=1b80h"
Stops the machine when execution reaches WinOpen() with di set to 1b80h.

Allows you to set fast conditional breakpoints.

event

event <subcommand>

The event command provides access to Swat's internal events. The subcommands are as follows:

handle <eventName> <handler> [<data>]
The <handler> procedure is invoked each time an event of type <eventName> is dispatched. The handler receives two arguments: an event-specific piece of data, and the given <data>. A handler procedure should be declared
proc <handler> {arg data} {<body>}

The handle subcommand returns an <event> for later use in deleting it. The <handler> should return one of event_handled , event_not_handled , or event_stop_handling . If it returns event_stop_handling , the event will not be dispatched to any other handlers of the event.

delete <event>
Deletes the given event handler given by the event handle command.
dispatch <eventName> <arg>
Dispatches the given event with the given <arg> to all handlers of that event. If <eventName> is a pre-defined event type, <arg> will be converted to the appropriate type before being dispatched. Otherwise it is passed as a string.
create
Returns a number that represents a new event type. Handlers may then be defined for and events dispatched of the new type.
list
Lists all Tcl-registered events by event-name and handler function.

The events which are currently defined are:

FULLSTOP
Generated when patient stops for a while. Argument is string telling why the patient stopped.
CONTINUE
Generated just before the patient is continued. The argument is non-zero if going to single-step.
TRACE
Generated when the execution of a source line completes and the patient is in line-trace mode.
START
Generated when a new patient/thread is created. Argument is patient token of the patient involved.
STACK
Current stack frame has changed. The argument is non-zero if the stack change comes from a change in patients/threads or zero if the change comes from actually going up or down the stack in the current patient.
DETACH
Detaching from the PC. The argument is always zero.
RESET
Returning to the top level. The argument is always zero.
ATTACH
Attached to the PC. The argument is always zero.
RELOAD
Kernel was reloaded. The argument is always zero.
CHANGE
Current patient has changed. The argument is the token for the previous patient.
STEP
Machine has stepped a single instruction. The argument is the value to pass to patient stop if you wish the machine to stay stopped.
STOP
Machine has hit a breakpoint. The argument is the value to pass to patient stop if you wish the machine to stay stopped.
INT
Machine has hit some other interrupt that's being caught. The argument is the interrupt number. The machine will remain stopped unless it is continued with continue-patient.

handle

handle lookup <id>
handle find <address>
handle all
handle nointerest <interest-record>
handle interest <handle> <proc> [<data>+]
handle segment <handle>
handle size <handle>
handle state <handle>
handle owner <handle>
handle patient <handle>
handle other <handle>
handle id <handle>
handle isthread <handle>
handle iskernel <handle>
handle isfile <handle>
handle isvm <handle>
handle ismem <handle>

Examples:

"handle lookup [read-reg bx]"
get the handle token for the handle whose ID is in the BX register.
"handle interest $h ob-interest-proc [concat si=$chunk $message]"
call ob-interest-proc, passing the list {si=$chunk $message}, whenever the state of the handle whose token is in $h changes.
"handle patient $h"
get the token for the patient that owns the handle whose token is in $h
"handle all"
get the list of the ID's of all handles currently in Swat's handle table.

The "handle" command provides access to the structures Swat uses to track memory and thread allocation on the PC.

patient

patient find <name>
patient name [<patient>]
patient fullname [<patient>]
patient data [<patient>]
patient threads [<patient>]
patient resources [<patient>] 
patient libs [<patient>]
patient path [<patient>]
patient all
patient stop [<addr>]

Examples:

"patient find geos"
Returns the patient token for the kernel, if it's been loaded yet.
"patient fullname $p"
Returns the permanent name for the patient whose token is stored in the variable p.
"patient stop $data"
Tells the dispatcher of the STEP event that it should keep the machine stopped when the STEP event has been handled by everyone.

This command provides access to the various pieces of information that are maintained for each patient (geode) loaded by GEOS.

src

src line <addr>
src read <file> <line>
src cache [<max>]
src addr <file> <line> [<patient>]

Examples:

"src line cs:ip"
Returns a two-list holding the source-line number, and the absolute path of the file in which it lies (not in this order), that encompasses CS:IP.
"src read /pcgeos/appl/sdk_c/hello/hello.goc 64"
Reads the single given source line from the given file.
"src addr icdecode.c 279"
Returns an address-list for the start of the code produced for the given line.
"src cache 10"
Allow 10 source files to be open at a time. This is the default.

The "src" command allows the Tcl programmer to manipulate the source- line maps contained in all the geodes' symbol files.

symbol

symbol find <class> <name> [<scope>]
symbol faddr <class> <addr>
symbol match <class> <pattern>
symbol scope <symbol>
symbol name <symbol>
symbol fullname <symbol>
symbol class <symbol>
symbol type <symbol>
symbol get <symbol>
symbol patient <symbol>
symbol tget <symbol>
symbol addr <symbol>
symbol foreach <scope> <class> <callback> [<data>]

Examples:

"symbol find type LMemType"
Locate a type definition named LMemType
"symbol faddr proc cs:ip"
Locate the procedure in which CS:IP lies.
"symbol faddr {proc label} cs:ip"
Locate the procedure or label just before cs:ip.
"symbol fullname $sym"
Fetch the full name of the symbol whose token is in the $sym variable.
"symbol scope $sym"
Fetch the token of the scope containing the passed symbol. This will give the structure containing a structure field, or the procedure containing a local variable, for example.

Provides information on the symbols for all currently-loaded patients. Like many of Swat's commands, this operates by using a lookup function (the "find", "faddr", "match", or "foreach" subcommands) to obtain a token for a piece of data that's internal to Swat. Given this token, you then use the other subcommands (such as "name" or "get") to obtain information about the symbol you looked up.

See Also: type.

table

table create [<initBuckets>]
table destroy <table>
table enter <table> <key> <value>
table lookup <table> <key>
table remove <table> <key>

Examples:

"var kitchen [table create 32]"
Create a new table with 32 hash buckets initially.
"table enter $t tbrk3 {1 2 3}"
Enter the value "1 2 3" under the key "tbrk3" in the table whose token is stored in the variable t.
"table lookup $t tbrk4"
Fetch the value, if any, stored under the key "tbrk4" in the table whose token is stored in the variable t.
"table remove $t tbrk3"
Remove the data stored in the table, whose token is stored in the variable t, under the key "tbrk3"
"table destroy $t"
Destroy the table $t and all the data stored in it.
(mess1:0) 159 => var yearTable [table create]
(mess1:0) 160 => table enter $yearTable synclavier 1979
(mess1:0) 161 => table enter $yearTable moog 1966
(mess1:0) 162 => table lookup $yearTable synclavier
1979
(mess1:0) 163 => var yearTable
1403188
(mess1:0) 164 => table lookup 1403188 moog
1966
(mess1:0) 165 => table remove $yearTable synclavier
(mess1:0) 166 => table lookup $yearTable synclavier
nil
(mess1:0) 167 => table destroy $yearTable

The "table" command is used to create, manipulate and destroy hash tables. The entries in the table are keyed on strings and contain strings, as you'd expect from Tcl.

thread

thread id <thread>
thread register <thread> <regName>
thread handle <thread>
thread endstack <thread>
thread number <thread>
thread all

Examples:

"thread register $t cx"
Fetches the value for the CX register for the given thread.
"thread number $t"
Fetches number swat assigned to thread when it was first encountered.
(mess1:0) 145 => patient threads
2667104
(mess1:0) 146 => thread id 2667104
11184
(mess1:0) 147 => thread all
767532 756068 1348520 1348868 1349216 1349748 1350236 1402096 1079392 2667104
(mess1:0) 148 => thread handle 756068
880428
(mess1:0) 149 => thread number 756068
0

Returns information about a thread, given its thread token. Thread tokens can be obtained via the "patient threads" command, or the "handle other" command applied to a thread handle's token.

type

type <basic-type-name> 
type make array <length> <base-type>
type make pstruct (<field> <type>)+
type make struct (<field> <type> <bit-offset> <bit-length>)+
type make union (<field> <type>)+
type make <ptr-type> <base-type>
type delete <type>
type size <type>
type class <type>
type name <type> <var-name> <expand>
type aget <array-type>
type fields <struct-type>
type members <enum-type>
type pget <ptr-type>
type emap <num> <enum-type>
type signed <type>
type field <struct-type> <offset>
type bfget <bitfield-type> 

Examples:

"type word"
Returns a type token for a word (2-byte unsigned quantity).
"type make array 10 [type char]"
Returns a type token for a 10-character array.
"type make optr [symbol find type GenBase]"
Returns a type token for an optr (4-byte global/local handle pair) to a "GenBase" structure.

Provides access to the type descriptions by which all PC-based data are manipulated in Swat, and allows a Tcl procedure to obtain information about a type for display to the user, or for its own purposes. As with other Swat commands, this works by calling one subcommand to obtain an opaque "type token", which you then pass to other commands.

See Also: gc, symbol, value.


Tool Command Language: 6.2 Coding: Examples

This section will contain a few examples of Tcl code for Swat commands, showing the use of some of included Tcl commands. A good way to view the code for a particular procedure is to type:

info body <procname>

on the Swat command line. This will print out the body of the given <procname> . One thing to watch out for, however, is the case when a procedure has not been loaded into Swat yet (i.e. it has not been used yet). If this is the case, Swat will have no information about the procedure and will thus print nothing. The command must be loaded into Swat either with the load command, or by just typing the command name which will usually autoload the command. (See Using a New Command .) Then the info body <procname> command can be used.

Some code examples:

The Whatat Command

[ defcommand whatat {addr} output
{Given an address, print the name of the variable at that address}
{
  var a [ sym faddr var $addr]
	 if {[ null $a]}{
	  echo *nil*
	} else {
	 echo [sym name $a]
 }
}]

This example shows the code of the whatat command. Note the use of the sym (an abbreviation for symbol ) command to find the address of the given variable <addr> of class <var>.

The Bytes Command

1	 var addr [ get-address $addr ds:si]
2	var base [ index [addr-parse $addr] 1]
3	 echo {Addr: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f}
4	#fetch the bytes themselves
5	var bytes [ value fetch $addr [  type make array $num [type byte]]]
6	#
	# $s is the index of the first byte to display on this row, $e is the
	# index of the last one. $e can get > $num. The loop handles this case.
	#
	var s 0 e [ expr 16-($base&0xf)-1]
	#
	# $pre can only be non-zero for the first line, so set it once here.
	# We'll set it to zero when done with the first line.
	# $post can be non-zero only for the last line, but we can't just
	# set it to zero and let the loop handle it, as the first may be the
	# last, so...
	#
	var pre [expr 16-($e-$s)-1]
	if {$e > $num} {
	var post [expr $e-($num-1)]
	} else {
	var post 0
	} 

	[ for {var start [expr {$base&~0xf}]}
	{$s < $num}
	{var start [expr $start+16]}
	{
28	#extract the bytes we want
29	var bs [ range $bytes $s $e]

30	echo [ format {%04xh: %*s%s%*s "%*s%s%*s"} $start
	[expr $pre*3] {}
	[ map i $bs {format %02x $i}]
	[expr $post*3] {}
	$pre {}
	[ mapconcat i $bs {
	if {$i >= 32 && $i < 127} {
	format %c $i
	} else {
	format .
	}
	}]
	$post {}]
	var s [expr $e+1] e [expr $e+16] pre 0
	if {$e >= $num} {
	var post [expr $e-($num-1)]
	}
	}]
	 set-address $addr+$num-1
	 set-repeat [format {$0 {%s} $2} $addr+$num]

This example shows the code for the bytes commands. Notice the use of the type command on the fifth line, and the range command on the twenty-ninth line.


Tool Command Language: 7 Using a New Command

Once a new command is written, it needs to be loaded into Swat so that it can be used. Depending on how the command is to be used, you may be interested in any of the following topics:


Tool Command Language: 7.1 Using a New Command: Compilation

It is possible to byte-compile a Tcl script. The bc Tcl command creates a .TLC file containing compiled Tcl code--this code will run faster than normal Tcl code. When loading, Swat will load a .TLC file instead of a .TCL file where possible. Making changes to compiled Tcl functions involves changing the source code and re-compiling.


Tool Command Language: 7.2 Using a New Command: Autoloading

If the development environment has been set up properly, there should already exist the /pcgeos/Tools/swat/lib directory on the workstation. This directory will contain all of the code files for the built-in Swat commands. To autoload a new command, copy its code file to the /pcgeos/Tools/swat/lib directory and add its name to the autoload. tcl file in the directory. This will load the command into Swat every time Swat is started. For example, say the command blitzburp has just been written to examine a new data structure. First, copy the file containing its code (say blitz. tcl) into the /pcgeos/Tools/swat/lib directory. Next, edit the autoload. tcl file and add one of the following lines:

[autoload blitzburp 0 blitz]
[autoload blitzburp 1 blitz]

This will ensure that blitz.tcl will be loaded when the command blitzburp is first used. The 0 indicates that the command must be typed exactly, and the 1 indicates that the interpreter will not evaluate arguments passed to the command. (Full reference information is available for the autoload command.)


Tool Command Language: 7.3 Using a New Command: Explicit Loading

Another way to load a command into Swat is to use the load command from the Swat command line. This command is simply load <path>/<filename> . If no path is given, then the <file> is loaded from the directories specified in the load-path variable. The load command will load the given file (a Tcl procedure or subroutine) into Swat for subsequent use, and it is mostly used to load infrequently accessed files. (See , for more information on the load command.)


This document is a single-page version of a a multi-page document, suitable for easy printing.