\documentstylearticle \begindocument \setlength\parindent0mm \setlength\parskip1 ex

\def\tilde\~

% % Formats for various types of identifiers. %

\def\filename\em \def\proc\em

% % Change page heading to correspond to current definitions. %

%(setheading=[ % (odd,immediate, %       right="\beginbox,boxtype standardrowlines, size 12)(text)(box)\")
% (even,immediate,
%       left="\beginbox,boxtype standardrowlines,size 12)(text)(box)\")])

\newcommand\addtomargins[1]
\addtolength\oddsidemargin#1
\addtolength\evensidemargin#1

%\newenvironmentarglist
\def\arglist
       % ``arglist'' begin text
Arguments:
\beginlist

\setlength\rightmargin\leftmargin
\setlength\itemsep0mm

\def\arg##1##2 \item[\ \ \bf ##1 (##2)]\mbox\\
%       \addtomargins4 em
%       \def\arg##1##2\addtomargins-2 cm\bf ##1 (##2)\\

\def\endarglist

\endlist

%
%

\newcommand\decl[1]
\vspace2 ex
Entry: \bf #1\\
% should set page headings here

\titleA Subsystem Utilities Package for UNIX
\authorKen Raeburn
\datePrinted: \today

% ****************************************************************

\maketitle

\centerlineCopyright \copyright 1987 MIT Student Information
Processing Board

\newpage
\tableofcontents
\newpage

\sectionWhy?

\it put some explanation of purpose here

\sectionCommand Table Source

The start of the source file for the command table compiler must indicate the
command table name, with the command:

\verb`command_table` \it table\_name;

This is the name of the table that will be used for external references.  After
the table name declaration, a list of subsystem requests should be provided,
of the form:

\verb`request` \it subr\_name, description of command,
request\_name \, request\_name\;

That is, the keyword ``request,'' the name of the subroutine to be invoked,
a comma, a short (one-line) description of the command (which will be displayed
with the ``list\_requests'' request), another comma, and a list of
comma-separated names by which the requst can be invoked.  Any information
in an entry which consists of non-alphanumeric characters (particularly
the description because it contains spaces, or special characters such as
``?'' in a request\_name) must be quoted.  The entry is terminated by a
semicolon.

One special form of entry can also be used for routines which are to be
listed in the command table, but have not yet been written.  (This should
not be used in the production version of programs, but may be useful
during the writing of them.)  The ``request'' keyword is replaced by the
keywork ``unimplemented,'' and the subroutine name (and the following
comma) is omitted, thus:

\beginverbatim
unimplemented   delete_all_files,
``Delete all my files.'',
delete_all_files, daf;
\endverbatim

When this request is called, a routine in the subsystem library will inform
the user that the request is not currently implemented.

There is also an optional ``options'' field, which appears as the last
request\_name and should be a parenthesized list of (comma-separated) options.
At present, the only options defined are ``dont\_list,'' which indicates that
the command should not be listed by the ``list\_requests'' request, and
``dont\_summarize,'' which has a similar effect on the ``summarize\_requests''
routine.

After all entries in the table have been specified, the end of the table must
be specified with the ``end'' keyword.

\subsectionStandard Requests

The following table is supplied with the subsystem library, and uses some of
the routines supplied in the library.  (Many of these have not yet been
implemented.)

\beginverbatim
command_table  ss_std_requests;

request ss_self_identify, ``Identify the subsystem.'',
``.'',
(dont_list, dont_summarize);

request ss_help, ``Display info on command or topic.'',
help;

unimplemented
ss_list_help,
``List topics for which help is available.'',
list_help, lh;

request ss_list_requests, ``List available commands.'',
list_requests, lr, ``?'';

request ss_quit, ``Leave the subsystem.'',
quit, q;

unimplemented
ss_abbrev,
``Enable/disable abbreviation processing of request lines.'',
abbrev, ab;

unimplemented
ss_execute,
``Execute a UNIX command line.'',
execute, e;

unimplemented
ss_summarize_requests,
``Produce a list of the most commonly used requests.'',
``?'';

request ss_subsystem_name,
``Return the name of this subsystem.'',
subsystem_name,
(dont_list);

request ss_subsystem_version,
``Return the version of this subsystem.'',
subsystem_version,
(dont_list);

end;
\endverbatim

The ``.'' request, \verb`ss_self_identify`, prints the name and
version of the currently running subsystem.  The \verb`ss_help`
routine searches for help files in a series of directories provided by
the program.  The abbreviations processor has not yet been
implemented, but it will allow the entering of abbreviations bythe
user, similar to the ``alias'' facility of \verb`csh`.  Since
\verb`ss_summarize_requests` has also not been implemented, the ``?''
command currently calls the same routine as ``list\_requests''.

\sectionCommand Table Compiler

The command table is converted to a usable form by the program
\verb`make_commands`.  It takes one mandatory argument, the name of
the file which contains the command table.  This filename should end
with the suffix \it .ct\/; the compiler will not work if it does
not.  (\verb`Make_commands` also takes one optional argument after the
filename, \verb`-n`, which will cause it to retain its temporary files
rather than deleting them.)

One output file is produced, with a suffix of \it .o\/; it contains
one object, the command table, and references to all the procedures
listed in the table.\footnoteThis file is compiled from an
intermediate C source file with options \verb`-O -R` to put the
command table into the shared (text) portion of the resulting
executable, and run through \verb`ld` to eliminate extra symbol table
entries. This table is of type \verb`ss_request_table`, which is
defined in the include file \it ss.h\/.

\sectionRuntime Usage

The only handle the programmer needs on the data structure manipulated
by the subsystem library is the index number of the subsystem control
info structure (sci\_idx) manipulated.  (It is conceivable that, in
some cases, a programmer might wish to have more than one subsystem
available at once, with the ability to switch from one to another
temporarily.)  This index is used by most of the routines in the
subsystem library, and is supplied to the application program at the
``creation'' of an invocation of the subsystem, which is done with the
following routine:

\beginverbatim
int ss_create_invocation(subsystem_name, version, info_ptr,
request_table_ptr, code_ptr)
char *subsystem_name, *version;
char *info_ptr;
ss_request_table *request_table_ptr;
int *code_ptr;
\endverbatim

If no errors occurred, the returned value is the index of the new
subsystem, and \verb`*code_ptr` is set to zero.  If \verb`*code_ptr`
is nonzero, it is an error code which may be examined with the
\verb`com_err` library.

When the subsystem is initially created, only the specified request
table is in its search list.  Others can be added or deleted using the
routine:

\beginverbatim
ss_add_request_table(sci_idx, request_table_ptr, position, code_ptr)
ss_delete_request_table(sci_idx, request_table_ptr, code_ptr)
int sci_idx;
ss_request_table *request_table_ptr;
int position;
int *code_ptr;
\endverbatim

Position can be used to specify the order of searching the tables.  A
large number (e.g., 9999) will insure that the table being added is at
the end of the search sequence.

Directories containing help files can be added to or deleted from the
internal list searched by using \verb`ss_add_info_dir` and
\verb`ss_delete_info_dir`:

\beginverbatim
void ss_add_info_dir(sci_idx, info_dir, code_ptr)
void ss_delete_info_dir(sci_idx, info_dir, code_ptr)
int sci_idx;
char *info_dir;
int *code_ptr;
\endverbatim

Initially, the input prompt for the subsystem will be the subsystem name
followed by a colon and two spaces, thus:

\beginverbatim
subsystem:  _
\endverbatim

The prompt can be examined with \verb`ss_get_prompt` and changed with
\verb`ss_set_prompt`:

\beginverbatim
ss_set_prompt(sci_idx, new_prompt)
char *ss_get_prompt(sci_idx)
char *new_prompt;
\endverbatim

The input/parse/dispatch loop is managed by the subroutine \verb`ss_listen`:

\beginverbatim
void ss_listen(sci_idx, code_ptr)
int sci_idx;
int *code_ptr;
\endverbatim

The subroutines called (listed in the command tables) should be
written to the following declaration:

\beginverbatim
int subroutine(argc, argv, sci_idx)
int argc;
char **argv;
int sci_idx;
\endverbatim

Until better argument parsing and interpretation is planned, the
subsystem library will do no more than parse the command line into a
list of arguments (as would be supplied to \verb`main()`).  The
argument \verb`sci_idx` is supplied last so that it may be omitted
when only one subsystem is involved in a program.

Command lines can be executed not only from the input loop, but also
from the program itself.  The subroutines \verb`ss_execute_command`
and \verb`ss_execute_line` will execute the commands supplied as if
they had been typed to the input loop.

\beginverbatim
int ss_execute_command(sci_idx, argv)
void ss_execute_line(sci_idx, line_ptr, code_ptr)
int sci_idx;
char **argv;
char *line_ptr;
int *code_ptr;
\endverbatim

The error code from \verb`ss_execute_command` is given as the return
value.  In a future version of this library, probably many, if not
most, of the routines will return error codes in this fashion.

To terminate the input loop, the user can enter a request which runs
the \verb`ss_quit` procedure, or the program can call
\verb`ss_abort_subsystem`:

\beginverbatim
void ss_abort_subsystem(sci_idx, code)
int sci_idx;
int code;
\endverbatim

When control returns to \verb`ss_listen`, it will return to its caller
with the error code supplied to \verb`ss_abort_subsystem`.  (The
subroutine \verb`ss_quit` simply executes a call to
\verb`ss_abort_subsystem`.)

While running within a subsystem request, the routines
\verb`ss_current_request` and \verb`ss_name` will return information
about the request.  The \verb`ss_current_request` function returns the
primary name of the request being executed (the first one listed in
the request table entry), or NULL if none is being executed.  This
string is internal information, and should not be modified.  The
routine \verb`ss_name` returns a string naming the subsystem and the
request, if any.  The returned string is of the form ``subsystem'' or
``subsystem (request)''.  The string returned is allocated and should
be freed when it is no longer needed.

\beginverbatim
char *ss_current_request(sci_idx, code_ptr)
char *ss_name(sci_idx)
\endverbatim

If output is being generated that may be more than one screenful for
the user, it may be output through a file descriptor generated by the
routine \verb`ss_pager_create()`.  This routine takes no arguments,
and returns an integer which is either -1 (some error occurred) or a
file descriptor number.  Currently, it generates output through
``more'', and a call to \verb`wait()` should be made after the file
descriptor is closed, but this should be changed at some point to make
the output routines internal; much nore control can be gained this
way.

If errors are encountered during the execution of the subsystem, they
should be reported through the routine \verb`ss_perror`.  It is
written to work with the \verb`com_err` library, and can therefore be
used to report errors returned from the UNIX operating system, from
the subsystem library, and from any other package written to use the
\verb`com_err` library. \footnoteAt the moment,it isn't written to
use the \verb`com\_err()` routine; it uses \verb`error\_message()` and
prints a message in a format similar to \verb`com\_err()`.  It will be
rewritten to use \verb`com\_err()`, so that the hooks for catching the
output with other procedures will work.

\beginverbatim
ss_perror(sci_idx, code, message)
int code;
char *message;
\endverbatim

\sectionCompilation-time Usage
To generate the object file, run the program \verb`make_commands`:

\beginverbatim
% make_commands commands
\endverbatim

This will generate \it commands.o\/ from \it commands.ct\/.  This
file and \tt libss.a should be linked with your object files.

If you are using a makefile, you can add the following lines to it to have
command-table object files automatically rebuilt:

\beginverbatim
# rule for rebuilding .o files from command table sources
.SUFFIXES:      ct
.ct.o:
make_commands $*.ct
\endverbatim

\sectionUser Interface

The user interface of this library is currently fairly weak, but
reliable.  Providing alternatives to the (only) existing one is a
major intended upcoming change to this library.  Currently, the user
sees a prompt string, must type a command and its arguments and hit
return, and the command will be executed if it is valid.  While this
is sufficient for some, others would prefer single-key commands, or
completion of commands and arguments; many would like to see an
interface based on the X window system.

\sectionIntended Changes

This section is sort of fuzzy, but some of the main inteded changes
are:

Revise calling sequence for some routines (at least the ones returning
``void'') so that error codes are handled as return values; this is
generally more efficient.

Build alternative interfaces:  Something based on curses.  Something
based on X, once version 11 and its toolkits become stabilized.

Get abbreviations working.

Do some argument parsing/interpretation/validation.  Some of the
problems with programs written today (and subroutines written for this
library today) is that it is very easy to make minor errors which
cause the argument parsing to work incorrectly.  This should probably
be done as a separate but integrable module, so that commands can use
their (UNIX-standard) command-line arguments (via argc/argv) this way
also.

Write info files for the subroutines supplied.  Maybe even a man page
for the library.

Completion of commands and maybe even arguments.

\enddocument