summaryrefslogtreecommitdiff
path: root/web/funnelAC/userman/u_ch3.tex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /web/funnelAC/userman/u_ch3.tex
Initial commit
Diffstat (limited to 'web/funnelAC/userman/u_ch3.tex')
-rw-r--r--web/funnelAC/userman/u_ch3.tex2986
1 files changed, 2986 insertions, 0 deletions
diff --git a/web/funnelAC/userman/u_ch3.tex b/web/funnelAC/userman/u_ch3.tex
new file mode 100644
index 0000000000..7669732fc8
--- /dev/null
+++ b/web/funnelAC/userman/u_ch3.tex
@@ -0,0 +1,2986 @@
+%==============================================================================%
+% Start of Ch3.tex %
+%==============================================================================%
+%
+% Copyright
+% ---------
+% Copyright (C) 1992 Ross N. Williams.
+% This file contains a chapter of the FunnelWeb User's Manual.
+% See the main TeX file for this manual for further information.
+%
+%==============================================================================%
+
+\chapter{FunnelWeb Definition}
+\label{chapdefinition}\xx{FunnelWeb}{definition}
+
+\section{Introduction}
+
+This purpose of this chapter is to provide a complete and consistent
+definition of the FunnelWeb input language and the behaviour of the
+FunnelWeb program. Usually, a chapter such as this is called a
+\dq{reference manual}, but this chapter is intended to go further
+by actually defining the language and program. This chapter takes
+precedence over all other chapters and all implementations of FunnelWeb.
+If an implementation contradicts this chapter, then the implementation
+is wrong.
+
+This is the chapter that you should turn if you find yourself asking a
+specific question about a specific aspect of FunnelWeb. In many
+cases it will be convenient to access this chapter through the index.
+
+\section{Notation}
+\x{notation}
+
+A particular variant of EBNF\xx{EBNF}{syntax}
+(Extended Bachus Naur Form) will be used to
+describe the FunnelWeb syntax. In this variant, literal strings are
+delimited by double quotes (\eg{}\p{"string"}), optional constructs by
+square brackets (\eg{}\p{[optional]}), and constructs repeated zero or
+more times by braces (\eg{}\p{\{zeroormore\}}). Constructs to be repeated
+a fixed number of times are enclosed in braces followed by a decimal
+number indicating the number of times to be repeated
+(\eg{}\p{\{sixtimes\}6}). Constructs to be
+repeated one or more times are
+enclosed in braces and followed by a \p{+} (\eg{}\p{\{oneormore\}+}).
+The traditional BNF \dqp{::=}
+is replaced by the visually simpler \dqp{=}. The traditional BNF angle
+brackets are abandoned.
+
+Although FunnelWeb allows the special character to be changed using the
+construct \dq{$<$special$>$=}, use of \dq{$<$special$>$} to refer to
+FunnelWeb's special character is cumbersome and abstract. To simplify
+the presentation, the default special character \dqp{@} is used throughout
+this chapter to represent the special character.
+
+\section{Terminology}
+\x{terminology}
+
+A specific terminology has arisen for dealing with FunnelWeb. Some
+particularly useful examples are:
+
+\narrowthing{Journal file:}{An output file containing
+a copy of the output sent to
+the user's console during an invocation of FunnelWeb. In other systems,
+this file is sometimes called a \dq{log file}.}
+
+\narrowthing{Product file:}{An output file, generated by the Tangle
+component of
+FunnelWeb, that contains the expansion of the macros in the input
+file.\footnote{Other names considered for this were:
+generated file, expanded file, result file, program file, and tangle file.}}
+
+A complete list of all the special FunnelWeb terminology appears in the
+glossary. Be sure to refer to it if any of the terms used are unclear.
+
+\section{An Architectural Overview}
+\xx{semantic}{architecture}\xx{FunnelWeb}{overview}
+
+An understanding of the internals of FunnelWeb assists with understanding
+its operation (\figphases{}).\xx{execution}{phases}
+
+During a single run, FunnelWeb reads and
+processes a single input file called the \newterm{input file} or
+the \newterm{FunnelWeb file}. The file is processed by passing it through
+a series of stages called \newterm{phases}. The result is that some
+\newterm{output files} are generated.
+A \newterm{journal file} is generated containing a copy of the messages that
+appear on the console during the FunnelWeb run. A \newterm{listing file}
+is created containing a summary of the run, including any error messages.
+A \newterm{documentation} file is generated containing typesetter commands
+that when fed into a typesetter program will result in
+printed documentation. Finally, one or more \newterm{product files}
+are generated containing the result of unscrambling the macro definitions
+of the input file.
+
+These files need not all be generated on any particular FunnelWeb run.
+Whether each output file appears is controlled by command line options.
+
+\begin{figure}[htbp]
+\begin{verbatim}
+
+ .fw Input File (FunnelWeb file)
+ V
+ +---------+ \
+ | Scanner | |
+ +---------+ |
+ V |
+ +--------+ |
+ | Parser | |
+ +--------+ |
+ V |
+ +----------+ >-------+------------+
+ | Analyser | | | |
+ +----------+ | | |
+ V | | |
+ +-----------+------------+ | V V
+ V V | | |
+ +--------+ +-------+ | | |
+ | Tangle | | Weave | | | |
+ +--------+ +-------+ / | |
+ | | | |
+ V V V V
+ Product Files Documentation File Listing File Journal File
+
+\end{verbatim}
+\mylabel{\figphases{}: FunnelWeb's processing phases.}{%
+%
+FunnelWeb processes each input file in a sequence of phases.
+If an error occurs during a phase, no subsequent phases are executed.
+%
+}
+\end{figure}
+
+The phases are briefly described below.
+
+\narrowthing{The Scanner}{reads\x{scanner} the input file, expands
+and reads in include files,
+scans the input stream, processes pragmas and typesetter directives,
+and parses all the
+FunnelWeb special sequences. The result is a list of tokens that
+is handed to the parser.}
+
+\narrowthing{The Parser}{reads\x{parser}
+the scanner's token list and parses it, constructing a
+document list\xx{document}{list} and a macro
+table.\xx{macro}{table} which are passed to later phases.}
+
+\narrowthing{The Analyser}{examines\x{analyser}
+the macro table generated by the parser
+and performs a number of checks of the macro structures
+that the parser could not make on its single pass.
+For example, the
+analyser detects and flags unused macros and recursive macros. The
+analyser forms the final stage of FunnelWeb's front-end processing.}
+
+\narrowthing{Tangle}{expands certain macros in the macro table
+to generate\x{tangle} one or more product files.}
+
+\narrowthing{Weave}{uses the document list to generate\x{weave}
+a documentation file.}
+
+A single run through these phases constitutes a single invocation of
+\newterm{FunnelWeb proper}. Most invocations of the
+\newterm{FunnelWeb program}
+will consist only of a single execution of FunnelWeb proper. However,
+FunnelWeb also provides a command shell that provides many useful commands,
+including a command to invoke FunnelWeb proper. Discussion of the command
+shell is deferred until Section~\ref{commandshell}.
+
+\section{Diagnostics}
+\label{diagnostics}\x{diagnostics}
+
+During execution, FunnelWeb proceeds cautiously with each of its phases,
+only proceeding with the next phase if the previous phase has been
+successful. This means that, when debugging
+a FunnelWeb file, you may find that the number of errors \i{increases}
+after you fix some of them, as you will be exposing yourself to the
+next FunnelWeb phase.
+
+FunnelWeb employs five levels of diagnostics\xx{diagnostics}{levels of}
+at different levels of
+severity.\x{severity}
+Severity is defined in terms of the level of activity at which the
+diagnostic causes FunnelWeb to abort.
+
+\narrowthing{Warning:}{A warning\xx{warning}{severity}
+does not cause FunnelWeb to terminate or
+curtail its operation in any way, but serves merely to warn the user of
+particular conditions that might be symptomatic of deeper problems.}
+
+\narrowthing{Error:}{An\xx{error}{severity} error causes
+FunnelWeb to terminate processing of the
+current input file at the end of the current phase. For example, if an
+error occurs during scanning, FunnelWeb will continue scanning (and possibly
+generate further scanning diagnostics), but will not invoke the parser.}
+
+\narrowthing{Severe Error:}{A\xx{severe}{severity} severe error
+(or \dq{severe} for short) is the same
+as an error except that FunnelWeb terminates the current phase immediately.}
+
+\narrowthing{Fatal Error:}{A\xx{fatal}{severity} fatal error
+causes FunnelWeb not only to terminate
+the current phase and run immediately, but also to terminate total
+FunnelWeb processing immediately. A severe error will not cause a
+FunnelWeb script to terminate, but a fatal error will. A fatal error
+causes FunnelWeb to return control to the operating system.}
+
+\narrowthing{Assertion Error:}{An\xx{assertion}{severity}
+assertion error occurs if FunnelWeb detects
+an internal inconsistency, in which case FunnelWeb terminates immediately
+and ungracefully. Such
+an error can occur only if there are bugs in FunnelWeb. With luck, such
+errors will be extremely rare.}
+
+FunnelWeb indicates the level of severity of each diagnostic that it issues
+by starting each diagnostic either with the full name of the severity level
+or with just the first letter of the severity level followed by a colon.
+
+FunnelWeb conveys the presence or absence of diagnostics at the operating
+system level by returning \p{EXIT\_SUCCESS}\xx{return}{status}
+status if no
+diagnostics occurred during the run and \p{EXIT\_FAILURE} status
+if one or more
+diagnostics (including warnings)
+occurred during the run.\footnote{From
+the symbols of the ANSI standard C library \p{stdlib.h}.
+See \paper{Kernighan88}, p.252.}
+
+
+\section{Typesetter Independence}
+\xx{typesetter}{independence}
+
+One of the design goals of FunnelWeb was to provide a \i{target-language}
+independent literate programming system. This goal has been achieved
+simply by treating the text written to the product file
+as homogeneous and typesetting
+it in \p{tt font}. A secondary goal was to provide
+a \i{typesetter} independent literate programming
+system. By this is meant that it be possible to create FunnelWeb input files
+that do not contain typesetter-specific commands.
+To a lesser extent this goal has also been achieved.
+
+The difficulty with providing typesetter-independent typesetting is that
+each desired typesetting feature must be recreated in a
+typesetter-independent FunnelWeb typesetting construct that FunnelWeb can
+translate into whatever typesetting language is being targeted by Weave.
+Taken to the extreme, this would result in FunnelWeb providing the full
+syntactic and semantic power of \TeX{}, but with a more generic,
+FunnelWeb-specific syntax. This was unfeasible in the time available, and
+undesirable as well.
+
+The compromise struck in the FunnelWeb design is to provide a set of
+primitive typesetter-independent typesetting features that are implemented
+by FunnelWeb. These are the \newterm{typesetter directives}.
+If the user is prepared to restrict to these directives,
+then the user's
+FunnelWeb document will be both target-language and typesetter independent.
+However, if the user wishes to use the more sophisticated features of the
+target typesetting system, the user can specify the typesetter
+in a \dqp{typesetter} pragma and then place typesetter commands
+in the free text
+of the FunnelWeb document where they will be passed verbatim to the
+documentation file. The choice of the trade-off between typesetter
+independence and typesetting power is left to the user.
+
+This said, experience with FunnelWeb V1 over a three year period,
+indicates that the typesetting facilities provided by FunnelWeb are
+sufficient for most documentation.
+
+\section{Command Line Interface}
+\xx{command line}{interface}
+
+\subsection{Invoking FunnelWeb}
+\xx{FunnelWeb}{invoking}\xx{FunnelWeb}{running}
+
+When a user invokes FunnelWeb at the operating system command level, the
+user must provide a command line instructing FunnelWeb what to do. Typically
+an operating system command line consists of a \i{verb} indicating that a
+particular program should be run, followed by a list of options. For example:
+
+\begin{verbatim}
+$ rename file1 file2
+\end{verbatim}
+
+In this case, the verb is \p{rename} and the command line options are
+\p{file1 file2}. The entire command line begins with the \p{\$} and ends with
+the \p{2}.
+
+Operating systems differ greatly in the depth with which
+they process their command\xx{command line}{processing}
+lines, ranging from systems that simply pass the entire command line string
+to the invoked program (\eg{}MSDOS) through to systems that perform complete
+command line parsing (\eg{}VMS). Syntax conventions vary considerably.
+
+So as to achieve maximum portability and consistency of invocation across
+different platforms, FunnelWeb reads its command line as a raw string and
+performs all its own parsing.\xx{command line}{parsing}
+This is portable because, at the very least, all
+operating systems allow invoked programs access to the raw command line.
+
+The command verb used to invoke FunnelWeb should be
+\dqp{fw}.\xx{fw}{command verb}
+
+\begin{verbatim}
+FunnelWeb_verb = "fw"
+\end{verbatim}
+
+If this verb is not available, some alternatives are
+\dqp{funweb}, \dqp{fun}, and \dqp{funnelweb}.
+The verbs \p{web} or \p{fweb} should be avoided
+as they are the names of other literate programming systems.
+
+\subsection{Command Line Arguments}
+\xx{command line}{argument}\xx{syntax}{command line}
+
+Following the verb is the body of the command line which
+FunnelWeb parses into
+zero or more \newterm{arguments} separated by runs
+of one or more blanks.
+
+\begin{verbatim}
+FunnelWeb_command_line = FunnelWeb_verb {{" "}+ argument}
+\end{verbatim}
+
+Because some operating systems convert
+their command line to upper case before handing it to the invoked program,
+FunnelWeb has been constructed so as to be \i{insensitive} to the case
+of its command line arguments.\xx{case}{dependence} However, when
+dealing internally with arguments, FunnelWeb \i{preserves} the case of
+its command line arguments so that it will be able to operate with
+operating systems (such as Unix\x{Unix})
+whose file names are case dependent.
+
+A valid FunnelWeb argument consists of a
+\newterm{sign}, an identifying \newterm{letter}, and an
+optional
+\newterm{string} with no spaces separating
+them.\xx{command line options}{syntax}\xx{options}{syntax}
+
+\begin{verbatim}
+argument = sign id_letter [non_blank_string]
+sign = "+" | "-" | "="
+id_letter = "B" | "C" | "D" | "F" | "H" |"I" | "J" | "K" |
+ "L" | "O" | "Q" | "S" | "T" | "W" | "X"
+\end{verbatim}
+
+In addition there is a special form of argument that does not begin with
+a sign.
+
+\begin{verbatim}
+argument = non_blank_string_not_beginning_with_+_=_or_-
+\end{verbatim}
+
+This form is exactly equivalent to the same string with \dqp{+F}
+prepended to it.
+
+The semantic effect of these arguments is
+defined in terms of \newterm{options} which are the
+internal parameters of FunnelWeb
+and which correspond closely with the set of legal command line arguments.
+FunnelWeb has a predefined set of options each identified
+by an identifying letter having two attributes: a \i{string}, and a
+\i{boolean}. The boolean determines whether an option is turned
+\i{on} or \i{off}. The string contains additional information
+depending on the option.
+
+When FunnelWeb starts up, its options have predefined default values.
+FunnelWeb then parses its command line sequentially from
+left to right
+executing the effect of each argument on the argument's corresponding
+option. The sign and the
+string components of the argument are processed \i{independently}.
+A sign of \p{+} turns the option on. A sign of \p{-} turns the option off.
+A sign of \p{=} leaves the option's boolean attribute unchanged. The argument
+string replaces the string of the corresponding
+option, unless the argument string is empty, in which case the
+option string is not changed.
+
+Because FunnelWeb processes its command line arguments from left to right,
+a later argument can cancel the effect of an earlier one.
+For example \p{fw +t -t} will result in the \p{t} option
+ending up \i{off}. This allows users to set up their own default arguments
+by defining a symbol in their operating system's command language. For
+example, a Unix user who wants FunnelWeb to delete all identical output
+files and create a documentation file on each run
+with a default \p{.typ} extension could simply place the following definition
+in their \dqp{.login} file.
+
+\begin{verbatim}
+alias fw fw +d +t.typ
+\end{verbatim}
+
+These default options can then later be easily overridden on the command line.
+
+\subsection{Options}
+\label{commandlineoptions}\x{options}\xx{list}{options}
+
+FunnelWeb's options are internal parameters which can be modified by
+corresponding arguments on FunnelWeb's command line. A description of each
+argument and option follows.
+
+\narrowthing{B1$\ldots$B6: Tracedumps:}{These\xx{B}{option}
+six\xx{tracedump}{options}\xx{dump}{option} options have been provided to
+assist in the debugging and testing
+of FunnelWeb. They determine which of six possible trace dumps are
+to be written to the listing file. Only the boolean attributes
+of these options are ever used. The six dumps are identified by the
+digits \p{1..6} as
+follows:\xx{dump}{mapped file}
+\xx{dump}{global line list}\xx{dump}{token list}
+\xx{dump}{macro table}\xx{dump}{document list}\xx{dump}{times}}
+
+\begin{enumerate}
+\item Dump a hexdump of each mapped input and include file.
+\item Dump the global line list created by the scanner.
+\item Dump the token list created by the scanner.
+\item Dump the macro table created by the parser.
+\item Dump the document list created by the parser.
+\item Dump a table summarizing CPU and real time usage.
+\end{enumerate}
+
+\narrowtext{Because these options are so closely related, a hack has been
+pulled to enable them to all to be controlled by the \p{B} argument.
+The
+string argument to the \p{B} argument determines which of the six options
+are to be affected by the sign. Examples: \p{+B134} turns on options \p{B1},
+\p{B3}, and \p{B4}. \p{-B1} turns off option \p{B1}.
+\p{Default:~-B123456}.}
+
+\narrowthing{B7: Determinism:}{If the \p{B7} option is turned on,
+FunnelWeb suppresses the output of anything
+non-deterministic,\x{non-determinism}
+or machine dependent. This assists in regression testing.
+Only the boolean attribute is used in this option.
+This option is controlled by the \p{B7} argument which falls under the
+same argument syntax as the other \p{B} options. Examples: \p{+B7}, \p{-B7}.
+\p{Default:~-B7}.}
+
+\narrowthing{C: Listing File Context:}{The\xx{C}{option}
+\p{C}\xx{listing file}{context}
+option is always turned on and
+cannot be turned off. Its only attribute is a number which determines the
+number of lines of context that the lister will place around lines flagged
+with diagnostics in the listing file (if a listing file is written).
+A value of 100 indicates infinite context\xx{infinite}{context}
+which means that the entire
+listing file will be written out if a single diagnostic occurs.
+The value of this number can be specified by specifying it as a string of
+decimal digits to the \p{+C} argument. Examples: \p{+C100}, \p{+C10}.
+\p{Default:~+C2}.}
+
+\narrowthing{D: Delete Identical Output Files:}{Only the boolean
+attribute of this option is used.\xx{D}{option}\xx{delete output}{option}
+When turned on, the option causes the suppression (deletion)
+of product files and documentation files
+(but not listing or journal files) that
+are identical to the currently existing files of the same name. For example,
+if FunnelWeb is instructed to generate \p{stack.h} as an product file, and
+the text to be written to \p{stack.h} is identical to the currently existing
+\p{stack.h}, then FunnelWeb will simply not write any product file, leaving the
+currently existing \p{stack.h} as it is (and in particular leaving the
+file's date attribute the same).
+This prevents unnecessary \p{make} propagations. For example, in a C program,
+if \p{stack.fw} is a
+FunnelWeb input file that generates \p{stack.h} and \p{stack.c},
+a modification to \p{stack.fw} that affects \p{stack.c} but does not
+affect \p{stack.h} will not provoke the recompilation of modules
+that \p{\#include stack.h}, so long as the intervening FunnelWeb run has
+\p{+D} set. Examples: \p{-D}, \p{+D}. \p{Default:~-D}.}
+
+\narrowthing{F: FunnelWeb Input File:}{If\xx{F}{option}
+this option is turned on, FunnelWeb\xx{input file}{option}
+processes the input file whose name is specified by the option string.
+Examples: \p{+Fsloth.fw}, \p{+Fwalrus}, \p{-F}.
+\p{Default:~-F}.}
+
+\narrowthing{H: Display Help Message:}{If\xx{H}{option}
+this option\xx{help}{option} is turned on, FunnelWeb
+displays the message specified by the argument string.
+Each message has a name. The main help message is called \dqp{menu}
+and contains a list of the other help messages. Examples: \p{+Hregistration},
+\p{+Hoptions}. \p{Default:~-Hmenu}.}
+
+\narrowthing{I: Include default file specification:}{This\xx{I}{option}
+option\xx{include file}{option}\xx{include}{file} is always turned
+on and cannot be turned off. Its string attribute is used as the default file
+specification for include files. Usually this option is used to specify
+a directory from which include files should be obtained.
+Examples: \p{=I/usr/dave/includes/}. \p{Default:~+I}.}
+
+\narrowthing{J: Journal File:}{If\xx{J}{option} this option is turned on,
+FunnelWeb generates a\xx{journal file}{option}\xx{journal}{file}
+journal file. A journal file contains a log of
+all the console input and output to FunnelWeb during a single invocation of
+the FunnelWeb program (Note: The \p{Q} option does not affect this.).
+The journal file is particularly useful for examining what happened during
+a FunnelWeb shell run. The string attribute is the name of the journal
+file. Examples: \p{+Jjournfile}, \p{-J}. \p{Default:~-J}.}
+
+\narrowthing{K: Keyboard:}{If\xx{K}{option}
+this option\xx{keyboard}{option}\xx{interactive}{option}
+is turned on, FunnelWeb enters an
+interactive mode in which the user can enter FunnelWeb shell commands
+interactively. The string attribute is unused.
+Examples: \p{+K}, \p{-K}. \p{Default:~-K}.}
+
+\narrowthing{L: Listing File:}{If\xx{L}{option}
+this option is turned on, FunnelWeb
+generates a\xx{listing file}{option}\xx{listing}{file}
+listing file containing a summary of a run on FunnelWeb proper.
+The string argument is the name of the listing file to be created.
+Examples: \p{+L}, \p{-L}, \p{+Llisting.lis}.
+\p{Default:~-L}.}
+
+\narrowthing{O: Product Files:}{If this option is turned on,
+FunnelWeb generates a product file for each macro in the input file
+that is bound to an output file. The string attribute contributes to the
+name of the product files. This option is controlled
+by the \p{O} argument
+because product files used to be called \dq{\b{O}utput files}).
+Examples: \p{-O}, \p{+O/usr/dave/product/}. \p{Default:~+O}.}
+
+\narrowthing{Q: Quiet:}{If\xx{Q}{option} this option is turned on,
+FunnelWeb suppresses all\xx{quiet}{option}\xx{suppress}{console output}
+output to the screen (standard output) unless one or more errors occur,
+in which case a single line summarizing the errors is sent to standard
+output at the end of the run. If this option is turned off, FunnelWeb
+writes to the console in its normal garrulous way. The string
+attribute is unused in this option. Examples: \p{-Q}, \p{+Q}. \p{Default:~-Q}.}
+
+\narrowthing{S: Screen:}{If\xx{S}{option} this option is turned on,
+FunnelWeb writes all\xx{screen}{option}
+diagnostics to the screen (standard output)
+as well as to the listing file.
+By default, they are sent only to the listing file.
+This option has a single numerical attribute
+that can be specified as a decimal string in the string component of the
+\p{S} argument. The number is the number of lines of context that should
+surround each diagnostic sent to the screen.\x{context}
+Examples: \p{-S}, \p{+S6}, \p{+S0}. \p{Default:~-S}.}
+
+\narrowthing{T: Documentation file:}{If\xx{T}{option} this
+option\footnote{This option is controlled by the \p{T} command line
+argument because documentation files used to be called typesetter files.} is
+turned on, FunnelWeb\xx{typeset}{option}\xx{typeset}{file}
+generates a documentation file in \TeX{} format.
+The string argument contributes to the
+name of the documentation file to be created.
+By default this option is turned off, as experience has
+shown that most FunnelWeb runs are made during program development;
+documentation runs occur far more rarely. Examples: \p{-T},
+\p{+Tsloth.tex}. \p{Default:~-T}.}
+
+\narrowthing{W: Width of Product Files:}{If\xx{W}{option}
+this option\xx{width}{option}\xx{product file}{width}
+is turned on, a limit is
+placed on the length of lines in product files generated during the
+run. Lines that breach the limit are flagged with error messages.
+This option has a single numerical attribute
+that can be specified as a decimal string in the string component of the
+\p{W} argument. The number is the specified maximum width.
+This option is one of two limits that are placed on the width of
+product files. The other limit is an attribute of the input file that
+defaults to 80 characters,
+but can be raised or lowered using an output line length
+pragma. The width that is enforced is the lower of this value and the
+value of the \p{W} option (if turned on).
+Examples: \p{-W}, \p{+W100}. \p{Default:~-W80}.}
+
+\narrowthing{X: Execute:}{If\xx{X}{option}
+this option\xx{execute script}{option}
+is turned on, FunnelWeb executes the FunnelWeb shell
+script file specified by the string attribute.
+Examples: \p{+Xmaster}, \p{-X}.
+\p{Default:~-X}.}
+
+\section{File Name Inheritance}
+\xx{filename}{inheritance}
+
+During a single run of FunnelWeb, FunnelWeb can produce many different
+output files. As it would be very tedious to have to specify the name
+of each of these files explicitly each time FunnelWeb is run, FunnelWeb
+provides a system of defaults that allows the user to specify the minimum
+required to successfully complete the run. To do this FunnelWeb allows
+file specifications to inherit fields from one another.
+
+FunnelWeb structures filenames into three fields\xx{filename}{fields}
+which are inherited
+independently. The fields are: \newterm{directory}, \newterm{name},
+and \newterm{extension}.
+On systems having other fields (\eg{}\i{network node}, \i{device name}),
+the extra fields are considered to be part of the directory field.
+Version numbers are
+ignored. A field can inherit a value if its current value is
+the empty string.
+
+The following table gives the full inheritance scheme used in FunnelWeb.
+
+\begin{center}
+\begin{tabular}{|l|l|l|l|l|l|l|} \hline
+Script & Input & Include & Journal & List & Document & Product \\ \hline
+ & & \p{@i} & & & & \p{@o} \\
+\p{+x} & \p{+f} & \p{+i} & \p{+j} & \p{+l} & \p{+t} & \p{+o} \\
+\dqp{.fws} & \dqp{.fw} & \dqp{.fwi} & \dqp{.jrn} & \dqp{.lis} & \dqp{.tex} & \\
+ & & \p{+f} & \p{+f} & \p{+f} & \p{+f} & \\
+DefDir & Defdir & Defdir & Defdir & Defdir & Defdir & Defdir \\ \hline
+\end{tabular}
+\end{center}
+
+The table is arranged with items of highest priority at the top.
+The \dqp{+<letter>} cells refer to the file
+specification supplied in the given command line argument.
+\dqp{+F} is the name of the input file.
+\dq{Defdir} refers to the default directory
+specification provided by the operating system. Empty cells
+do not contribute.
+
+The following example shows how the table is used.
+Suppose that the user invoked FunnelWeb as
+follows:\xx{filename inheritance}{example}
+
+\begin{verbatim}
+fw /usr/ross/work/sloth.fw +twalrus
+\end{verbatim}
+
+To work out what the documentation file should be called, FunnelWeb starts
+with the empty string and then works down the Document column of the table.
+The top entry is empty
+so we ignore it and proceed to the second entry which consists of \dqp{+T}.
+The user specified the string \dqp{walrus} as the value of this option, and
+as our current (empty)
+string does not have a name field, we insert the string
+\dqp{walrus} into the name field, resulting in the string \dqp{walrus}.
+Moving down to the next row, we encounter the constant string \dqp{.tex}.
+This string consists of an empty directory and name field, but a \dqp{.tex}
+file extension. As our current string \dqp{walrus}, does not already
+have a file extension (\ie{}the file extension field of our current string
+is empty), we add in \dqp{.tex},
+resulting in the string \dqp{walrus.tex}. Next we encounter the \dqp{+F} field
+which is the input filename \dqp{/usr/ross/work/sloth.fw} consisting of
+a directory field \dqp{/usr/ross/work/}, a name field \dqp{sloth}, and a
+file extension field \dqp{.fw}. Our \dqp{walrus.tex} string already has
+name and file extension fields, but its directory field is empty, and
+so we add in the directory field from the input file specification,
+resulting in the string \dqp{/usr/ross/work/walrus.tex}. Finally, we hit
+the default directory specification, which is (say)
+\dqp{/usr/ross/play/}. However, as the directory field of our walrus
+string is already full, it has no effect.
+
+In general, there is no need to remember the exact details of FunnelWeb's
+filename inheritance. The important thing is to know that it exists, and to
+use it.
+
+\section{FunnelWeb Startup}
+\xx{FunnelWeb}{startup}\xx{FunnelWeb}{initialization}
+
+FunnelWeb's command line options can be divided into two groups.
+\newterm{Action options} instruct FunnelWeb to performs some sort of
+independent action such as processing a file. \newterm{Ordinary options}
+merely modify the way in which FunnelWeb executes the actions.
+
+The four action options are: \p{+F}, \p{+K}, \p{+X}, and \p{+H}. For
+FunnelWeb to be successfully invoked, at least one action option must be
+specified. If zero action options are specified, FunnelWeb terminates
+with failure status.
+If more than one action option is specified, FunnelWeb performs
+the specified actions in a predefined order.
+
+Assuming that the user has specified at least one action, the order in which
+actions are executed is as follows:\xx{action execution}{order}
+
+\narrowthing{Initialization script:}{FunnelWeb\xx{initialization}{script}
+starts by
+looking in the current
+directory for a file called \dqp{fwinit.fws}.\x{fwinit.fws}
+If it doesn't find one, it
+doesn't raise any error. If it does find one, it executes it as a FunnelWeb
+shellscript. Initialization scripts are useful for setting up FunnelWeb
+options (\eg{}using the \dqp{set}
+command without having to type them each time).}
+
+\narrowthing{Execute argument script:}{If a shellscript has been specified
+using the \dqp{+X} option, FunnelWeb executes it.}
+
+\narrowthing{Process input file:}{If the user has specified an input file
+using the \dqp{+F} option, then this is processed next (by FunnelWeb proper).}
+
+\narrowthing{Display help message:}{If the user requested,
+using the \dqp{+H} option, that a help message be displayed,
+the message is displayed at this time.}
+
+\narrowthing{Interactive mode:}{If the user specified the
+\dqp{+K} option, FunnelWeb enters interactive (keyboard) mode.}
+
+FunnelWeb processes these actions in the above order regardless of the
+order in which they appear on the command line.
+
+It may be hard to see how some of these actions might be combined.
+Nevertheless, FunnelWeb allows this. For example, a user might wish
+to process a batch of files as specified in a script (\dqp{+Xscript.fws}),
+be reminded of the interactive commands available (\dqp{+Hcommand}), and
+then enter interactive mode so as to be able to
+reprocess files for which FunnelWeb
+reported errors (after correcting the errors in a different
+workstation window).
+
+
+\section{Scanner}
+\x{scanner}
+
+The scanner reads in the input file and produces a list of tokens
+which it hands onto the parser. In addition, some input constructs may cause
+the scanner to modify some of FunnelWeb's options.
+
+\subsection{Basic Input File Processing}
+
+In order to read in an input file or include file, the scanner calls a
+submodule called the \newterm{mapper}
+that reads a file in and creates a contiguous copy of
+it in memory. The scanner then performs three checks on the file, the first
+(file termination) of
+which is performed before scanning commences, and the other two of which take
+place during scanning before each line is scanned.
+
+\narrowthing{File Termination:}{The\xx{file}{termination}
+first check the scanner makes\xx{line}{termination}
+is whether
+the file is terminated properly. A file is considered to be properly
+terminated if it either contains no lines, or if the last line in the file
+is terminated by an end-of-line marker. If the scanner detects that an
+input file is not properly terminated, it adds an end-of-line marker
+itself (to the copy in memory only).}
+
+\narrowthing{Unprintable Characters:}{The second check the
+scanner makes is for\xx{unprintable}{characters}
+unprintable characters (ASCII 0--31 and 127--255
+(except for EOL(10))) which it flags
+as errors and replaces by question marks.}
+
+\narrowthing{Line Lengths:}{The third check
+the scanner makes is input line length.\xx{line}{length}
+When FunnelWeb starts up, a default maximum
+input line length of 80 is set. This can be changed dynamically during scanning
+using a \p{@p maximum\_input\_line\_length} pragma.
+If the number of characters on a line (not including the end of line marker)
+exceeds this limit, FunnelWeb generates an error.\checked{}}
+
+\subsection{Special Sequences}
+\xx{special}{sequences}
+
+The scanner scans the input file from top to bottom, left to right, treating
+the input as ordinary text (to be handed directly to the parser as a text
+token) unless it encounters the \newterm{special character}\footnote{This sort
+of character is often referred to as the \dq{escape character} or the
+\dq{control character} in other
+systems. However, as there is great potential to confuse these names
+with the \dq{escape} character (ASCII 27) and ASCII \dq{control} characters,
+the term \dq{special} has been chosen instead. This results in the terms
+\i{special character} and \i{special sequence}.} which introduces
+a \newterm{special sequence}. Thus, the
+scanner partitions the input file into ordinary text and special sequences.
+
+\begin{verbatim}
+input_file = {ordinary_text | special_sequence}
+\end{verbatim}
+
+Upon startup, the special character\xx{default}{special character}
+is \p{@}, but it can
+be changed using the $<$special$>$\p{=}$<$new\_special$>$ special sequence.
+Rather than using $<$special$>$ whenever the special character appears,
+this document uses the default special character \dqp{@} to represent the
+current special character.
+More importantly, FunnelWeb's
+error messages all use the default special character in their error messages
+even if the special character has been changed.
+
+An occurrence of the special character in the input file introduces a
+special sequence. The kind of special sequence is determined by the
+character following the special character. Only printable characters can
+follow the special character.
+
+The following list gives all the possible characters that can follow the
+special character, and the legality of each sequence.
+The first column gives the ASCII number of each ASCII character. The second
+column gives the special sequence for that character. The next column contains
+one of three characters: \dqp{-} means that the sequence is illegal. \dqp{S}
+indicates that the sequence is a \newterm{simple sequence} (with no attributes
+or side effects) that appears exactly as shown and is
+converted directly into a token and fed to the parser. Finally, \dqp{C}
+indicates that the special sequence is complex, possibly having a following
+syntax or producing funny side effects.
+
+\begin{verbatim}
+ASC SEQ COMMENT
+-----------------
+000 \
+016 | Unprintable characters and hence illegal specials.
+031 /
+032 @ - Illegal (space).
+033 @! C Comment.
+034 @" S Parameter delimeter.
+035 @# C Short name sequence.
+036 @$ S Start of macro definition.
+037 @% - Illegal.
+038 @& - Illegal.
+039 @' - Illegal.
+040 @( S Open parameter list.
+041 @) S Close parameter list.
+042 @* - Illegal.
+043 @+ C Insert newline.
+044 @, S Parameter separator.
+045 @- C Suppress end of line marker.
+046 @. - Illegal.
+047 @/ S Open or close emphasised text.
+048 @0 - Illegal.
+049 @1 S Formal parameter 1.
+050 @2 S Formal parameter 2.
+051 @3 S Formal parameter 3.
+052 @4 S Formal parameter 4.
+053 @5 S Formal parameter 5.
+054 @6 S Formal parameter 6.
+055 @7 S Formal parameter 7.
+056 @8 S Formal parameter 8.
+057 @9 S Formal parameter 9.
+058 @: - Illegal.
+059 @; - Illegal.
+060 @< S Open macro name.
+061 @= C Set special character.
+062 @> S Close macro name.
+063 @? - Illegal. Reserved for future use.
+064 @@ C Insert special character into text.
+065 @A S New section (level 1).
+066 @B S New section (level 2).
+067 @C S New section (level 3).
+068 @D S New section (level 4).
+069 @E S New section (level 5).
+070 @F - Illegal.
+071 @G - Illegal.
+072 @H - Illegal.
+073 @I C Include file.
+074 @J - Illegal.
+075 @K - Illegal.
+076 @L - Illegal.
+077 @M S Tag macro as being allowed to be called many times.
+078 @N - Illegal.
+079 @O S New macro attached to product file. Has to be at start of line.
+080 @P C Pragma.
+081 @Q - Illegal.
+082 @R - Illegal.
+083 @S - Illegal.
+084 @T C Typesetter directive.
+085 @U - Illegal.
+086 @V - Illegal.
+087 @W - Illegal.
+088 @X - Illegal.
+089 @Y - Illegal.
+090 @Z S Tags macro as being allowed to be called zero times.
+091 @[ - Illegal. Reserved for future use.
+092 @\ - Illegal.
+093 @] - Illegal. Reserved for future use.
+094 @^ C Insert control character into text
+095 @_ - Illegal.
+096 @` - Illegal.
+097 @a \
+109 @m | Identical to @A..@Z.
+122 @z /
+123 @{ S Open macro body/Open literal directive.
+124 @| - Illegal.
+125 @} S Close macro body/Close literal directive.
+126 @~ - Illegal.
+127 to 255 are not standard printable ASCII characters and are illegal.
+\end{verbatim}
+
+The most important thing to remember about the scanner is that \i{nothing
+happens unless the special character is seen.} There are no funny sequences
+that will cause strange things to happen. The best way to view a FunnelWeb
+document at the scanner level is as a body of text punctuated by special
+sequences that serve to structure the text at a higher level.
+
+The remaining description of the scanner consists of a detailed description
+of the effect of each complex special sequence.
+
+\subsection{Setting the Special Character}
+\xx{setting}{special character}
+
+The special character can be set using the sequence
+$<$special$>$\p{=}$<$newspecialchar$>$. For example, \p{@=\#} would change the
+special character to a hash (\p{\#}) character. The special character may
+be set to any printable ASCII character except the blank character
+(\ie{}any character in the ASCII range $[33,126]$). In normal use, it
+should not be necessary to change the special character of FunnelWeb, and it
+is probably best to avoid changing the special character so as not to
+confuse FunnelWeb readers conditioned to the \p{@} character.
+However, the feature is very useful where the text being prepared contains
+many \p{@} characters (\eg{}a list of internet electronic mail addresses).
+
+\subsection{Inserting the Special Character into the Text}
+\xx{special character}{inserting into text}
+
+The special sequence $<$special$>$\p{@} inserts the special character
+into the text as if it were not special at all. The \p{@} of this
+sequence has nothing to do with the current special character. If the
+current special character is \p{P} then the sequence \p{P@} will insert
+a \p{P} into the text. Example: \p{@@\#@=\#@\#@\#=@@@} translates
+to \p{@\#@\#@}.
+
+\subsection{Inserting Arbitrary Characters into the Text}
+\xx{arbitrary characters}{inserting into text}
+\xx{control characters}{inserting into text}\x{@circumflex}
+
+While FunnelWeb does not tolerate unprintable characters in the input file
+(except for the end of line character),
+it does allow the user to specify that unprintable characters appear in the
+product file. The \p{@\circumflex{}} sequence inserts a single character
+of the user's choosing into the text.
+The character can be specified by giving its
+ASCII number in one of four bases:
+binary, octal, decimal, and hexadecimal. Here is the syntax:
+
+\begin{verbatim}
+control_sequence = "@^" char_spec
+char_spec = binary | octal | decimal | hexadecimal
+binary = ("b" | "B") "(" {binary_digit}8 ")"
+octal = ("o" | "O" | "q" | "Q") "(" {octal_digit}3 ")"
+decimal = ("d" | "D") "(" {decimal_digit}3 ")"
+hexadecimal = ("h" | "H" | "x" | "X") "(" {hex_digit}2 ")"
+binary_digit = "0" | "1"
+octal_digit = binary_digit | "2" | "3" | "4" | "5" | "6" | "7"
+decimal_digit = octal_digit | "8" | "9"
+hex_digit = decimal_digit | "A" | "B" | "C" | "D" | "E" | "F"
+ | "a" | "b" | "c" | "d" | "e" | "f"
+\end{verbatim}
+
+Example:
+
+\begin{verbatim}
+@! Unix Make requires that productions commence with tab characters.
+@^D(009)prog.o <- prog.c
+\end{verbatim}
+
+Note that the decimal \dqp{9} is expressed with leading zeros
+as \dqp{009}. FunnelWeb requires
+a fixed number of digits for each base. Eight digits for base two, three
+digits for base ten, three digits for base eight and two digits for base
+sixteen.
+
+FunnelWeb treats the character resulting from a
+\p{@\circumflex{}} sequence as ordinary text in every sense.
+If your input file contains many instances of a particular control
+character,
+you can package it up in a macro like any other text. In particular,
+quick names can be used to great effect:
+
+\begin{verbatim}
+@! Unix "Make" requires that productions commence with tab characters.
+@! So we define a macro with a quick name as a tab character.
+$@#T@{@^D(009)@}
+@! And use it in our productions.
+@#Tprog.o <- prog.c
+@#Ta.out <- prog.o
+\end{verbatim}
+
+Warning: If you insert a Unix\x{Unix newline}
+newline character (decimal 10) into the text,
+FunnelWeb will treat this as an end of line sequence regardless of what
+the character sequence for end of line is on the machine upon which it is
+running. Unix EOL is FunnelWeb's internal representation for end of line.
+Thus, in the current version of FunnelWeb, inserting character 10 into the
+text is impossible unless this also happens to be
+the character used by the operating system to mark the end of line.
+
+\subsection{Comments}
+\xx{comments}{FunnelWeb}
+
+When FunnelWeb encounters the \p{@!}\x{@!}
+sequence during its left-to-right scan
+of the line, it throws away the rest of the line (including the EOL)
+without analysing it further.
+Comments can appear in any line except \dqp{@i},
+\dqp{@t}, and \dqp{@p} lines.
+
+FunnelWeb comments can be used to insert
+comments into your input file that will
+neither appear in the product files nor in the documentation file,
+but will be
+solely for the benefit of those reading and editing the input
+file directly. Example:
+
+\begin{verbatim}
+@! I have used a quick macro for this definition as it will be used often.
+@$@#C@{--@}
+\end{verbatim}
+
+Because comments are defined to include the end-of-line marker,
+care must be taken when they are being added or removed within the text
+of macro bodies. For example
+the text fragment
+
+\begin{verbatim}
+for (i=0;i<MAXVAL;i++) @! Print out a[0..MAXVAL-1].
+ printf("%u\n",a[i]);
+\end{verbatim}
+
+will expand to
+
+\begin{verbatim}
+for (i=0;i<MAXVAL;i++) printf("%u\n",a[i]);
+\end{verbatim}
+
+This problem really has no solution; if FunnelWeb comments were defined to
+omit the end of line marker, the expanded text would contain trailing blanks!
+As it is, FunnelWeb comments are designed to support single line comments
+which can be inserted and removed as a line without causing trouble.
+For example:
+
+\begin{verbatim}
+@! Print out a[0..MAXVAL-1].
+for (i=0;i<MAXVAL;i++)
+ printf("%u\n",a[i]);
+\end{verbatim}
+
+If you want a comment construct that does not enclose the end of line
+marker, combine the insert end of line construct \p{@+} with the comment
+construct \p{@!} as in
+
+\begin{verbatim}
+for (i=0;i<MAXVAL;i++) @+@! Print out a[0..MAXVAL-1].
+ printf("%u\n",a[i]);
+\end{verbatim}
+
+FunnelWeb comments should really only be used to comment the FunnelWeb
+constructs being used in the input file. Comments on the target code are
+best placed in comments in the target language or in the documenting text
+surrounding the macro definitions. In the example above, a C
+comment would have been more appropriate.
+
+\subsection{Quick Names}
+\xx{quick}{names}
+
+FunnelWeb provides a \newterm{quick name} syntax as an alternative,
+for macros whose name consists of a single character, to the
+angle bracket syntax usually used (\eg{}\p{@<Sloth@>}).
+A quick name sequence consists of \p{@\#}$x$\x{@hash}
+where $x$, the name of the macro,
+can be any printable character except space.
+
+\begin{verbatim}
+quick_name = "@#" non_space_printable
+\end{verbatim}
+
+The result is identical to the
+equivalent ordinary name syntax, but is
+shorter. For example, \p{@\#X} is equivalent to \p{@<X@>}.
+This shorter way of writing one-character macro names is more convenient where
+a macro must be used very often. For example, the macro calls in the
+following fragment of an Ada program are a little clumsy.
+
+\begin{verbatim}
+@! Define @<D@> as "" to turn on debug code and "--" to turn it off.
+@$@<D@>@{--@}
+@<D@>assert(b>3);
+@<D@>if x>7 then write("error") end if
+\end{verbatim}
+
+The calls can be shortened using the alternative syntax.
+
+\begin{verbatim}
+@! Define @#| as "" to turn on debug code and "--" to turn it off.
+@$@#|@{--@}
+@#|assert(b>3);
+@#|if x>7 then write("error") end if
+\end{verbatim}
+
+\subsection{Inserting End of Line Markers}
+\xx{EOL markers}{inserting}
+
+An end of line marker/character can be inserted into the text
+using the \p{@+}\x{@+} sequence. This is
+exactly equivalent to a real end of line in the text at the point where
+it occurs.
+While this feature may sound rather useless,
+it is very useful for laying out the input file. For
+example, the following input data for a database program
+
+\begin{verbatim}
+Animal = Kangaroo
+Size = Medium
+Speed = Fast
+
+Animal = Sloth
+Size = Medium
+Speed = Slow
+
+Animal = Walrus
+Size = Big
+Speed = Medium
+\end{verbatim}
+
+can be converted into
+
+\begin{verbatim}
+Animal = Kangaroo @+Size = Medium @+Speed = Fast @+
+Animal = Sloth @+Size = Medium @+Speed = Slow @+
+Animal = Walrus @+Size = Big @+Speed = Medium @+
+\end{verbatim}
+
+which is easier to read, and more easily allows comparisons between
+records.
+
+\subsection{Suppressing End of Line Markers}
+\xx{EOL markers}{suppressing}
+
+End of line markers can be suppressed by the \p{@-}\x{@-}
+sequence.
+A single occurrence of a \p{@-} sequence serves to suppress only the end of line
+marker following it and must appear \i{exactly} before the end of line marker to
+be suppressed. No trailing spaces, \p{@!} comments, or any other characters
+are permitted between a \p{@-} sequence and the end of line that it is
+supposed to suppress. The \p{@-} sequence is useful for constructing
+long output lines without them having to appear in the input.
+It can also be used in the same way as the \p{@+}
+was used in the previous section to assist in exposing the structure of output
+text without affecting the output text itself. Finally, it is invaluable for
+suppressing the EOL after the opening macro text \p{@\{} construct.
+For example:
+
+\begin{verbatim}
+@$@<Walrus@>@{@-
+I am the walrus!@}
+\end{verbatim}
+
+is equivalent to
+
+\begin{verbatim}
+@$@<Walrus@>@{I am the walrus!@}
+\end{verbatim}
+
+The comment construct (\p{@!}) can also be used to suppress end of lines.
+However, the \p{@-} construct should be preferred for this purpose as it
+makes explicit the programmer's intent to suppress the end of line.
+
+\subsection{Include Files}
+\xx{include}{files}
+
+FunnelWeb provides an include file facility with a maximum depth of 10.
+When FunnelWeb sees a line of the form \p{@i <filename>},\x{@i}
+it replaces the entire line (including the EOL) with the
+contents of the specified include file. FunnelWeb's include file
+facility is intended to operate at the line level. If the last line of the
+include file is not terminated by an EOL, FunnelWeb issues a warning
+and interts one (in the copy in memory).
+
+The
+\p{@i} construct is illegal if it appears anywhere except
+at the start of a line.
+The construct must be followed by a single blank. The file
+name is defined to be everything
+between the blank and the end of the line (no
+comments (\p{@!}) please!). Example: If the input file is
+
+\begin{verbatim}
+"Uh Oh, It's the Fuzz. We're busted!" said Baby Bear.
+@i mr_plod.txt
+"Quick! Flush the stash down the dunny and let's split." said Father Bear.
+\end{verbatim}
+
+and there is a file called \p{mr\_plod.txt} containing
+
+\begin{verbatim}
+"'Ello, 'Ello, 'Ello! What's all this 'ere then?" Mr Plod exclaimed.
+\end{verbatim}
+
+then the scanner translates the input file into
+
+\begin{verbatim}
+"Uh Oh, It's the Fuzz. We're busted!" said Baby Bear.
+"'Ello, 'Ello, 'Ello! What's all this 'ere then?" Mr Plod exclaimed.
+"Quick! Flush the stash down the dunny and let's split." said Father Bear.
+\end{verbatim}
+
+As a point of terminology, FunnelWeb calls the original input file the
+\newterm{input file} and calls include files and their included files
+\newterm{include files}.
+
+The include file construct operates at a very low level. An include
+line can appear anywhere in the input file regardless of the context
+of the surrounding lines.
+
+FunnelWeb sets the special character to the default (\p{@}) at the
+start of each include file and restores it to its previous value at the end
+of the include file. This allows macro libraries to be constructed and
+included that are independent of the prevailing special character
+at the point of inclusion.
+The same goes for the input line length limit
+which is reset to the default
+value at the start of each include file and
+restored to its previous value afterwards.
+
+\subsection{Pragmas}
+\x{pragmas}\xx{pragmas}{visible}\xx{pragmas}{invisible}
+
+Most tools have to support some essential, but rather inelegant features.
+In FunnelWeb these messy bits have all been stuffed into the
+scanner's \newterm{pragma} (for \i{pragma}tic) construct.
+
+A pragma consists of a single line of input (including the EOL)
+commencing with \p{@p}. This
+must be followed by a single space, and then the pragma verb.
+This must
+be followed by a sequence of zero or more arguments separated by one or
+more spaces. Four pragmas are available
+
+\begin{verbatim}
+pragma = pragma_ident | pragma_mill | pragma_moll | pragma_typesetter
+\end{verbatim}
+The following syntax definitions assist in defining the pragmas.
+
+\begin{verbatim}
+s = {" "}+
+ps = ("@p" | "@P") " "
+number = { decimal_digit }+
+numorinf = number | "infinity"
+\end{verbatim}
+
+The arguments to pragmas are case-sensitive and must be specified in
+lower case.
+
+Pragmas are processed and consumed entirely by the scanner. The parser
+never sees them and so they can play
+no part in the parser level syntax. As a result, pragma lines
+can appear anywhere in the entire input file regardless of the surrounding
+context (\eg{}even in the middle of a macro definition).
+The sole effect of a pragma is to modify some internal parameter of
+FunnelWeb.
+
+The following sections describe the four FunnelWeb pragmas.
+
+\subsubsection{Indentation}
+\label{indentationpragma}\xx{indentation}{macro expansion}
+
+When FunnelWeb expands a macro, it can do so in two ways. First it can treat
+the text it is processing as a one-dimensional stream of text, and merely
+insert the body of the macro in place of the macro call. Second, it can
+treat the text of the macro as a two dimensional object and
+indent each line of the macro body by the amount that the macro
+call itself was indented. Consider the following macros.
+
+\begin{verbatim}
+@$@<Loop Structure@>@{@-
+i=1;
+while (i<=N)
+ @<Loop body@>
+endwhile
+@}
+
+@$@<Loop body@>@{@-
+a[i]:=0;
+i:=i+1;@}
+\end{verbatim}
+
+Under the regime of \newterm{no indentation}\xx{indentation}{none}
+the loop structure
+macro expands to:
+
+\begin{verbatim}
+i=1;
+while (i<=N)
+ a[i]:=0;
+i:=i+1;
+endwhile
+\end{verbatim}
+
+Under the regime of \newterm{blank indentation}\xx{indentation}{blank}
+the loop structure macro expands to:
+
+\begin{verbatim}
+i=1;
+while (i<=N)
+ a[i]:=0;
+ i:=i+1;
+endwhile
+\end{verbatim}
+
+The \p{indentation} pragma determines which of these two regimes will be used
+to expand the macros when constructing the product files. The syntax of the
+pragma is:
+
+\begin{verbatim}
+pragma_ident = ps "indentation" s "=" s ("blank" | "none")
+\end{verbatim}
+
+Its two forms look like this:
+
+\begin{verbatim}
+@p indentation = blank
+@p indentation = none
+\end{verbatim}
+
+In the current version of FunnelWeb, the indentation regime is an attribute
+that is attached to an entire run of Tangle; it is not possible to bind it
+to particular product files or to particular macros. As a result, it doesn't
+matter where indentation pragmas occur in the input file or how many
+there are so long as they are all the same. By default FunnelWeb uses
+blank indentation.
+
+\subsubsection{Maximum Input Line Length}
+\label{millpragma}\xx{input}{line length}\xx{maximum}{input line length}
+
+FunnelWeb generates an error for each input line
+that exceeds a certain maximum number of characters. At the start of the
+processing of each input
+file and each include file, this maximum is set to a default value of 80.
+However,
+the maximum can be changed using a maximum input line length
+pragma.\xx{pragma}{input line length}
+
+\begin{verbatim}
+pragma_mill = ps "maximum_input_line_length" s "=" s numorinf
+\end{verbatim}
+
+The maximum input line length can be varied
+\i{dynamically} throughout the input file. Each maximum input line length
+pragma's scope covers the line following the pragma through to and including
+the next maximum input line length pragma, but not covering any intervening
+include files. At the start of an include file, FunnelWeb resets
+the maximum input line length to the default value. It restores it to
+its previous value at the end of the include file.
+
+This pragma is useful for detecting text that has strayed off the
+right side of the screen when editing. If you use FunnelWeb, and set the
+maximum input line length to be the width of your editing window, you will
+never be caught by, for example, off-screen opening comment symbols.
+You can also be sure that your source text can be printed raw, if necessary,
+without lines wrapping around.
+
+\subsubsection{Maximum Output File Line Length}
+\label{mollpragma}%
+\xx{maximum}{product file line length}%
+\xx{pragma}{maximum product file line length}%
+\xx{maximum}{output file line length}%
+\xx{pragma}{maximum output file line length}
+
+As well as keeping an eye on input line lengths, FunnelWeb also keeps an
+eye on the line lengths of product files and flags all lines longer
+than a certain limit with error messages.
+Unlike the
+maximum input line length, which can vary dynamically throughout the input
+file, the maximum product file line length remains fixed throughout the
+generation
+of all the product files. The maximum product file
+line length pragma allows this
+value to be set. If there is more than one such pragma in an input file, the
+pragmas must all specify the same value.
+
+\begin{verbatim}
+pragma_moll = ps "maximum_output_line_length" s "=" s numorinf
+\end{verbatim}
+
+The default value is 80 characters.
+
+This pragma is only one of two constraints on the length of the lines of the
+product files. The \p{+W} command line option also contributes.
+The actual value that FunnelWeb uses is the minimum of the limits
+specified in the command line and pragmas.
+
+FunnelWeb does not monitor the length of the lines of its other output files
+(journal file, listing file, documentation file).
+
+\subsubsection{Typesetter}
+\xx{typesetter}{pragma}\xx{typesetter}{independence}
+
+The \p{typesetter} pragma allows the user to specify whether the input
+file is supposed to be typesetter-independent, or whether it contains
+commands in a particular typesetter language. The pragma has the
+following syntax.
+
+\begin{verbatim}
+pragma_typesetter = ps "typesetter" s "=" s ("none" | "tex")
+\end{verbatim}
+
+The two forms of the pragma look like this.
+
+\begin{verbatim}
+@ typesetter = none
+@ typesetter = tex
+\end{verbatim}
+
+A source file can contain more than one typesetter pragma, but they must
+all specify the same value. The default is \p{none}.
+The typesetter setting affects two things:
+
+\narrowthing{Handling of free text:}{If the typesetter is not \p{none},
+Weave writes the free text \i{directly}
+to the documentation file without changing it whatsoever. This means that
+if (say) \p{\char`\\ centerline} appears in the input file, it will copied
+directly to the documentation file. If the typesetter is \p{none}, Weave
+intercepts any characters or sequences that might have a special
+meaning to the target typesetter and replaces them
+with typesetter commands to typeset the sequences so that they will appear
+as they do in the input. For example, if the typesetter is \p{none} and
+the target typesetter is \TeX{}, then if
+\p{\$} (the \TeX{} \dq{mathematics mode} character)
+appears in the input file, it will be
+be written to the documentation file as \p{\char`\\ \$}.}
+
+\narrowthing{Restrictions on the target typesetter:}{At a later date,
+different weave modules might be incorporated into FunnelWeb to cater
+for a variety
+of different typesetters. If this happens, it will be important to ensure
+that typesetter-specific source files
+(\ie{}\p{typesetter} $\ne$ \p{none}) are not processed with different
+target typesetters. For example, a user might innocently attempt to generate
+a \p{troff} documentation file from a
+FunnelWeb source file containing a \p{typesetter = tex} (and by
+implication \TeX{} control sequences). The pragma could also be useful
+for catching typesetter clashes in source and include files. The setting
+\p{none} is special because it is guaranteed to work with any
+future target typesetter.}
+
+The aim of all this is
+to ensure that any typesetter dependency is correctly proclaimed.
+Because \p{none} is the default typesetter,
+a user who creates a source file without a \p{typesetter = x} pragma
+will soon find that the control sequences they are inserting into
+the source document are appearing verbatim in the printed documentation!
+In order to activate these sequences, they will be forced to add a
+\p{typesetter} pragma, thus making the dependency explicit.
+
+It may seem strange to place the \p{typesetter} setting facility within
+a pragma (\p{@p}) when there is a separate typesetting construct (\p{@t}).
+This has been done to sustain the rule of thumb that says that
+pragmas do not participate in the parser-level syntax, but typesetter
+directives do.
+
+\subsection{Freestanding Typesetter Directives}
+\xx{typesetter}{directives}
+
+FunnelWeb provides two kinds of typesetter directive to assist the user
+to produce documentation. These are \newterm{inline} and
+\newterm{freestanding}. Unlike pragmas,
+each of these categories of directive participates in the parser-level
+syntax and can appear only in certain contexts (see the parser section).
+Inline directives are
+designed to be used within paragraphs to alter the look of the enclosed
+text. Freestanding typesetter directives are designed to
+appear on lines of their own and have a bigger typographical impact.
+
+The syntax of freestanding typesetter directives is almost identical to that
+of pragmas. All the same syntax rules apply (except that the actual
+keywords are different).
+The following subsections describe the four typesetter directives
+available.
+
+\begin{verbatim}
+ftd = ftd_newpage | ftd_toc | ftd_vskip | ftd_title
+ts = "@t "
+\end{verbatim}
+
+\subsubsection{New Page}
+\x{new page}\xx{pragma}{new page}
+
+The new page pragma is a typesetting pragma with the following syntax.
+
+\begin{verbatim}
+ftd_newpage = ts "new_page"
+\end{verbatim}
+
+It only form looks like this.
+
+\begin{verbatim}
+@t new_page
+\end{verbatim}
+
+Its sole effect is to cause a \dq{skip to a new page} command to be inserted
+into the documentation file.
+The new page command is such that if the typesetter is already at
+the top of a page, it will skip to the top of the next page.
+
+\subsubsection{Table of Contents}
+\xx{table of}{contents}\xx{pragma}{table of contents}
+
+The new page pragma is a typesetting pragma with the following syntax.
+
+\begin{verbatim}
+ftd_toc = ts "table_of_contents"
+\end{verbatim}
+
+It only form looks like this.
+
+\begin{verbatim}
+@t table_of_contents
+\end{verbatim}
+
+Its sole effect is to instruct Weave to insert a table of contents at
+this point in the printed documentation.
+This pragma does not skip to a top of a new page first.
+
+\subsubsection{Vertical Skip}
+\xx{vertical}{skip}\xx{pragma}{vskip}
+
+The vertical skip pragma is a typesetting pragma that
+instructs Weave to insert a specified amount of
+vertical space into the documentation. The pragma has the following syntax.
+
+\begin{verbatim}
+ftd_vskip = ts "vskip" s number s "mm"
+\end{verbatim}
+
+For example:
+
+\begin{verbatim}
+@t vskip 26 mm
+\end{verbatim}
+
+\subsubsection{Title}
+\x{title}\xx{pragma}{title}
+
+The title pragma is a typesetting pragma with the following syntax.
+
+\begin{verbatim}
+ftd_title = ts "title" s font s alignment text
+font = "normalfont" | "titlefont" | "smalltitlefont"
+alignment = "left" | "centre" | "right"
+text = """" {printable_char} """"
+\end{verbatim}
+
+It's effect is to instruct Weave to insert a single line
+into the printed documentation
+containing the specified text set in the specified font
+and aligned in the specified manner. The double quotes delimiting
+the text are for show only; if you want to put a double quote in the string,
+you don't need to double them.
+
+Here is an example of the pragma.
+
+\begin{verbatim}
+@t title smalltitlefont centre "How to Flip a Bit"
+\end{verbatim}
+
+\subsection{Scanner/Parser Interface}
+
+If the scanner terminates without any errors, control
+is passed to the parser. The parser parses the token list generated by
+the scanner. The token list consists of text scraps, freestanding
+typesetter directives,
+and special sequence tokens.
+
+The user should bear in mind that
+\i{the scanner finishes running before the
+parser starts running.} This means that the scanner cannot be influenced
+in any way by higher order structures such as the parser might parse.
+For example,
+it is impossible to write a FunnelWeb macro to include a file, or insert
+a \p{vskip} pragma into the input text.
+
+\section{Parser}
+\x{parser}
+
+By the time the parser starts, the scanner has completely terminated.
+At this point, it
+is not possible for any more files to be included, and special characters are
+no longer present to confuse things. All that remains is a list of
+\newterm{text tokens},
+\newterm{special tokens}, and \newterm{typesetter directive tokens}.
+Text tokens consist entirely of
+sequences of printable characters and end of line markers. Special tokens
+represent the special sequences that the scanner found in the input file.
+Typesetter directive tokens represent the freestanding typesetter directives
+that the scanner encountered.
+The parser consumes the token list and builds a macro table that is
+later used to generate product files. It also constructs
+a document list that is used to generate the documentation file.
+
+The syntax rules appearing in the following sections refer to the
+token list.
+
+\subsection{High Level Structure}
+\xx{syntax}{high level}
+
+At the highest level, the FunnelWeb parser parses the input file (token
+list) into a sequence of text scraps, macro definitions,
+and typesetter directives.
+
+\begin{verbatim}
+input_file = {text | macro | directive}
+\end{verbatim}
+
+All three of these kinds of components contribute to the documentation file,
+but only macro definitions
+contribute to the product files. If all the free text
+and directives were removed from a FunnelWeb input file, the
+product files would not be affected.
+
+\subsection{Free Text}
+\xx{free}{text}
+
+\newterm{Free text} is any text that is not part of a macro definition or a
+directive. A scrap of free text consists of a sequence of items drawn
+from the following list:
+non-special printable characters, insert-eol special
+sequences, insert special character special sequences, insert arbitrary
+character special sequence.
+
+\begin{verbatim}
+free_text = ordinary_text
+ordinary_text = {ordinary_char | eol | text_special}+
+text_special = "@+" | "@@" | "@^" char_spec
+ordinary_char = " ".."~"-special
+\end{verbatim}
+
+An example of some rather messy free text is as follows:
+
+\begin{verbatim}
+This@@ is a very@+ messy
+@^D(009)chunk of text indeed.
+But FunnelWeb still views it as
+a single chunk of text.
+\end{verbatim}
+
+FunnelWeb never sees two text chunks next to each other in the input;
+they are always merged into a single text token.
+
+The free text in an input file
+does not affect the product files. However, by default, it appears in the
+printed documentation exactly as it is given in the input file, except
+that it is filled and justified into paragraphs.
+
+Any printable character
+or particular sequence of characters
+may appear in the free text of a document. FunnelWeb ensures that they
+will appear exactly as given in the input file, even if they happen to be
+escape characters or commands in the target typesetter.
+However, FunnelWeb also provides a special mode that allows
+this censoring to be
+overridden. See Section~\label{typesetterpragma} for more information.
+
+\subsection{Typesetter Directives}
+\x{directives}
+
+FunnelWeb provides a variety of typesetter directives to assist the
+user to typeset the document in a typesetter-independent way. These are
+divided into \newterm{freestanding typesetter directives} (ftd) and
+\newterm{inline typesetter directives} (itd). The internal syntax of the
+freestanding typesetter directives has already been discussed
+in the scanner section. The following syntax rule defines
+the context in which these constructs can appear.
+
+\begin{verbatim}
+directive = ftd | itd
+itd = section | literal | emphasis
+\end{verbatim}
+
+The remainder of this section describes the inline typesetter directives.
+
+\subsubsection{Section}
+\xx{section}{constructs}
+
+The section directive
+provides a way for the user to structure the program and documentation into
+a hierarchical tree structure,\xx{tree}{structure}
+just as in most large documents.
+A section construct consists of a case-insensitive
+identifying letter, which determines the
+absolute level of the section in the document, and an optional section
+name, which has exactly the same syntax as a macro name.
+
+\begin{verbatim}
+section = "@" levelchar [name]
+levelchar = "A" | "B" | "C" | "D" | "E" |
+ "a" | "b" | "c" | "d" | "e"
+\end{verbatim}
+
+The section construct is not quite \dq{inline} as it must appear only
+at the start of a line. However, unlike the \dqp{@i}, \dqp{@p}, and
+\dqp{@t} constructs, it does not consume the remainder of the line
+(although it would be silly to place anything on the same line anyway).
+
+FunnelWeb provides five levels of sections, ranging from the highest level
+of \p{A} (like a \LaTeX{}\x{LaTeX}
+chapter) to the lowest level of \p{E} (like a \LaTeX{}
+subsubsubsection). FunnelWeb input files need not contain
+any sections at all, but if they do, the first section must be at level \p{A},
+and following sections must not skip hierarchical levels (\eg{}an \p{@D} cannot
+follow an \p{@C}). FunnelWeb generates an error if a level is skipped.
+
+All section \i{must} have names associated with them, but for convenience,
+the section name is optional if the section contains one or more
+macro definitions
+(\ie{}at least one macro definition appears between the section construct
+in question and the
+next section construct in the input file.). In this case, the section
+\i{inherits} the name of the first macro defined in the section. This
+feature streamlines the input file, avoiding duplicate name inconsistencies.
+
+Any sequence of printable characters can be used in the
+section name,\xx{section}{name}
+even the target typesetter's escape sequence (\eg{}in \TeX{},
+\dqp{\bs{}}).
+
+The following example demonstrates the section construct.
+
+\begin{verbatim}
+@A@<Life Simulation@>
+
+This is the main simulation module for planet earth, simulated down to the
+molecular level. This is a REALLY big program. I mean really big. I mean,
+if you thought the X-Windows source code was big, you're in for a shock...
+
+@B We start by looking at the code for six legged stick insects as they
+form a good example of a typical object-oriented animal implementation.
+
+@$@<Six Legged Stick Insects@>@{@-
+slsi.creep; slsi.crawl; slsi.creep;@}
+\end{verbatim}
+
+In the above example, the name for the level A section is provided
+explicitly, while the name for the level B section will be inherited from the
+macro name.
+
+\subsubsection{Literal Directive}
+\xx{literal}{directive}
+
+Experience has shown that one of the most common typesetting requirement
+is that of being able to typeset small program fragments
+in the middle of the documenting free text. Typically
+there is a frequent need to refer to program identifiers, and it
+assists the reader to have such identifiers typeset in the same manner
+as the program text in the macro definition.
+FunnelWeb~V1
+defined a \TeX{} macro for this (called \p{p}) that simply typeset its
+argument in \p{tt font}. This proved so
+useful, that the facility has been made typesetter-independent in
+FunnelWeb~V3.
+
+To specify that some text be typeset in \p{tt font},
+enclose the text in curly brace special sequences as follows.
+
+\begin{verbatim}
+literal = "@{" ordinary_text "@}"
+\end{verbatim}
+
+As in macro names, section names, and macro bodies, the text contained
+within the literal
+construct is protected by FunnelWeb from any non-literal interpretation by
+the typesetter and the user is
+free to enclose \i{any} text covered by the definition \p{ordinary\_text}.
+FunnelWeb guarantees that, no matter what the text is, it will
+be typeset in \p{tt font} exactly as it appears. However, the text will be
+filled and justified into a paragraph as usual.
+
+Here is an example of the use of the construct:
+
+\begin{verbatim}
+@C The @{WOMBAT@} (Waste Of Money, Brains, And Time) function
+calls the @{kangaroo@} input function which has been
+known to cause keybounce.
+This keybounce can be dampened using the @{wet_sloth@} subsystem.
+\end{verbatim}
+
+\subsubsection{Emphasis Directive}
+\xx{emphasis}{directive}
+
+The emphasis directive is very similar to the literal directive except that
+it causes its argument to be typeset in an emphasised manner
+(\eg{}italics). Like the literal directive,
+the emphasis directive protects its text argument.
+
+\begin{verbatim}
+emphasise = "@/" ordinary_text "@/"
+\end{verbatim}
+
+Example:
+
+\begin{verbatim}
+@C What you @/really@/ need, of course, is a @/great@/, @/big@/,
+network with packets just flying @/everywhere@/.
+This section implements an interface
+to such a @/humungeous@/ network.
+\end{verbatim}
+
+\subsection{Macros}
+\xx{macro}{definition}
+
+The third category of
+construct appearing at the highest syntactic level in a FunnelWeb
+input file is the macro definition.
+A macro definition binds a unique
+\newterm{macro name} to a \newterm{macro body} containing an
+\newterm{expression} consisting of text, calls to
+other macros, and formal parameters. The syntax for a macro definition is as
+follows:
+
+\begin{verbatim}
+macro = ("@O" | "@$") name [formal_parameter_list]
+ ["@Z"] ["@M"] ["==" | "+="] "@{" expression "@}"
+\end{verbatim}
+
+The complexity of the macro definition syntax is mostly to enable the user
+to attach various attributes to the macro.\xx{macro}{attributes}
+If the user chooses \p{@O},
+then the macro cannot be called, but is instead
+attached to a product file. If the user chooses \p{@\$}, then the macro is
+an ordinary macro definition that is not attached to a file.
+
+By default, a non-file macro must be invoked exactly once by one other
+macro. Macros that
+aren't are flagged with errors by the FunnelWeb analyser. However, if the
+user uses the \p{@Z}\x{@Z} sequence in the macro definition, the macro is then
+permitted to be invoked zero times, as well as once. Similarly, if the
+user uses the \p{@M}\x{@M}
+sequence in the macro definition, the macro is
+permitted to be called many times as well as once. If both \p{@Z} and
+\p{@M} are present then the macro is permitted to be invoked zero, one,
+or many times.
+
+The purpose of enforcing the default \dq{exactly one call} rule is to
+flag pieces of code that the user may have defined in a macro but not
+hooked into the rest of the program. Experience shows that this is a
+common error. Similarly, it can be dangerous to multiply invoke a
+macro intended to be invoked only once. For example, it may be dangerous
+to invoke a scrap of non-idempotent initialization code in two different
+parts of the main function of a program! However, FunnelWeb will not
+generate an error if a macro without \p{@M} is called by another
+macro that is called more than once.
+
+If the text string \p{==}\x{==} (or nothing) follows the macro name,
+the expression that follows
+is the entire text of the macro body. If the text string \p{+=}\x{+=}
+follows
+the macro name, then more than one such definition is allowed
+(but not required) in the document
+and the body of
+the macro consists of the concatenation of all such expressions in the order
+in which they occur in the input file. Such a macro is said to be
+additive and is
+\newterm{additively defined}. Thus a macro body can either be defined
+in one place using one definition (using \p{==}) or it can be \i{distributed}
+throughout the input file in a sequence of one or more macro definitions (using
+\p{+=}). If neither \p{==} and \p{+=} are present, FunnelWeb assumes a
+default of \p{==}.
+
+Macros attached to product files cannot be additively defined.
+Additively defined macros can have parameter lists and \p{@Z} and \p{@M}
+attributes, but these must be specified only in the first definition of the
+macro. However, \p{+=} must appear in each definition.
+
+\subsubsection{Names}
+\x{names}\xx{macro}{names}\xx{section}{names}
+
+Names are used to identify macros and sections.
+A name consists of a sequence of from zero to 80 printable characters,
+including the blank
+character. End of line characters are not permitted in names.
+Names are case sensitive; two different macros are permitted to have names
+that differ in case only. Like free text, names are typeset by FunnelWeb and
+are safe from misinterpretation by the target typesetter. For example, it
+is quite acceptable to use the macro name \p{@<\bs{}medskip@>}
+even if the target typesetter is \TeX{}.
+
+\begin{verbatim}
+name = "@<" name_text "@>"
+name_text = {ordinary_char | text_special}
+\end{verbatim}
+
+\subsubsection{Formal Parameter Lists}
+\xx{parameter lists}{formal}
+
+FunnelWeb allows macros to have up to nine macro parameters, named
+\p{@1},\x{@1...}
+\p{@2}, $\ldots$, \p{@9}. If a macro does not have a formal
+parameter list,
+it is defined to have no parameters, and an actual parameter list must not
+appear at the point of call. If a macro has a formal parameter list, it
+is defined to have one or more parameters, and a corresponding actual
+parameter must be supplied for each formal parameter, at the point of call.
+
+Because FunnelWeb parameters have predictable names, the only information
+that a formal parameter list need convey is \i{how many} parameters a macro
+has. For this reason a formal parameter list takes the form of the highest
+numbered formal parameter desired, enclosed in parentheses sequences.
+
+\begin{verbatim}
+formal_parameter_list = "@(" formal_parameter "@)".
+formal_parameter = "@1" | "@2" | "@3" | "@4" | "@5" |
+ "@6" | "@7" | "@8" | "@9"
+\end{verbatim}
+
+\subsection{Expressions}
+\xx{macro}{expressions}
+
+Expressions are FunnelWeb's most powerful form of expressing a text
+string.
+Macro bodies are defined as expressions. Actual parameters consist of
+expressions.
+
+An expression consists of a sequence of zero or more expression elements.
+An expression element can be ordinary text, a macro call, or a formal
+parameter of the macro \i{definition} in which the formal parameter occurs.
+
+\begin{verbatim}
+expression = {ordinary_text | macro_call | formal_parameter}
+\end{verbatim}
+
+\subsection{Macro Calls}
+\xx{macro}{calls}
+
+A macro call consists of a name optionally followed by an actual parameter
+list. The
+number of parameters in the actual parameter list must be the same as
+the number of formal parameters specified in the definition of the
+macro. If the macro has no formal parameter list, its call must have no
+actual parameter list.
+
+\begin{verbatim}
+macro_call = name [actual_parameter_list]
+actual_parameter_list = "@(" actpar { "@," actpar } "@)"
+actpar = expression |
+ ( whitespace "@""" expression "@""" whitespace )
+whitespace = {" " | eol}
+\end{verbatim}
+
+FunnelWeb allows parameters to be passed directly, or delimited by
+special double
+quotes.\xx{macro parameter}{delimiting}
+Each form is useful under different circumstances. Direct specification
+is useful where the parameters are short and can be all placed on one line.
+Double quoted parameters allow whitespace on either side
+(that is not considered part of the parameter) and are useful for laying out
+rather messy parameters. Here are examples of the two forms.
+
+\begin{verbatim}
+@<Generic Loop@>@(
+ @"x:=1;@" @,
+ @"x<=10;@" @,
+ @"print "x=%u, x^2=%u",x,x*x;
+ x:=x+1;@+@"
+@)
+
+@<Colours@>@(red@,green@,blue@,yellow@)
+\end{verbatim}
+
+As shown, the two forms may be mixed within the same parameter list.
+
+Experience has shown that the vast majority of macros have no parameters.
+
+\subsection{Formal Parameters}
+\xx{formal}{parameters}
+
+Formal parameters can appear in the expressions forming macro bodies
+in accordance with the syntax rules defined above. A formal parameter
+expands to the text of the expansion of its corresponding
+actual parameter. There is nothing preventing a formal
+parameter being provided as part of an expression that forms an actual
+parameter.
+In that happens, the formal parameter is bound to the actual parameter of the
+calling macro, not the called macro.
+After the following definitions,
+
+\begin{verbatim}
+@$@<One@>@(@1@)=@{A walrus in @1 is a walrus in vain.@}
+@$@<Two@>@(@1@)=@{@<One@>@(S@1n@)@}
+\end{verbatim}
+
+the call
+
+\begin{verbatim}
+@<Two@>@(pai@)
+\end{verbatim}
+
+will result in the expansion
+
+\begin{verbatim}
+A walrus in Spain is a walrus in vain.
+\end{verbatim}
+
+\subsection{Macros are Static}
+\xx{macro}{definition}\xx{macro}{expansion}\xx{macros}{static}
+
+In FunnelWeb, the actions of \i{macro definition} and \i{macro
+expansion} occur during two separate phases (parser and tangle)
+and cannot be interleaved. As a result, the FunnelWeb macro facility is
+completely static.
+It is not possible for one macro to
+define another while the first macro is being
+expanded; each must be defined statically. It is not possible to define a
+macro to even assist in the definition of other macros. Because the scanner,
+parser, analyser, and tangler phases are all invoked sequentially, there is
+no room for feedback of definitions between different levels (\eg{}the user
+cannot define a macro for the \p{vskip} pragma).
+
+This lack of power is fully intentional. By totally excluding the more
+incomprehensible ways in which a general purpose macro preprocessor can be
+used, FunnelWeb provides definite guarantees to the reader of its input files:
+
+\begin{itemize}
+\item FunnelWeb guarantees that a piece of text does not contain a macro call
+unless it contains the special character followed by \p{$<$} or \p{\#}.
+\item FunnelWeb allows calls to be made to macros that are defined later
+in the input file.
+\end{itemize}
+
+\section{Analyser}
+\x{analyser}\xx{checks}{macro}
+
+The effect of the parser is to construct a macro table containing a
+representation of all the macros defined within the document, and a document
+list which contains a complete representation of the entire document.
+If there are no error diagnostics (or worse) at the end of the parser
+run, FunnelWeb invokes the analyser which tests for the following conditions
+and flags them with errors if they arise.
+
+\begin{itemize}
+\item No macros defined in the input file.
+\item No macros connected to output files.
+\item Call of an undefined macro.
+\item Call having the wrong number of parameters.
+\item Call of a macro that is connected to an output file.
+\item No calls made to a macro without the \p{@Z} option.
+\item More than one call made to a macro without the \p{@M} option.
+\item Directly or indirectly recursively defined macros.
+\item Unnamed sections that contain no macro definitions.
+\end{itemize}
+
+FunnelWeb performs a static analysis\xx{static}{analysis} to detect
+recursion.\xx{macro}{recursion}
+Unfortunately, the recursion detection algorithm
+flags all macros that have an infinite expansion
+rather than just all macros
+with a recursive definition. If A calls B, and B calls
+C, and C calls B, then FunnelWeb will flag A as well
+as B and C. It is hoped that this problem will be fixed in a later version.
+
+Because FunnelWeb does not provide any kind of conditional feature, the
+prevention of recursion does not represent a curtailment of expressive power.
+
+Macros may be invoked recursively, but may not be recursive. Thus:
+
+\begin{verbatim}
+@<Sloth@>@(@<Sloth@>@(Walrus@)@) @! LEGAL recursive invocation.
+
+@$@<Teapot@>==@{@<Teapot@>@} @! ILLEGAL recursive definition.
+\end{verbatim}
+
+\section{Tangle}
+\x{tangle}
+
+If the scanner, parser, and analyser have successfully (\ie{}with no
+errors, severe errors, or fatal errors) completed, and the Tangle option
+(\p{+O}) is turned on (it is by default), then the Tangle component of
+FunnelWeb is invoked to generate the product files specified in the \p{@O}
+macros of the input file.
+
+The operation of Tangle is very simple. Each \p{@O} macro is expanded and
+written to a file of the same name. As there are a finite number of macros,
+and the analyser guarantees that the
+macro structure is non-recursive, Tangle is guaranteed to terminate.
+
+Three remaining points are worth discussing.
+
+\begin{enumerate}
+
+\item Tangle expands macros using blank indentation unless the
+user has specified otherwise in an indentation pragma in the
+input file (see Section~\ref{indentationpragma}).
+
+\item Tangle keeps track of the
+length of the lines that it is writing
+and issues an error if any line of any product file that it generates is
+longer than the maximum. The maximum is the minimum of a value defaulted
+or specified in the input file (Section~\ref{mollpragma}),
+and the value (if any) provided by the
+\p{+w} command line argument (Section~\ref{commandlineoptions}).
+
+\item It is worth the user obtaining
+some understanding of the resources
+that FunnelWeb requires to perform its task.
+
+\end{enumerate}
+
+When FunnelWeb's scanner
+executes, it reads each file into memory where it is kept for the duration
+of the run. Thus, there must be room in memory for the entire
+input file, including all include files. While this approach may seem
+expensive in memory, it is almost necessary in order to support
+forward references. To merely scan the input file, recording the macro
+names, but leaving the text on disk, would require many random
+access disk seeks.
+
+In contrast, FunnelWeb never builds an internal representation
+of the product file.
+Instead, each piece of output is written immediately to the
+product file. This means that as long as the input file fits in memory,
+the product file can be arbitrarily large. It also means that users need
+not fear to define or call macros that they know will expand to megabytes
+of text. Nor need they fear placing a call to such a macro as part of
+an actual parameter. FunnelWeb does not ever expand actual parameters
+internally. In fact, it does not expand them until it hits the corresponding
+formal parameter during its expansion of the called macro. At that point, it
+looks up the \i{expression} (not the expansion of the expression) for the
+corresponding actual parameter, and starts expanding it.
+
+\section{Weave}
+\x{weave}\x{typesetting}
+
+If the scanner, parser, and analyser have successfully (\ie{}with no
+errors, severe errors, or fatal errors) completed, and the Weave option
+(\p{+T}) is turned on (it is \i{off} by default), then the Weave component of
+FunnelWeb is invoked to generate a text file in the format of a particular
+typesetter. The result, when fed through the particular typesetter and printed,
+is a fully typeset representation of the entire input file complete with
+cross referencing information.
+
+\subsection{Target Typesetter}
+\xx{target}{typesetter}
+
+Currently, FunnelWeb produces documentation files
+in the format of only one typesetter ---
+\TeX{}. However, the Weave package of FunnelWeb is fairly small, and it
+is hoped that it can be rewritten so as to provide
+a collection of typesetter modules from which
+the user will be able to choose using a command line argument.
+
+\subsection{Cross Reference Numbering}
+\xx{cross}{referencing}\xx{cross reference}{numbering}
+\xx{section}{numbering}
+
+When FunnelWeb produces its typeset documentation, it \i{numbers} each
+section and each macro definition and cross references the macro definitions.
+The exact scheme used has been carefully thought out. However, as it can
+be a little confusing to the beginner, it is explained here in full.
+
+The most important thing is that there is \i{no relation} between the
+macro numbering and the section numbering. In Knuth's Web there are only
+section numbers. In FunnelWeb, the numbering of sections and macros
+is separated.
+
+In FunnelWeb, \i{sections} are numbered
+hierarchically in ascending order. For example, the second level-C section
+of the third level-B section of the first level-A section is
+numbered \dq{1.3.2}. In contrast, \i{macro definitions} are numbered
+sequentially in ascending order. For example, the first macro definition is
+number 1, the second is number 2, and so on. Note that it is \i{macro
+definitions} that are numbered, not \i{macros}. This distinction is necessary
+because additive macros (\ie{}the ones with \p{+=})
+can be defined by a collection
+of partial definitions scattered throughout the input file. A single additive
+macro may be defined in definitions 5, 67, 128, and 153.
+
+\section{FunnelWeb Shell}
+\label{commandshell}%
+\xx{FunnelWeb}{command shell}\xx{commands}{FunnelWeb}\xx{FunnelWeb}{shell}
+
+\subsection{Introduction}
+
+One of the goals of FunnelWeb is
+that it must be extremely portable. Huge efforts, desperate actions,
+and great sacrifices were made in the name of portability.
+For example, FunnelWeb is written in~C.
+
+An equally important goal was that of correctness and reliability. To this
+end, it was determined that a large automated suite of test programs be
+prepared to assist in regression testing. Preparing the test suite was
+tedious, but achievable. Automating it portably was more difficult.
+
+The difficulty faced was that if FunnelWeb was implemented in the form of
+a utility that could be
+invoked from the operating system command language, the only way to set up
+regression testing was in the command language of the operating system
+of the target machine (shellscripts for UNIX, DCL for VMS, batch files
+for MSDOS, and \i{nothing} on the Macintosh). The huge variation in these
+command languages led to the conclusion that either the automation of
+regression testing would have to be rewritten on each target machine, or
+a small command language would have to be created within FunnelWeb. In the
+end, the twin goals of portability and regression testing were considered so
+important that a small command
+shell was constructed inside FunnelWeb. This is called the
+\newterm{FunnelWeb command shell}, or just \dq{the shell} for short.
+
+By default, when FunnelWeb is invoked, it does not enter its shell. If
+just given the name of an input file, it will simple process the input file
+in the normal manner and then terminate. To instruct FunnelWeb to
+invoke its shell, the \p{+K} or \p{+X} command line option must be specified
+when FunnelWeb is invoked from the operating system. It is also
+invoked upon startup if the file \p{fwinit.fws} exists.
+
+Most FunnelWeb users will never need to use the shell and need not even
+know about it. There are four main uses of the shell:\xx{uses}{shell}
+
+\begin{enumerate}
+
+\item As a tool to support automated regression testing.
+
+\item As a development tool on machines that do not have a built in shell
+(\eg{}the Macintosh). The shell can be used to process whole groups of
+files automatically.
+
+\item As a convenience. A user working on a multi-tasking, multi-window
+workstation\x{workstation}
+may wish to keep an interactive session of FunnelWeb going in
+one window rather than having to run up the utility each time it is required.
+
+\item As a convenient
+vehicle for enclosing utilities. The FunnelWeb shell contains
+useful general purpose commands such as the
+differences command \p{diff}.
+
+\end{enumerate}
+
+\subsection{Return Statuses}
+\xx{errors}{shell}\xx{status}{success}%
+\xx{status}{warning}\xx{status}{error}\xx{status}{severe}\xx{status}{fatal}%
+\xx{status}{assertion}
+
+The hierarchy of diagnostics described in Section~\ref{diagnostics}
+is also used in the
+shell commands. Each shell command returns a status which can affect
+further processing.
+
+\narrowthing{Success}{status is the normal command return status.}
+
+\narrowthing{Warning}{status is returned if some minor problem
+arose with the execution of the command.}
+
+\narrowthing{Error}{status is returned if a significant problem
+arises during the execution of the command.
+However, unlike a severe error,
+it does \i{not} cause termination of the enclosing shellscript.}
+
+\narrowthing{Severe error}{status is returned if a problem arises
+during the execution of the command that prevents the command from
+delivering on its \dq{promise}. A severe error causes FunnelWeb
+to abort the script (and any stacked scripts) to the interactive level.
+(However, the \p{tolerate} command allows this to be temporarily
+overridden).}
+
+\narrowthing{Fatal error}{status is returned if a problem arises
+that is so serious that execution of FunnelWeb cannot continue.
+A fatal error causes FunnelWeb to abort to the operating system level.}
+
+\narrowthing{Assertion error}{status is never returned. If an assertion
+error occurs, FunnelWeb bombs out ungracefully to the operating system.
+Assertion errors should never happen. If they do, then there is a bug
+in FunnelWeb.}
+
+To be precise, the status returned by each command
+is a vector of numbers being the number of each of the different kinds of
+diagnostic generated by the command. Usually only one kind
+of diagnostic is generated. However, the \p{fw} command and a few of the other
+commands can generate more than one kind of diagnostic.
+These status vectors are summed internally where they may later be accessed
+using the \p{status} command. However, the current diagnostic state
+evaporates as soon as the next command is encountered.
+
+\subsection{Command Line Length}
+\xx{command}{length}
+
+The maximum length of a shell command line is guaranteed to be
+at least 300 characters.
+
+\subsection{String Substitution}
+\label{stringsubstitution}\xx{string}{substitution}
+
+Most command shells provide some form of string substitution so
+as to provide some degree of parameterization.
+The FunnelWeb shell provides 36 different string variables named
+\p{\$0..\$9} and \p{\$A..\$Z} (case insensitive).
+Each variable can hold a string containing
+any sequence of printable characters and can be as long as a command line.
+
+The \p{define} command\xx{define}{command}
+allows the user to assign a value to these variables.
+The \p{define} command takes two arguments. The first is the digit or letter
+of the
+variable to be defined. The second is a double quote delimited string being the
+string value to be assigned to the variable. If you want to include a
+double quote character within the string, you don't need to double it.
+
+Examples:
+
+\begin{verbatim}
+define 3 "/root/usr/usrs/users/users5/thisuser/workdir/fwdir/testdir"
+define M "/user/local/rubbish/bin/fw"
+define Q "You don't need to double" double quotes"
+\end{verbatim}
+
+Only the identifying character of the variable being assigned
+is used in the definition. This syntax is a simple way of preventing
+the variable from being substituted before it has a chance to be
+defined!
+
+The following points clean up the remaining semantic details:
+
+\begin{itemize}
+
+\item There is only one set of variables and they are global to all
+shellscripts. There are \i{no local variables}.
+
+\item When a shellscript is invoked using the \p{execute} command, the
+substitution variables \p{0} through \p{9} are affected. See
+Section~\ref{executecommand} for more details.
+
+\item If you want to include a dollar sign character in a command
+use \dqp{\$\$}.
+
+\item FunnelWeb also defines \dqp{\$/} which translates to the character
+that separates directory and file name fields in file names on the host
+machine. For example: Sun=\dqp{/}, Vax=\dqp{]}, Mac=\dqp{:},
+PC=\dqp{\bs{}}.
+
+\item Substitution is not performed recursively.
+
+\end{itemize}
+
+\subsection{How a Command Line is Processed}
+\xx{command line}{processing}
+
+When FunnelWeb reads in a command line (from the console or a script file),
+it processes it in the following sequence:
+
+\begin{enumerate}
+
+\item The command line is checked for non-printable characters. If there
+are any, they are flagged with a severe error.
+
+\item All dollar string substitution variables in the command line are
+replaced by their corresponding string.
+The command line is processed from left to right. Substitutions are
+performed non recursively.
+
+\item At this point, if the line is empty, or consists entirely of
+blanks, it is ignored and the interpreter moves to the next line.
+
+\item A severe error is generated if the line at this stage begins with
+a blank.
+
+\item If the first character of the line is \dqp{!}, the line is a
+comment line and is ignored.
+
+\item The run of non-blanks commencing at the start of the line is
+compared case-insensitively to each of the legal command verbs. If the
+command is illegal, a severe error is generated, otherwise the command
+is processed.
+
+\end{enumerate}
+
+\subsection{Options}
+\xx{command}{options}\xx{default}{options}
+
+The FunnelWeb shell maintains three sets of command line options.
+
+\begin{enumerate}
+
+\item The set of options resulting from applying the operating system
+level command line
+arguments to the default option settings.
+
+\item A set of shell options that prevail during the shell invocation.
+
+\item The set of option values active during a particular invocation
+of FunnelWeb proper.
+
+\end{enumerate}
+
+When FunnelWeb is invoked from the operating system with just \p{+F},
+only the first of these three sets comes into existence. If the user
+invokes the FunnelWeb shell, the shell options come into existence and are
+initialized with the value of the first set. These shell options are
+used as the default for all subsequent \p{fw} commands. However,
+they can be altered using the script command \p{set}. If a
+\p{fw} command executed in a shell contains additional command line options,
+these override the shell options for that run, but do not change the
+shell options. An example follows:
+
+\begin{verbatim}
+$ fw +k +t ! Original invocation of FunnelWeb from OS.
+ ! Shell options are now default with "+t".
+FunnelWeb>fw sloth ! Equivalent to fw sloth +t.
+FunnelWeb>set -l ! Change the l shell option.
+FunnelWeb>fw sloth +q ! Equivalent to fw sloth +t -l +q.
+FunnelWeb>fw sloth ! Equivalent to fw sloth +t -l.
+\end{verbatim}
+
+The existence of the shell option set means that the user can set up
+a set of defaults to be applied to all \p{fw} commands issued within
+the shell.
+
+\subsection{Shell Commands}
+\xx{shell commands}{list}\xx{commands}{shell}
+
+This section describes each of the FunnelWeb shell commands. The syntax
+is:
+
+\begin{verbatim}
+shell_command = absent | codify | compare | define | diff | diffsummary |
+ diffzero | eneo | execute | exists | fixeols | help |
+ here | quit | set | show | skipto | status |
+ tolerate | trace | write | writeu
+s = {" "}+
+\end{verbatim}
+
+As a rule, FunnelWeb shell commands return severe status if their
+arguments are syntactically incorrect or if they are
+unable to successfully operate on argument files.
+
+\subsubsection{Absent}
+\xx{command}{absent}
+
+The \p{absent} command performs no action except to return a status. If the
+file specified in its argument doesn't exist
+it returns success status, otherwise it returns severe status.
+
+\begin{verbatim}
+Syntax : absent = "absent" s filename
+Example: absent result.out
+\end{verbatim}
+
+This command is useful in regression testing
+for making sure that
+FunnelWeb \i{hasn't} produced a particular output file.
+
+\subsubsection{Codify}
+\xx{command}{codify}
+
+The \p{codify} command takes two arguments: an input file and an output file.
+It reads each line of the input file and writes a corresponding line to the
+output file. The corresponding line consists of a C macro call containing
+a string containing the input line. The command converts all backslashes in
+input lines to double backslashes so as to avoid unwanted interpretations by
+the C compiler. It also converts double quotes in the line to backslashed
+double quotes.
+
+\begin{verbatim}
+Syntax : codify = "codify" s filename s filename
+Example: codify header.tex header.c
+\end{verbatim}
+
+The following example demonstrates the transformation.
+
+\begin{verbatim}
+Input Line: \def\par{\leavevmode\endgraf}% A "jolly good hack".
+Output Line: WX("\\def\\par{\\leavevmode\\endgraf}% A \"jolly good hack\".");
+\end{verbatim}
+
+The \p{codify} command was introduced to assist in the
+development of FunnelWeb.
+It is used to convert longish text files
+into C code to write them out. The C code is then included within
+the FunnelWeb C program. For example,
+the set of \TeX{} definitions that appears at the top of every
+documentation file was \p{codif}ied and inserted into the
+FunnelWeb code so that FunnelWeb would not have to look for a file containing
+the definitions at run time.
+
+\subsubsection{Compare}
+\xx{command}{compare}
+
+The \p{compare} command takes two filename arguments and performs a binary
+comparison of the two files. If the files are identical, success status
+is returned. If they are different, severe status is returned. No information
+about the manner in which the files differ is conveyed.
+
+\begin{verbatim}
+Syntax : compare = "compare" s filename s filename
+Example: compare result.txt answer.txt
+\end{verbatim}
+
+The \p{compare} command was created as the main checking mechanism for
+regression testing. However, its binary output was soon found to be
+unworkable and the more sophisticated \p{diff} command was added so
+that the actual differences between the files could be examined.
+
+\subsubsection{Define}
+\xx{command}{define}\xx{string}{substitution}
+
+The \p{define} command
+assigns a value to a shell string substitution variable.
+The \p{define} command takes two arguments. The first is the digit or letter
+of the
+variable to be defined. The second is a double quote delimited string being the
+string value to be assigned to the variable. If you want to include a
+double quote character within the string, you don't need to double it.
+
+\begin{verbatim}
+Syntax : define = "define" s letter s """" text """"
+Examples: define 3 "/usr/usrs/thisuser/workdir/fwdir/testdir"
+ define M "/user/local/rubbish/bin/fw"
+ define Q "You don't need to double" double quotes"
+\end{verbatim}
+
+The command interpreter expands the command line before it executes the
+\p{define} command. This means that you can define string substitution
+variables in terms of each other with static binding.
+
+The \p{define} command was introduced to allow the parameterization
+of the directories involved in regression testing.
+
+See Section~\ref{stringsubstitution} for more details.
+
+\subsubsection{Diff}
+\xx{command}{diff}\xx{file}{differences}
+
+The \p{diff} command reads in two text files and \i{appends} a report to a log
+file containing a list of the differences between the two input
+files. If the log file does not already exist, an empty one is created first.
+
+\begin{verbatim}
+Syntax : diff = "diff" s filename s filename s filename s ["ABORT"]
+Examples: diff result.tex answer.tex diff.log
+ diff $Otest23.out $Atest23.out $Ldiff.log ABORT
+\end{verbatim}
+
+The \p{diff} command performs a full line-based differences operation.
+It will identify different sections in a file, even if they are of differing
+length.
+
+The implementation of the \p{diff} command is quite complicated. To be
+sure that it is at least getting its same/different proclamation right,
+the \p{diff} command performs a binary comparison as an extra check.
+
+The following points describe the rules for determining the result status.
+
+\begin{enumerate}
+
+\item \p{diff} aborts with a
+severe error if the log file cannot be opened or
+created for appending.
+
+\item An ordinary error is generated if either or both of the input files
+cannot be opened.
+
+\item If, at the end of the run, the two input files have not
+been proven to be identical, and the \p{ABORT} keyword is present, \p{diff}
+returns severe status.
+
+\item \p{diff} returns success status if none of the above conditions
+(or similar conditions) occur, even if the two files are different.
+
+\end{enumerate}
+
+The \p{diff} command \i{appends} its differences report rather than
+merely writing it. This allows a regression test script to perform
+a series of regression tests and produce a report for the user.
+
+The \p{diff} command was added to the shell after it had become apparent
+that the simpler \p{compare} command was not yielding enough information.
+Whereas early on, regression testing was treated
+mainly as a tool to ensure that FunnelWeb was being ported to other machines
+correctly, it began to place an increasing role during development in
+identifying the effects of changes made to the code. The \p{diff} command
+supports this application of regression testing by pinpointing the
+differences between nearly-identical text files.
+
+\subsubsection{Diffsummary}
+\xx{command}{diffsummary}
+
+The \p{diffsummary} command writes a short report to the
+console giving the number of
+difference operations that have taken place and how many of the pairs
+of files compared were identical. Counting starts at the most recent
+execution of a \p{diffzero} command, or if there has been none, when
+FunnelWeb started up.
+
+\begin{verbatim}
+Syntax : diffsummary = "diffsummary"
+Examples: diffsummary
+\end{verbatim}
+
+The \p{diffsummary} command was added so as to allow regression testing
+scripts to display a summary of the results of the test. If the summary
+indicates that no pair of files differed, then there is no need to look
+in the \p{diff} log file.
+
+\subsubsection{Diffzero}
+\xx{command}{diffzero}
+
+The \p{diffzero} command zeros the different summary counters used by the
+\p{diff} and \p{diffsummary} commands.
+
+\begin{verbatim}
+Syntax : diffzero = "diffzero"
+Examples: diffzero
+\end{verbatim}
+
+The \p{diffzero} command was added so as to allow regression testing
+shellscripts to zero their differences counters at the start of a run.
+This allows testers to invoke the same regression testing script
+twice in one interactive session without receiving an inflated
+differences summary.
+
+\subsubsection{Eneo}
+\xx{command}{eneo}
+
+The \p{eneo} command takes one filename argument. If the file does
+not exist, no action is taken. If the file does exist, it is deleted.
+In both cases success status is returned. However, if the file exists
+and cannot be deleted, \p{eneo} returns severe status.
+
+\begin{verbatim}
+Syntax : eneo = "eneo" s filename
+Examples: eneo result.out
+\end{verbatim}
+
+The \p{eneo} command was added so as to allow regression testing scripts
+to ensure that existing output files were not present before proceeding
+with a test run. If FunnelWeb were to fail to generate an output file, it
+would be
+extremely undesirable for the old version to be used.
+
+ENEO stands for \b{E}stablish the \b{N}on \b{E}xistence \b{O}f.
+Most operating systems provide a command to delete files. Typically
+these commands are verbs such as \dq{delete}, \dq{remove}, and \dq{kill}.
+As a consequence, the designers of delete commands usually
+consider the command to have failed if it fails to find the file to be
+deleted. However, in my experience, the most common use
+for the delete command
+is to \i{establish the non-existence of} one or more files. Typically, a
+script is starting up and needs to clear the air before getting started.
+If the files are there, they should be deleted; if they are not, then that's
+OK too.\footnote{As far as I know, the \p{eneo} command is original.}
+
+\subsubsection{Execute}
+\label{executecommand}\xx{command}{execute}
+
+The \p{execute} command causes a specified text file to be
+executed as a FunnelWeb shellscript. The first argument is the
+name of the script file.
+The remaining arguments are assigned to the substitution
+variables \p{\$1}, \p{\$2}, $\ldots$, \p{\$9}.
+Substitution variables in the range
+\p{\$1} to \p{\$9} that do not correspond to an argument are set to
+the empty string \p{""}. \p{\$0} is set to the empty string regardless.
+The execute command can be used recursively, allowing shell scripts to
+invoke each other. A file extension default of \dqp{.fws}
+(FunnelWeb Script) applies to script files.
+
+\begin{verbatim}
+Syntax : execute = "execute" s filename {argument_string}
+Examples: execute megatest.fws /usr/users/ross/fwtest !
+ execute sloth
+\end{verbatim}
+
+The first example above will result in the following substitution variable
+assignments.
+
+\begin{verbatim}
+$0 = ""
+$1 = "/usr/users/ross/fwtest"
+$2 = "!"
+$3 = ""
+...
+$9 = ""
+\end{verbatim}
+
+It should be stressed that there are no local variables in the FunnelWeb
+command language; the variables above are globally modified.
+
+The \p{execute} command was added to allow the creation of sub-scripts
+to test FunnelWeb in particular ways.
+
+\subsubsection{Exists}
+\xx{command}{exists}
+
+The \p{exists} command performs no action except to return a status. If the
+file specified in its argument exists
+it returns success status, otherwise it returns severe status.
+
+\begin{verbatim}
+Syntax : exists = "exists" s filename
+Example: exists test6.fw
+\end{verbatim}
+
+This command is useful in regression testing
+for ensuring that
+FunnelWeb has produced a particular output file.
+
+\subsubsection{Fixeols}
+\xx{command}{fixeols}
+
+The \p{fixeols} command takes two filename arguments: an input file and
+an output file. It reads in the input file and writes it to the output file
+changing all the end of line control character
+sequences to the local format. It can also take one filename argument, in
+which case it replaces the target file with its transformation.
+
+\begin{verbatim}
+Syntax : fixeols = "fixeols" s filename [s filename]
+Examples: fixeols imported.hak result.kln
+ fixeols sloth.dat
+\end{verbatim}
+
+The \p{fixeols} command works by parsing the input file into alternating
+runs of
+printable characters (ASCII 20 to ASCII 126) and runs of non-printable
+characters (all the others).
+It then\xx{non-printable}{characters}
+parses each run of non-printable characters from left to right into
+subruns of non-printables not containing the same character twice.
+It then replaces each subrun with a native EOL.\footnote{Note: A native
+EOL can be inserted into a text file in a portable manner
+simply by writing \dqp{\bs{}n} to the text output stream.}
+For example,
+if a native EOL is \p{X}, and \p{ABCD} are non-printable characters, and
+the file to be converted is
+
+\begin{verbatim}
+thisABisABCDanABABexampleABCCCof the conversion.
+\end{verbatim}
+
+then \p{fixeols} would produce
+
+\begin{verbatim}
+thisXisXanXXexampleXXXof the conversion.
+\end{verbatim}
+
+The \p{fixeols} command was devised to solve the problem created sometimes
+when text files are moved from one machine to another
+(\eg{}with the kermit program)
+using a binary transfer mode rather than a text transfer mode.
+If such a transfer is made, and the text file line termination conventions
+differ on the two machines, one can wind up with a set of
+text files with improperly terminated lines. This can cause problems
+on a number of fronts, but in particular affects regression testing
+which relies heavily on exact comparisons between files. The \p{fixeols}
+command provides a solution to this problem by providing a portable way
+to \dq{purify} text files whose end of lines have become incorrect.
+The regression testing scripts all apply \p{fixeols} to their input and
+output files before each test.
+
+\subsubsection{Fw}
+\xx{command}{fw}
+
+The \p{fw} command allows FunnelWeb proper to be invoked from a shell
+script. The syntax is almost identical to the syntax with which FunnelWeb is
+invoked from the operating system.
+
+\begin{verbatim}
+Syntax : fw = "fw" s ordinary_funnelweb_command_line
+Examples: fw sloth +t +d
+ fw -l walrus
+\end{verbatim}
+
+Some important points about this \p{fw} command are:
+
+\begin{itemize}
+\item Options are inherited from the default shell options.
+\item The \p{F} (input file option) must be turned on.
+\item The \p{K}, \p{H}, and \p{X} options must be turned off.
+\item The \p{J} option must be turned off.
+\item The options specified in a \p{fw} command do not affect the default
+shell options.
+\item This command performs no action in the VAX VMS version of FunnelWeb.
+\end{itemize}
+
+\subsubsection{Help}
+\xx{command}{help}
+
+The \p{help} command provides online help from within the FunnelWeb shell.
+It provides access to all of the same messages that the \p{+H} command
+line option does.
+
+\begin{verbatim}
+Syntax : help = "help" [s help_message_name]
+Examples: help
+ help commands
+\end{verbatim}
+
+If no message name is given, the default message is displayed. It contains
+a list of the other help messages and their names. The actual messages
+themselves are not listed here.
+
+\subsubsection{Here}
+\xx{command}{here}
+
+The \p{here} command acts as a target for the \p{skipto} command. When
+the shell interpreter encounters a \p{skipto} command, it ignores all
+the following commands until it encounters a \p{here} command.
+
+\begin{verbatim}
+Syntax : here = "here"
+Example: here
+\end{verbatim}
+
+The \p{skipto}/\p{here} mechanism was created to allow groups of
+regression tests to be skipped during debugging without having to comment
+them out. For more information, see Section~\ref{skiptocommand}.
+
+\subsubsection{Quit}
+\xx{command}{quit}
+
+The \p{quit} command terminates FunnelWeb immediately and returns
+control to the operating system. This applies regardless of the depth
+of the script being executed.
+
+\begin{verbatim}
+Syntax : quit = "quit"
+Example: quit
+\end{verbatim}
+
+\subsubsection{Set}
+\xx{command}{set}
+
+The \p{set} command modifies the default shell options.
+For example, \p{set +t} sets the \p{+t} option for all subsequent
+FunnelWeb runs within the shell until another set command
+sets \p{-t}.
+
+\begin{verbatim}
+Syntax : set = "set" s ordinary_funnelweb_command_line
+Examples: set sloth +t +d
+ set -lwalrus
+\end{verbatim}
+
+The restrictions on the \p{set} command are identical to those on the
+\p{fw} command except that, in addition,
+the \p{+F} option cannot be turned on in the \p{set} command.
+
+The set command is useful for setting option defaults before a long run
+of regression tests. It could also be useful to set default options in
+a FunnelWeb shell kept by a user in a workstation window.
+
+\subsubsection{Show}
+\xx{command}{show}
+
+The \p{show} command displays the current default shell options.
+These options are the options that subsequent \p{fw} commands will
+inherit.
+
+\begin{verbatim}
+Syntax : show = "show"
+Example: show
+\end{verbatim}
+
+\subsubsection{Skipto}
+\label{skiptocommand}\xx{command}{skipto}
+
+The \p{skipto} command causes the shell to ignore all subsequent commands
+until a \p{here} command is encountered.
+
+\begin{verbatim}
+Syntax : skipto = "skipto"
+Examples: skipto
+\end{verbatim}
+
+The \p{skipto}/\p{here} mechanism was created to allow groups of
+regression tests to be skipped during debugging without having to comment
+them out. It is like a cut price \p{goto}.
+For example, supposing that there were eight tests and that
+you had debugged the first five. You might want to skip the first five
+tests so that you can concentrate on the next three. The following
+code shows how this can be done.
+
+\begin{verbatim}
+skipto
+execute test infile1
+execute test infile2
+execute test infile3
+execute test infile4
+execute test infile5
+here
+execute test infile6
+execute test infile7
+execute test infile8
+\end{verbatim}
+
+It should be stressed that FunnelWeb performs full command line processing
+including the dollar substitutions before testing the line to see if
+it is \p{here}. This can lead to non-obvious problems. For example.
+
+\begin{verbatim}
+skipto
+! Test the Parser
+! ---------------
+define X "execute parsertest.fws"
+$X infile1
+$X infile2
+$X infile3
+$X infile4
+$X infile5
+here
+\end{verbatim}
+
+The above looks correct, but, because the \p{define} command isn't executed
+(and \p{\$X} is not defined) the subsequent \p{\$X} lines result in a
+leading blanks error. The problem can be corrected by defining \p{\$X}
+before the \p{skipto} command.
+
+\subsubsection{Status}
+\xx{command}{status}
+
+The \p{status} command takes two forms. In its first form in which
+no arguments are given, it writes out the number of warnings, errors
+and severe errors that 1) were generated by the previous command
+and 2) have been generated during the entire shell invocation.
+In its second form it takes from one to three arguments each of which
+specifies a diagnostic severity and a number. The \p{status} command
+compares each of these numbers with the number of that diagnostic
+generated by the previous command and generates a severe error if
+they differ.
+
+\begin{verbatim}
+Syntax : status = "status" {s ("w"|"e"|"s") num}0..3
+Examples: status
+ status w1 e5 s1
+ status w4
+ status s1 e2
+\end{verbatim}
+
+The \p{status} command was introduced to test the status results of
+commands during their debugging. It is also useful for checking to see that
+the right number of diagnostics have been generated at particular points
+in test scripts.
+
+\subsubsection{Tolerate}
+\xx{command}{tolerate}
+
+The \p{tolerate} command instructs the shell not to abort processing
+of the script if the next command generates one or more warnings, errors,
+or severe errors. For the purposes of this command, a blank line counts
+as a command, so be sure to place the \p{tolerate} command immediately
+above the command about which you wish to be tolerant.
+
+\begin{verbatim}
+Syntax : tolerate = "tolerate"
+Example: tolerate
+\end{verbatim}
+
+The tolerate command was introduced to allow FunnelWeb (\ie{}the
+\p{fw} command) to be tested
+in a script under conditions which would normally cause it to abort the
+script.
+
+\subsubsection{Trace}
+\xx{command}{trace}
+
+The \p{trace} command turns on or off command tracing during script
+execution. By default, tracing is turned off.
+
+\begin{verbatim}
+Syntax : trace = "trace" [s ("on" | "off")]
+Examples: trace on
+ trace off
+\end{verbatim}
+
+The \p{trace} command was introduced to assist in the debugging of
+regression test scripts.
+
+\subsubsection{Write}
+\xx{command}{write}
+
+The \p{write} command accepts a double-quoted argument and writes it followed
+by an EOL to the console (standard output).
+There is no need to double any double quotes
+occurring within the string.
+
+\begin{verbatim}
+Syntax : write = "write" s string
+Examples: write "Now about to start the next test."
+ write "You don't need to " double enclosed double quotes."
+\end{verbatim}
+
+The \p{write} command was added so as to allow regression testing scripts
+to inform the user of their progress.
+
+\subsubsection{Writeu}
+\xx{command}{writeu}
+
+The \p{writeu} command is identical to the \p{write} command except that it
+underlines the text on an additional following output line.
+
+\begin{verbatim}
+Syntax : writeu = "writeu" s string
+Examples: writeu "Test 6"
+\end{verbatim}
+
+\section{Concluding Remarks}
+
+This chapter defines the semantics of the FunnelWeb program. As stated
+at the start of this chapter, this document takes precedence over the
+FunnelWeb program. While the
+definition of FunnelWeb in this chapter is reasonably solid, it is far
+from watertight, and it is hoped that it can be tightened further in
+future versions. All constructive criticism will be gratefully received
+by the author Ross Williams (\p{ross@spam.adelaide.edu.au}).
+
+%==============================================================================%
+% End of Ch3.tex %
+%==============================================================================%