\documentstyle{article}
\begin{document}
\setlength{\parindent}{0mm}
\setlength{\parskip}{1 ex}

\def\tilde{\~{ }}

%
% Formats for various types of identifiers.
%

\def\filename{\em}
\def\proc{\em}

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

%@textform(setheading=[
%    @pageheading(odd,immediate,
%       right="\begin{box,boxtype standardrowlines, size 12)@parm(text)@end(box)@\")
%    @pageheading(even,immediate,
%       left="\begin{box,boxtype standardrowlines,size 12)@parm(text)@end(box)@\")])

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

%\newenvironment{arglist}
\def\arglist
{       % ``arglist'' begin text
        Arguments:
        \begin{list}
                { }
                {
                        \setlength{\rightmargin}{\leftmargin}
                        \setlength{\itemsep}{0mm}
                }
        \def\arg##1##2{ \item[\ \ {\bf ##1} (##2)]\mbox{}\\}
%       \addtomargins{4 em}
%       \def\arg##1##2{\addtomargins{-2 cm}{\bf ##1} (##2)\\}
}
\def\endarglist
{
        \end{list}
}

%
%

\newcommand{\decl}[1]{
        \vspace{2 ex}
        Entry: {\bf #1}\\
        % should set page headings here
}

\title{A Subsystem Utilities Package for UNIX}
\author{Ken Raeburn}
\date{Printed: \today}

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

\maketitle

\centerline{Copyright \copyright 1987 MIT Student Information
Processing Board}

\newpage
\tableofcontents
\newpage

\section{Why?}

{\it put some explanation of purpose here}

\section{Command 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:

\begin{verbatim}
          unimplemented   delete_all_files,
                          ``Delete all my files.'', 
                          delete_all_files, daf;
\end{verbatim}

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.

\subsection{Standard 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.)

\begin{verbatim}
          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;
\end{verbatim}

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''.

\section{Command 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.\footnote{This 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\/}.

\section{Runtime 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:

\begin{verbatim}
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;
\end{verbatim}

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:

\begin{verbatim}
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;
\end{verbatim}

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`:

\begin{verbatim}
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;
\end{verbatim}

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

\begin{verbatim}
        subsystem:  _
\end{verbatim}

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

\begin{verbatim}
ss_set_prompt(sci_idx, new_prompt)
char *ss_get_prompt(sci_idx)
        char *new_prompt;
\end{verbatim}

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

\begin{verbatim}
void ss_listen(sci_idx, code_ptr)
        int sci_idx;
        int *code_ptr;
\end{verbatim}

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

\begin{verbatim}
int subroutine(argc, argv, sci_idx)
        int argc;
        char **argv;
        int sci_idx;
\end{verbatim}

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.

\begin{verbatim}
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;
\end{verbatim}

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`:

\begin{verbatim}
void ss_abort_subsystem(sci_idx, code)
        int sci_idx;
        int code;
\end{verbatim}

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.

\begin{verbatim}
char *ss_current_request(sci_idx, code_ptr)
char *ss_name(sci_idx)
\end{verbatim}

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. \footnote{At 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.}

\begin{verbatim}
ss_perror(sci_idx, code, message)
        int code;
        char *message;
\end{verbatim}

\section{Compilation-time Usage}
To generate the object file, run the program \verb`make_commands`:

\begin{verbatim}
        % make_commands commands
\end{verbatim}

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:

\begin{verbatim}
# rule for rebuilding .o files from command table sources
.SUFFIXES:      ct
.ct.o:
        make_commands $*.ct
\end{verbatim}

\section{User 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.

\section{Intended 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.

\end{document}
