GP: Routines for parsing command lines

The  routines  described  here are  a  convenient  package  for parsing
command lines and doing a  few related functions. They may be  found in
GP.Bcpl (source)  and GP.Br (binary).  No external routines  are called
except those supplied by the operating system.

An "unpacked  string" is a  vector v such  that v!1, v!2,  ..., v!(v!0)
contain the characters of the string, one per word, right justified.

A "parameter" in a command line is a maximal sequence of characters not
containing $*S or $*N. All  the characters before the first $/  are the
"body"; the remaining characters,  with any $/ characters  ignored, are
the "switches". Thus

          BCPL/F FOO.Bcpl

contains two parameters.  The first has  body "BCPL" and  switches "F".
The second has body "FOO.Bcpl" and no switches.

SetupReadParam (stringVec, switchVec, stream, comSwitchVec)

    .     stringVec is a vector whose length in words should be greater
          than  the number  of characters  in the  longest body  in the
          command  line.  A  0   defaults  it  to  a   256-word  vector
          inacessible  to  the user;  this  may be  useful  if  all the
          parameters  of  the command  are  files or  numbers  (see the
          discussion of ReadParam below).

    .     switchVec is a vector whose length in words should be greater
          than  the  largest number  of  switches on  any  unit  in the
          command  line.   A  0  defaults  it  to  a   128-word  vector
          inaccessible to the user.

    .     stream is an OS character stream from which the  command line
          will be read. It will not be Reset or Closed. A 0 defaults it
          to  the  disk  file  "Com.Cm".  The  stream  is  left  in the
          external static ReadParamStream.

    .     comSwitchVec  is a  vector whose  length in  words  should be
          greater than the number of switches on the first unit  in the
          command line. A 0 defaults it to switchVec.

Missing parameters are defaulted.

                   Copyright Xerox Corporation 1979

GP: parse command lines     January 2, 1978                           2

This routine initializes the parameter-reading machinery. It  then does
a ReadParam() which will pick  off the first parameter (i.e.,  the name
of the program) and leave the name and switches as unpacked  strings in
stringVec  and comSwitchVec.  If either  of these  was defaulted  to an
inaccessible vector, the corresponding information is lost.

ReadParam (type, prompt, resultVec, switchVec, returnOnNull)

    .     type is an integer  or Bcpl string representing  the expected
          type of the parameter. If type < 256, it is interpreted  as a
          character  which must  select a  defined type  from  the list
          described  below. If  type  > 256  it  is treated  as  a Bcpl
          string.  If  the  string   is  one  character  long,   it  is
          interpreted as though that character had been used. If  it is
          longer, the first two  characters must select a  defined type
          from the list below.

    .     prompt is a Bcpl string which is used to prompt the  user for
          another try at the parameter if a syntax error is discovered.
          A 0 defaults it to "Try again: ".

    .     resultVec is  a vector  used to return  the result  for types
          which need more than one word to represent their result.  A 0
          defaults  it to  the stringVec  passed to  SetupReadParam (in
          which case there  must have been  one or else  ReadParam will
          call Swat).

    .     switchVec  is a  vector  used to  return the  switches  as an
          unpacked string. A 0  defaults it to the switchVec  passed to

    .     returnOnNull is  a boolean  which decides what  to do  if the
          parameter body is null.  It defaults to false.

Missing parameters are defaulted.  If type is missing, it  is defaulted
to 0.

One parameter  is read  from the stream  passed to  SetupReadParam. The
switches are  separated off  and left in  switchVec. Any  $/ characters
among  the  switches  are  stripped  off.  If  there  are  no switches,
switchVec!0 will be 0.

Then the body is handled in a way which depends on the type:

    0:    (the integer 0, not the  character $0 or the string  "0"!) It
          is returned  in resultVec  as an  unpacked string.  Result is

    P:    It is returned in resultVec as a packed (Bcpl) string. Result
          is resultVec.

GP: parse command lines     January 2, 1978                           3

    I or IC:  It is treated as the name of an input character  file, to
          be opened  with OpenFile(body, ksTypeReadOnly,  charItem). If
          the open fails, prompt for another name. Result is the stream
          returned by OpenFile.  In addition, the file name is returned
          in resultvec as a Bcpl string.

    IW:   Like I, but a word stream is created.

    O or OC:  Like I, but OpenFile(body, ksTypeWriteOnly,  charItem) is

    OW:   Like O, but a word stream is created.

    F or EF:  Like I, but OpenFile(body, ksTypeReadWrite,  wordItem) is

    B:    An octal number is collected and returned. Numbers  may start
          with #, which forces them octal, and may end with B, b, O, or
          o (which forces them octal) or with D or d, which forces them
          decimal. Anything else is a syntax error and causes  a prompt
          for another number. Result is the number.

    D:    Like B, but for decimal number.

Any undefined type results in a call on Swat.

If the body is empty, ReadParam immediately prompts, without generating
an error  message from the  null body, unless  returnOnNull is  true or
prompt eq -1,  in which case  it returns -1 when  it sees a  null body.
When prompting for new input,  DEL cancels whatever has been  typed and
allows another try, and BS and control-A backspace one character.

EvalParam (body, type, prompt, resultVec)

    .     body is an unpacked string

    .     the  other  arguments  are like  the  corresponding  ones for
          ReadParam. resultVec defaults to body.

body and type may not be omitted.

Works exactly like  ReadParam, using body  as the parameter  body. Does
nothing  about  switches. This  routine  is useful  for  programs whose
interpretation of parameters depends on the switches attached to them.

ReadString (result, breaks, inStream, editFlag, prompt)

    .     result is a vector in which the string read will be returned,
          unpacked. May not be defaulted.

    .     breaks is a Bcpl string containing the characters  which will
          cause reading to terminate. Defaults to "*N".

GP: parse command lines     January 2, 1978                           4

    .     inStream is the stream to read from. Defaults to keys.

    .     editFlag  says  whether  DEL,  BS  and  control-A  should  be
          interpreted as editing characters.  If it is false,  they are
          not. Otherwise they  are, and furthermore, editFlag  is taken
          as the stream on which  echoing of the input should  be done.
          It defaults to false  unless inStream is keys, in  which case
          it defaults to dsp.

    .     prompt is echoed after a DEL. It defaults to "".

Reads characters from inStream until one of the characters in breaks is
encountered,  leaving  the characters  read  in result  as  an unpacked
string. Returns  the break  character. Allows editing  of the  input as
described under editFlag above.

AddItem (vek, value)

    .     vek is a vector whose current size is given by vek!0.

    .     value is an uninterpreted 16-bit quantity.

Increments vek!0 and stores value at the new vek!(vek!0).