Google
 

Trailing-Edge - PDP-10 Archives - mit_emacs_170_teco_1220 - info/sail-libs.info
There are no other files named sail-libs.info in the archive.
-*-text-*-

 
File: Sail-Libs, Node: Top, Up: (Sail)

	Libraries are useful routines written by someone else that
you may use in your program. To use a the procedures from a library
include the statement, REQUIRE "libname.HDR" SOURCE!FILE; in your
program. This declares all the external library routines for you.

* Menu:

* Comnd::	This library implements the Comnd jyses, allowing
		you use command completion, help on question marks,
		default values, and other similar neat stuff. (This
		is rather long.)

* Routin::	This library contains i/o and string manipulation
		routines. (This too is rather long.)

* Sort::	This library contains many different routines for
		sorting integer, real, and string arrays. 

* Syminv::	This library will take the inverse of a symmetric 
		matrix.

* Texti::	A smart and easily used interface to the RDTTY jsys.

* Ttyio::	Yet another i/o interface.


File: Sail-Libs, Node: Comnd, Up: Top, Next: Routin




















                    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


	
File: Sail-Libs, Node: Routin, Previous: Comnd, Up: Top, Next: Sort



  The routines in this package are mostly for terminal I/O and
  string processing.  This file is intended to provide adequate
  description for each routine as well as the declarations necessary
  for you to use them in your programs.  Unless otherwise indicated,
  the routines were written by (and comments should be directed to)

  Frank da Cruz
  Columbia University Center for Computing Activities
  New York, N.Y.  10027


  For each routine, the declaration is given first, followed by
  a comment that describes it.  In procedure declarations, any
  argument followed by a quantity in parentheses is optional.
  If it is not given in the procedure call, the value in parens
  is supplied to the procedure by default.  Only trailing optional
  arguments may be omitted.
simple external string procedure rdtty
 (value string prompt, sofar(null);
  value boolean quiet (false));


    Simulates the Rdtty jsys.  Allows input from the terminal using
    all the TOPS-20 editing characters (delete, ^U, ^W, ^R).
    Reissues the prompt after ^U, prints the current contents of the
    input buffer and waits for further input upon ^R.
    Disallows editing into the prompt.

  Inputs:
    prompt - string to prompt with.
    sofar  - (optional)
             string to insert into the input buffer before the user
	     starts typing.  This is useful for the case when the
	     user wants to be prompted with what (s)he typed so far
	     (e.g. in a previous call to Rdtty) and then be able to
	     complete it.
    quiet -  (optional)
	     If true, don't print the prompt or sofar.  This is useful
	     if you're trying to simulate recognition.

  Outputs:
    The string which the user types is returned as the value of the
    function.  The break character is returned in the break-character
    variable defined in the most recent call to Setty.

  Note:  You should call Setty (see below) at the beginning of your
	 program to establish what characters Rdtty should break on
	 and to specifiy various other characteristics of Rdtty.

  Rdtty and Setty originally came from Stanford but were corrected and
  enhanced at Columbia.
external procedure setty
 (value string mode, brea;
  reference integer break);


  Sets TTY parameters for use by subsequent calls to Rdtty.

  Inputs:
    opts - Options.  One or more of the following:
		"T" - break on ^L ^G ^Z esc cr Lf.
		"P" - break on any punctuation character.
		"Z" - break on ^Z or esc.
		"L" - break on cr or Lf.
		"K" - convert input to upper case.
		"U" - return if ^U.
		"S" - suppress ^U indication.
		"C" - don't suppress crlf.
		space or tab - ignore spaces and tabs.
	    example: "LK" breaks on carriage return or line feed
	      and converts any lower case letters in the input to
	      upper case.
    brea - Break characters.  A string of break characters on which
	      to terminate input in addition to any specified in opts.
    brk  - A variable (which you have declared) in which Rdtty can
	      return the break character.

  Outputs:
    The global variable !!opts and !!brea are set to have the values
    of opts and brea respectively so that these can be saved and
    restored by routines that may want to temporarily change the
    TTY paramaters.


  Routines that use the rescan facility.  See the description of
  the Rscan jsys in the monitor calls reference manual for more
  information.

  (these routines were written at Stanford but debugged locally);

external procedure pscan
 (value string A);


  Puts the argument string (up to 79 chars) into the rescan buffer.
  This facility allows a program to store a string in the Job
  Storage Block.  The string remains there until it is fetched
  by the Rscan jsys (for instance, by the Gtscan function defined
  below), thus one program can store an argument for a program
  that is to be run subsequently without the overhead of file
  processing.

external string procedure gtscan;


  Returns (and destroys) the contents of the rescan buffer.
  Especially useful for programs that you want to invoke from
  the EXEC with an argument.  For instance, if you have a program
  called Strip and you type "strip foo.bar" to the EXEC, Strip
  can call this function which will return "strip foo.bar" (the
  EXEC command line).  The program can then parse this command
  line to find its argument ("foo.bar").


  -- String-processing Functions --  

simple external string procedure Ltrim
 (value string A);

 strips leading blanks and tabs.

simple external string procedure trim
 (value string A);

 strips trailing blanks and tabs;

simple external string procedure Caps
 (value string A);

  Returns a new copy of the string A
  with all lower-case letters converted to
  upper case.

simple external integer procedure index
 (value string A, B;
  value integer n(1));

  Returns the position of the first occurrence,
  scanning from the left and starting at position n,
  of the string B in the string A, or 0 if B is not
  a substring of A.  If B is null then 1 will be
  returned.  The default value for n is 1.  If n is
  less than 1 it will be forced to 1.

simple external integer procedure verify
 (value string A, B;
  value integer n(1));

  Returns the position of the first character in A that is
  not in B, starting from position n in A and scanning from
  the left.  Returns 0 if A is null, 1 if B is null.
  The default value for n is 1.  If n is less than 1 it
  is forced to be 1.

simple external integer procedure break
 (value string A, B;
  value integer n(1));

  Returns the position of the first character in A,
  scanning from the left starting from position n,
  that is also in B (or 0 if none or if A is null,
  or n if B is null).
  The default value for n is 1.  If n is specified
  but is less than 1, then it will be forced to 1.

simple external string procedure repeat
 (value string A;
  value integer n);

 returns a string consisting of n repetitions of A


  -- String Comparison Functions --

Alphabetic case is significant unless otherwise indicated.

simple external boolean procedure GT
 (value string A, B);

  Returns True if A is lexically greater than B,
  otherwise False.

simple external boolean procedure GE
 (value string A, B);

  Returns True if A is lexically greater than or equal to B,
  otherwise False.

simple external boolean procedure LT
 (value string A, B);

  Returns True if A is lexically less than B,
  otherwise False.

simple external boolean procedure LE
 (value string A, B);

  Returns True if A is lexically less than or equal to B,
  otherwise False.

external boolean procedure keq
 (value string A, B);

  "Keyword equal" - returns True if A is lexically equal
  to B with alphabetic case ignored, otherwise False.


  -- Miscellaneous Routines -- 

external boolean procedure OK
 (value string prompt ("  OK"), default (null));

  Type a question and get a yes/no answer.
  COMND-Jsys-like keyword lookup (and recognition) are done
  on the keywords "yes", "no", and "ok" (note: if you don't
  want escape to echo as "$" during recognition, then call escOff
  before the first time you call this routine.  Call escOn to
  turn escape echoing back on).
  The alphabetic case of the answer is not significant.
  If a default is given in the call, it will be supplied if the
  user types carriage return alone in response to the question.
  The function returns true if the answer was affirmative and
  false if the answer was negative.
  The default prompt is "  OK?".  A default answer can be
  supplied as a parameter.

external recursive procedure ermsg
 (value integer errno(-1);
  value string msg(null));

  Print the most recent Jsys error message if no arguments.
  If arguments are provided then the results are as follows:
    The left half of errno is discarded.
    If errno is a valid Jsys error number, then the appropriate
      message is printed.
    If errno is '777777 (-1) the most recent Jsys error is
      printed.
    If errno is not 0 and not '777777 and not a valid Jsys error
      number, then this routine calls itself to print an
      appropriate message (it can only 'recurse' once).
    If errno is 0, then if msg is not null it (msg) is printed,
      and if msg is null, then the most recent jsys error
      message is printed.
  This routine uses the Esout jsys, which clears typeahead.
  See the description of this jsys in the Monitor Calls Reference
  Manual for further information.

simple external procedure typef
 (value string file,
  msg (" [file not available]"));

  The file whose name is given is typed at the
  job's controlling terminal, or if the file is
  not available the message is typed.

external recursive procedure qsort
 (reference string array A;
  value integer m, n);

  Sorts elements m through n of the string array A
  in ascending lexical order using the quicksort algorithm.


  -- Routines to simulate some simple Comnd jsys functions --

  For full Comnd functionality, use the routines in sai:comnd.*.
  The routines defined here provide only limited functionality
  but are somewhat easier to use than those in the comnd
  package and they provide an additional advantage:  they allow
  specification (via Setty) of arbitrary break characters and
  they make the break character actually used available to the
  caller.

simple external string procedure cmtxt
 (reference integer brkchar;
  value string prompt ("? "), help (" Please type a string"),
               default (null));



    This routine simulates the .CMTXT function of the COMND Jsys.
    Confirmation is required, so this routine is not suitable
    for multifield commands.  If access to the actual Comnd
    jsys is required, use the routines in sai:comnd.*.

    Inputs:
      brkchar - the break character variable obtained by a prior
                call to Setty,
      prompt  - the prompt to issue,
      help    - a help message to type if the user types "?".
      default - a string to be supplied if the user enters nothing.

    Outputs:
      The string which the user types in response to the prompt
      is returned as the value of cmtxt.  The terminating character
      is retuned in brkchar.

    Action:
      Cmtxt adds "L" to whatever options you may have chosen in
      your most recent call to Setty, and adds "?" to the list
      of break characters, so that a help message may be issued
      if the user types "?".  All the standard editing characters
      (DEL, ^U, ^W, ^R) work correctly.  The user is reprompted
      after typing ^U or ^R.  Deleting into the prompt is prevented.
      The previous Setty parameters are restored upon return from
      cmtxt.
external integer procedure cmkey
 (reference integer brkchar;
  reference string array kwd;
  value integer n;
  value string prompt ("? "), help (null), default (null));


  Simulates the operation of the function .CMKEY of the
  Comnd Jsys, except that confirmation is required - the keyword
  must be terminated by a break character (other than "?" or
  escape) as established in the most recent call to Setty.
  Therefore this function is not useful for multifield commands.
  If the full power of the actual Comnd Jsys is required, use
  the routines in sai:comnd.*.
  
  Inputs:
    brkchar - the break character variable obtained by a prior
              call to Setty.
    kwd     - a string array of keywords (alphabetic case is not
              significant).  They need not be in alphabetical
              order.
    n       - the number of keywords in the array (the array is
              assumed to have elements 1 ... n).
    prompt  - the string to issue as a prompt.
    help    - a string to describe what the keywords are.
              This string will have the string
              ", one of the following:" appended to it
              (unless it is null, in which case "One of the ...").
              The string so constructed is printed if the user
              types a question mark.
    default - a string (one of the keywords) that will be used if
              the user types carriage return (or any currently
              enabled break character other than "?" or ESC) in
              response to the prompt.

  Outputs:
    The index of the user's response in the keyword array if found,
    or 0 if the string was not found,
    or -1 if the string was not unique,
    or -2 if the string was null.
    The break character is returned in brkchar.

  Action:
    Any unique abbreviation of a keyword will be accepted.
    Recognition will be done if the user types ESC (the escape
    character).  Help will be given if the user types "?".
    These facilities all work in roughly the same way as they
    do in the .CMKEY function of the COMND Jsys.

  Note:
    To prevent escape from echoing as "$", call EscOff at some
    point before calling this routine.  To turn escape echoing
    back on, call EscOn.
comment

  -- Support Routines for Comnd Simulation --  ;

simple external procedure escon;
  causes the escape character to be echoed as "$".

simple external procedure escoff;
  causes the escape character not to be echoed.

simple external procedure mcrlf;
   prints a crlf if tty cursor (or print head) is not at left
   margin, otherwise null.

simple external integer procedure lukup
 (value string A;
  reference string array X;
  value integer first, last);

  Looks up the string A in the string array X,
  in the segment X[first] thru X[last].
  Returns the index in X where A was found if
  A is a unique prefix of one and only one element
  of the segment or the index of the first element in
  the segment that exactly matches A, or

    first-1 if A is not a prefix of any element in
      the segment of X, or

    first-2 if A is a prefix of more than one element
      in the segment of X.

  Alphabetic case is ignored.


File: Sail-Libs, Node: Sort, Up: Top, Previous: Routin, Next: Syminv


File: Sail-Libs, Node: Syminv, Up: Top, Previous: Sort, Next: Texti

File: Sail-Libs, Node: Texti, Up: Top, Previous: Syminv, Next: Ttyio

File: Sail-Libs, Node: Ttyio, Up: Top, Previous: Texti

comment: ttyio header (most recent update: 2:12pm  Monday, 18 June 1979)

  Prompting-style TTY i/o using COMND.

  Use these routines when you want to write programs that issue a
  a specific sequence of prompts, rather than normal COMND-style
  keyword parsing.  Not all COMND functions are supported, but it
  is easy to add new ones, using the existing ones as models.

  Note: this file, ttyio.doc, can be required as a source file, but
    ttyio.hdr - which lacks the comments - can is more appropriate
    to this purpose, as in:

  require "sai:ttyio.hdr" source!file;

comment

  F. da Cruz		CUCCA		 June 1979;


comment - ttText: Get a text string from the terminal.

The string is returned as the value of the procedure.
;
external string procedure ttText
 (value string prompt, help("text string"),default(null);
  value boolean raise(false));



comment - ttInt: Get an integer from the terminal.

The integer, which is the result of interpreting the string
which the user types in the specified radix (2 to 10),
is returned as the value of the procedure.

All illegal input is caught and appropriate error messages
issued.  The procedure does not return until the user has typed
a legal number in the given radix or, if a legal default is
specified, the user has typed CR (or ESC CR) to accept the default.
;
external integer procedure ttInt
 (value string prompt, help("decimal integer"), default("0");
  value integer radix(10));



comment - ttUser: Get a user name from the terminal.

The string representation of the user name is returned
as the value of the procedure.  The procedure does not return
until the user has typed a valid user name (i.e. the id of an
existing user).  Recognition may be used.
;
external string procedure ttUser
 (value string prompt, help("user name"), default(null));



comment - ttInF: Get an input filespec from the terminal.

The file is opened in 7-bit read mode and its jfn is returned as the
value of the procedure.  The procedure does not return until the
user has specified an existing file to which s/he has read access.
Recognition may be used.
;
external integer procedure ttInF
 (value string prompt("Input file: "),
        help("specify an existing file"),
        default(null));
 


comment - ttOutF: Get an output filespec from the terminal.

The file is opened in 7-bit write mode and its jfn is returned
as the value of the procedure.  The procedure does not return until
until the user has specified a new file to which s/he has write access.
Recognition may be used.
;
external integer procedure ttOutF
 (value string prompt("Output file: "),
        help("specify a file that doesn't exist yet"),
        default(null));



comment - ttTime: Get date and time from the terminal.

Returns an integer containing the internal representation of the
date/time that was parsed.

If date is true, then a date will be required.
If time is true, then a time will be required.
  In the default case, both are required.

The procedure does not return until the user has typed a valid
date and/or time (depending on the values of the 'date' and 'time'
parameters).
;
external integer procedure ttTime
 (value string prompt("Date and time: "),
        help("type date, a space, then time in almost any format"),
        default(null);
  boolean date(true), time(true));

require "sai:ttyio.rel" library;
require "sai:comnd.hdr" source!file;