tstol is the command interpreter for the TPOCC Systems Test and Operations Language (TSTOL). TSTOL is derived from previous generations of the Systems Test and Operations Language (STOL) used in existing NASA satellite control centers.
TSTOL is a procedural command language consisting of a core set of generic commands, supplemented by mission-specific extensions. The generic TSTOL commands provide the following capabilities:
By defining a new set of foreign directives, a project can modify or extend the language recognized by TSTOL - without changing the executable tstol program. Although the simplest foreign directives are structured as a keyword followed by a list of parameters, TSTOL's support of regular expression pattern matching allows foreign directives to apply sophisticated lexical and syntactical analysis to their command lines - again, without any changes to the executable tstol program.
This manual is divided into the following sections and subsections:
tstol can be run in one of three modes: as a multi-user, network-based
server; as a single-user, network-based client; or as a single-user,
terminal-based parser. If invoked as a server (see the -answer command
line option), tstol listens at an assigned network port for connection
requests from client user interface (UI) processes. When a connection request
is received from a prospective client, tstol forks a child tstol
process to service that connection. There may be many child tstol
processes, each parsing and processing commands from different UI processes (or
different command input windows in the same UI process). The child parsers can,
in turn, establish network connections to other applications programs (e.g., a
spacecraft command processor).
tstol was originally written to be a network server; subsequent circumstances, however, made it necessary for tstol to initiate the network connection with the UI process. When invoked with the -call option, tstol, rather than passively listening for connection requests, actively attempts to establish a network connection with a UI process functioning as a server.
If invoked with the -tty option, tstol inputs commands from and outputs messages directly to the operator's terminal. This stand-alone mode is useful for debugging and testing the tstol program.
To invoke tstol as a network-based server (the standard mode of operation), enter:
% tstol -mission mission
To invoke tstol as a network client, enter:
% tstol -call server[@host] -mission mission
To invoke tstol as a terminal-based parser (for stand-alone testing), enter:
% tstol -tty -mission mission
Stand-alone testing of the network-based tstol server is possible using the -single_user command line option:
% tstol -single_user -mission mission
tstol expects certain items to be present in its run-time environment. The names of most of these items are based on the mission name (see the -mission option). tstol performs all case conversions needed to construct the run-time environment names, regardless of how the mission name was specified on the command line. The following items should be present when the parser is run:
Server name mission_tstol - determines the network port at which tstol listens for connection requests from display processes. The server name (with mission in all lower case letters) should be entered in the system /etc/services file; for example,
hst_tstol 24681/tcp
assigns server name "hst_tstol" to TCP port 24681.
Environment variable $mission_PROC_FILE - specifies the defaults for missing components of TSTOL procedure file names. For example, the following C Shell command specifies the default directory ("/home/hst/source/procs") and file extension (".prc") for procedure files:
setenv HST_PROC_FILE /home/hst/source/procs/.prc
A "start TEST" directive would then read and execute the TSTOL procedure found in /home/hst/source/procs/test.prc. $mission_PROC_FILE can also contain multiple directory (and/or extension) specifications, separated by commas or spaces. For example:
setenv HST_PROC_FILE "./.prc, /home/hst/source/procs/"
If the operator enters a "start TEST" directive, tstol would first search its current working directory for test.prc and then search /home/hst/source/procs. A directory specification without an extension must have a trailing "/". Note that the parser's current working directory is not necessarily the operator's current directory, particularly if tstol was brought up as a network server. The cd directive will display and/or change your parser's current working directory.
Environment variable $mission_SYV_FILE - specifies the system variable definition file. The information in this database file is used by tstol to access system variables. The -nosysvar command line option inhibits the loading of this file.
Data Services subsystem - must be up and running if system variables will be accessed. The data server should be running under the server name mission_data_server on the expected host (see the -host command line option and the %liv(host) internal variable).
Events subsystem (or a suitable substitute) - must be up and running. tstol's interface to the event logger requires the setup of 4 environment variables:
The TPOCC Systems Test and Operations Language (TSTOL) is a general-purpose, programmable, operator interface language. The capabilities of TSTOL can be divided into two categories: generic capabilities and mission-specific capabilities. The following sections describe (i) the basics of the TSTOL language, (ii) the generic command set, and (iii) the mission-specific command sets.
As in prior generations of STOL, a TSTOL statement can consist of up to four possible fields:
[label: ] directive [ arguments ] [ ; comment ]
An alphanumeric label, if present, is the first field in the statement and is followed by a colon; the first character of a label must be alphabetic. Labels may appear on a line by themselves or may precede a directive on the same line. Reserved words (e.g., BEGIN, END) may be used as labels without causing syntax errors. Examples: "ADD_2_AND_2:", "RETRY_COMMAND:", etc.
A command directive is the keyword that identifies the command to be executed. Directive keywords are reserved words and generally should not be used as identifiers (e.g., variable names, mnemonics, etc.). Keywords for built-in directives can be used for foreign directives; typing in such a keyword then invokes the foreign directive. The built-in directive can still be executed by prefixing the keyword with a "\\". Examples: "acquire", "page", "\\reset", etc.
Arguments to a command are separated from the directive keyword by blanks or tabs; multiple arguments are separated from each other by blanks, commas, or tabs. Example: "page page_name, update_rate"
A semi-colon (";") in a statement introduces a comment. Comments can be on a line all by themselves. Blank lines and form feeds are also allowed. Example: "history on ; Turn on NASCOM block recording."
Commands with many arguments can be continued on successive lines by ending each line with two semi-colons (";;"). These line continuation markers also double (no pun intended!) as comment delimiters.
tstol implements a primitive command line history mechanism, similar to that of the UNIX csh(1). The parser saves the most recent N lines of operator input; the currently saved set of lines can be displayed on the operator's screen. Particular lines can be recalled upon request; a recalled line is submitted to the parser as if the operator typed in the directive again. An exclamation mark ("!") is used to access the command line history:
By default, tstol saves the 20 most recent lines of operator input. This number can be changed by setting a local internal variable, %liv(savehist).
The TSTOL parser supports a number of different data types, including integers, reals, and character strings. Integer constants range from -2**31-1 to +2**31 and can be specified in decimal, octal, or hexadecimal using the Standard C conventions for integer constants:
Decimal Constants: 37-1Octal Constants: 04507777777Hexadecimal Constants: 0x2BAD0xFAB4
TSTOL discourages the use of, but supports, the old STOL notations for binary (B), octal (O), and hexadecimal (H or X) numbers:
B'100101' O'1234567' H'DAD1' X'C3D2'
Floating point numbers are stored internally as double-precision reals with a possible range of approximately -4.9E-324 to +1.8E308 (on computers that utilize the IEEE floating point representation); they can be written in a variety of ways ("D" and "E" are accepted interchangeably for the exponent):
1.0 -879.5 2.25D03 3.6E-01
Character string constants should be enclosed in double-quotes; a double-quote can be inserted in a string by typing in two consecutive double-quotes:
"S/C Attitude" "OFF" "can""t means won""t"
Single-quotes are used to delimit identifiers containing special characters. This single- vs. double-quote convention can be reversed using the -quotes1 command line option.
Date/time constants are expressed in the form YY-DDD-HH:MM:SS.LLL, where the fields are year, day of year, hour, minutes, seconds, and milliseconds, respectively. Embedded blanks are not permitted; leading zeroes are not required. One or more fields in a date/time constant may be omitted, subject to the following rules:
Missing fields are supplied by TSTOL: the year and day default to the current date; the remaining fields default to zero. In the year field of a date/time constant, "70" through "99" represent the years 1970 through 1999; "00" through "69" represent the years 2000 through 2069.
Logical constants can be written in a number of forms:
true false .TRUE. .FALSE. .T. .F.
UNIX pathnames (file names) are recognized in certain instances. The standard C Shell file naming conventions are followed, although "$var" references to environment variables should be avoided (they will cause unwanted text substitution). Unfortunately, UNIX file name conventions conflict with TSTOL's lexical conventions; for example, ~/.login is an acceptable pathname in TSTOL, but /home/tpocc looks like a badly-formed arithmetic expression. If a desired pathname might be mistaken for a variable name or for an arithmetic expression, enclose the file name in quotes (either double- or single-quotes can be used):
~/.login startup.prc 'this_file' "../that_file"
Other data types (e.g., telemetry values) are supported to some degree, but they primarily come into play when accessing system variables.
TSTOL variables are distinguished by their name, their scope, and their data type. TSTOL follows the usual naming conventions regarding variable names: an initial alphabetic character ("A"-"Z") followed by zero or more alphanumeric characters or underscores ("_"). TSTOL variable names are case-insensitive (e.g., "BAbCd" and "BaBcD" are equivalent identifiers) and are limited to 32 characters. Special characters can be embedded in variable names by enclosing the entire variable name in single quotes (but see the -quotes1 command line option).
The scope of a variable defines its accessibility. Procedure-local variables (declared by the local directive) can only be referenced within a procedure and not from a parent or child procedure. Formal parameters passed by value are, for all practical purposes, procedure-local variables. Procedure-local variables disappear when the procedure exits. Procedure-global variables (declared using the global directive) are global to all procedures; they can be accessed at any level of procedure nesting or when no procedures are active. (The "console-local" variables, X1..X16, of MAE STOL can be emulated by declaring procedure-global variables X1 through X16.) Process-global variables (a.k.a. system variables) are global to all parser processes and, in a sense, to all the computers on the network.
The resolution of variable references follows the hierarchy described above. First, the variable is looked up in the procedure-local symbol table. If the variable is not found there, the procedure-global symbol table is searched. If that search fails, the system variable access table is consulted.
TSTOL variables assume the data types of the values assigned to them, usually integers, reals, or strings. More exotic data types are possible via references to system variables.
The following procedure-global variables are predefined in TSTOL:
MISSION- is assigned the mission name specified by the -mission command line option. The value assigned to MISSION is all upper case, regardless of how it was specified on the command line. MISSION is assigned its value before the server initialization file is loaded and executed, so a multi-mission initialization procedure can test MISSION's value and configure the TSTOL parser as needed. Of course, any other TSTOL procedure can also reference MISSION.
- %status
- is a global status flag intended for use in programming foreign directives. %status is automatically set to true if a command completion status message received from a remote process indicates success and false if the message indicates failure. Foreign directives (and TSTOL procedures) can test and set %status as they see fit.
Variables external to a parser process are called system variables. These variables are stored in shared memory segments on the local host computer or possibly on remote hosts. Examples of system variables include current telemetry values, processing statistics, etc. Each system variable is uniquely identified by three items: the host computer on which the variable is resident, the process that "owns" the variable, and the variable's mnemonic (name).
Due to the distributed nature of system variables, TSTOL utilizes a special construct to reference system variables:
mnemonic[#process][@host][[index]]
A system variable can be referenced by mnemonic only, if the mnemonic uniquely identifies the system variable (i.e., no two processes share a mnemonic name) and the name has not been superseded by a procedure-local or -global variable name. Otherwise, the process name must be specified. If a host is not specified, the default system variable host (see the -host command line option and the %liv(host) internal variable) is used. The one-dimensional array index (1..N) is optional.
If used in the context of an expression (e.g, on the right hand side of a let directive), a system variable reference retrieves the value of a system variable:
let local_variable = mnemonic[#process][@host][[index]]
To store a value in a system variable, place the reference on the left hand side of a let directive:
let mnemonic[#process][@host][[index]] = expr
Recalling or storing a system variable is actually performed by a TPOCC data server on the host computer. The first reference to a system variable on host causes the TSTOL parser to establish a network connection to host's data server. When recalling a value, the parser passes process, mnemonic, and index to the data server; the data server then returns the value of the variable to the parser. To store a value, the parser passes process, mnemonic, index, and expr to the data server; the data server then stores the value in its local system variable shared memory.
A system variable reference can be prefixed with the "P@" modifier in order to retrieve the processed value of the variable. If the variable contains an analog telemetry point, its processed value is the current raw telemetry count converted to engineering units (EU) - a real number. The conversion is performed by the telemetry decommutation process, not by tstol. If the variable is a discrete telemetry or non-telemetry system variable, then its processed value is the state name (a string) assigned to the current value; this translation is performed by tstol.
The telemetry decommutation process stores telemetry values in Current Value Table (CVT) entries. CVT entries can be of several types: signed and unsigned integer, single- and double-precision floating point, text, and time. A CVT entry generally consists of 3 fields: the telemetry point's current raw value, the processed value (in engineering units), and a status word whose bits indicate the quality of the telemetry value. Normally, when you assign a value to a telemetry variable via TSTOL, you're simply replacing the telemetry point's raw value; the EU-converted value and the status word are not updated. It is possible, for testing purposes, to update these fields from TSTOL. To do so, just encode the 3 field's values in a string:
let system_variable = "raw_value EU_value status_word"
The format of the different fields depends upon the data type of the CVT:
CVT_SLI(signed long integer)CVT_ULI(unsigned long integer)- The raw value and the status word can be specified in decimal, octal, or hexadecimal, if you follow the standard C conventions for numeric constants; i.e., N, 0N, and 0xN, respectively. The EU-converted value should be specified as a real number, following the standard C conventions for floating point numbers.
CVT_SFP(single-precision floating point)CVT_DFP(double-precision floating point)- The raw and EU-converted values should be specified as real numbers, following the standard C conventions for floating point numbers. The status word can be specified in decimal, octal, or hexadecimal.
CVT_TEXT(text)- A CVT_TEXT entry only has 2 fields: the raw text and the status word. The raw value for CVT_TEXT entries is specified as a sequence of ASCII characters, with no embedded blanks or tabs. An arbitrary character can be included by specifying the decimal, octal, or hexadecimal equivalent of the character, preceded by "\". The status word can be specified in decimal, octal, or hexadecimal. Example: let SC_TEXT = "Hello\041 0x6D4"
CVT_TIME(time)- A CVT_TIME entry itself has 3 fields: the raw time value received in the telemetry stream, the raw value converted to UNIX time (seconds and microseconds since 1970), and the status word. Assigning a value to a CVT_TIME entry requires 5 fields: the raw value, the time in seconds, the left-over microseconds, a time status word, and the CVT status word. The raw time value is specified as a sequence of ASCII characters, the same as is done for CVT_TEXT strings. The remaining fields can be specified in decimal, octal, or hexadecimal.
Variables internal to a parser process are called local internal variables (LIV). LIVs are used to examine and control the internal workings of the parser, primarily for debugging and testing purposes. To set the value of an internal variable, the variable is referenced on the left hand side of an assignment statement using the special %liv construct:
let %liv(keyword) = expr
where keyword can be one of the following:
- echo_network
- enables or disables echoing on the operator's display of network input and output (e.g., commands to applications programs). Network I/O is normally invisible to the operator.
- echo_stored
- enables or disables echoing on the operator's display of internally-stored input. Stored input consists of directives that the parser submits to itself; for instance, an earlier version of the dialog directive waited for a response from its source by submitting and executing a pause directive. Stored input is normally not displayed on the operator's screen.
- errno
- assigns a numeric value to the C Library global variable,
errno.- events
- terminates the current event logger connection and establishes a new connection to the event logger on host expr.
- host
- changes the default host name for system variable access to expr.
- ignore_wait
- if expr evaluates to true, wait directives will be ignored - a real convenience during procedure testing.
- lex_debug
- enables or disables lex_util debug output (useful for monitoring what the parser is reading).
- libalex_debug
- enables or disables str_dupl() debug output (useful for tracking down memory leaks).
- log_procedure
- enables or disables the logging of executable procedure input. The echo directive controls the echoing of procedure input to the operator's screen. %liv(log_procedure) controls the recording of procedure input in the events log.
- malloc_debug
- sets the debug level for malloc() heap verification. If expr is 0 (the default), malloc() behaves normally. If expr is 1, the system checks the arguments passed to malloc() (and its relatives); messages are written to stderr if errors are detected. If expr is 2, the system verifies the integrity of the entire heap on each call to malloc() (or one of its relatives); if an error is detected, the parser aborts with a core dump. Running at level 2 is useful for detecting (presumably) inadvertent corruption of your allocated memory. This option is only supported (i) if the program was linked with the TPOCC
libmalloclibrary, or (ii) under SunOS if the program was linked with the system's/usr/lib/debug/malloc.ofile; see the SunOS documentation on malloc(3) for more information.- malloc_trace
- enables or disables malloc() trace output. This debug output, written to stdout, traces the allocation and freeing of dynamic memory. Tracing is only possible if the program was linked with the TPOCC libmalloc library.
- net_debug
- enables or disables debug output from the TPOCC networking functions. When debug of this type is enabled, data read from or written to any of the network connections established by tstol is dumped to stdout in hexadecimal and ASCII form.
- savehist
- adjusts the maximum number of operator input lines saved by tstol's command line history facility; the default is 20.
- screen_debug
- enables or disables screen debugging (e.g., with the xstol program). If screen debugging is enabled, tstol outputs file and line number information to the display interface when executing procedures. Normally, screen debugging is disabled.
- text_substitution
- enables or disables the application of text substitution to input lines. If text substitution is enabled, a parameter reference ("$" followed by a number or a variable name) in the input text is replaced by the value of the parameter. Usually, if no procedures or foreign directives are active, text substitution is enabled. At the start of a procedure, text substitution is automatically enabled. At the start of a foreign directive, text substitution is automatically disabled.
- timeout
- sets the timeout value for dialog, pause, and transact directives and system variable access to expr seconds; the default is 60 seconds. In the case of the directives, the timeout value controls how long the parser will wait for the applications task to respond (e.g., with a status message). During an attempt to reference a system variable, the timeout value controls how long the parser will wait for the data server to return the requested value.
- yydebug
- enables or disables YACC debug output - you must be desperate!
Internal variables can also be referenced within an expression (e.g., on the right hand side of an assignment statement):
%liv(keyword)
where different keywords return different values:
- help
- returns a string containing the possible keywords.
- echo_network
- returns true if echoing of network I/O is enabled and false otherwise.
- echo_stored
- returns true if echoing of internally-stored input is enabled and false otherwise.
- errno
- returns the system error message corresponding to the current value of C Library global variable,
errno.- events
- returns the name of the host on which the current event logger is running.
- host
- returns the default host used when accessing system variables.
- ignore_wait
- returns true if wait directives will be ignored and false otherwise.
- lex_debug
- returns true if lex_util debug output is enabled and false otherwise.
- libalex_debug
- returns true if str_dupl() debug output is enabled and false otherwise.
- localhost
- returns the name of the host machine on which tstol is running.
- log_procedure
- returns true if logging of procedure input is enabled and false otherwise.
- malloc_debug
- returns the current malloc() debug level.
- malloc_marker
- inserts a marker string in malloc()'s list of allocated memory and returns a string containing the address of the marker string. The marker can be used (in a call to malloc_dump() or malloc_totals()) to monitor memory allocation activity after the marker's creation.
- malloc_verify
- calls malloc_verify() to verify the integrity of the memory allocation heap. true is returned if the heap passed the test and false if the verification failed.
- net_debug
- returns true if debug output for the TPOCC networking functions is enabled and false otherwise.
- privileges
- returns a string containing a comma-separated list of the operator's current privileges. The access directive must be used to set the operator's privileges.
- screen_debug
- returns true if screen debugging is enabled and false otherwise.
- text_substitution
- returns true if text substitution is enabled and false otherwise.
- timeout
- returns the maximum number of seconds the parser will wait for (i) an applications task to respond with a message, or (ii) a remote data server to return the value of a system variable.
- version
- returns the version number of the TSTOL program. This number is actually the version number of TSTOL's YACC source file, the most frequently changed file in the program.
- yydebug
- returns true if YACC debug output is enabled and false otherwise.
- yydepth
- returns the current depth of the YACC token stack.
TSTOL supports the normal complement of arithmetic, logical, and relational expressions.
Arithmetic operations include addition (+), subtraction (-), multiplication (*), division (/), modulus (mod), remainder (rem), and exponentiation (**). The data type of an arithmetic expression is determined by the data types of its operands. An expression consisting entirely of integer operands gives an integer result. An expression involving at least one real number generates a real value. mod and rem always return integers. A string containing a number is converted to the appropriate real or integer value; e.g., "123" + "4.56" is equivalent to 123 + 4.56.
Only addition and subtraction are defined for date/time constants. Date/time constants are represented internally as the number of seconds and microseconds since January 1, 1970 (a UNIX convention). Adding two date/time constants is allowed, but probably not meaningful. Adding or subtracting an integer or real number X to or from a date/time constant produces a date/time constant offset by X number of seconds. Subtracting a date/time constant from another date/time constant gives the difference in seconds (a floating point number) between the two times.
The string concatenation operator (&) concatenates the string values of two expressions.
Logical operators (and, or, xor, not) accept numeric or logical operands and generate logical values of true or false. In a logical expression, a zero-valued numeric operand is treated as false and a non-zero value is treated as true. The left-to-right evaluation of subexpressions is short-circuited as soon as the truth or falsity of a logical expression is known. (The standard FORTRAN dot notation for logical operators and values is supported, but its use is discouraged.)
Date/time constants are given special treatment in logical expressions. If a date/time constant precedes or is equal to the current GMT, it evaluates to true (i.e., the time is past). If the date/time constant is greater than the current GMT, it evaluates to false (i.e., the time is still in the future).
Relational operators (=, <>, <, <=, >, and >=) accept two operands of any data type and compare them. A relational expression produces a logical value of true or false if the relational condition succeeds or fails, respectively. If the two operands are of dissimilar data types that prevent a meaningful comparison, false is always returned. (The standard FORTRAN dot notation for relational operators is supported, but its use is discouraged.)
Ordered from highest to lowest, TSTOL operator precedences are as follows:
Except for exponentiation, which is right-associative, operations at the same precedence level are evaluated from left to right. Parentheses may be used to alter the order of evaluation.
In TSTOL, variables may be assigned a value in one of several ways: directly using the let or ask directive, and indirectly by passing the variable by reference to a procedure.
TSTOL provides a number of built-in functions that ease the job of coding TSTOL procedures and directive definitions; these functions can be used freely wherever an expression is allowed. In the trigonometric functions, all angles are expressed in radians.
- abs (expr)
- returns the absolute value of an expression.
- nint (expr)
- returns the integer nearest the value of an expression.
- sqrt (expr)
- returns the square root of an expression.
- sin (expr)
- returns the sine of an angle.
- cos (expr)
- returns the cosine of an angle.
- tan (expr)
- returns the tangent of an angle.
- asin (expr)
- returns the angle having the given sine.
- acos (expr)
- returns the angle having the given cosine.
- atan (expr)
- returns the angle having the given tangent.
- %arg (expr)
- returns the i-th argument of the currently executing procedure or foreign directive body. Arguments are numbered from 1 to the number of arguments (see the %nargs function).
- %bin (expr [, width])
- returns a string containing expr formatted in binary; e.g., the number 23 would be returned as "...00010111". The optional field width argument controls the number of digits in the returned value; if not specified, width defaults to the number of bits in a long integer (usually 32).
- %chkgrp (group)
- returns true if the tstol process is a member of the specified UNIX group. group is case-sensitive and should be enclosed in string quotes if specified as a literal.
- %chkprv (privilege)
- returns true if the operator currently has the specified privilege. privilege is case-sensitive and should be enclosed in string quotes if specified as a literal.
- %dec (expr [, width])
- returns a string containing expr formatted in decimal; e.g., the number 23 would be returned as "23". The optional field width argument controls the number of digits in the returned value; if not specified, width defaults to the number of decimal digits (plus a sign, if necessary) required to represent expr. Unlike the binary, hexadecimal, and octal conversion functions, %dec pads the field with leading blanks, not zeroes.
- %default ([expr], [default])
- returns expr if it's defined and default otherwise. The default expression is not evaluated if the primary expression is defined. This function is intended for specifying defaults for missing directive arguments.
- %ds (...)
- is used to send commands to the data server. Since this %-function can be entered as a stand-alone directive, it is documented in the section, Generic TSTOL Commands.
- %env (expr)
- returns the value of a UNIX environment variable. A zero-length string ("") is returned if the environment variable is not defined.
- %eval (expr)
- returns the value of expr, converted to a string and evaluated as if it had been typed in. For example, given the string "COUNT+1", %eval would look up the value of variable COUNT and add 1 to it. %eval is useful for evaluating non-standard arguments in foreign directives (since, by definition, non-standard arguments are not directly evaluated by the parser).
- %float (expr)
- returns the value of expr, converted to a real number.
- %fparse ([file_spec [, default_file_spec [, related_file_spec]]] [, field])
- parses and constructs file names. %fparse expands file_spec into a full pathname. Missing components in the pathname are supplied by the default and related file specifications or, if necessary, by system defaults. If field is not specified, %fparse returns the fully-expanded pathname. If field is specified, %fparse extracts and returns the desired field from the fully-expanded pathname. Valid fields are "ALL", "DIRECTORY", "FILENAME", "EXTENSION", "VERSION", "FILEXTVER" (file name, extension, and version combined), and "NODE". File specifications or field names should be entered as strings in double quotes or as expressions that evaluate to strings. A file specification for a UNIX directory must have a trailing "/"; otherwise, %fparse will treat the last component of the directory path as a file name. When called without any arguments, "%fparse ()" returns your current working directory.
- %fsearch ([wildcard_file_spec [, default_file_spec [, related_file_spec]]])
- returns, on successive calls, the name of the next file matched by the wildcard file specification; an empty string ("") is returned when no more files are matched. The default and related file specifications are used to fill in missing components of the wildcard file specification (see %fparse). %fsearch returns the fully-expanded pathname for each file matched. Under UNIX, a sequence of calls to %fsearch with the same wildcard file specification can only scan a single directory; putting wildcard characters in a directory name will not effect a multiple-directory scan. Invoking the search function without any arguments ("%fsearch ()") terminates the current directory scan.
- %gmt
- returns the current GMT as a date/time constant.
- %hex (expr [, width])
- returns a string containing expr formatted in hexadecimal; e.g., the number 23 would be returned as "00000017". The optional field width argument controls the number of digits in the returned value; if not specified, width defaults to the number of hexadecimal digits required to represent a long integer (usually 8).
- %ident (expr)
- instructs the TSTOL parser to treat the string value of expr as a keyword. This "function" only works in certain places, so its use is currently discouraged. Directives can be constructed "on-the-fly" just as easily with the parse directive.
- %int (expr)
- returns the value of expr, converted to an integer. The fractional portion of expr is truncated, not rounded.
- %isint (expr)
- returns true if expr can be interpreted as an integer and false otherwise. Integers are integers, of course, as are floating point numbers which have no fractional part. Strings can also be interpreted as integers if they follow the standard C conventions (see strtol(3)) for decimal, octal, and hexadecimal constants: N, 0N, and 0xN, respectively.
- %isnum (expr)
- returns true if expr can be interpreted as a number (integer or floating point) and false otherwise. (Also see the %isint and %isreal functions.)
- %isreal (expr)
- returns true if expr can be interpreted as a real number and false otherwise. Floating point numbers and integers are considered real. Strings can be interpreted as reals if they follow the standard C conventions (see strtod(3)) for floating point numbers; e.g., 1, 2.3, 4.56E-78, etc.
- %lex (target, regexp [, retval0 [, retval1 [, ...]]] [, remainder ])
- dissects a target string using the given regular expression. %lex supports the full functionality of regcmp(3), including M-to-N closure ("RE{[m][,[n]]}") and subexpression assignment ("(RE)$n"); in addition, lex(1)-style alternation ("RE1 | RE2") is supported. If the regular expression match is successful, designated subexpressions are stored in the corresponding retvalN variables (for N = 0..9) and %lex returns true. If the match is unsuccessful, zero-length strings are assigned to the return variables and %lex returns false. In either case, remainder returns the text following the text matched by the regular expression. (See the subsection, Regular Expressions, for more information.)
- %liv (keyword)
- looks like a %-function, but it's really a reference to an internal variable; see the earlier section, Local Internal Variables.
- %lower (expr)
- returns the value of expr as a string, with all alphabetic characters converted to lower case.
- %match (target, expr [, expr ...])
- matches the target string against a list of expressions. Matches are case-insensitive; both the target string and the match strings are converted to upper case before a match is attempted. Use %rex if alphabetic case is important. A string in the list of expressions can specify a fixed-length abbreviation by embedding a "#" in the string; e.g., "SIM#INT" will match simint and its short form, sim. Variable-length abbreviations are denoted by a "*" embedded in the match string; e.g., "INIT*IALIZE" matches init, initi, ..., initialize. %match returns the index 1..N (all true values in TSTOL) of the matching string in the list of expressions; 0 (false in TSTOL) is returned if no match was found.
- %nargs
- returns the actual number of arguments passed to the currently executing procedure or foreign directive body.
- %net (...)
- is used for establishing and communicating across network connections. Since this %-function can be entered as a stand-alone directive, it is documented in the section, Generic TSTOL Commands.
- %nwords (exp)
- returns the total number of "words" in a string, including null words. (See the %word function.)
- %oct (expr [, width])
- returns a string containing expr formatted in octal; e.g., the number 23 would be returned as "00000000027". The optional field width argument controls the number of digits in the returned value; if not specified, width defaults to the number of octal digits required to represent a long integer (usually 11).
- %pick (index, expr [, expr ...])
- returns the i-th expression from a list of expressions. When used in conjunction with %match or %rex, %pick provides an easy way to convert abbreviations to fixed keywords.
- %real (expr [, format])
- returns a string containing expr formatted as a real number; e.g., the number 2.345E-4 would be returned as "0.0002345". The optional format argument can be any standard C format string for floating point numbers; the default format is "%G", which lets the system choose an appropriate format, with or without an exponent, depending on the value of expr.
- %replace (target, regexp, replacement_text [, max_substitutions])
- returns a copy of the target string, with text matched by a regular expression (regexp) replaced by replacement_text. Up to max_substitutions are applied to the target string; if max_substitutions is not specified, all occurrences of text matched by regexp are replaced (global substitution). The text matched by regexp can be manipulated to some extent using special character sequences ($n, $&, etc.) embedded in the replacement text; see the section on regular expressions for more information. To prevent $-character sequences from producing unwanted text substitution (if enabled), you may need to split replacement_text into several strings connected by the & string concatenation operator. (Very awkward!) Substitutions are not recursive; the search for the next regexp match begins following the last substitution. (See the subsection, Regular Expressions, for more information.)
- %rest (expr, index)
- returns the rest of a string, beginning with the i-th "word" in the string; words are delimited by blanks, commas, or tabs. Using the same scanning mechanism as %word, %rest skips arguments 1 through i-1 of expr and then returns the rest of expr (i.e., arguments i through N). A zero-length string ("") is returned if index exceeds the number of words in the string (see the %nwords function). %rest is useful for scanning non-standard arguments.
- %rex (target, regexp [, regexp ...])
- matches the target string against a list of regular expressions. The matches are case-sensitive - target is not converted to upper case before the match is attempted. If a regular expression must match the entire target string, be sure to include the "^" and "$" anchors at the beginning and end, respectively, of the regular expression. %rex returns the index 1..N (all true values in TSTOL) of the matching string in the list of regular expressions; 0 (false in TSTOL) is returned if no match was found. (See the subsection, Regular Expressions, for more information.)
- %search (target, regexp [, regexp ...])
- returns a string containing the text matched by a regular expresssion in a target string. More than one regular expression may be specified; the first regular expression that produces a match terminates the search. A zero-length string ("") is returned if none of the regular expressions is matched in the target string. The matches are case-sensitive - target is not converted to upper case before a match is attempted. (See the subsection, Regular Expressions, for more information.)
- %shell (...)
- is used to execute commands in the host operating system's shell. Since this %-function can be entered as a stand-alone directive, it is documented in the section, Generic TSTOL Commands.
- %source (type)
- returns the source of the current directive, where type is CONTEXT, LINE, or INTERACTIVE; the latter is probably the most useful. A new lexical context is pushed on the lexical stack whenever a foreign directive is executed or a procedure is started; the lexical context is popped from the stack when the directive or procedure completes. %source (CONTEXT) returns the source of the current lexical context; i.e., the keyword for a foreign directive and the file name for a TSTOL procedure. A context source is fixed throughout the lifetime of its lexical context. Because TSTOL has multiple input sources, a directive may be received from a source other than the current lexical context's source. The dynamic source of the current directive is returned by %source (LINE). For example, if a line of input is read from a network source during the execution of a TSTOL procedure, the context source will be the procedure and the line source will be the logical name of the network source. If the network input is itself a foreign directive, a new lexical context for the directive is pushed on the lexical stack; the new context source and line source will then be the foreign directive's keyword. The original source of the executing directive has not been lost, however. %source (INTERACTIVE) scans the lexical stack to determine the "interactive" source of the current directive; i.e., the source of the network or operator input that resulted in the execution of the current directive. For example, the interactive source of a foreign directive executing within a procedure started by the operator is the operator; %source scans past the foreign directive's lexical context and the procedure's lexical context until it encounters the interative source, the operator's lexical context. A zero-length string ("") is returned if the requested source type is the operator.
- %status
- looks like a %-function, but it's really a reference to TSTOL's global status variable, %status; see the earlier section, TSTOL Variables.
- %time (expr)
- returns the value of expr, converted to a date/time constant. If expr is a string in the format of a date/time constant, the string is converted to that date/time constant (useful when parsing non-standard directive arguments). Otherwise, expr is treated as the number of seconds since January 1, 1970 and is converted to the equivalent date/time constant.
- %upper (expr)
- returns the value of expr as a string, with all alphabetic characters converted to upper case.
- %word (expr, index)
- returns the i-th "word" from a string, where words are delimited by blanks, commas, or tabs. Null words in a string can be specified with consecutive commas (with intervening white space allowed). A zero-length string ("") is returned if index specifies a null word or if it exceeds the number of words in the string (see the %nwords function). %word is useful for scanning non-standard arguments.
Automatic sequencing and execution of directives is possible using TSTOL procedure files. Once a sequence of directives is stored in a procedure file, the procedure can be called up at a later time and the directives will be automatically executed, one after another.
TSTOL procedures files are normal UNIX text files that can be created and modified using the standard system text editors. Full- and in-line comments, form feeds, and blank lines can be used to document procedures and improve their readability.
A procedure definition has the following form:
proc name (formal_parameters)
... body of procedure ...
endproc
name is the name assigned to the procedure. The formal parameters are place holders for the arguments being passed into the procedure. The specification of formal parameters can take one of two forms. The traditional STOL approach specifies the number of arguments that will be passed into the procedure. In the body of the procedure, the arguments are referenced by number: $1, $2, ..., $N (see Text Substitution in the next section). For example:
proc ADD_NUMBERS (2)
X1 = $1 + $2
write "Sum = ", X1
endproc
TSTOL also supports named procedure parameters. Arguments are then referenced by the corresponding names in the formal parameter list. As an example:
proc ADD_NUMBERS (FIRST, SECOND)
X1 = FIRST + SECOND
write "Sum = ", X1
endproc
When a start directive is executed, the file containing the procedure is loaded into memory; the memory is deallocated when the procedure returns. There are no limits on the size of a procedure file, as long as the parser doesn't run out of memory - a remote possibility thanks to virtual memory.
When a procedure is invoked, each line in the body of the procedure is echoed on the operator's screen and then executed. Various control flow directives (e.g., goto, return, killproc, etc.) are available to alter the sequential execution of statements. These directives can appear in the procedure itself or may be manually entered by the operator as the procedure executes.
The execution of a procedure continues until: (i) a return directive is executed, (ii) the endproc directive terminates the procedure, or (iii) the operator aborts the procedure (see the killproc directive).
In the event of a syntax error or a processing error, tstol displays an informative error message on the operator's screen and halts procedure execution in an unconditional wait state. The operator can then enter zero or more directives to correct the error, followed by a go or goto directive to exit the wait state and continue execution. (Another option, of course, is to just kill the procedure.)
The following list summarizes the TSTOL directives that affect procedure control flow:
- ask
- prompts the operator for input and waits until something is entered.
- break
- breaks out of the current do loop.
- continue
- continues with the next iteration of the current do loop.
- do-enddo
- repeatedly executes a block of statements - an unconditional do loop.
- for-do-enddo
- executes a block of statements a certain number of times - a counted do loop.
- go
- causes a procedure to exit wait mode and continue execution.
- goto
- unconditionally shifts execution to the specified line number or label.
- if
- provides for the conditional execution of a single directive.
- if-then-elseif-else-endif
- provides for the conditional execution of blocks of statements.
- killproc
- aborts the currently active procedure, as if a return directive was executed.
- position
- causes procedure execution to branch to a specified line number or label and to enter an unconditional wait state, pending operator input.
- return
- exits the currently active procedure and returns control to the next higher level procedure.
- start
- starts a procedure up and passes it the specified arguments.
- step
- allows the operator to control the rate of procedure execution. If timed step mode is selected, the parser pauses for the specified amount of time between each statement executed. If manual step mode is selected, the parser pauses after each statement executed; the operator must enter go before execution can continue with the next directive in sequence.
- wait
- suspends procedure execution. There are four types of wait states: unconditional (wait for operator direction), conditional (wait until an expression evaluates to true), delta timed (wait for a certain amount of time), and absolute timed (wait until the specified GMT is reached).
- while-do-enddo
- executes a block of statements as long as an expression evaluates to true - a conditional do loop.
Since TSTOL is a block-structured language, there are restrictions on the destinations of goto, position, and start-at directives. A block is a group of consecutive TSTOL directives, bracketed by certain language constructs. TSTOL blocks include if-then blocks, elseif blocks, else blocks, and do loops. Performing a goto from outside of a block into the middle of a do loop, for instance, is generally meaningless. Consequently, TSTOL prohibits such transfers of control, as the following example shows:
goto Label_2 ; Illegal jump.
if (expr1) then
... block 1 ...
goto Label_5 ; Legal jump.
elseif (expr2) then
Label_2:
... block 2 ...
else
... block 3 ...
goto Label_4 ; Illegal jump.
endif
for I = 1 to N do
Label_4:
... block 4 ...
enddo
Label_5:
...
In MAE and most earlier STOLs, there was only one means of passing arguments to procedures: text substitution. In text substitution, the text of an argument string is substituted in the procedure text wherever the argument is referenced (via "$1", "$2", etc.) This substitution occurs before the affected directive is parsed. Text substitution is essentially macro expansion, a form of call-by-name argument passing.
TSTOL supports a more general form of text substitution, applicable to any variable (procedure-local or procedure-global), not just procedure arguments. Text substitution is initiated using the "$n" or "$variable" constructs; parentheses can be used to separate n or variable from surrounding text. For example, the following code executes the killproc all directive:
let COMMAND_OF_THE_DAY = "killproc all"
$COMMAND_OF_THE_DAY ; Text substitution.
Text substitution can be turned on and off by setting or resetting the local internal variable, %liv(text_substitution). Text substitution is initially enabled when TSTOL comes up. When a procedure starts up, text substitution is automatically enabled; the procedure can explicitly disable text substitution if need be. When a foreign directive is invoked, text substitution is automatically disabled; if necessary, text substitution can be explicitly enabled in the directive's definition. The current text substitution mode is saved and restored as procedures or directives are called and return. If procedure A disables text substitution and then calls procedure B, text substitution is automatically enabled in B and disabled when B returns to A. Foreign directives manipulate the substitution mode in a similar fashion.
Text substitution is applied to an input line before the line is passed to the parser's lexical analyzer. Consequently, substitutions are performed without regard to the presence of string delimiters or non-standard argument designations. If invoked by "start BROKE ("an elephant")", the following procedure:
proc BROKE (1)
write "I have $1 in my pocket!"
endproc
will display "I have an elephant in my pocket!", probably not what was intended. A different formulation of the write directive, that avoids text substitution, would be:
write "I have $" & "1 in my pocket!"
As the command-of-the-day example illustrates, the syntax of a TSTOL statement involving text substitution cannot be determined until the text substitution actually takes place. Compiling TSTOL procedures into a fast-executing, intermediate form (a future possibility) would be hampered by the use of text substitution. Consequently, its use in procedures is discouraged. The advantages of text substitution can still be achieved in other ways in TSTOL. The %arg(number) function provides the ability to reference arguments by number. The parse directive allows the construction and execution of an arbitrary directive. The following procedure emulates the example code above:
proc EXECUTE_COD (COMMAND_OF_THE_DAY)
parse %arg(1) ; Equivalent to $(COMMAND_OF_THE_DAY)
endproc
In addition to text substitution, TSTOL also supports call-by-value and call-by-reference mechanisms for passing arguments to procedures. If an argument is passed by value (the default mode), TSTOL makes a copy of the argument's value; the called procedure is free to manipulate the argument as it pleases. If an argument is passed by reference (similar to FORTRAN-style argument passing), the address of the argument is passed to the called procedure. Any changes to the argument in the called procedure are reflected back outside of the called procedure. Call-by-reference arguments thus provide a means of returning values from procedures.
How are arguments specified in a start directive? Since TSTOL is primarily a command language, not a programming language, a simple identifier in an argument list is interpreted as a text string, not a variable name. To treat the identifier as a variable reference, enclose it in parentheses or explicitly request call-by-value or call-by-reference argument passing:
- start XYZ (ABC, arg2, ...)
- passes the text string "ABC" to procedure XYZ.
- start XYZ ((ABC), arg2, ...)
- looks up the value of variable ABC and passes that value to procedure XYZ.
- start XYZ (%val (ABC), arg2, ...)
- passes the value of variable ABC to procedure XYZ.
- start XYZ (%ref (ABC), arg2, ...)
- passes the address of variable ABC to procedure XYZ. An assignment (via a let directive, for instance) to the corresponding formal parameter in procedure XYZ will store a new value in variable ABC.
Numerical and string expressions can be specified as arguments without surrounding parentheses, but avoid statements such as "start XYZ (ABC+2, ...)" - the parser tries to add 2 to the string "ABC"!
If the number of actual arguments M in a start directive is less than the number of formal parameters N specified in the proc declaration, the missing parameters (M+1 to N) are treated as null arguments. If the number of arguments exceeds the number of expected parameters (M>N), the extra arguments are retained and can be referenced within the procedure using the %arg(number) function.
tstol is a programmable parser that provides the user with the ability to define new directives at run-time using "internal" procedures. With this approach, similar to that used in extensible text editors (UNIX Emacs, VMS TPU, and assorted MS-DOS editors), a directive is defined in terms of other TSTOL directives. "Foreign" directive definitions are structured as follows:
directive name (formal_parameters) is
... directive attributes ...
begin
... body of directive definition ...
end
name specifies the directive keyword and can incorporate abbreviated short forms. Directive arguments can be specified using the argument count (MAE STOL-style) or by listing the named arguments (TSTOL-style). Directive attributes include keyword aliases (short forms), operations classes, if the directive is built-in (generic TSTOL?), and if the directive arguments should be interpreted (non-standard arguments?). The body of the directive definition specifies the procedural implementation of the directive and is not required for built-in directives. Any TSTOL directive is allowed in the body of the procedure, including do loops, procedure calls, and foreign commands. For example, the ICE/IMP orbit directive is defined as follows:
directive 'ORB#IT' (ORBIT_NUMBER) is
class CC
begin
ORBIT_NUMBER = %int (ORBIT_NUMBER)
if ((ORBIT_NUMBER < 1) or (ORBIT_NUMBER > 99999)) then
write "Enter an orbit number between 1 and 99999."
else
transact STATE_MANAGER "[XQ] ORBIT ", ORBIT_NUMBER
endif
end
The "#" in the keyword indicates a fixed-length abbreviation (orb is an abbreviation of orbit); "*" can be used for variable-length abbreviations. Within the directive body, the orbit number is range-checked and an ORBIT command is forwarded to the State Manager subsystem.
tstol reads the directive definitions (from the server initialization file, for instance) and stores the internal procedures in memory for fast access. When the operator enters a "foreign" keyword, the parser collects up the remaining arguments on the command line and passes them to the internal procedure defined for the keyword. The effect is the same as if the foreign directive were defined as a procedure in a TSTOL procedure file and the operator entered a start directive. Text substitution is automatically disabled when a foreign directive is invoked; it can be explicitly enabled within the body of the directive by setting local internal variable, %liv(text_substitution).
The arguments to some directives cannot be parsed correctly by tstol. For example, the parser has trouble with ICE/IMP's "simint init E-SCI" directive; "E-SCI" looks too much like an arithmetic expression. Directives such as this are marked as not standard in the directive definition. When the operator enters the keyword for a non-standard directive, the parser simply reads the rest of the command line into a string and passes it as a single argument to the keyword's internal procedure. The directive definition (somewhat abbreviated) for simint looks as follows:
directive 'SIM#INT' (REST_OF_LINE) is
class CC
not standard
begin
local ACTION, FMT
ACTION = %word (REST_OF_LINE, 1)
ACTION = %pick (%match (ACTION, "INIT*IALIZE", ;;
"CHANGE", "CHG", "TERM*INATE"), ;;
"INIT", "CHG", "CHG", "TERM")
if (ACTION = "") then
... invalid action ...
elseif (ACTION = "INIT") then
let FMT = %upper (%word (REST_OF_LINE, 2))
if (%lex (FMT, "^[E-J]-(SCI | ENG | VA[A-D])$")) then
transact STATE_MANAGER "[XQ] SIMINT INIT ", FMT
else
... invalid format ...
endif
else
... other actions ...
endif
end
%word is a built-in function that returns the i-th "word" from a string (the remainder of the command line, in this case), where words are delimited by blanks or commas. The %pick-%match expression validates the action keyword. Regular expressions provide a more concise way of matching the 30 possible telemetry formats, so a %lex expression is used to validate the telemetry format.
The ubiquitous "shoval value format" directive illustrates the use of some other built-in functions to process non-standard arguments:
directive SHOVAL (REST_OF_LINE) is
not standard
begin
local FMT, VALUE
VALUE = %word (REST_OF_LINE, 1)
FMT = %upper (%word (REST_OF_LINE, 2))
if (FMT = "B") then
write "Value = B'", %bin (%eval (VALUE)), "'"
elseif (FMT = "E") then
write "Value = ", %real (%eval (VALUE), "%E")
elseif (FMT = "H") then
write "Value = H'", %hex (%eval (VALUE)), "'"
elseif (FMT = "I") then
write "Value = ", %dec (%eval (VALUE))
elseif (FMT = "O") then
write "Value = O'", %oct (%eval (VALUE)), "'"
elseif (FMT = "R") then
write "Value = ", %real (%eval (VALUE), "%f")
elseif (FMT = "") then
write "Value = ", %eval (VALUE) ; Strings, etc.
else
write "Invalid SHOVAL format: ", FMT
error "Valid formats are B, E, H, I, O, R, or none."
endif
end
%eval evaluates the contents of a string as if they had been typed directly into the parser. For example, "shoval 2**12" passes the string "2**12" to shoval; %evaling the string produces the number 4096, which is then displayed. (Note that %word doesn't allow embedded blanks or commas in value.) %bin, %dec, %hex, %oct, and %real convert the number to the desired output format.
tstol attempts to make the invocation and execution of a foreign directive indistinguishable from the invocation and execution of a hypothetical, built-in directive that performs the same function. Doing so has introduced some subtleties into the process of resolving variable references, subtleties that affect foreign directives which pass non-standard arguments to the parse directive or the %eval function. Imagine a procedure called LOOP that simply displays an incrementing counter:
proc LOOP (N)
local COUNTER
for COUNTER = 1 to N do
shoval COUNTER
enddo
endproc
When the LOOP procedure is run, a new block containing LOOP's local variables is pushed on the symbol table stack; when LOOP returns, its block of local symbols is popped from the stack. When the shoval directive is executed, the string "COUNTER" is passed as a non-standard argument to the body of shoval. In earlier versions of tstol, a new local symbol block was created for foreign directives. %evaling "COUNTER" then produced a symbol not found error, since COUNTER would not be found in the current (shoval) block of local symbols or in the global symbols.
Later releases of tstol corrected this problem by implementing local symbol subblocks. When a TSTOL procedure is run, a local symbol block is pushed on the symbol table stack. A local symbol block itself is a stack of local symbol subblocks. The base subblock contains the procedure's local symbols. When a foreign directive is invoked, a subblock for the directive's local symbols is pushed on the subblock stack of the current local symbol block; when a foreign directive completes, its subblock is popped from the stack. A picture is worth a thousand words (the symbol stack is growing down towards the bottom of the page):
MISSION <-- global symbol block
%status
N <-- LOOP's local symbol block (and base subblock)
COUNTER
REST_OF_LINE <-- shoval's local symbol subblock
FMT
VALUE
When no procedure is active, the global symbol block functions as the current, "local" symbol block. Foreign directive subblocks are pushed and popped as needed, but the base subblock containing the global symbols is never popped from the symbol table stack.
Subblocks are considered part of the current local symbol block as far as the symbol resolution process is concerned. The search for a symbol in a local symbol block begins at the top of the subblock stack and descends through parent subblocks (if any) down to the base subblock. %eval (COUNTER) in shoval now returns the value of LOOP's variable. If shoval also declared a local variable called COUNTER, then its declaration would hide, within the body of shoval, LOOP's COUNTER variable.
Normally, the details of symbol table subblocks are of no concern. Foreign directives that make use of parse or %eval, however, should be aware of the implications of evaluating a string containing a variable name: the variable might have been declared local to the directive, local to a parent foreign directive, local to the base subblock's procedure, or global. Of particular concern are nested foreign directives, since a symbol table search will scan each of the nested subblocks. To guard against problems, declare all local variables and use unique names. For example, "shoval FMT" and "shoval VALUE" will probably display meaningless numbers, given the definition of shoval above (FMT and VALUE are local to shoval!).
Watchpoints provide a means of monitoring the values of system variables (e.g., telemetry mnemonics). Multiple watchpoints can be set up and simultaneously active. A requested value can be sampled every N seconds (asynchronous sampling) or when the value is decommutated (synchronous sampling). Whenever a value is received, a user-defined foreign directive procedure is invoked and passed the value of the system variable. Once activated, a watchpoint effectively executes in "background" mode; the operator can go on and enter other TSTOL directives, run procedures, etc. (Currently, watchpoints cannot "make themselves heard" if TSTOL is stopped because of a syntax error.)
Watchpoints are defined and activated by the watch directive. The watch directive can be entered with or without a body:
watch variable [ sampling_type [ rate ] ] is
begin
... watch body ...
end
watch variable [ sampling_type [ rate ] ]
The sampling type is asynchronous (the default) or synchronous. The watch body defines and is stored as a temporary, foreign directive (called a watchpoint directive) that will be executed whenever a value is received for the specified system variable. If no watch body is defined in the watch directive, a default watchpoint directive is substituted that just displays the variable's value on the operator's screen.
After storing the foreign directive, the TSTOL parser requests a stream of values for the system variable from the data server. If an asynchronous data stream is requested, the data server will sample and send the system variable's value every rate seconds. If a synchronous data stream is requested, the data server sends every rate-th occurrence of a system variable's value; the data stream is synchronous with respect to when the values are generated (e.g., when they are decommutated). Synchronous data streams are serviced by mission-specific applications, not the data server, so this mode is not necessarily supported for all system variables.
When a system variable's value is received, the watchpoint's foreign directive is invoked with a single argument, the variable's value encoded in ASCII. Watchpoint directives for telemetry points (data type: CVT_type) will receive a string containing several values: the raw value, the EU or processed value (if applicable), and the status flags (use %word to access the individual values). If the "P@" modifier is specified in the watch directive, the EU-converted value or the translated state name, whichever is applicable, is passed to the watchpoint's directive.
The foreign directive temporarily defined for a watchpoint is marked as non-standard; i.e., the rest of the command line following the keyword is packaged as a single string and passed to the directive. Specifying directive attributes in the watchpoint definition seems to serve no useful purpose.
A "watch MNF_COUNT" directive would simply display the satellite's MNF counter every 5 seconds. The following, more complex example monitors the setting (ON or OFF) of the master switch in the satellite's power subsystem:
watch P@MASTER_SWITCH#POWER@orion synchronous is
begin
if (%arg (1) = "OFF") then
write "Who turned out the lights?"
endif
end
The show watch directive displays a list of active watchpoints on the operator's screen. The stop watch directive cancels an active watchpoint:
stop watch watchpoint
watchpoint is the index (1..N) in the active watchpoints list of the watchpoint to be cancelled. The following example illustrates the normal procedure for stopping a watchpoint:
show watch ; Display list of active watchpoints.
stop watch 2 ; Cancel #2 on the list.
TSTOL execution privileges limit the set of directives available to an operator. For example, an operator must typically have Command Controller privilege ("CC") in order to issue spacecraft commands. The privileges required to execute a directive are specified by the "class privilege(s)" clause in the foreign directive definition for the directive. For example, /cmd is defined as follows:
directive '/CMD' (REST_OF_LINE) is
class CC ; Must be Command Controller
not standard
begin
...
end
At first, the operator has no privileges; he or she can only execute those directives which have no privileges defined for them. Execution privileges can be changed and examined using the following directives:
- access add privilege [, privilege ... ]
- attempts to add the requested privileges to the operator's current privileges.
- access delete privilege [, privilege ... ]
- deletes the specified privileges from the operator's current privileges.
- shoacc [ keyword ]
- displays the operator's current privileges. If a keyword is given, shoacc displays the privileges needed to execute that directive.
Prior to executing a directive, TSTOL checks the privileges assigned to the directive's keyword against the operator's current privileges. If the operator has at least one of the keyword's privileges (or if no privileges are required), the directive is executed. Otherwise, an error message is displayed on the operator's screen; if a procedure was active, the procedure is halted.
Although privileges can be assigned to built-in directives, TSTOL currently checks privileges on foreign directives only. At this time, it doesn't appear that privileges are needed for the built-in directives.
Because of the way execution privileges are implemented (described below), TSTOL doesn't know or care what operations classes are defined for a mission. TSTOL doesn't mind that ICE/IMP only has 2 classes (CC and FC) while GRO has 9 (MC, CC, PROC, FC, AN, EXR, EXL, OP, or DOCS).
How does TSTOL know that some untrustworthy operator can't become Master Controller ("MC") and take over the world? Well, TSTOL doesn't know. The access add directive internally calls a foreign directive, _ _access, and passes it the list of requested privileges (minus any that the operator already has).
_ _access is a mission-supplied foreign directive that is responsible for determining if the operator can have the requested privileges. In a typical TPOCC-based system that includes TSTOL, display, and state manager subsystems, the _ _access directive must communicate with Display and State Manager to verify the operator's new privileges. The following definition of the _ _access directive does just that:
directive _ _ACCESS (REST_OF_LINE) is
not standard
begin
local ACTION, PRIVILEGES
%status = false
ACTION = %word (REST_OF_LINE, 1)
PRIVILEGES = %rest (REST_OF_LINE, 2)
if (%match (ACTION, "ADD")) then
transact OPIO "[XQ] ACCESS ADD ", PRIVILEGES
if (%status) ;;
transact STATE_MANAGER "[XQ] ACCESS ADD ", PRIVILEGES
elseif (%match (ACTION, "DEL#ETE")) then
transact STATE_MANAGER "[XQ] ACCESS DEL ", PRIVILEGES
else
write "Invalid action, ", ACTION, ", passed to _ _ACCESS directive."
endif
end
If the operator already had Flight Controller ("FC") privilege, an "access add MC, CC" directive would result in the following exchange of messages:
TSTOL ----> "[XQ] ACCESS ADD MC, CC" ----> Display
TSTOL <---- "[ST] 0" <---- Display
TSTOL ----> "[XQ] ACCESS ADD MC, CC" ----> State Manager
TSTOL <---- "[ST] 0" <---- State Manager
TSTOL ----> "[CL] FC, MC, CC" ----> Display
If a bad status message (non-zero status code) is received from either Display or State Manager, the access add directive fails and none of the requested privileges are granted. The "[CL]" message is generated internally by the TSTOL parser, not by the _ _access foreign directive. It lets the display subsystem know what the operator's current privileges are.
If _ _access is not defined, then TSTOL will automatically check if the operator is a member of the UNIX groups corresponding to the requested privileges. Actually, TSTOL checks if the person who started up the TSTOL program is a member of the specified groups. That person may or may not be the operator. After the privileges are verified, a "[CL]" message is output to the display subsystem.
The access delete directive deletes the specified privileges from the operator's current privileges, calls the _ _access foreign directive, and then writes a "[CL]" message to Display. When deleting privileges, the _ _access code should send an "ACCESS DEL" message to the state manager:
TSTOL ----> "[XQ] ACCESS DEL CC" ----> State Manager
TSTOL <---- "[ST] 0" <---- State Manager
TSTOL ----> "[CL] FC, MC" ----> Display
The display subsystem must handle two types of message, the "ACCESS ADD" command and the "[CL]" screen update. The state manager must handle both the "ACCESS ADD privilege(s)" message and the "ACCESS DEL privilege(s)" message. In both cases, an "[ST]" status message is expected in return. The bad ADD status message will abort the original access directive. A bad DEL status message is too late to do any good!
Regular expressions are a means of specifying text patterns. Built-in TSTOL functions %rex and %lex provide foreign directive and TSTOL procedure programmers with a means of applying regular expressions to arbitrary strings (e.g., directive arguments or operator input). %rex allows you to verify that a text string matches a given pattern. %lex not only lets you verify that a string matches a pattern, it also lets you extract fields from within the string based on the pattern.
The following components of regular expressions are supported by TSTOL:
- c
- matches one instance of the specified character. For example, regular expression "abc" matches the string abc. To match a special character, such as "." or "$", escape it with a forward slash: "\\c".
- .
- matches one instance of any character. For example, regular expression "a.c" matches the text strings aac, abc, acc, etc.
- ^
- at the beginning of a regular expression, anchors the left edge of the match at the beginning of the target string. If a regular expression is not anchored, %rex and %lex will scan the entire text string looking for a match. For example, regular expression "abc" would match both abc and xyzabc. Anchored regular expression "^abc", on the other hand, will only match abc, not xyzabc.
- $
- at the end of a regular expression, anchors the right edge of the match to the end of the target string. For example, regular expression "abc$" matches abc and xyzabc, but not abcxyz. A regular expression anchored at both ends ("^...$") must consume the entire target string in order for the match to succeed.
- [characters]
- matches one instance of a character in the specified set of characters. Character sets can be specified literally (e.g., "[abc]" matches a, b, or c) or as a range of characters (e.g., "[A-Za-z0-9]" matches any upper case letter, lower case letter, or digit.
- [^characters]
- matches one instance of a character not in the specified set of characters.
- [:class:]
- matches one instance of any character that belongs to the specified class of characters. The possible classes are alpha, upper, lower, digit, xdigit, alnum, space, punct, print, cntrl, and graph. Class names are not case-sensitive. Although the meanings of some of the classes are obvious, check the UNIX documentation for ctype(3) before using this regular expression construct.
- [^:class:]
- matches one instance of any character that does not belong to the specified class of characters.
- RE*
- matches zero or more instances of regular expression RE. For example, "a*b" matches b, ab, aab, aaab, etc.
- RE+
- matches one or more instances of regular expression RE. For example, "a+b" matches ab, aab, aaab, etc.
- RE?
- matches zero or one instance of regular expression RE. For example, "a?b" matches b and ab only.
- RE{[m][,[n]]}
- matches m through n instances of regular expression RE. If not specified, m defaults to 0 and n defaults to m ("RE{m}") or to a very large number ("RE{m,}"). "RE*" is equivalent to "RE{0,}". "RE+" is equivalent to "RE{1,}". "RE?" is equivalent to "RE{0,1}".
- (RE)
- matches regular expression RE. The parentheses allow you to group regular expressions. For example, regular expression "(ab)*cd" matches cd, abcd, ababcd, etc.
- (RE)$n
- matches regular expression RE and assigns the text matched by RE to the nth variable (where n is a single digit in the range 0 through 9). This capability is only available in the %lex function; when used in a call to %rex, "(RE)$n" is equivalent to "(RE)". For example, if regular expression "((ab)*)$0(cd)$1" matches ababcd in a call to %lex, then abab is stored in retval0 and cd in retval1.
- RE1 RE2
- matches regular expression RE1 followed immediately by regular expression RE2; there should be no intervening spaces in the composite regular expression or in the target string. For example, regular expression "a*b" is the concatenation of regular expressions "a*" and "b".
- RE1 | RE2
- matches either RE1 or RE2. For example, regular expression "((abc)|(def))ghi" matches abcghi and defghi.
Regular expressions add powerful lexical analysis capabilities to foreign directives and TSTOL procedures, capabilities that do not need to be hard-coded into the underlying tstol program. The following regular expression, for instance, recognizes ICE serial magnitude spacecraft commands of the form "mnemonic/X:77.777.777.777.777", where X is command decoder A or B:
[:alnum:]+-?[:alnum:]*/[AB]:[0-7]{2}(\\ .[0-7]{3}){4}
(Example ICE command mnemonics include "137", "ANXMEM", and "BAM-ION"; hence, the double alphanumeric pattern for the mnemonic.) Another example is the directive from the original ICE POCC that is used for changing values in a simulated, telemetry data stream:
simint chg=sxxxyyyzzz-n,m/value
where xxx is the word location, yyy is the minor frame, zzz is the major frame, n is the start bit, m is the stop bit, and value is the value to be inserted in the data stream. simint is defined as a foreign directive with non-standard arguments; consequently, simint receives a single argument called REST_OF_LINE. A call to %lex validates the format of the user input and extracts the individual "arguments". The regular expression used to parse the command line is:
^CHG=S([:digit:]{3})$0([:digit:]{3}?)$1([:digit:]{3}?)$2-([0-7])$3,([0-7])$4/([:digit:]+)$5$
And the actual directive definition:
directive 'SIM#INT' (REST_OF_LINE) is
not standard
begin
local MJF, MNF, RE, START_BIT, STOP_BIT, VALUE, WORD
RE = "^CHG=S([:digit:]{3})$0([:digit:]{3}?)$1" & ;;
"([:digit:]{3}?)$2-([0-7])$3,([0-7])$4/([:digit:]+)$5$"
if (%lex (%upper (REST_OF_LINE), RE, ;;
WORD, MNF, MJF, START_BIT, STOP_BIT, VALUE)) then
... Range-check the arguments and
... forward them to the internal simulator.
else
... invalid argument ...
endif
end
Two of TSTOL's lexical functions, %search and %replace, provide powerful search-and-replace capabilities based on regular expressions. %search returns the text matched by a regular expression in a target string. For example,
%search ("MB012345.678", "[:digit:]{3,3}")
returns "012", the day field from an IMP block history file name. (Actually, %lex is more suited to field extraction, but I can't think of a good example off the top of my head!)
%replace provides TSTOL with string editing abilities and is invoked as follows:
%replace (target, regexp, replacement_text [, max_substitutions])
%replace scans target, looking for a substring matched by regexp; if found, the matched substring is replaced in a copy of target by replacement_text. Up to max_substitutions are made in target; the default is to replace all occurrences of the matched substring by replacement_text. The following character sequences embedded in the replacement text provide additional editing capabilities:
- $n
- Insert the subexpression (0..9) matched by "(RE)$n" in the regular expression.
- $&
- Insert the text matched by the full regular expression. For example, "$&$&" replaces the matched text by two copies of itself.
- $ln
- Insert the matched subexpression (0..9), converted to lower case.
- $l&
- Insert the text matched by the full regular expression, converted to lower case.
- $un
- Insert the matched subexpression (0..9), converted to upper case.
- $u&
- Insert the text matched by the full regular expression, converted to upper case.
- \\c
- Insert character c; e.g., "\\$" inserts a dollar sign in the replacement text.
To illustrate, the following invocation of %replace
%replace ("** abcdef **", "(abc)$1(def)$2", "$2$1 is $& split in half and reversed")
returns the following string:
"defabc is abcdef split in half and reversed"
A more useful application of replace is found in the definition of directive LIST_PAGES, a foreign directive which lists the names of pages the operator can bring up with the page command. Environment variable $UIDPATH is used by TPOCC's display subsystem to locate page definition files. The value of UIDPATH is a colon-separated list of UNIX pathnames, as in the following example:
/home/mission/display/uil/%U.uid:/home/mission/database/dandr/uil/%U.uid
When processing a page name directive, the display subsystem substitutes name for "%U" in the UIDPATH string and scans the list of directories, looking for the "name.uid" page definition file. The LIST_PAGES directive, on the other hand, is not looking for a specific file, but for a whole set of files. LIST_PAGES uses %replace to convert the UIDPATH to a comma-separated list of csh(1)-style wildcard file names:
/home/mission/display/uil/*.uid, /home/mission/database/dandr/uil/*.uid
A list of all file names matching these wildcard pathnames is displayed on the operator's console. The complete directive definition for LIST_PAGES is shown here:
directive LIST_PAGES is
begin
local FILE_NAME, I, UIDPATH
UIDPATH = %default (%env ("UIDPATH"), "./%U.uid")
UIDPATH = %replace (UIDPATH, ":", ",")
UIDPATH = %replace (UIDPATH, "%[:alpha:]", "*")
for I = 1 to %nwords (UIDPATH) do
do
FILE_NAME = %fsearch (%word (UIDPATH, I))
break if (FILE_NAME = "")
write %upper (%fparse (FILE_NAME, "FILENAME"))
enddo
enddo
end
The first %replace substitutes commas for colons in UIDPATH; the second %replaces converts "%X"s to asterisks.
The following TSTOL commands are available in all TSTOL languages, regardless of their mission dependencies. Sample definitions of aliases and operations classes for the built-in, generic commands can be found in /home/tpocc/source/generic.prc. A "start GENERIC" statement in your server initialization file will process these definitions, although the TSTOL parser still works without them. See the directive directive for more information on assigning directive attributes.
changes the operator's current privileges for executing directives. The access add directive attempts to add the requested privileges to the operator's current privileges. If any one of the requested privileges is refused, the directive fails and none of the requested privileges are added. The access delete directive deletes the specified privileges from the operator's current privileges. The shoacc directive displays the operator's current privileges.
Abbreviations:acc delExamples:access add MC, CC, DOC ; Rule the world. access del CC ; Relinquish command controller status.
issues a prompt to the operator and stores the next line of input from the operator into variable. If variable is not specified, the input is stored in local variable ANSWER. abort (or ab) can be entered to terminate the ask prompt with an error.
Example:ask "Host name of front-end computer? " FRONT_END
breaks out of the current do loop if expr evaluates to a non-zero value. break by itself is an unconditional break.
Example:(see do-enddo)
changes the parser's current working directory to pathname; if a pathname is not specified, cd simply displays the current directory. This directive is useful if you're running a network-based parser server, you're editing and testing TSTOL procedures in pathname, and the parser's $mission_PROC_FILE environment variable was set so the parser can search pathname for TSTOL procedures. Difficult-to-parse pathnames (e.g., VMS directory specifications) should be enclosed in string quotes.
Examples:cd ~/test_procs ; On UNIX. cd "[operations.test_procs]" ; On VMS.
skips the remaining code in the current do loop and continues with the next iteration of the loop. continue if continues if expr evaluates to a non-zero value. continue by itself unconditionally continues the loop.
Example:(see for-do-enddo)
turns debug on and off. If debug is on, the parser outputs to stdout the lexical and syntactical rules that are matched during the parsing of input. If on or off is not specified, the current debug state is displayed.
performs a dialog mode transaction. The dialog directive should only be submitted by applications programs communicating with the parser over a network connection (established via the remote directive). When a dialog manual directive is received, zero or more messages are displayed in the operator output window and the operator is prompted for input by prompt; the next line entered is returned to the source of the dialog directive. The parser then waits for another message from source; e.g., another dialog directive or a status message. The effect of dialog manual is basically equivalent to the following sequence of directives:write message ... other messages ... ask prompt let ANSWER = %upper (ANSWER) transact source "[DRtag] ", ANSWERIf no procedure file is active, dialog prompt functions just like dialog manual. If a procedure is active, the dialog input will be read from the procedure file, not the operator. dialog manual is typically used for dialogs such as critical command acknowledgements; dialog prompt is intended for dialogs such as spacecraft command entry.
Before a dialog response is returned to the source of a dialog directive, text substitution is applied to the response, leading and trailing blanks are deleted, and the entire line is converted to upper case.
Both dialog directives allow an optional tag that will be returned to source along with the input. A tag is a string of arbitrary characters enclosed in square brackets that the applications task can use to keep track of dialog directives and responses.
defines a "foreign" directive. The directive definition specifies the keyword that invokes the foreign directive, assigns attributes (aliases, operations classes, etc.) to the keyword, and provides a procedural definition of the directive's execution. Directive attributes include:The directive body is essentially a TSTOL procedure - rather than being input and executed from a file upon demand, the directive body is input at start-up time and stored in memory. During the processing of a directive definition and after the begin keyword has been parsed, the directive body is input line-by-line - no parsing and no text substitution - until a line whose first word is end is encountered. Consequently, directive definitions should not be nested within other directive definitions. Directive definitions can appear in if-then-else blocks, however.
- alias alias [ , ... ]
- defines aliases for the directive keyword. Fixed- and variable-length abbreviations can be specified by enclosing the alias in single quotes (assuming the -quotes2 command line option) and embedding one of the special characters, "#" or "*". "#" denotes a fixed-length abbreviation; e.g., 'P#AGE' matches p and page. "*" denotes a variable-length abbreviation; e.g., 'P*AGE' matches p, pa, pag, and page.
- built_in
- indicates that the directive is built-in, i.e., the generic TSTOL directives that are hard-coded in the parser. In this case, no directive body is defined; the foreign directive definition is used only to assign attributes to the built-in directive.
- class class [ , ... ]
- assigns operations classes to the directive. In order to execute the directive, the operator must possess one of the corresponding capabilities.
- [ not ] standard
- controls the interpretation of the directive arguments. Arguments to standard directives are interpreted in the same fashion as arguments in a start directive. Arguments to non-standard directives are not interpreted; the parser treats the remainder of the command line following the directive keyword as a single argument. Non-standard directives should be declared as expecting a single argument; e.g., "directive name (REST_OF_LINE) is ...". The procedure body is responsible for parsing and interpreting the contents of REST_OF_LINE, not a difficult task if you use the %-functions available in TSTOL.
repeats a group of commands over and over. do until loops until expr evaluates to true (a non-zero value). do by itself loops forever. break terminates a loop; continue skips to the next iteration. (The do if and do while directives available in an earlier version of TSTOL are still supported, but the use of while-do is preferred.)
Example:do ask "Finished (y/n)? " break if (ANSWER = "y") ... continue processing ... enddo
sends an ASCII command string to the primary data server (designated by the %liv(host) internal variable). %ds returns true if the command was successfully sent and false otherwise. Currently, the data server only responds to "DEBUG ON" and "DEBUG OFF" commands.
Example:%ds ("debug on") ; Enable data server debug.
turns command input echo on and off. By default, operator and procedure input are echoed to the operator's display. If on or off is not specified, the current echo state is displayed. echo save and echo restore push and pop settings on an echo state stack, allowing procedures to turn echo on and off without affecting the echo settings of parent procedures.
Example:proc CLASSIFIED echo save off ... secret stuff ... echo restore endproc
simulates an error condition. The optional expressions are formatted, concatenated, and displayed on the operator's screen as a single message and execution is suspended until further direction is received from the operator. error is useful in procedures for signalling user-detected error conditions.
Example:proc CONNECT (HOST) remote STATE_MANAGER is MISSION & "_stmgr_parser" on HOST if (%status) error "Unable to contact the state manager on " & HOST & "." endproc
sets the internal execution mode of the parser. These modes include nop, execute, proc_search, proc_exit, wait, etc. If the parser gets lost executing your commands, exec on will unconditionally return the parser to execute mode. exec by itself displays the current execution mode.
Examples:exec ... "Modes: Execution = "proc_search"" is displayed on the screen ... exec on ... "Modes: Execution = "execute"" is displayed on the screen ...
terminates the parser. If prompt is specified, the operator is first asked if he/she really wants to exit; if the answer is yes, the program exits. This directive only terminates the parser associated with the current TSTOL input window; the directive does not bring down parsers attached to other windows or the parent server process.
Examples:exit exit "The pass is still in progress; do you really want to exit (Y/N)? "
repeats a group of commands a specified number of times. In an incrementing loop:for counter = lower to upper [ step increment ] dothe counter variable is initialized to the lower bound; the loop is executed as long as the counter's value is less than the upper bound (the loop may not be executed at all). After each loop iteration, the step-value is added to counter. In a decrementing loop:
for counter = upper down to lower [ step decrement ] dothe counter variable is initialized to the upper bound; the loop is executed as long as the counter's value is greater than the lower bound (zero iterations are possible). After each loop iteration, the step-value is added to counter, so be sure and specify a negative increment. In all cases, break will prematurely exit a loop; continue will skip to the next iteration.
Example:for I = 1 to NUM_ITEMS do ask "Process item " & I & " (y/n)? " continue if %match (ANSWER, "N#O") ... process item i ... enddo
declares one or more global variables. The global command can be used anywhere and anytime, but, once entered, global variables remain in the symbol table forever. Global variables are accessible at any procedure level, unlike local variables (see the local command) which can only be referenced at the level in which they were declared.
Example:global MISSION, PI let MISSION = "HST" let PI = 3.14
terminates a wait condition (see the wait command) or single-steps through a procedure (see the step command).
Abbreviations:g
causes the parser to branch to a specified line number or label in the current procedure. Branching into the middle of an if-then-else block or a do loop is forbidden; see Procedure Definition and Control, for more information about this restriction.
Examples:goto ICE_SKATE ... ICE_SKATE: ...
conditionally executes a single command. The command following if is executed if expr evaluates to a non-zero value. (Also see the block-structured if-then-else command.)
Examples:if (VALUE > LIMIT) write "Value ", VALUE, " exceeds limit." if (ERROR) goto ERROR_EXIT
conditionally executes blocks of commands. The commands following if are executed if the if's expr evaluates to a non-zero value. Commands following elseifs are executed if the previous if-elseifs failed and the new elseif's expr evaluates to a non-zero value. Commands following else are executed if all else fails. elseif and else blocks are optional. if-then-else blocks can be nested.
Example:do ask "Choice (1 = first choice, 2 = second choice, 3 = third choice)? " if (ANSWER = 1) then goto CHOICE_1 elseif (ANSWER = 2) then goto CHOICE_2 elseif (ANSWER = 3) then goto CHOICE_3 else write "Invalid choice: ", ANSWER endif enddo
aborts the currently executing procedure and resumes execution of the parent procedure. If all is specified, all levels of procedure execution are aborted.
Abbreviations:kp killp
assigns a value to a variable. variable can be any local or global variable (see the global and local commands); if not yet declared, variable is automatically declared as a local variable. System variables on both the left and right hand sides of the equals sign can be referenced as:mnemonic[#process][@host][[index]]
The parser automatically establishes a network connection with the data server on the remote host and transmits the commands needed to store or recall a system variable's value.
Examples:global GVAR local LVAR ... let GVAR = 123.456 LVAR = "abcdef" ; System variables are on both sides in the following assignment: FORMAT_STR[2] = FORMAT_STR#ICE_DECOM@space[3]
declares one or more local variables. Local variables are local to the currently executing procedure and can be declared anywhere within a proc-endproc definition. A procedure's local variables disappear when the procedure exits (via return, endproc, or killproc). If no procedure is running, a local declaration is equivalent to a global declaration.
Example:(see proc-endproc)
displays the amount of memory allocated via str_dupl(). This command is useful for detecting memory leaks during debug and test of the parser.