Trailing-Edge
-
PDP-10 Archives
-
decuslib20-01
-
decus/20-0002/comnd.doc
There are 2 other files named comnd.doc in the archive. Click here to see a list.
SAIL-COMND Interface
====================
Andrew R. Lowry
and
David S. Millman
Columbia University
Center for Computing Activities
User Services Group
15 June 1979
Table of Contents i
Table of Contents
Preface 1
1. The Jsys 3
1.1 General Information 3
1.2 How It Works 3
1.2.1 Information Needed By COMND 3
1.2.2 The Parsing Process 5
1.2.3 The Command Line 7
1.2.4 The Control/H Feature 8
1.2.5 Multiple Function Calls 9
2. The Interface 11
2.1 General Rules 11
2.1.1 Loading the Routines 11
2.1.2 Naming Conventions 11
2.1.3 Handling Error and Reparse Conditions 12
2.1.3.1 Cm!Err and Cm!Reparse Flags 12
2.1.3.2 Cm!Retry - An Alternative Error 13
Recovery Mechanism
2.1.3.3 The Built-in Error Handler 14
2.1.4 The Atom Buffer 15
2.1.5 Command Files 16
2.1.6 Common Parameters 17
2.2 Specifics 19
2.2.1 The Cm!Act Procedure 19
2.2.2 The Cm!Cfm Procedure 19
2.2.3 The Cm!Cma Procedure 20
2.2.4 The Cm!Dev Procedure 21
2.2.5 The Cm!Dir Procedure 21
2.2.6 The Cm!Fil Procedure 22
2.2.7 The Cm!Fld Procedure 24
2.2.8 The Cm!Flt Procedure 25
2.2.9 The Cm!Getatm Procedure 25
2.2.10 The Cm!Ifi Procedure 25
2.2.11 The Cm!Ini Procedure 26
2.2.12 The Cm!Key Procedure 27
2.2.13 The Cm!Nod Procedure 29
2.2.14 The Cm!Noi Procedure 29
2.2.15 The Cm!Num Procedure 30
2.2.16 The Cm!Nux Procedure 30
2.2.17 The Cm!Ofi Procedure 31
2.2.18 The Cm!Qst Procedure 31
2.2.19 The Cm!Retry Procedure 32
2.2.20 The Cm!Size Procedure 33
2.2.21 The Cm!Swi Procedure 33
2.2.22 The Cm!Tad Procedure 34
2.2.23 The Cm!Take Procedure 35
2.2.24 The Cm!Tbuild Procedure 36
2.2.25 The Cm!Tok Procedure 38
2.2.26 The Cm!Txt Procedure 38
2.2.27 The Cm!Uqs Procedure 39
2.2.28 The Cm!Usr Procedure 39
ii SAIL-COMND Interface
2.3 Multiple FDBs 40
3. Examples 43
3.1 Example 1 - Nothing Fancy 43
3.1.1 SAIL Code 43
3.1.2 Remarks 47
3.2 Example 2 - The Ctrl/H Feature And Switches 48
3.2.1 SAIL Code 49
3.2.2 Remarks 53
A. Standard Break Tables 55
Index 59
Preface 1
PREFACE
This document describes a package of SAIL procedures
designed to make the TOPS-20 COMND jsys easily available to
the SAIL programmer. All functions of COMND are included,
including provisions for up to ten alternate functions in a
single call. Two features of COMND which are not
implemented are the following: A reparse dispatch address
may not be specified in word 0 of the command state block,
and the cm!tbuild procedure for constructing TBLUK lookup
tables from string arrays does not make provision for
declaring strings as abbreviations for other strings in the
array (see the discussion of the CM%ABR bit in the
description of the CMKEY function call in the Monitor Calls
Reference Manual).
The document is in three parts. The first part
describes the COMND jsys itself in moderate detail. The
second part describes the SAIL-COMND interface routines and
how to use them. The third part gives some brief examples
of the use of the interface routines.
Many thanks go to Frank da Cruz, Chris Ryland and
Norman Kincl of the CUCCA Systems Group, and to Ted
Markowitz, Ken Rossman, Harry Yudenfriend and Jeffrey
Slavitz of the CUCCA User Services Group for their technical
assistance and numerous suggestions. Also thanks to any
others who used the preliminary versions of the package
during its development, for bearing with the many bugs and
misfeatures and for any contributions which they have made.
2 SAIL-COMND Interface
The Jsys 3
1. THE JSYS
1.1 General Information
Every user of the DECsystem-20 quickly becomes familiar
with the workings of the COMND jsys, although he may not be
aware of his education. The COMND jsys is the thing that
figures out what he means when he abbreviates his commands
to the EXEC and finishes up his commands for him when he
types an escape character. It is also what types guide
words in parentheses telling him what he must type next, and
it is the thing that will untiringly answer his question
marks with lists of alternatives for him to choose from. In
short, it is one of the things that makes learning and
typing in commands to the EXEC as easy as it is. Hence its
name -- COMND.
1.2 How It Works
Using the COMND jsys mainly consists of the following:
you tell it what you're looking for, and it tells you what
it finds. All the complexities have to do with how this
communication takes place. A great deal of this is common
to all the calls you can give to COMND, but some of it
depends on exactly what you're asking COMND to look for.
1.2.1 Information Needed By COMND
All the information which you must supply to COMND may
be broken down basically into two sets, the Command State
Block (CSB) and the Function Descriptor Block (FDB).
4 SAIL-COMND Interface
The CSB is ten words (storage locations) long and
contains information about what has been typed so far, how
much more can be typed without overflowing the space that
has been set aside to store it, and where COMND can find
other information that it needs. Most of this information
must be supplied only once by the program using COMND, and
from that point on COMND will update the information as it
goes. Exact information on the contents of the CSB is not
necessary for the SAIL programmer who wants to use COMND,
but for those interested, it can be found in the
DECsystem-20 Monitor Calls Reference Manual.
The FDB is four words long and contains information
which is more specific to the type of call which is being
made than is the information in the CSB. It is here that
COMND finds out what type of information it should be
looking for -- file name, time of day, one out of a list of
possible keywords, or any other of the 24 different items it
knows how to look for. Also in the FDB it finds pointers to
a help string and a default string which the controlling
program supplies. The help string is what will be typed if
the user types a question mark, and the default string is
what COMND will fill in if the user types an escape
character. Finally, COMND finds several indicators in the
FDB telling it how to process the request -- things like
whether or not to convert lower case input into upper case,
whether or not to accept indirect file specifications, etc.
The SAIL programmer who wishes to use the COMND
The Jsys 5
interface need not worry at this point how the information
is stored in the FDB and the CSB. He will simply supply the
information as parameters to the package routines, and they
will take over from there. Those who are interested,
however, are referred to the DECsystem-20 Monitor Calls
Reference Guide.
The only thing left to do after the CSB and FDB have
been properly filled in is to tell COMND where they are and
let it go do its work.
1.2.2 The Parsing Process
When COMND is invoked, it starts accepting characters
from (usually) the job's controlling terminal. It keeps
taking characters until the user types what is called an
"action" chatacter. Action characters include question
mark, escape, ctrl/f and carriage return, and they are
called action characters because COMND won't start doing
what it is supposed to do until one of them is typed. Once
an action character is encountered, COMND will determine
whether or not the user has finished typing what he was
supposed to type, and if so, will return control to the
calling program. This can be done in any of three possible
states.
If COMND was able to interpret what was typed, and
decided that it was an appropriate response, then it returns
normally with the data that it received stored somewhere
where the program can easily retrieve it.
6 SAIL-COMND Interface
If COMND was unable to understand what was typed in the
context of what it was told it was looking for, then it will
return with an error indicator set so that the program will
know that something went wrong.
The third possibility is best shown by example.
Suppose a program desires to obtain from the user first a
file name, then a time of day. This will involve two calls
to COMND. When the first call is executed, suppose the user
(call him Fred) types in FOO.BAR as his file name. COMND
accepts this as a valid file name and returns normally to
the calling program, which then executes COMND again, this
time asking for a time of day.
At this point, Fred decides that he really didn't want
to use FOO.BAR, but wanted FOO.BAZ instead. So he deletes
back to the R and types in a Z, and then he goes ahead and
types in a time of day as required. Now it looks like
trouble ... COMND has already told the program that Fred
wanted FOO.BAR, and now it needs some way to let the program
know that he changed his mind. In COMND jargon, we say that
a "reparse" is needed. COMND sets a flag to let the program
know what has happened, and now the program must start right
from the beginning and reissue all the calls that it made to
COMND for the current command line (this rather vague term
will be firmed up shortly). Thus it redoes the call to get
a file name, and COMND fills in FOO.BAZ this time, and then
it continues with the time of day call just like before. If
there had been other calls on this command line before the
The Jsys 7
file name, they too would have to be reissued in the same
order as they originally were called. This may seem rather
complicated, but with SAIL's block structure and its NEXT
and CONTINUE statements it all becomes fairly simple, as
will be demonstrated in Part III of this document.
1.2.3 The Command Line
The term "command line" was used a few times in the
preceeding paragraph, and although it may have a fairly
intuitive meaning, it also has a very strict meaning in the
context of the COMND jsys, which will be explained now and
should be kept in mind when trying to understand the reparse
mechanism.
One of the calls that can be made to COMND is called
"CMINI" (each different call has its own slightly mnemonic
name). The CM signifies that it has something to do with
COMND, and the INI stands for "INItialize". This call,
unlike the rest of the calls, accepts no input from the
terminal. It is used to set up initial values in the CSB
and to type out the command line prompt. The end of this
prompt is the farthest back that a user may delete when
using the program.
A "command line", then, consists of all responses to
COMND calls made between successive CMINI's. For a reparse,
the program reissues COMND calls starting with the one after
the CMINI call that initiated the command line. The CMINI
call should not be reissued. That would be done if an error
were detected and the entire command line had to be
8 SAIL-COMND Interface
restarted. The difference is that when CMINI is done, COMND
forgets everything that was previously contained in the
buffer. This is appropriate for a complete restart after an
error, but not for merely backing up on a reparse.
1.2.4 The Control/H Feature
It was explained in the previous section that when a
parsing error occurs during a call to COMND, a flag will be
set and the calling program should reissue all the COMND
calls for the current command line, including the CMINI.
When that is done, the user may retype all of the
information that he previously typed correctly, and then
finish the command line.
Often, however, this will mean that the user will have
to retype quite a bit of correct information. This may be
avoided by using the cm!retry procedure as described above,
but there is a safer way of going about things. If the
program leaves the CSB in the correct state, then the user
will have the option of typing a contro/h
(backspace) character as the very first character after the
new prompt, which will cause the previous contents of the
command line to automatically be retyped up to but not
including the erroneous field. All this can be perfectly
transparent to the calling program; although there is a way
for the program to find out that a ctrl/h was typed, it may
ignore this information and issue its calls exactly as if
the user were typing everything in again by hand.
To find out how to adopt the ctrl/h feature in your
The Jsys 9
SAIL programs, see the description of the cm!ini procedure
(section 2.2.11, page 26).
1.2.5 Multiple Function Calls
The only topic left to cover in Part I is concept of
multiple function calls. This refers to giving COMND more
than one alternative to look for. For instance, it may be
equally acceptable at a particular point in a command line
for the user to type either a date, or simply a decimal
integer, specifying possiblly a number of days from the
current date. It would be advantageous for COMND to know
about the alternatives and not have to return an error if
the second alternative were chosen.
To accomplish this, it is possible to have several
FDB'S all linked together in a chain. The first one
contains a pointer to the second, which contains a pointer
to the third, etc. Then if COMND can't make sense of what
is typed in the context of the first FDB, it goes on and
tries the next FDB, and so on right down the line until it
gets to an FDB that does not point to another one. At that
point, if none of the FDB's succeeded, an error condition is
finally signalled and COMND returns. If one of the FDB's
does fit, then not only is the normal data returned, but
also the location of the succeeding FDB so that the program
will be able to determine what ultimately happened.
The same procedures apply to multiple FDB's as to
single ones in regard to reparsing, error restarts, etc.
Remember that when using multiple FDB's only one input item
10 SAIL-COMND Interface
is parsed, not several. The multiple nature comes from the
fact that COMND is given several choices as to how it should
attempt to interpret that item.
Note that when using multiple FDB's, only one CSB is
used. This fact underlines the main difference between the
natures of information stored in the two blocks, the CSB
being fairly call-independent, while almost all of the
information in the FDB depends on exactly what call is being
made.
This concludes Part I of this document. At this point you
should have an idea of what is involved in getting the COMND
jsys to do your work for you. You are not prepared to go
out and use COMND in your assembler programs (unless you
have done some reading in other sources), but you should
have enough understanding now to be able to follow Part II,
which goes into the details of using COMND from SAIL
programs.
The Interface 11
2. THE INTERFACE
The information in this part describes the use of the
SAIL-COMND interface. This interface allows the programmer
to implement the COMND jsys in his programs in the form of a
set of SAIL procedure calls. The information which must be
stored in the CSB and FDB is passed in the form of procedure
parameters, and the procedures take care of storing them in
their final form.
This part is broken up into three sections, the first
describing conventions and procedures common to all COMND
calls using the interface. The second section describes
each call in detail, indicating what information must be
supplied and what is returned. The third section gives an
overview of how to implement multiple FDB's using the
interface.
2.1 General Rules
2.1.1 Loading the Routines
To include the interface as part of a SAIL program, the
programmer should use the statement,
REQUIRE "SAI:COMND.HDR" SOURCE!FILE;
somewhere within his declarations. This will cause all
the necessary declarations to be made and will instruct the
loader as to where to find the compiled procedures.
2.1.2 Naming Conventions
All of the procedures, arrays, variables, etc. in the
12 SAIL-COMND Interface
COMND interface package with which the SAIL programmer need
concern himself have names beginning with either "cm!" or
"cm#". Those beginning with "cm#" have to do specifically
with using multiple FDB's, whereas those beginning with
"cm!" either have nothing to do with multiple FDB's or are
equally applicable to multiple and single FDB's.
The vast majority of the "cm!"-type procedures actually
perform a call to COMND. These are named according to the
particular call they perform. Thus the procedure cm!key
performs the CMKEY function call, and the procedure cm!act
performs the CMACT function call. The rest of the cm!
procedures are used to set up arrays, etc. needed by other
procedures. Thus cm!tbuild will construct a table in the
necessary format for cm!key and cm!swi from a string array
of keywords.
In contrast, only one of the "cm#"-type procedures
actually executes a call to COMND. That procedure is called
cm#call. Most of the rest of the cm# procedures set up
their own particular FDB'S and link them into the chain.
Thus the cm#key procedure sets up and links in an FDB which
when used will cause the CMKEY function to be performed.
Once several FDB's have been set up, the cm#call procedure
is used to set things moving.
2.1.3 Handling Error and Reparse Conditions
2.1.3.1 Cm!Err and Cm!Reparse Flags
When a field is unparsable (the user types in something
The Interface 13
that doesn't make sense), the variable cm!err will be set to
the TOPS-20 error code indicating the error. Otherwise,
cm!err will be zero upon return. If a reparse is required,
the variable cm!reparse will be set to true. Otherwise it
will be false. Thus by testing these two variables after
each call, the program can always determine what it must do
next -- go on and parse the next field, reissue all parse
requests following the last cm!ini, or reissue all parse
requests including the cm!ini. This will be shown in Part
III.
2.1.3.2 Cm!Retry - An Alternative Error Recovery Mechanism
In Part I it was explained that when a field is
unparsable (cm!err would be non-zero when using the
interface), the program must start all over right from the
prompt. This is not the only alternative, however, when
using the SAIL-COMND interface. The procedure cm!retry
takes one string parameter and acts as follows: First it
prints its argument followed by a carriage return -
linefeed, then it retypes the entire command line up to but
not including the unparsable field. The program should then
reissue the call only for that field. It need not back up
all the way to the beginning, and the user need not retype
all the things he typed correctly in the command line. This
was not mentioned in Part I since it is not a feature of the
COMND jsys. It is accomplished by playing with the CSB in
such a way as to fool COMND into thinking that everything
has been redone as it should be.
14 SAIL-COMND Interface
2.1.3.3 The Built-in Error Handler
There is an error handler built into the interface
which will trap all errors occurring during execution of the
COMND jsys and will act according to the values of two
variables which may be set by the program.
Errors are divided into two basic types: major errors
and minor errors. Major errors include all those errors
which, if not trapped, would cause an illegal instruction
interrupt and stop the program dead. This category includes
such things as command line overflow (the user types in more
than can be held in the command line buffer), an invalid CSB
or FDB, etc. Minor errors are all other errors which may
occur. This would include things such as failing to confirm
a command line with a carriage return when required, typing
a word that does not match anything in a list of acceptable
keywords, etc.
The error handler handles minor and major errors in
different ways. If a minor error occurs, the error handler
will look at the value of the variable cm!minor. If that
value is true, then the TOPS-20 error message corresponding
to the error is printed. If it is false, nothing is
printed. In either case, control is returned to the program
with the appropriate TOPS-20 error code in the cm!err
variable.
If a major error occurs, the error handler inspects the
value of the variable cm!major. If that value is true, the
appropriate TOPS-20 error message is printed and the program
The Interface 15
halts. Otherwise, nothing is printed, the TOPS-20 error
code is placed in the variable cm!err, and the variable
cm!fatal is set to true. Then control is returned to the
program.
Until the program explicitly changes them, cm!minor and
cm!major will both be true.
2.1.4 The Atom Buffer
Many of the procedures in the interface return values
other than the user's input as a string. The cm!usr
procedure, for instance, returns a TOPS-20 user number,
rather than the user name as typed in by the person running
the program. When using these procedures, however, it is
often required to obtain the input string itself. In this
case the cm!getatm procedure is useful.
When accepting input from the keyboard, COMND stores
the user's input as typed for each field in what is called
the "atom buffer" (thus the name cm!getatm). Only one
field's worth of input is stored in the atom buffer at a
time. Thus, if a program makes a call to COMND to first get
an output file name, then a quoted string, the atom buffer
will evolve as follows: Before the initial CMINI call, the
contents of the atom buffer will be unpredictable. Between
CMINI and the CMOFI call (the call to get an output file
specification), the atom buffer will be empty. After the
CMOFI call, the atom buffer will contain the file
specification as typed by the user, even though the cm!ofi
procedure returns a SAIL channel number. After the CMQST
16 SAIL-COMND Interface
call (the call to get a string delimited by double quotes),
the atom buffer will contain the string typed by the user,
not including the quotes.
The cm!getatm procedure always returns the current
contents of the atom buffer in the form of a SAIL string.
Remember that the input for a particular field is available
only until the next COMND call (any call) is made.
2.1.5 Command Files
Often it is desirable for COMND to accept its input
from somewhere other than the keyboard. This idea is most
familiar to most users in the form of the LOGIN.CMD and
COMAND.CMD files that the EXEC can take commands from, and
in terms of the EXEC's TAKE command. The cm!take procedure
may be used to achieve this effect. After a call to
cm!take, all following input to COMND is gotten from the
file specified, until the end of that file is reached. At
that point, the file is closed, the cm!eof variable is set
to true, and the previous source of input is resumed.
There are two ways of handling errors that occur while
input is coming from a command file.
1. Automatically abort the file and resume taking
input from the previous source. In this case, the
cm!abort variable is set to true, and a message is
printed saying that the file is being aborted if
the values of cm!minor and cm!major allow it.
2. Print error messages according to the values of
cm!minor and cm!major and continue to take
commands from the command file.
Both of these options are available with the cm!take
The Interface 17
procedure.
2.1.6 Common Parameters
Many of the procedures in the interface have almost
identical parameters. Those that are common to a very large
number of the procedures will be described now. In the
descriptions of the particular procedures these parameters
will not be rediscussed.
help a string which will be printed if the user
types a question mark as his response. The
COMND jsys also has its own standard help
messages, one for each different call.
These are listed in the Monitor Calls
Reference Manual. The standard help message
will follow the supplied help message when
both are printed. When using multiple
FDB's, the help message for each FDB will be
printed on a new line, with the word "or"
separating help messages. If this parameter
is unspecified, it will default to a null
string.
def a string which will be used as the default
response to this call. If the user types an
escape character, and what he has typed so
far matches this string, then it will be
filled in automatically for him. If this
parameter is unspecified, it will default to
a null string. When using multiple FDB's,
only one default string may be specified, so
this parameter is included in the cm#call
procedure, and left out of all the other cm#
procedures.
sup$help a boolean value (true or false). If this
parameter is true, then the standard help
message will not be typed, whether or not
the help parameter is null. If unspecified,
sup$help defaults to false.
raise$input a boolean value. If this parameter is true,
then the user's input will be converted to
upper case before it is analyzed. While
this may not seem to make any difference in
many of the function calls, since they do
not return strings (e.g. cm!usr returns a
TOPS-20 user number), it may be necessary
for a program to look in the atom buffer
(via the cm!getatm procedure), in which the
18 SAIL-COMND Interface
conversion would be visible. If the
parameter is not specified it defaults to a
value of false.
no$indirect a boolean value. If this parameter is
false, then the user will be able to respond
to this field with something of the form
"@filename", causing the contents of the
file whose name is filename to be used to
complete the field. If no$indirect is true,
this will not be allowed, and a minor error
will result if such an attempt is made. If
the parameter is not specified it will
default to a value of false.
wake$always It was mentioned in Part I that when COMND
is accepting input from the terminal, it
won't start looking at it until an action
character is typed. This is not always
true, however. If the wake$always parameter
is true, then COMND will wake up whenever it
senses that the field has been completed.
Thus it will wake up on such characters a
spaces, commas, etc. One use for this comes
when it is required to obtain a password
from a user. The command line would be
parsed with wake$always true on every call,
and then as soon as the field before the
password has been completed, the program
would turn off terminal echoing so that the
password would not show up on the terminal
as it was typed. If wake$always were false
in this case, COMND may not even begin
parsing the password field until after it
has been typed in, and then it would
probably be too late to turn off echoing.
If wake$always is not specified it will
default to a value of false.
Brchars This is a string of characters on which the
current field is to be broken. That is, if
any of these characters is encountered while
parsing this field, the field will be
considered terminated. These characters do
not become action characters. If the string
is null, the standard break table will be
used for the field. Different field types
(i.e. COMND functions) have different
standard break tables, and only a few of
them use break tables at all. Of those few,
only about half have user-changeable break
tables. The standard break tables will be
described along with the descriptions of the
cm!-type procedures for the corresponding
COMND functions. There is also a convenient
table showing the standard break tables for
The Interface 19
all COMND functions that use them in
Appendix 1.
2.2 Specifics
This section looks at all the cm! - type procedures in
the interface in detail. The discussions appear in
alphabetical order, and each description is introduced by a
reproduction of the procedure definition header. Note that
those parameters which were discussed in the preceding
section will be included in the procedure headers, but
otherwise will not be mentioned in the descriptions in this
section.
2.2.1 The Cm!Act Procedure
string procedure cm!act
(string help(null),def(null);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false));
The cm!act procedure performs the CMACT (ACT = ACcounT)
function call of the COMND jsys. It is used to parse an
account name string. The string, up to but not including
the first non-alphanumeric character typed is returned as
the value of the function. No verification of the account
name is done, so a minor error cannot occur in this
procedure. There is no standard help message for the CMACT
call, so if the help parameter is null, no help message will
be printed when the user types a question mark.
2.2.2 The Cm!Cfm Procedure
procedure cm!cfm
(string help(null);
20 SAIL-COMND Interface
boolean sup$help(false));
The cm!cfm procedure performs the CMCFM (CFM = ConFirM)
function call of the COMND jsys. The only valid user input
for this call is a carriage return. It is generally good
practice to make this the last call of every command line.
This gives the user a chance to correct mistakes in the
command line before any action is taken. The standard help
message for the CMCFM function call is "CONFIRM WITH
CARRIAGE RETURN". Note that several of the common
parameters are not included in this procedure, simply
because they do not make sense here.
2.2.3 The Cm!Cma Procedure
procedure cm!cma
(string help(null);
boolean sup$help(false));
The cm!cma procedure performs the CMCMA (CMA = CoMmA)
function call of the COMND jsys. The only valid user input
for this call is a comma. This procedure would be used, for
instance, when a list of input file names is needed. The
program would keep calling first the cm!ifi procedure (see
below), then the cm!cma procedure until cm!cma fails, at
which point the user did not type a comma, so the program
should try other possibilities, such as cm!cfm (above). The
standard help message for the CMCMA function call is
"COMMA". Note that, as with the cm!cfm procedure, several
of the common parameters are not included in this procedure,
because they do not make sense here.
The Interface 21
2.2.4 The Cm!Dev Procedure
integer procedure cm!dev
(string help(null),def(null);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false);
string brchars(null));
The cm!dev procedure performs the CMDEV (DEV = DEVice)
function call of the COMND jsys. It is used for parsing a
device name. This could be a physical device name or a
logical name. The procedure returns the device designator
corresponding to the device name input. The standard help
message for the CMDEV call is "DEVICE NAME".
The standard break table for CMDEV is as follows:
ASCII Codes Description
0 - 37 All Control Characters
40 - 54 Space Through Comma
56 - 57 Dot and Slash
72 - 76 Colon Through Pound Sign (#)
100 Atsign (@)
133 - 136 Open Bracket Through Up-Arrow
140 Apostrophe
173 - 177 Close Bracket Through Tilde
2.2.5 The Cm!Dir Procedure
integer procedure cm!dir
(string help(null),def(null);
boolean sup$help(false),
allow$wild(false),
raise$input(false),
no$indirect(false),
wake$always(false),
parse$only(false));
The cm!dir procedure performs the CMDIR (DIR = DIRectory)
function call of the COMND jsys. It is used for parsing a
directory name (with angle brackets - <>). The procedure
returns the 36-bit directory number corresponding to the
directory named by the user's input. If the allow$wild
22 SAIL-COMND Interface
parameter is true, wildcard characters ("*" and "%") will be
allowed as part of the directory name. Otherwise they will
cause a minor error. If parse$only is true, then the field
will be parsed, but if the input does not match an existing
directory no minor error will occur. The directory number
can be translated into a directory name string using SAIL's
DIRST built-in function. The standard help message for the
CMDIR function call is "DIRECTORY NAME".
2.2.6 The Cm!Fil Procedure
integer procedure cm!fil
(string help(null),def(null);
integer flag$gen('440004000000);
string device(null),
directory(null),
name(null),
extension(null),
protection(null),
account(null);
integer jfn(0);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false));
The cm!fil procedure performs the CMFIL (FIL = FILe)
function call of the COMND jsys. It is used to parse an
arbitrary file specification (i.e. where neither cm!ifi nor
cm!ofi is quite right). This call uses the GTJFN jsys to
process the file specification, and so there many new
parameters for this procedure which are used to fill in the
GTJFN Argument Block. To find the details of the contents
of this block, see the Monitor Calls Reference Manual. The
new parameters are as follows:
flag$gen The integer passed for this parmeter will
be placed into word 0 (.GJGEN) of the GTJFN
argument block. It contains various flags
in the left half, and a default generation
The Interface 23
number in the right half. See the Monitor
Calls Reference Manual for details on the
contents of this word. If the flag$gen
parameter is not specified, it will default
to octal 440004000000, and cm!fil will
behave like cm!ofi.
device A pointer to the string supplied for this
parameter will be placed in word 2 (.GJDEV)
of the GTJFN Argument Block. The string
will become the default for the device field
of thef file specification. If no string is
specified, the default device will be the
currently connected structure.
directory A pointer to the string supplied for this
parameter will be placed in word 3 (.GJDIR)
of the GTJFN Argument Block. The string will
become the default for the directory field
of the file specification. If no string is
passed, the default directory will be the
currently connected directory.
name A pointer to the string supplied for this
parameter will be placed in word 4 (.GJNAM)
of the GTJFN Argument Block. The string will
become the default for the name field of the
file specification. If no string is passed,
there will be no default name field.
extension A pointer to the string supplied for this
parameter will be placed in word 5 (.GJEXT)
of the GTJFN Argument Block. The string will
become the default for the extension field
of the file specification. If no string is
passed the default extension will be null.
protection A pointer to the string supplied for this
parameter will be stored in word 6 (.GJPRO)
of the GTJFN Argument Block. The string will
become the default for the protection field
of the file specification. If no string is
passed the default protection will be
whatever is specified in the directory, or
the protection of the next lower generation.
account A pointer to the string passed for this
parameter will be placed in word 7 (.GJACT)
of the GTJFN Argument Block. The string will
become the default account for the file
specification. If no string is specified
the default account will be the LOGIN
account set for the user.
jfn The integer passed for this parameter will
be placed in word 10 (.GJJFN) of the GTJFN
24 SAIL-COMND Interface
Argument Block. The system will attempt to
assign this number as the jfn for the file
specification obtained in the call. If you
specify this parameter, make sure you set
bits 9 and 10 (GJ%JFN) in flag$gen
appropriately. See the Monitor Calls
Reference Manual to find out the possible
bit patterns. If this parameter is not
specified it will be given the value zero.
Note that any fields present in the def parameter will
take precedence over any defaults passed in the parameters
listed above.
The cm!fil procedure will return a SAIL channel number
for the file that is obtained. The channel will not be
open. Use the OPENF built-in SAIL function to open the
file. The standard help message for CMFIL is "OUTPUT
FILESPEC" if bits 0 and 2 (GJ%FOU and GJ%OLD) are both on in
flag$gen. Otherwise it is "INPUT FILESPEC".
2.2.7 The Cm!Fld Procedure
string procedure cm!fld
(string help(null),def(null);
boolean raise$input(false),
no$indirect(false),
wake$always(false);
string brchars(null));
The cm!fld procedure performs the CMFLD (FLD = FieLD)
function call of the COMND jsys. This procedure is used
when none of the other procedures seem to fit the required
application. The user's input, as delimited by the first
non-alphanumeric character, is returned as the value of the
function. The delimiting character is not part of the
string returned. There is no standard help message for the
CMFLD function call.
The Interface 25
The standard break table for CMFLD is as follows:
ASCII Codes Description
0 - 37 All Control Characters
40 - 54 Space Through Comma
56 - 57 Dot and Slash
72 - 77 Colon Through Question Mark
100 Atsign (@)
133 - 140 Open Bracket Through Accent Grave
173 - 177 Close Bracket Through Tilde
2.2.8 The Cm!Flt Procedure
real procedure cm!flt
(string help(null),def(null);
boolean sup$help(false),
no$indirect(false),
wake$always(false));
The cm!flt procedure performs the CMFLT (FLT = FLoaT)
function call of the COMND jsys. This procedure is used to
parse a real number. The number is returned as the value of
the function. There is no raise$input parameter, since
alphabetic characters are invalid for this field anyway.
The standard help message for the CMFLT function call is
"NUMBER".
2.2.9 The Cm!Getatm Procedure
string procedure cm!getatm;
The cm!getatm returns the current contents of the atom
buffer (see discussion in Part II, Section 1 above). The
procedure does not call the COMND jsys or alter the state of
any related storage areas (in particular the atom buffer is
unchanged).
2.2.10 The Cm!Ifi Procedure
integer procedure cm!ifi
(string help(null),def(null);
boolean sup$help(false),
raise$input(false),
26 SAIL-COMND Interface
no$indirect(false),
wake$always(false));
The cm!ifi procedure performs the CMIFI (IFI = Input FIle)
function call of the COMND jsys. It is used for parsing the
name of a file to be used for input (i.e., the file must
exist). The procedure returns a SAIL channel number as its
value (so the calling program need not use SAIL's SETCHAN
built-in function). The file is not opened by cm!ifi. To
open the file for reading, the calling program would use
SAIL's OPENF built-in procedure using the channel number
returned by cm!ifi. The standard help string for the CMIFI
function call is "INPUT FILESPEC".
2.2.11 The Cm!Ini Procedure
boolean procedure cm!ini
(string prompt;
boolean newcomm(true));
The cm!ini procedure performs the CMINI (INI = INItialize)
function of the COMND jsys. It is always the first call
that should be made when starting to parse a new command
line. When called it will initialize the CSB and the
various buffers used to hold the user's input, and will
issue the command line prompt. This prompt is supplied via
the prompt parameter to the procedure. The end of this
prompt marks the farthest back that the user will be allowed
to delete when using COMND. The cm!ini procedure causes no
input to be read from the keyboard, unlike all the rest of
the COMND function calls. And of course, there is no
standard help message.
The newcomm parameter determines whether or not the
The Interface 27
ctrl/h feature will be available in this command line (see
section 1.2.4, page 8). If this call to cm!ini is being
made because a parsing error was just encountered in a
command line, then it would probably be desirable to
activate the ctrl/h feature. In this case, specify a value
of false for the newcomm parameter.
If this is the beginning of a new command line, or if
for some other reason the ctrl/h feature should not be
activated, specify a value of true for the newcomm
parameter.
If the ctrl/h feature is activated and the user
actually does use the feature to retype a portion of the
command line, then the cm!ini will return a value of false.
Otherwise it will return a value of true. Note that this
value, like any value returned by a SAIL procedure, may be
ignored, and the newcomm parameter is an optional parameter
defaulting to true, so the ctrl/h feature is upward
compatible with previous versions of the interface which did
not provide for the feature.
An example using the ctrl/h feature is included in Part
III.
2.2.12 The Cm!Key Procedure
integer procedure cm!key
(integer array table;
string help(null),def(null);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false);
string brchars(null));
28 SAIL-COMND Interface
The cm!key procedure performs the CMKEY (KEY = KEYword)
function call of the COMND jsys. It is used when the user
must type one out of a list of possible keywords. The
keywords are originally stored in a string array, one
keyword per array element. The array is then submitted to
the cm!tbuild procedure (below) which converts it into a
TBLUK lookup table (see the description of the TBLUK jsys in
the Monitor Calls Reference Manual for details on the format
of this table), which is stored in an integer array. This
array is then supplied to cm!key as the table parameter. If
the user's input matches one of the valid keywords, then the
index of that keyword in the original string array is
returned as the value of the function. Otherwise a minor
error will occur, and a zero will be returned.
Note to wizards: If you are planning to build
your own TBLUK lookup tables, take note! The right
half of the table entry for each keyword should
contain the integer that you want returned by COMND
if that keyword is selected. The cm!tbuild
procedure stores the original string array indices
in these half-words.
The standard help message for the CMKEY function call
is "ONE OF THE FOLLOWING", followed by an alphabetical list
of all the keywords which could still possibly match what
the user has typed in so far. If there are no possible
matches, the message "KEYWORD (NO DEFINED KEYWORDS MATCH
THIS INPUT)" is typed.
The standard break table for CMKEY is:
ASCII Codes Description
0 - 37 All Control Characters
40 - 54 Space Through Comma
56 - 57 Dot and Slash
The Interface 29
72 - 77 Colon Through Question Mark
100 Atsign (@)
133 - 140 Open Bracket Through Accent Grave
173 - 177 Close Bracket Through Tilde
2.2.13 The Cm!Nod Procedure
string procedure cm!nod
(string help(null),def(null);
boolean sup$help(false),
no$indirect(false),
wake$always(false));
The cm!nod procedure performs the CMNOD (NOD = NODe)
function call of the COMND jsys. This procedure is used to
parse a network node name, which consists of from 1 to 6
characters followed by two colons. The node name (without
the colons) is returned as the value of the procedure.
Lowercase characters are always converted to upper case
(hence no raise$input parameter). Note that a successful
return does not guarantee the existence of the node - only
that the field was typed in the correct syntax. The
standard help message for CMNOD is "NODE NAME".
2.2.14 The Cm!Noi Procedure
procedure cm!noi
(string noise);
The cm!noi procedure performs the CMNOI (NOI = NOIse word)
function call of the COMND jsys. It is used to display a
string which will guide the user by telling him what should
be input for the next field, or by qualifying what he typed
in the last field. If the user terminates a field with an
ESCAPE character, and the next procedure executed is cm!noi,
then the noise string supplied as a parameter will be output
surrounded by parentheses (the parentheses should not be
30 SAIL-COMND Interface
included as part of the parameter passed to cm!noi). If he
terminates the field with a non-action character, then he
has the option of either typing the guide word himself, or
ignoring it altogether. It will not be typed for him. The
only minor error that can occur here will result if the user
attempts to type in the noise word by himself, but gets it
wrong. There is no standard help message (or nonstandard,
for that matter) for the CMNOI function call.
2.2.15 The Cm!Num Procedure
integer procedure cm!num
(string help(null),def(null);
boolean sup$help(false);
integer radix(10);
boolean no$indirect(false),
wake$always(false));
The cm!num procedure performs the CMNUM (NUM = NUMber)
function call of the COMND jsys. It is used for parsing an
integer number. The radix parameter specifies in what base
the number is to be interpreted, and must be between 2 and
10 inclusive. The number typed is returned as the value of
the procedure. There is no raise$input parameter, since, as
in cm!flt, no alphabetic characters are valid anyway. The
standard help message is "DECIMAL NUMBER" if radix is 10,
"OCTAL NUMBER" if radix is 8, and "A NUMBER IN BASE nn" if
radix (nn) is anything else. The radix parameter defaults
to 10 if it is left unspecified.
2.2.16 The Cm!Nux Procedure
integer procedure cm!nux
(string help(null),def(null);
boolean sup$help(false);
integer radix(10);
boolean no$indirect(false),
The Interface 31
wake$always(false));
The cm!nux procedure performs the CMNUX (NUX = NUmber, sort
of) function call of the COMND jsys. This procedure is used
to parse an integer number field, as in cm!num, the only
difference being that cm!nux will terminate on the first
non-numeric character, without giving a minor error, even if
that character is not one of the valid terminators for
cm!num. The number is returned as the value of the
procedure. The radix parameter is as in cm!num. The
standard help message for CMNUX is the same as for CMNUM.
2.2.17 The Cm!Ofi Procedure
integer procedure cm!ofi
(string help(null),def(null);
boolean sup$help(false),
rase$input(false),
no$indirect(false),
wake$always(false));
The cm!ofi procedure performs the CMOFI (OFI = Output FIle)
function call of the COMND jsys. It is almost identical to
cm!ifi (above), but the user's input is this time expected
to specify an output file. Thus, it is not necessary that
the file exist already, and if it does exist, then the
default generation number will be one higher than the
highest existing generation number for the file. Like
cm!ifi, cm!ofi returns a SAIL channel number, not just a
JFN. To open the file for output, use SAIL's OPENF built-in
procedure. The standard help message for the CMOFI function
call is "OUTPUT FILESPEC".
2.2.18 The Cm!Qst Procedure
string procedure cm!qst
32 SAIL-COMND Interface
(string help(null),def(null);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false));
The cm!qst procedure performs the CMQST (QST = Quoted
STring) function call of the COMND jsys. It is used to
parse a string of text surrounded by double quotes. The
string is returned without the quotes. This function is
useful for obtaining strings which may include action
characters, since these characters lose their significance
after the opening quote in cm!qst. If a quote is desired in
the string, the user must type two consecutive quotes. A
carriage return is an illegal character inside the string.
The standard help message for CMQST is "QUOTED STRING".
2.2.19 The Cm!Retry Procedure
procedure cm!retry
(string errmsg);
The cm!retry may be used as an alternative to reparsing the
entire command line when an invalid response is given by the
user to a field. Instead, upon detecting a non-zero cm!err,
the program calls cm!retry with an appropriate error message
as a parameter, and then it reissues the COMND call just for
the field in which the error occurred. When cm!retry is
called, it first prints its argument, then it patches up the
CSB to make COMND think everything up to that field has
already been reparsed. This procedure should be used with
caution, since it plays with the CSB in such a way that, if
the COMND jsys internals were changed in a later monitor
release, cm!retry could fall flat on its face.
The Interface 33
2.2.20 The Cm!Size Procedure
integer procedure cm!size
(string array strarr);
This procedure computes and returns the number of storage
words necessary to build a TBLUK lookup table containing the
strings in strarr (see cm!tbuild below). This number could
be used as a dimensioning bound on an integer array which
will be used to hold the table. The lower bound on the
integer array should be zero.
2.2.21 The Cm!Swi Procedure
integer procedure cm!swi
(integer array table;
string help(null),def(null);
bollean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false);
string brchars(null);
The cm!swi procedure performs the CMSWI (SWI = SWItch)
function call of the COMND jsys. It operates almost
identically with the cm!key procedure. The main difference
is that a switch should start with a slash ("/") when typed
in by the user. A minor error occurs here if that is not
the case. Slashes should not, however, be included in the
strings making up the TBLUK lookup table. Their presence is
assumed. As in the cm!key procedure, the table parameter
may be prepared by using the cm!tbuild procedure (below).
Wizards should read the "Note to Wizards" in the description
of the cm!key procedure above. Often a switch will be
terminated by a colon, usually indicating that some value is
to follow. When this occurs, the variable cm!colon will be
set to true by the cm!swi procedure. Colons may be included
34 SAIL-COMND Interface
in the strings making up the TBLUK lookup table, in which
case they will be included whenever the user uses
recognition to finish typing the switch name. The standard
help message is "ONE OF THE FOLLOWING", followed by an
alphabetical list of those switches which still may be
matched by what has been typed so far. If no switch can
possibly be matched, the message "KEYWORD (NO DEFINED
KEYWORDS MATCH THIS INPUT)" is typed.
The standard break table for CMSWI is as follows:
ASCII Codes Description
0 - 37 All Control Characters
40 - 54 Space Through Comma
56 - 57 Dot and Slash
72 - 77 Colon Through Question Mark
100 Atsign (@)
133 - 140 Open Bracket Through Accent Grave
173 - 177 Close Bracket Through Tilde
2.2.22 The Cm!Tad Procedure
integer procedure cm!tad
(string help(null),def(null);
boolean sup$help(false),
date(true),time(true),
no$convert(false),
raise$input(false),
no$indirect(false),
wake$always(false));
The cm!tad procedure performs the CMTAD (TAD = Time And
Date) function call of the COMND jsys. This procedure is
used to parse a time and/or a date. If the date parameter
is true, a date will be parsed. If time is true a time will
be parsed. Both default to true. If no$convert is false
(the default) then the date/time is returned in internal
format (see the Monitor Calls Reference Manual). Otherwise
a zero is returned, and the date and time information are
The Interface 35
stored in integer array cm!datime (dimensioned [2:4] so as
to agree with accumulator assignments in the IDTNC monitor
call return) as follows:
Element Contents
cm!datime[2] Year in Left Half
Month (0=Jan) in Right Half
cm!datime[3] Day of Month (0=1st Day) in Left Half
Day of Week (0=Mon) in Right Half
cm!datime[4] Flag Bits in Left Half
Seconds Since Midnight in Right Half
The flag bits returned in the left half of cm!datime[4] are
as follows:
Bit Number Meaning (if bit is on)
0 A Time Zone was input
1 Daylight Savings Time was input
2 A Time Zone was input
3 A Julian Day Format was input
12-17 Time Zone, if one was specified, or
the Local Time Zone
The standard help message for CMTAD is "DATE" if date was
true, "TIME" if time was true, and "DATE AND TIME" if both
were true.
2.2.23 The Cm!Take Procedure
procedure cm!take
(integer ichan, ochan(nulio);
boolean errpop(true));
The cm!take procedure facilitates the redirection of input
and output during operation of COMND to other files. It
gets its name from its functional similarity to the EXEC's
TAKE command. The ichan parameter holds a channel number
associated with the file to be used for input. This file
should not be open (i.e., it should be the result of a call
to one of GTJFN, GTJFNL, cm!ifi, cm!ofi, cm!fil, or some
other procedure that returns a channel number without
opening the file on that channel). The ochan parameter
36 SAIL-COMND Interface
holds a channel number associated with the file to be used
for output. By output we mean everything the user normally
sees at his keyboard other than normal input echoing (i.e.
noise words, editing characters, help messages, etc.). This
file also should not be open. The cm!take procedure will
push the old JFNs on a stack and make those passed for ichan
and ochan the ones to be used in COMND calls from that point
on. When the file associated with ichan runs out, the old
JFNs are automatically popped back into use, and the cm!eof
variable is set to true.
The errpop parameter controls what action is taken when
an error (other than end-of-file) occurs while using the new
JFNs. If errpop is true, then upon encountering such an
error, the old JFNs are immediately popped back and if
cm!minor and cm!major allow it, an error message is printed.
Also the cm!abort variable is set to true. If errpop is
false, then the JFNs are popped only for end-of-file, and
error messages will be printed as usual according to the
values of cm!minor and cm!major.
2.2.24 The Cm!Tbuild Procedure
integer procedure cm!tbuild
(string array keys;
reference integer array table);
The cm!tbuild procedure converts a string array of keywords
into a TBLUK lookup table for use by the cm!key and cm!swi
procedures (see the description of the TBLUK jsys in the
Monitor Calls Reference Manual for details on the internals
of a TBLUK lookup table). The keywords are passed by way of
The Interface 37
the keys array, and the table is stored in the table array.
If enough room was available in table to store the entire
lookup table, a 0 is returned by cm!tbuild. Otherwise, a -1
is returned, and chances are the lookup table is in an
unacceptable format for cm!key and cm!swi. One convenient
way to insure that enough room will be available is by using
the cm!size procedure (above). The keys parameter is a
string array of keywords which are to be inserted into the
table, and need not be alphabetized. cm!tbuild will not
insert duplicate entries twice, and if two elements of keys
are identical it will place the index of the last duplicate
entry found in the cm!err variable. Each string in keys may
be prefixed by either or both of two punctuation characters.
If a "%" character appears within the first two characters
of a string the CM%INV (INV = INVisible) bit will be turned
on for the corresponding entry in the lookup table. The
effect of this is that the keyword will not appear in the
standard help message of the CMKEY or CMSWI function calls.
In this way it is essentially "invisible" to the user. If a
"#" character appears within the first two characters of a
string in the keys array, the CM%NOR (NOR = igNORe) bit will
be turned on in the corresponding lookup table entry. Its
effect is such that the corresponding keyword will be
"invisible" as above, but it will also not be recognized,
even if an exact match is typed by the user. Thus the
keyword is effectively "ignored" by cm!key and cm!swi. This
is useful when you wish to rule out an abbreviation. For
instance, if you wish the user to be required to type at
38 SAIL-COMND Interface
least "MINIM" as an abbreviation for "MINIMAL", you could
include the string "#MINI" as one of the strings in the keys
array, and the desired result would be achieved. Note that
the cm!tbuild procedure does not include a facility for
setting the CM%ABR (ABR = ABbReviation) bit in a lookup
table entry. For information on what this bit does, see the
description of the CMKEY function call of the COMND jsys in
the Monitor Calls Reference Guide. It is possible for
wizards to set this bit themselves, but they should read the
description of the TBLUK jsys in the Monitor Calls Reference
Guide, as well as the "Note to Wizards" in the description
of the cm!key procedure above.
2.2.25 The Cm!Tok Procedure
boolean procedure cm!tok
(string token,
help(null),def(null);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false));
The cm!tok procedure performs the CMTOK (TOK = TOKen)
function call of the COMND jsys. This procedure is used to
test whether or not the string passed for the token
parameter matches the characters that appear next in the
input buffer. The procedure returns true if the string
matches, false otherwise. There is no standard help message
for CMTOK.
2.2.26 The Cm!Txt Procedure
string procedure cm!txt
(string help(null),def(null);
boolean sup$help(false),
raise$input(false),
The Interface 39
no$indirect(false),
wake$always(false);
string brchars(null));
The cm!txt procedure performs the CMTXT (TXT = TeXT)
function call of the COMND jsys. It returns all text typed
by the user up to but not including the next carriage
return. The standard help message for the CMTXT function
call is "TEXT STRING".
The standard break table for CMTXT is as follows:
ASCII Codes Description
12 Linefeed
15 Carriage Return
2.2.27 The Cm!Uqs Procedure
string procedure cm!uqs
(string brchars;
string help(null),def(null);
boolean raise$input(false),
no$indirect(false),
wake$always(false));
The cm!uqs procedure performs the CMUQS (UQS = UnQuoted
String) function call of the COMND jsys. This procedure is
used for parsing a string field with arbitrary break
characters. The procedure will return all characters typed
up to, but not including the first break character typed.
Note that all action characters lose their special meaning
unless they are included in the brchars string. There is no
standard help message for CMUQS.
2.2.28 The Cm!Usr Procedure
integer procedure cm!usr
(string help(null),def(null);
boolean sup$help(false),
raise$input(false),
no$indirect(false),
wake$always(false),
40 SAIL-COMND Interface
parse$only(false));
The cm!usr procedure performs the CMUSR (USR = USeR)
function call of the COMND jsys. It is almost identical to
the cm!dir procedure, except that user names are not
surrounded by angle brackets ("<>") as are directory names.
Also, there is no allow$wild parameter, since wildcards do
not make sense with user names. A user number is returned
by the procedure, which may be tranlated into a user name
string via SAIL's DIRST built-in procedure. The standard
help message for the CMUSR function call is "USER NAME".
2.3 Multiple FDBs
It was mentioned in Part I of this document that it is
possible to give COMND several alternatives from which to
choose in a single call. This section of the document
describes the implementation and use of this feature in the
SAIL-COMND interface package.
Room is set aside for building a chain of up to ten
FDB's to be used in a call to COMND. These FDB's are set up
by using procedures which parallel those just described in
Section 2. Each of the cm! procedures which actually calls
the COMND jsys into action (all but cm!getatm, cm!retry,
cm!size, cm!take and cm!tbuild) has a companion procedure
whose name starts with "cm#" instead of "cm!" (thus cm!key
becomes cm#key, etc.). These cm# procedures are called in
exactly the same way as the corresponding cm! procedures,
except that all def, raise$input, no$indirect and
wake$always parameters are left off. Each procedure returns
The Interface 41
an integer: 0 if there was room in the multiple FDB block
to set up the new FDB, and -1 otherwise (10 FDB's max). The
FDB's are linked together in the order in which the
procedures are called. Thus if the program calls first
cm#key, then cm#usr, then cm#tad, COMND will try first to
match a keyword, then a user name, then a time and date.
COMND will stop as soon as one of the FDB's caused a
success. If none of them succeeds, cm!err will be set to
the error code appropriate to the last FDB tried.
Before starting to set up the FDB's, however, the
program should issue a call to the cm#reset procedure (no
arguments, no value returned), which initializes the
multiple FDB block.
After all the FDB's have been set up, the program
issues a call to the cm#call procedure, whose procedure
definition header is as follows:
integer procedure cm#call
(string def(null);
boolean raise$input(false),
no$indirect(false),
wake$always(false));
Here the parameters are the same as they were in the cm!
procedures, but they apply to all the FDB's taken as a
whole. The cm#call procedure returns an integer which
indicates which FDB was successful, according to the order
in which the FDB's were set up (1 is the first). The result
of the parsing will always be a string, an integer, or a
real number. Upon completion of the cm#call procedure, this
result will be found in one of three variables corresponding
42 SAIL-COMND Interface
to these types: cm#str (for strings), cm#int (for
integers), or cm#real (for real numbers). It is up to the
calling program to determine (via the integer returned by
cm#call) where to look for the response. Thus if a CMKEY
function call succeeds the program should look in the cm#int
variable. If a CMQST function call succeeds, the program
should look in the cm#str variable.
Examples 43
3. EXAMPLES
3.1 Example 1 - Nothing Fancy
This example does nothing fancy, but then, many real
applications are that way. The example is a routine that
could be used to perform the parsing for the TERMINAL
command of the EXEC. The routine would be called by the
main parsing routine when the keyword "terminal" is parsed.
This routine should return upon a reparse or error
condition, or upon a completed command. Note that the code
for actually performing the various tasks is not included
here, but it is indicated by the various block names where
such code should go.
3.1.1 SAIL Code
******************** Start of Example 1 ********************
! Set up the keyword and noise word tables to be used;
Preload!With
"flag","formfeed","immediate","indicate","lowercase",
"raise","tabs","page","halfduplex","line-halfduplex",
"fullduplex","length","speed","width","help","no","type",
"33","35","37","bantam","concept-100","datamedia-1520",
"execuport","glass-tty","la30","la36","perkin-elmer-1100",
"system-default","terminet","ti","ti733","vt05","vt50",
"vt52";
String Array ModeKeys[1:35]; ! Keywords to select mode;
Preload!With
"0","50","75","110","134","150","200","300","600","1200",
"1800","2400","4800","9600";
String Array SpeedKeys[1:14]; ! Allowable Terminal Speeds;
Preload!With
"flag","formfeed","immediate","indicate","lowercase",
"raise","tabs","page";
String Array NoKeys[1:8]; ! Allowable Keywords after
! "no" keyword;
Preload!With
"33","35","37","bantam","concept-100","datamedia-1520",
44 SAIL-COMND Interface
"execuport","glass-tty","la30","la36","perkin-elmer-1100",
"system-default","terminet","ti","ti733","vt05","vt50",
"vt52";
String Array TypeKeys[18:35]; ! Possible keywords after;
! 'type' keyword (indices ;
! chosen to match ModeKeys);
Preload!With
"upper case output","exists on terminal","echo mode",
"formfeed","exists on terminal","terminal input",
"exist on terminal","mode","mode for terminal",
"mode for terminal","mode for terminal","of page is",
"of input","of line is";
String Array Noises[1:14]; ! Noise words for ModeKeys
! and NoKeys;
Procedure Ter!Comm;
Begin "Parse a 'Terminal' command line"
! Miscellaneous declarations;
Integer ModeNo, ISpeed, OSpeed, PLen, PWid;
Integer TOption, TType;
Boolean ModeOn; ! False if a 'no ...' command;
Boolean NoLen; ! True if no len was specified;
! on a 'terminal page' command;
! Declarations for keyword tables;
Integer Array ModeTab[0:cm!size(ModeKeys)];
Integer Array SpeedTab[0:cm!size(SpeedKeys)];
Integer Array NoTab[0:cm!size(NoKeys)];
Integer Array TypeTab[0:cm!size(TypeKeys)];
! Build the TBLUK Lookup Tables;
cm!tbuild(ModeKeys,ModeTab);
cm!tbuild(SpeedKeys,SpeedTab);
cm!tbuild(NoKeys,NoTab);
cm!tbuild(TypeKeys,TypeTab);
cm!noi("mode is"); ! Noise word for 'terminal' command;
If cm!err or cm!reparse then return;
ModeOn := true; ! Until we get a 'no' command;
ModeNo := cm!key(ModeTab); ! Get the desired mode;
If cm!err or cm!reparse then return;
! First 14 modes require noise word next;
If Modeno leq 14 then
Begin "Noise"
cm!noi(Noises[ModeNo]);
If cm!err or cm!reparse then return;
End "Noise";
! Now treat any that require more fields;
Case ModeNo of
Begin "Extra Parsing"
Examples 45
[8] Begin "Page Mode"
! Possible next field for page length;
! Turn off minor error messages in case
! length is not given;
cm!minor := false;
PLen := cm!num
("Carriage return or page length",null,true);
! Now turn minor error messages back on;
cm!minor := true;
If cm!reparse then return;
! Signal whether or not page was specified -;
! if it wasn't we'll try a cm!cfm later on;
NoLen := cm!err;
End "Page Mode";
[12]Begin "Length Mode"
! We get a page length next;
PLen := cm!num
("Length of page in decimal",null,true);
If cm!err or cm!reparse then return;
End "Length Mode";
[13]Begin "Speed Mode"
! We get an input speed first;
ISpeed := cm!key(SpeedTab);
If cm!err or cm!reparse then return;
! Now a noise word;
cm!noi("and output");
If cm!err or cm!reparse then return;
! Now get an output speed;
! Default is same as input speed;
OSpeed := cm!key
(SpeedTab,null,SpeedKeys[ISpeed]);
If cm!err or cm!reparse then return;
End "Speed Mode";
[14]Begin "Width Mode"
! We get a page width;
PWid := cm!num
("Terminal line width in decimal",null,true);
If cm!err or cm!reparse then return;
End "Width Mode";
[16]Begin "No ... Mode"
! Find out what he doesn't want;
ModeNo := cm!key(NoTab);
If cm!err or cm!reparse then return;
! Put out a noise word;
cm!noi(Noises[ModeNo]);
If cm!err or cm!reparse then return;
46 SAIL-COMND Interface
! Reset flag to indicate 'no';
ModeOn := false;
End "No ... Mode";
[17]Begin "Type Mode";
! We get either a type number or name;
! Use multiple FDBs to parse this field;
! Default is 'system-default';
cm#reset; ! Clear the multiple FDBs;
cm#key(TypeTab);
cm#num("Terminal type",true);
TOption := cm#call("system-default");
If cm!err or cm!reparse then return;
! If user typed one of the strings in;
! TypeKeys, then pretend that the user;
! never even typed the word 'type';
If TOption = 1 then ModeNo := cm#int
! Otherwise, set the TType variable;
Else TType := cm#int;
End "Type Mode";
Else ! Do nothing more for other modes;
End "Extra Parsing";
! Now the command line is almost complete - only;
! thing left to do is confirm;
cm!cfm;
If cm!err or cm!reparse then return;
! We have an acceptable command line - now implement it;
Case ModeNo of
Begin "Execute the command"
[1] Begin "flag"
! Code to set flag mode goes here;
End "flag";
[2] Begin "formfeed"
! Code to set formfeed mode goes here;
End "formfeed";
.
.
.
[35]Begin "vt52"
! Code to set terminal vt52 goes here;
End "vt52"
End "Execute the command";
Examples 47
! We are all finished - now return successfully;
Return;
End "Parse a 'Terminal' command line";
********************* End of Example 1 *********************
3.1.2 Remarks
1. The keyword tables are built every time the
Ter!Comm procedure is called. This is quite
wasteful, and in most applications the keyword
tables will all be built in an outside block only
once, and will never need to be rebuilt. There
are two prevalent ways of doing this:
- The keyword table array may be declared with
fixed bounds in the programs outer block. In
this case, the cm!size procedure will not be
used as it was in the example. The advantage
of this method is that the array is static
and can be declared in the same block as the
string array containing the keywords. The
disadvantage is that the fixed bounds may
have to be altered if a new keyword needs to
be added to the table.
- The string arrays for the tables may be
declared in the program's outer block, and
the table arrays may be declared in an inner
block, using the cm!size procedure to
calculate upper array bounds. The advantage
is that it is very easy to add a new keyword
to the table. The disadvantages are the
extra time required for computing the bound
and allocating the array, and the extra level
of nesting that will probably result.
2. All the parsing was done prior to the execution of
the command. An alternative method would be to
execute each command as soon as it is determined
(e.g. in the above example, we could have
included a cm!cfm and the code for setting page
mode within the "Page Mode" block, etc.). The
disadvantage of this is that it makes the parsing
process more difficult to follow. Sometimes,
however, this method is unavoidable where the
results of some action taken on one field can
change some parsing parameters of a following
field.
3. In this example reparse and error conditions were
treated identically. This is because the cm!ini
and the first field of the line were both taken
48 SAIL-COMND Interface
care of by the calling routine, so the action for
either condition would have to start there. The
calling routine can easily check the values of
cm!err and cm!reparse immediately following the
call to Ter!Comm.
4. The Case statement almost always accompanies the
use of cm!key or cm#key, and often will go along
with any multiple FDB uses.
5. Although in this example all the keywords were in
preloaded arrays whose contents were never
changed, this need not be the case. Keyword
arrays may change in any way desired, and tables
rebuilt from them. Do not forget to rebuild the
table arrays, however; the changes will not show
up in the COMND calls that use the tables until
they are.
6. It is easy to finish reading part II with the
impression that the routines in the interface are
very complicated and difficult to use, since they
all seem to have so many parameters. This is a
false impression, however, as this example and
those that follow demonstrate. The reason is that
almost all the parameters used in the interface
routines are optional parameters that are rarely
specified.
7. A complete program that uses the Ter!Comm
procedure and merely reports what it finds exists
as sai:tercom.sai and sai:tercom.exe.
3.2 Example 2 - The Ctrl/H Feature And Switches
In this example we see how to go about using the ctrl/h
feature (see section 1.2.4, page 8) of COMND in SAIL
programs. Also, a technique is given for parsing a list of
similar objects separated by commas.
The command line is one that might be used for a crude
mail sending program. There are two commands: exit and
send. The exit command causes the program to halt. The
send command takes as its second field an input file name
where a message is stored, and then a list of switches.
Examples 49
Possible switches are /to, /cc, and /subject. The /to and
/cc switches both take as arguments a list of userids
separated by commas. The /subject switch takes a quoted
string as an argument. The switches may be intermingled as
desired, and any switch may be used more than once. If the
/subject switch is used more than once, the old subject
string is discarded. If the /to or /cc switch is used more
than once, the new list is tacked onto the old list.
3.2.1 SAIL Code
******************** Start of Example 2 ********************
Begin "Compost"
require "sai:comnd.hdr" source!file;
require "{}{}" delimiters;
define ! = {comment};
! "Compost" stands for "Computer Post Office";
! Declare keyword arrays;
Preload!With "send", "exit";
String Array Commands[1:2];
Preload!With "to:","cc:","subject:";
String Array Switches[1:3];
! Now descend into another block so we can dynamically;
! allocate the table arrays;
Begin "Main Level"
! Declare the table arrays;
Integer Array Comm!Tab[0:cm!size(commands)];
Integer Array Swit!Tab[0:cm!size(switches)];
! Declare a record class to hold linked lists of;
! message recipients, along with list head pointers;
Record!Class Recips(Integer Userid;
Record!Pointer(Recips) Next);
Record!Pointer(Recips) To!List, Cc!List;
! Integer to hold channel number for message file;
Integer Channel;
! String to hold subject of message;
String Subject;
! Boolean determines whether or not ctrl/h feature is
! activated on each call to cm!ini (activated if false);
50 SAIL-COMND Interface
Boolean Ctrl!H!Off;
! Other miscellaneous variables;
Integer Comm!No, Swit!No, Option, Userid;
Record!Pointer(Recips) Temp;
! Build the lookup tables;
cm!tbuild(Commands,Comm!Tab);
cm!tbuild(Switches,Swit!Tab);
! Initialize Ctrl!H!Off to deactivate ctrl/h feature;
Ctrl!H!Off := true;
! A useful definition;
Define Check =
{If cm!err then continue "outer loop";
If cm!reparse then continue "inner loop"};
! Now go parse the command line;
While true do
Begin "outer loop"
! Issue the prompt and set up the command line;
cm!ini("Compost> ", Ctrl!H!Off);
! Set Ctrl!H!Off so that ctrl/h feature will be;
! activated if we come here again due to an error.;
! If we return from a successful command line, the;
! variable should be reset before we get here;
Ctrl!H!Off := false;
While true do
Begin "inner loop"
! Release any currently unopened JFN. It is;
! the result of an error after the JFN;
! has already been obtained;
Start!code "release"
hrroi 1,-1;
Rljfn;
Haltf;
End "release";
! Clear the recipients lists;
To!List := Cc!List := Null!Record;
! Get a command;
Comm!No := cm!key(Comm!Tab);
Check; ! Checks for error and reparse;
! Halt on 'exit' command;
If Comm!No = 2 then
Begin "exit"
cm!cfm;
Check;
Examples 51
While true do Start!code Haltf End;
End "exit";
! Otherwise, 'send' command - guide word next;
cm!noi("message file");
Check;
! Now get an input file specification;
Channel := cm!ifi;
Check;
! Now parse any switches;
! May also get a carriage return, so use ;
! multiple FDB's;
While true do
Begin "Parse Switch"
! Use multiple FDBs for either carriage;
! return or a switch;
! Reset the multiple FDB chain;
cm#reset;
! Now build the a new chain;
cm#swi(Swit!Tab);
cm#cfm;
! Get next field;
Option := cm#call;
Check;
! If cm#cfm then we're through;
If Option = 2 then Done "inner loop";
! If no colon after switch, get another one;
If not cm!colon then continue "Parse Switch";
! Otherwise, process the switch;
Swit!No := cm#int;
While true do
Begin "Process Switch"
Case Swit!No of
Begin "Pick a Switch"
[1] [2]
Begin "Get userid list"
! Now we need a userid list;
While true do
Begin "Get a userid"
! Get one userid;
Userid := cm!usr;
Check;
! Allocate a record to hold new userid;
Temp := New!Record(Recips);
Recips:Userid[Temp] := Userid;
52 SAIL-COMND Interface
! Tack it onto the appropriate list;
If Swit!No = 1 then
Begin "New to"
Recips:Next[Temp] := To!List;
To!List := Temp;
End "New to";
If Swit!No = 2 then
Begin "New cc"
Recips:Next[Temp] := Cc!List;
Cc!List := Temp;
End "New cc";
! Now get a comma, a new switch,;
! or a carriage return;
cm#reset;
cm#cma;
cm#swi(Swit!Tab);
cm#cfm;
Option := cm#call;
Check;
! if cm#cfm was used, we're done;
If Option = 3 then done "inner loop";
! if cm#cma was used, get another userid;
If Option = 1 then continue "Get a userid";
! if cm#swi without colon, ignore switch;
If not cm!colon then
continue "Parse Switch";
! Otherwise, process the switch;
Swit!No := cm#int;
Continue "Process Switch";
End "Get a userid";
End "Get userid list";
[3]
Begin "Get subject string"
! Use cm!qst to get quoted string;
Subject := cm!qst("Subject of message");
Check;
! Now get next switch;
Continue "Parse Switch";
End "Get subject string"
End "Pick a Switch";
End "Process Switch";
End "Parse Switch";
End "inner loop";
! When we get here, we have successfully parsed a line;
! Deactivate ctrl/h feature for next time around;
Examples 53
Ctrl!H!Off := true;
! Now process the request;
Begin "Process Request"
! Code for processing the request goes here;
End "Process Request";
! Now we're ready for another line;
End "outer loop";
End "Main Level";
End "Compost"
********************* End of Example 2 *********************
3.2.2 Remarks
1. The most important part of this example, other
than demonstrating the ctrl/h feature, the use of
switches, and the accumulation of a list of
similar items, is the demonstration of a very
widespread style of writing a command line parser
using the interface. The general format goes
something like this:
2.
While true do
Begin "A"
cm!ini( ... );
While true do
Begin "B"
.
.
.
cm!xxx( ... );
if cm!err then continue "A";
if cm!reparse then continue "B";
.
.
.
cm!cfm;
if cm!err then continue "A";
if cm!reparse then continue "B";
Done "B";
.
.
.
End "B";
.
. ! Process the command line;
54 SAIL-COMND Interface
.
End "A";
With this format the command line will be repeated
immediately after it is processed. An alternative
is to move everything between 'End "B";' and 'End
"A";' outside of the "A" block and change the
'Done "B";' to 'Done "A";'. This would be
preferable if the command line is not to be
repeated after the current contents are processed.
3. Parsing a list of similar objects (userids, in the
above example) can be very difficult, and the form
of the code will not always resemble the code in
Example 2 very closely. The example is meant to
give a general idea of what is involved in a
concrete framework.
4. In this example the table arrays were built using
the second suggestion of remark number one in
Example 1.
5. As can be seen, nesting can get quite deep in a
parsing routine that uses the interface. In
Example 2, indenting of new levels had to be
decreased from two spaces (the author's normal
style) to one space, just to fit the code within
the page boundaries.
6. A complete program which interprets the command
line of this example and merely reports what it
found exists as sai:compos.sai and sai:compos.exe.
Standard Break Tables 55
A. STANDARD BREAK TABLES
Following is a chart of the complete ASCII character
set, with twelve columns indicating which characters are in
the standard break tables for each of the twelve COMND
functions that use them. Starred (*) columns indicate that
the break tables are user-changeable, and the interface
procedures corresponding to those functions include a
brchars parameter.
| | C O M N D F u n c t i o n |
ASCII|Gra- | C | C | C | C | C | C | C | C | C | C | C | C |
Code |phic | M | M | M | M | M | M | M | M | M | M | M | M |
(Dec)| | A | D | D | F | F | I | K | O | S | T | U | U |
| | C | E | I | I | L | F | E | F | W | X | Q | S |
| | T | V | R | L | D | I | Y | I | I | T | S | R |
| | | * | | | * | | * | | * | * | * | |
------------------------------------------------------------
0 | ^@ | X | X | X | X | X | X | X | X | X | | | X |
1 | ^A | X | X | X | X | X | X | X | X | X | | | X |
2 | ^B | X | X | X | X | X | X | X | X | X | | | X |
3 | ^C | X | X | X | X | X | X | X | X | X | | | X |
4 | ^D | X | X | X | X | X | X | X | X | X | | | X |
5 | ^E | X | X | X | X | X | X | X | X | X | | | X |
6 | ^F | X | X | X | X | X | X | X | X | X | | | X |
7 | ^G | X | X | X | X | X | X | X | X | X | | | X |
8 | ^H | X | X | X | X | X | X | X | X | X | | | X |
9 | ^I | X | X | X | X | X | X | X | X | X | | | X |
10 | ^J | X | X | X | X | X | X | X | X | X | X | | X |
11 | ^K | X | X | X | X | X | X | X | X | X | | | X |
12 | ^L | X | X | X | X | X | X | X | X | X | | | X |
13 | ^M | X | X | X | X | X | X | X | X | X | X | | X |
14 | ^N | X | X | X | X | X | X | X | X | X | | | X |
15 | ^O | X | X | X | X | X | X | X | X | X | | | X |
16 | ^P | X | X | X | X | X | X | X | X | X | | | X |
17 | ^Q | X | X | X | X | X | X | X | X | X | | | X |
18 | ^R | X | X | X | X | X | X | X | X | X | | | X |
19 | ^S | X | X | X | X | X | X | X | X | X | | | X |
20 | ^T | X | X | X | X | X | X | X | X | X | | | X |
21 | ^U | X | X | X | X | X | X | X | X | X | | | X |
22 | ^V | X | X | X | X | X | X | X | X | X | | | X |
23 | ^W | X | X | X | X | X | X | X | X | X | | | X |
24 | ^X | X | X | X | X | X | X | X | X | X | | | X |
25 | ^Y | X | X | X | X | X | X | X | X | X | | | X |
26 | ^Z | X | X | X | X | X | X | X | X | X | | | X |
27 | ESC | X | X | X | X | X | X | X | X | X | | | X |
28 | ^\ | X | X | X | X | X | X | X | X | X | | | X |
29 | ^] | X | X | X | X | X | X | X | X | X | | | X |
30 | ^^ | X | X | X | X | X | X | X | X | X | | | X |
31 | ^_ | X | X | X | X | X | X | X | X | X | | | X |
56 SAIL-COMND Interface
| | C O M N D F u n c t i o n |
ASCII|Gra- | C | C | C | C | C | C | C | C | C | C | C | C |
Code |phic | M | M | M | M | M | M | M | M | M | M | M | M |
(Dec)| | A | D | D | F | F | I | K | O | S | T | U | U |
| | C | E | I | I | L | F | E | F | W | X | Q | S |
| | T | V | R | L | D | I | Y | I | I | T | S | R |
| | | * | | | * | | * | | * | * | * | |
------------------------------------------------------------
32 |space| X | X | X | X | X | X | X | X | X | | | X |
33 | ! | X | X | X | X | X | X | X | X | X | | | X |
34 | " | X | X | X | X | X | X | X | X | X | | | X |
35 | # | X | X | X | X | X | X | X | X | X | | | X |
36 | $ | X | | | | X | | X | | X | | | X |
37 | % | | X | | | X | | X | | X | | | |
38 | & | X | X | X | X | X | X | X | X | X | | | X |
39 | ' | X | X | X | X | X | X | X | X | X | | | X |
40 | ( | X | X | X | X | X | X | X | X | X | | | X |
41 | ) | X | X | X | X | X | X | X | X | X | | | X |
42 | * | | X | | | X | | X | | X | | | |
43 | + | X | X | X | X | X | X | X | X | X | | | X |
44 | , | X | X | X | X | X | X | X | X | X | | | X |
45 | - | | | | | | | | | | | | |
46 | . | | X | | | X | | X | | X | | | |
47 | / | X | X | X | X | X | X | X | X | X | | | X |
48 | 0 | | | | | | | | | | | | |
49 | 1 | | | | | | | | | | | | |
50 | 2 | | | | | | | | | | | | |
51 | 3 | | | | | | | | | | | | |
52 | 4 | | | | | | | | | | | | |
53 | 5 | | | | | | | | | | | | |
54 | 6 | | | | | | | | | | | | |
55 | 7 | | | | | | | | | | | | |
56 | 8 | | | | | | | | | | | | |
57 | 9 | | | | | | | | | | | | |
58 | : | X | X | | | X | | X | | X | | | X |
59 | ; | X | X | | | X | | X | | X | | | X |
60 | < | X | X | | | X | | X | | X | | | X |
61 | = | X | X | X | X | X | X | X | X | X | | | X |
62 | > | X | X | | | X | | X | | X | | | X |
63 | ? | X | X | X | X | X | X | X | X | X | | | X |
64 | @ | X | X | X | X | X | X | X | X | X | | | X |
65 | A | | | | | | | | | | | | |
66 | B | | | | | | | | | | | | |
67 | C | | | | | | | | | | | | |
68 | D | | | | | | | | | | | | |
69 | E | | | | | | | | | | | | |
70 | F | | | | | | | | | | | | |
71 | G | | | | | | | | | | | | |
72 | H | | | | | | | | | | | | |
73 | I | | | | | | | | | | | | |
74 | J | | | | | | | | | | | | |
75 | K | | | | | | | | | | | | |
76 | L | | | | | | | | | | | | |
77 | M | | | | | | | | | | | | |
78 | N | | | | | | | | | | | | |
79 | O | | | | | | | | | | | | |
Standard Break Tables 57
| | C O M N D F u n c t i o n |
ASCII|Gra- | C | C | C | C | C | C | C | C | C | C | C | C |
Code |phic | M | M | M | M | M | M | M | M | M | M | M | M |
(Dec)| | A | D | D | F | F | I | K | O | S | T | U | U |
| | C | E | I | I | L | F | E | F | W | X | Q | S |
| | T | V | R | L | D | I | Y | I | I | T | S | R |
| | | * | | | * | | * | | * | * | * | |
------------------------------------------------------------
80 | P | | | | | | | | | | | | |
81 | Q | | | | | | | | | | | | |
82 | R | | | | | | | | | | | | |
83 | S | | | | | | | | | | | | |
84 | T | | | | | | | | | | | | |
85 | U | | | | | | | | | | | | |
86 | V | | | | | | | | | | | | |
87 | W | | | | | | | | | | | | |
88 | X | | | | | | | | | | | | |
89 | Y | | | | | | | | | | | | |
90 | Z | | | | | | | | | | | | |
91 | [ | X | X | | | X | | X | | X | | | X |
92 | \ | X | X | X | X | X | X | X | X | X | | | X |
93 | ] | X | X | | | X | | X | | X | | | X |
94 | ^ | X | X | X | X | X | X | X | X | X | | | X |
95 | _ | X | | X | X | X | X | X | X | X | | | X |
96 | ` | X | X | X | X | X | X | X | X | X | | | X |
97 | a | | | | | | | | | | | | |
98 | b | | | | | | | | | | | | |
99 | c | | | | | | | | | | | | |
100 | d | | | | | | | | | | | | |
101 | e | | | | | | | | | | | | |
102 | f | | | | | | | | | | | | |
103 | g | | | | | | | | | | | | |
104 | h | | | | | | | | | | | | |
105 | i | | | | | | | | | | | | |
106 | j | | | | | | | | | | | | |
107 | k | | | | | | | | | | | | |
108 | l | | | | | | | | | | | | |
109 | m | | | | | | | | | | | | |
110 | n | | | | | | | | | | | | |
111 | o | | | | | | | | | | | | |
112 | p | | | | | | | | | | | | |
113 | q | | | | | | | | | | | | |
114 | r | | | | | | | | | | | | |
115 | s | | | | | | | | | | | | |
116 | t | | | | | | | | | | | | |
117 | u | | | | | | | | | | | | |
118 | v | | | | | | | | | | | | |
119 | w | | | | | | | | | | | | |
120 | x | | | | | | | | | | | | |
121 | y | | | | | | | | | | | | |
122 | z | | | | | | | | | | | | |
123 | { | X | X | X | X | X | X | X | X | X | | | X |
124 | | | X | X | X | X | X | X | X | X | X | | | X |
125 | } | X | X | X | X | X | X | X | X | X | | | X |
126 | ~ | X | X | X | X | X | X | X | X | X | | | X |
127 | DEL | X | X | X | X | X | X | X | X | X | | | X |
58 SAIL-COMND Interface
Index 59
INDEX
Account Name Fields 19
Account Parameter 23
Acknowledgements 1
Action Characters 5, 32, 39
Extending 18
Allow$Wild Parameter 21
Arbitrary Fields 24
Atom Buffer 15, 25
Backspace 8
Brchars Parameter 18
Break Characters 18
Standard 18, 54
Building TBLUK Lookup Tables 36, 47
Carriage Return 5, 32
CASE Statement In SAIL 48
Changing Contents of TBLUK Lookup Tables 48
Cm! - Procedures 12
Cm!Act 19
Cm!Cfm 19
Cm!Cma 20
Cm!Dev 21
Cm!Dir 21
Cm!Fil 22
Cm!Fld 24
Cm!Flt 25
Cm!Getatm 15, 25
Cm!Ifi 25
Cm!Ini 26
Cm!Key 27
Cm!Nod 29
Cm!Noi 29
Cm!Num 30
Cm!Nux 30
Cm!Ofi 31
Cm!Qst 31
Cm!Retry 13, 32
Cm!Size 33
Cm!Swi 33
Cm!Tad 34
Cm!Take 16, 35
Cm!Tbuild 36
Cm!Tok 38
Cm!Txt 38
Cm!Uqs 39
Cm!Usr 39
Cm!Abort Variable 16, 36
Cm!Act Procedure 19
Cm!Cfm Procedure 19
Example of Use 46, 50
Cm!Cma Procedure 20
Cm!Colon Variable 33
60 SAIL-COMND Interface
Example of Use 51, 52
Cm!Datime Array 34
Cm!Dev Procedure 21
Cm!Dir Procedure 21
Cm!Eof Variable 16, 36
Cm!Err Variable 12, 14, 15
Example of Use 44, 45, 46
Cm!Fatal Variable 15
Cm!Fil Procedure 22
Cm!Fld Procedure 24
Cm!Flt Procedure 25
Cm!Getatm Procedure 15, 25
Cm!Ifi Procedure 25
Example of Use 51
Cm!Ini Procedure 26
Example of Use 50
Cm!Key Procedure 27
Example of Use 44, 45, 50
Cm!Major Variable 14
Cm!Minor Variable 14
Example of Use 45
Cm!Nod Procedure 29
Cm!Noi Procedure 29
Example of Use 44, 45, 51
Cm!Num Procedure 30
Example of Use 45
Cm!Nux Procedure 30
Cm!Ofi Procedure 31
Cm!Qst Procedure 31
Example of Use 52
Cm!Reparse Variable 13
Example of Use 44, 45, 46
Cm!Retry Procedure 13, 32
Caution 32
Cm!Size Procedure 33
Example of Use 44, 49
Cm!Swi Procedure 33
Cm!Tad Procedure 34
Cm!Take Procedure 16, 35
Cm!Tbuild Procedure 36
Example of Use 44, 50
Cm!Tok Procedure 38
Cm!Txt Procedure 38
Cm!Uqs Procedure 39
Cm!Usr Procedure 39
Example of Use 51
Cm# - Procedures 12, 40
Cm#Call 12, 41
Cm#Reset 41
(All Others) 40
Cm#Call Procedure 12, 41
Example of Use 46, 51, 52, 51, 52
Cm#Int Variable 41
Example of Use 46, 51, 52, 46
Cm#Real Variable 41
Cm#Reset Procedure 41
Index 61
Example of Use 46, 51, 52
Cm#Str Variable 41
Example of Use 51, 52
Colon 33
COMAND.CMD File 16
Comma Fields 20
Command Files 35
Command Line 7
Terminating 20
Command Line Prompt 7, 26
Command State Block 3
COMND Functions
CMACT 19
CMCFM 20
CMCMA 20
CMDEV 21
CMDIR 21
CMFIL 22
CMFLD 24
CMFLT 25
CMIFI 26
CMINI 7, 26
CMKEY 27
CMNOD 29
CMNOI 29
CMNUM 30
CMNUX 31
CMOFI 31
CMQST 32
CMSWI 33
CMTAD 34
CMTOK 38
CMTXT 39
CMUQS 39
CMUSR 40
COMND.HDR File 11
COMPOS Sample Program 54
Confirmation Fields 19
Control/T Character 5
CSB 3
Ctrl/H Character 8
Date Fields 34
Date Parameter 34
Def Parameter 17
Default String 4, 17
And Multiple FDBs 17
Device Name Fields 21
Device Parameter 23
Directory Name Fields 21
Directory Parameter 23
DIRST Built-in SAIL Function 22, 40
Errmsg Parameter 32
Error Handler 14
And Major Errors 14
62 SAIL-COMND Interface
And Minor Errors 14
Errpop Parameter 36
Escape Character 5, 17, 29
EXEC 3, 16, 35, 43
Extension Parameter 23
FDB 3, 4
FDB Chain 9, 40
File Name Fields 22, 25, 31
Flag$Gen Parameter 22
Fred 6
Function Descriptor Block 3, 4
GTJFN Argument Block 22
Word 0 (.GJGEN) 22
GJ%FOU Bit 24
GJ%JFN Bits 24
GJ%OLD Bit 24
Word 2 (.GJDEV) 23
Word 3 (.GJDIR) 23
Word 4 (.GJNAM) 23
Word 5 (.GJEXT) 23
Word 6 (.GJPRO) 23
Word 7 (.GJACT) 23
Word 10 (.GJJFN) 23
GTJFN Built-in SAIL Function 35
GTJFN Jsys 22
GTJFNL Built-in SAIL Function 35
Guide Words 29
Help Message 4, 17
And Multiple FDBs 17
Standard 17
Help Parameter 17
Ichan Parameter 35
IDTNC jsys 35
Ignored Keywords 37
Illegal Instruction Interrupts 14
Indirect Files 18
Initializing The CSB 26
Input File Fields 25
Integer Fields 30
Internal Date/Time Format 34
Invisible Keywords 37
Jfn Parameter 23
Keys Parameter 36
Keyword Abbreviations 1, 38
Keyword Fields 27
LOGIN.CMD File 16
Major Errors 14
Minor Errors 14
Index 63
Multiple Function Calls 9
Example of Use 46, 51, 52
Name Parameter 23
Newcomm Parameter 26
No$Convert Parameter 34
No$Indirect Parameter 18
Node Name Fields 29
Noise Parameter 29
Noise Words 29
Number Bases 30
Numeric Fields 25, 30
Obtaining Passwords 18
Ochan Parameter 35
Optional Parameters 48
Output File Fields 31
Parse$Only Parameter 22
Parsing Errors 5, 7, 12
And Cm!Retry 13, 32
In Command Files 16
With Multiple FDBs 9
Procedure Parameters
Account 23
Allow$Wild 21
Brchars 18
Date 34
Def 17
Device 23
Directory 23
Errmsg 32
Errpop 36
Extension 23
Flag$Gen 22
Help 17
Ichan 35
Jfn 23
Keys 36
Name 23
Newcomm 26
No$Convert 34
No$Indirect 18
Noise 29
Ochan 35
Parse$Only 22
Prompt 26
Protection 23
Radix 30, 31
Raise$Input 17
Strarr 33
Sup$Help 17
Table 28, 33, 36
Time 34
Token 38
Wake$Always 18
64 SAIL-COMND Interface
Prompt Parameter 26
Protection Parameter 23
Punctuation In TBLUK Lookup Tables 37
Question Mark 5, 17
Quoted String Fields 31
Radix Parameter 30, 31
Raise$Input Parameter 17
Real Number Fields 25
Reparse 6, 7, 13
Reparse Dispatch Address 1
REQUIRE Statement 11
Slash 33
Standard Break Characters 18, 55
CMDEV 21
CMFLD 24
CMKEY 28
CMSWI 34
CMTXT 39
Standard Help Message 17
CMACT 19
CMCFM 20
CMCMA 20
CMDEV 21
CMDIR 22
CMFIL 24
CMFLD 24
CMFLT 25
CMIFI 26
CMINI 26
CMKEY 28
CMNOD 29
CMNOI 30
CMNUM 30
CMNUX 31
CMOFI 31
CMQST 32
CMSWI 34
CMTAD 35
CMTOK 38
CMTXT 39
CMUQS 39
CMUSR 40
Suppressing 17
Strarr Parameter 33
Sup$Help Parameter 17
Switch Fields 33
Switches 33
Table Parameter 28, 33, 36
TAKE Command 16, 35
TBLUK Jsys 28
TBLUK Lookup Table 28
Abbreviated Entries 1, 38
Index 65
Building 36, 47
Changing Contents 48
Computing Size With Cm!Size 33
Ignored Entries 37
Invisible Entries 37
Special Punctuation 37
TERCOM Sample Program 48
TERMINAL command 43
Terminating Command Lines 20
Text Fields 38
Time And Date Fields 34
Time Fields 34
Time Parameter 34
Token Fields 38
Token Parameter 38
Turning Off Echoing 18
Unimplemented Features 1
Unquoted String Fields 39
Upper Case Conversion 17
User Name Fields 39
Variables
Cm!Abort 16, 36
Cm!Colon 33
Cm!Datime (Array) 34
Cm!Eof 16, 36
Cm!Err 12, 14, 15
Cm!Fatal 15
Cm!Major 14
Cm!Minor 14
Cm!Reparse 13
Cm#Int 41
Cm#Real 41
Cm#Str 41
Wake$Always Parameter 18
Wildcard Characters 21
Wizard Note 28