home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / unix / volume26 / funnlweb / part20 < prev    next >
Encoding:
Text File  |  1993-04-10  |  118.4 KB  |  3,035 lines

  1. Newsgroups: comp.sources.unix
  2. From: ross@spam.adelaide.edu.au (Ross Williams)
  3. Subject: v26i140: funnelweb - a tool for literate programming in C, Part20/20
  4. Sender: unix-sources-moderator@vix.com
  5. Approved: paul@vix.com
  6.  
  7. Submitted-By: ross@spam.adelaide.edu.au (Ross Williams)
  8. Posting-Number: Volume 26, Issue 140
  9. Archive-Name: funnelweb/part20
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 20 (of 20)."
  18. # Contents:  userman/u_ch3.tex
  19. # Wrapped by vixie@gw.home.vix.com on Sun Apr 11 11:00:35 1993
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'userman/u_ch3.tex' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'userman/u_ch3.tex'\"
  23. else
  24. echo shar: Extracting \"'userman/u_ch3.tex'\" \(117966 characters\)
  25. sed "s/^X//" >'userman/u_ch3.tex' <<'END_OF_FILE'
  26. X%==============================================================================%
  27. X%                                Start of Ch3.tex                              %
  28. X%==============================================================================%
  29. X%
  30. X% Copyright
  31. X% ---------
  32. X% Copyright (C) 1992 Ross N. Williams.
  33. X% This file contains a chapter of the FunnelWeb User's Manual.
  34. X% See the main TeX file for this manual for further information.
  35. X%
  36. X%==============================================================================%
  37. X
  38. X\chapter{FunnelWeb Definition}
  39. X\label{chapdefinition}\xx{FunnelWeb}{definition}
  40. X
  41. X\section{Introduction}
  42. X
  43. This purpose of this chapter is to provide a complete and consistent
  44. definition of the FunnelWeb input language and the behaviour of the
  45. XFunnelWeb program. Usually, a chapter such as this is called a
  46. X\dq{reference manual}, but this chapter is intended to go further
  47. by actually defining the language and program.  This chapter takes
  48. precedence over all other chapters and all implementations of FunnelWeb.
  49. If an implementation contradicts this chapter, then the implementation
  50. is wrong.
  51. X
  52. This is the chapter that you should turn if you find yourself asking a
  53. specific question about a specific aspect of FunnelWeb. In many
  54. cases it will be convenient to access this chapter through the index.
  55. X
  56. X\section{Notation}
  57. X\x{notation}
  58. X
  59. A particular variant of EBNF\xx{EBNF}{syntax}
  60. X(Extended Bachus Naur Form) will be used to
  61. describe the FunnelWeb syntax. In this variant, literal strings are
  62. delimited by double quotes (\eg{}\p{"string"}), optional constructs by
  63. square brackets (\eg{}\p{[optional]}), and constructs repeated zero or
  64. more times by braces (\eg{}\p{\{zeroormore\}}). Constructs to be repeated
  65. a fixed number of times are enclosed in braces followed by a decimal
  66. number indicating the number of times to be repeated
  67. X(\eg{}\p{\{sixtimes\}6}). Constructs to be
  68. repeated one or more times are
  69. enclosed in braces and followed by a \p{+} (\eg{}\p{\{oneormore\}+}).
  70. The traditional BNF \dqp{::=}
  71. is replaced by the visually simpler \dqp{=}. The traditional BNF angle
  72. brackets are abandoned.
  73. X
  74. Although FunnelWeb allows the special character to be changed using the
  75. construct \dq{$<$special$>$=}, use of \dq{$<$special$>$} to refer to
  76. XFunnelWeb's special character is cumbersome and abstract. To simplify
  77. the presentation, the default special character \dqp{@} is used throughout
  78. this chapter to represent the special character.
  79. X
  80. X\section{Terminology}
  81. X\x{terminology}
  82. X
  83. A specific terminology has arisen for dealing with FunnelWeb. Some
  84. particularly useful examples are:
  85. X
  86. X\narrowthing{Journal file:}{An output file containing
  87. a copy of the output sent to
  88. the user's console during an invocation of FunnelWeb. In other systems,
  89. this file is sometimes called a \dq{log file}.}
  90. X
  91. X\narrowthing{Product file:}{An output file, generated by the Tangle
  92. component of
  93. XFunnelWeb, that contains the expansion of the macros in the input
  94. file.\footnote{Other names considered for this were: 
  95. generated file, expanded file, result file, program file, and tangle file.}}
  96. X
  97. A complete list of all the special FunnelWeb terminology appears in the
  98. glossary. Be sure to refer to it if any of the terms used are unclear.
  99. X
  100. X\section{An Architectural Overview}
  101. X\xx{semantic}{architecture}\xx{FunnelWeb}{overview}
  102. X
  103. An understanding of the internals of FunnelWeb assists with understanding
  104. its operation (\figphases{}).\xx{execution}{phases}
  105. X
  106. During a single run, FunnelWeb reads and
  107. processes a single input file called the \newterm{input file} or
  108. the \newterm{FunnelWeb file}. The file is processed by passing it through
  109. a series of stages called \newterm{phases}. The result is that some
  110. X\newterm{output files} are generated.
  111. A \newterm{journal file} is generated containing a copy of the messages that
  112. appear on the console during the FunnelWeb run. A \newterm{listing file}
  113. is created containing a summary of the run, including any error messages.
  114. A \newterm{documentation} file is generated containing typesetter commands
  115. that when fed into a typesetter program will result in
  116. printed documentation. Finally, one or more \newterm{product files}
  117. are generated containing the result of unscrambling the macro definitions
  118. of the input file.
  119. X
  120. These files need not all be generated on any particular FunnelWeb run.
  121. Whether each output file appears is controlled by command line options.
  122. X
  123. X\begin{figure}[htbp]
  124. X\begin{verbatim}
  125. X
  126. X         .fw Input File (FunnelWeb file)
  127. X                     V
  128. X                +---------+                  \
  129. X                | Scanner |                  |
  130. X                +---------+                  |
  131. X                     V                       |
  132. X                +--------+                   |
  133. X                | Parser |                   |
  134. X                +--------+                   |
  135. X                     V                       |
  136. X                +----------+                 >-------+------------+
  137. X                | Analyser |                 |       |            |
  138. X                +----------+                 |       |            |
  139. X                     V                       |       |            |
  140. X         +-----------+------------+          |       V            V
  141. X         V                        V          |       |            |
  142. X     +--------+               +-------+      |       |            |
  143. X     | Tangle |               | Weave |      |       |            |
  144. X     +--------+               +-------+      /       |            |
  145. X         |                        |                  |            |
  146. X         V                        V                  V            V
  147. X   Product Files         Documentation File    Listing File  Journal File
  148. X
  149. X\end{verbatim}
  150. X\mylabel{\figphases{}: FunnelWeb's processing phases.}{%
  151. X%
  152. XFunnelWeb processes each input file in a sequence of phases.
  153. If an error occurs during a phase, no subsequent phases are executed.
  154. X%
  155. X}
  156. X\end{figure}
  157. X
  158. The phases are briefly described below.
  159. X
  160. X\narrowthing{The Scanner}{reads\x{scanner} the input file, expands
  161. and reads in include files,
  162. scans the input stream, processes pragmas and typesetter directives,
  163. and parses all the
  164. XFunnelWeb special sequences. The result is a list of tokens that
  165. is handed to the parser.}
  166. X
  167. X\narrowthing{The Parser}{reads\x{parser}
  168. the scanner's token list and parses it, constructing a
  169. document list\xx{document}{list} and a macro
  170. table.\xx{macro}{table} which are passed to later phases.}
  171. X
  172. X\narrowthing{The Analyser}{examines\x{analyser}
  173. the macro table generated by the parser
  174. and performs a number of checks of the macro structures
  175. that the parser could not make on its single pass.
  176. XFor example, the
  177. analyser detects and flags unused macros and recursive macros. The
  178. analyser forms the final stage of FunnelWeb's front-end processing.}
  179. X
  180. X\narrowthing{Tangle}{expands certain macros in the macro table
  181. to generate\x{tangle} one or more product files.}
  182. X
  183. X\narrowthing{Weave}{uses the document list to generate\x{weave}
  184. a documentation file.}
  185. X
  186. A single run through these phases constitutes a single invocation of
  187. X\newterm{FunnelWeb proper}. Most invocations of the
  188. X\newterm{FunnelWeb program}
  189. will consist only of a single execution of FunnelWeb proper. However,
  190. XFunnelWeb also provides a command shell that provides many useful commands,
  191. including a command to invoke FunnelWeb proper. Discussion of the command
  192. shell is deferred until Section~\ref{commandshell}.
  193. X
  194. X\section{Diagnostics}
  195. X\label{diagnostics}\x{diagnostics}
  196. X
  197. During execution, FunnelWeb proceeds cautiously with each of its phases,
  198. only proceeding with the next phase if the previous phase has been
  199. successful. This means that, when debugging
  200. a FunnelWeb file, you may find that the number of errors \i{increases}
  201. after you fix some of them, as you will be exposing yourself to the
  202. next FunnelWeb phase.
  203. X
  204. XFunnelWeb employs five levels of diagnostics\xx{diagnostics}{levels of}
  205. at different levels of
  206. severity.\x{severity}
  207. Severity is defined in terms of the level of activity at which the
  208. diagnostic causes FunnelWeb to abort.
  209. X
  210. X\narrowthing{Warning:}{A warning\xx{warning}{severity}
  211. does not cause FunnelWeb to terminate or
  212. curtail its operation in any way, but serves merely to warn the user of
  213. particular conditions that might be symptomatic of deeper problems.}
  214. X
  215. X\narrowthing{Error:}{An\xx{error}{severity} error causes
  216. XFunnelWeb to terminate processing of the
  217. current input file at the end of the current phase. For example, if an
  218. error occurs during scanning, FunnelWeb will continue scanning (and possibly
  219. generate further scanning diagnostics), but will not invoke the parser.}
  220. X
  221. X\narrowthing{Severe Error:}{A\xx{severe}{severity} severe error
  222. X(or \dq{severe} for short) is the same
  223. as an error except that FunnelWeb terminates the current phase immediately.}
  224. X
  225. X\narrowthing{Fatal Error:}{A\xx{fatal}{severity} fatal error
  226. causes FunnelWeb not only to terminate
  227. the current phase and run immediately, but also to terminate total
  228. XFunnelWeb processing immediately. A severe error will not cause a
  229. XFunnelWeb script to terminate, but a fatal error will. A fatal error
  230. causes FunnelWeb to return control to the operating system.}
  231. X
  232. X\narrowthing{Assertion Error:}{An\xx{assertion}{severity}
  233. assertion error occurs if FunnelWeb detects
  234. an internal inconsistency, in which case FunnelWeb terminates immediately
  235. and ungracefully.  Such
  236. an error can occur only if there are bugs in FunnelWeb. With luck, such
  237. errors will be extremely rare.}
  238. X
  239. XFunnelWeb indicates the level of severity of each diagnostic that it issues
  240. by starting each diagnostic either with the full name of the severity level
  241. or with just the first letter of the severity level followed by a colon.
  242. X
  243. XFunnelWeb conveys the presence or absence of diagnostics at the operating
  244. system level by returning \p{EXIT\_SUCCESS}\xx{return}{status}
  245. status if no
  246. diagnostics occurred during the run and \p{EXIT\_FAILURE} status
  247. if one or more
  248. diagnostics (including warnings)
  249. occurred during the run.\footnote{From
  250. the symbols of the ANSI standard C library \p{stdlib.h}.
  251. See \paper{Kernighan88}, p.252.}
  252. X
  253. X
  254. X\section{Typesetter Independence}
  255. X\xx{typesetter}{independence}
  256. X
  257. One of the design goals of FunnelWeb was to provide a \i{target-language}
  258. independent literate programming system. This goal has been achieved
  259. simply by treating the text written to the product file
  260. as homogeneous and typesetting
  261. it in \p{tt font}. A secondary goal was to provide
  262. a \i{typesetter} independent literate programming
  263. system. By this is meant that it be possible to create FunnelWeb input files
  264. that do not contain typesetter-specific commands.
  265. To a lesser extent this goal has also been achieved.
  266. X
  267. The difficulty with providing typesetter-independent typesetting is that
  268. each desired typesetting feature must be recreated in a
  269. typesetter-independent FunnelWeb typesetting construct that FunnelWeb can
  270. translate into whatever typesetting language is being targeted by Weave.
  271. Taken to the extreme, this would result in FunnelWeb providing the full
  272. syntactic and semantic power of \TeX{}, but with a more generic,
  273. XFunnelWeb-specific syntax. This was unfeasible in the time available, and
  274. undesirable as well.
  275. X
  276. The compromise struck in the FunnelWeb design is to provide a set of
  277. primitive typesetter-independent typesetting features that are implemented
  278. by FunnelWeb. These are the \newterm{typesetter directives}.
  279. If the user is prepared to restrict to these directives,
  280. then the user's
  281. XFunnelWeb document will be both target-language and typesetter independent.
  282. However, if the user wishes to use the more sophisticated features of the
  283. target typesetting system, the user can specify the typesetter
  284. in a \dqp{typesetter} pragma and then place typesetter commands
  285. in the free text
  286. of the FunnelWeb document where they will be passed verbatim to the
  287. documentation file. The choice of the trade-off between typesetter
  288. independence and typesetting power is left to the user.
  289. X
  290. This said, experience with FunnelWeb V1 over a three year period,
  291. indicates that the typesetting facilities provided by FunnelWeb are
  292. sufficient for most documentation.
  293. X
  294. X\section{Command Line Interface}
  295. X\xx{command line}{interface}
  296. X
  297. X\subsection{Invoking FunnelWeb}
  298. X\xx{FunnelWeb}{invoking}\xx{FunnelWeb}{running}
  299. X
  300. When a user invokes FunnelWeb at the operating system command level, the
  301. user must provide a command line instructing FunnelWeb what to do. Typically
  302. an operating system command line consists of a \i{verb} indicating that a
  303. particular program should be run, followed by a list of options. For example:
  304. X
  305. X\begin{verbatim}
  306. X$ rename file1 file2
  307. X\end{verbatim}
  308. X
  309. In this case, the verb is \p{rename} and the command line options are
  310. X\p{file1 file2}. The entire command line begins with the \p{\$} and ends with
  311. the \p{2}.
  312. X
  313. Operating systems differ greatly in the depth with which
  314. they process their command\xx{command line}{processing}
  315. lines, ranging from systems that simply pass the entire command line string
  316. to the invoked program (\eg{}MSDOS) through to systems that perform complete
  317. command line parsing (\eg{}VMS). Syntax conventions vary considerably.
  318. X
  319. So as to achieve maximum portability and consistency of invocation across
  320. different platforms, FunnelWeb reads its command line as a raw string and
  321. performs all its own parsing.\xx{command line}{parsing}
  322. This is portable because, at the very least, all
  323. operating systems allow invoked programs access to the raw command line.
  324. X
  325. The command verb used to invoke FunnelWeb should be
  326. X\dqp{fw}.\xx{fw}{command verb}
  327. X
  328. X\begin{verbatim}
  329. XFunnelWeb_verb =  "fw"
  330. X\end{verbatim}
  331. X
  332. If this verb is not available, some alternatives are
  333. X\dqp{funweb}, \dqp{fun}, and \dqp{funnelweb}.
  334. The verbs \p{web} or \p{fweb} should be avoided
  335. as they are the names of other literate programming systems.
  336. X
  337. X\subsection{Command Line Arguments}
  338. X\xx{command line}{argument}\xx{syntax}{command line}
  339. X
  340. XFollowing the verb is the body of the command line which
  341. XFunnelWeb parses into
  342. zero or more \newterm{arguments} separated by runs
  343. of one or more blanks.
  344. X
  345. X\begin{verbatim}
  346. XFunnelWeb_command_line = FunnelWeb_verb {{" "}+ argument}
  347. X\end{verbatim}
  348. X
  349. Because some operating systems convert
  350. their command line to upper case before handing it to the invoked program,
  351. XFunnelWeb has been constructed so as to be \i{insensitive} to the case
  352. of its command line arguments.\xx{case}{dependence} However, when
  353. dealing internally with arguments, FunnelWeb \i{preserves} the case of
  354. its command line arguments so that it will be able to operate with
  355. operating systems (such as Unix\x{Unix}) 
  356. whose file names are case dependent.
  357. X
  358. A valid FunnelWeb argument consists of a
  359. X\newterm{sign}, an identifying \newterm{letter}, and an
  360. optional
  361. X\newterm{string} with no spaces separating
  362. them.\xx{command line options}{syntax}\xx{options}{syntax}
  363. X
  364. X\begin{verbatim}
  365. argument  = sign id_letter [non_blank_string]
  366. sign      = "+" | "-" | "="
  367. id_letter = "B" | "C" | "D" | "F" | "H" |"I" | "J" | "K" |
  368. X            "L" | "O" | "Q" | "S" | "T" | "W" | "X"
  369. X\end{verbatim}
  370. X
  371. In addition there is a special form of argument that does not begin with
  372. a sign.
  373. X
  374. X\begin{verbatim}
  375. argument = non_blank_string_not_beginning_with_+_=_or_-
  376. X\end{verbatim}
  377. X
  378. This form is exactly equivalent to the same string with \dqp{+F}
  379. prepended to it.
  380. X
  381. The semantic effect of these arguments is
  382. defined in terms of \newterm{options} which are the
  383. internal parameters of FunnelWeb
  384. and which correspond closely with the set of legal command line arguments.
  385. XFunnelWeb has a predefined set of options each identified
  386. by an identifying letter having two attributes: a \i{string}, and a
  387. X\i{boolean}. The boolean determines whether an option is turned
  388. X\i{on} or \i{off}. The string contains additional information
  389. depending on the option.
  390. X
  391. When FunnelWeb starts up, its options have predefined default values.
  392. XFunnelWeb then parses its command line sequentially from
  393. left to right
  394. executing the effect of each argument on the argument's corresponding
  395. option.  The sign and the
  396. string components of the argument are processed \i{independently}.
  397. A sign of \p{+} turns the option on. A sign of \p{-} turns the option off.
  398. A sign of \p{=} leaves the option's boolean attribute unchanged. The argument
  399. string replaces the string of the corresponding
  400. option, unless the argument string is empty, in which case the
  401. option string is not changed.
  402. X
  403. Because FunnelWeb processes its command line arguments from left to right,
  404. a later argument can cancel the effect of an earlier one.
  405. XFor example \p{fw +t -t} will result in the \p{t} option
  406. ending up \i{off}. This allows users to set up their own default arguments
  407. by defining a symbol in their operating system's command language. For
  408. example, a Unix user who wants FunnelWeb to delete all identical output
  409. files and create a documentation file on each run
  410. with a default \p{.typ} extension could simply place the following definition
  411. in their \dqp{.login} file.
  412. X
  413. X\begin{verbatim}
  414. alias fw fw +d +t.typ
  415. X\end{verbatim}
  416. X
  417. These default options can then later be easily overridden on the command line.
  418. X
  419. X\subsection{Options}
  420. X\label{commandlineoptions}\x{options}\xx{list}{options}
  421. X
  422. XFunnelWeb's options are internal parameters which can be modified by
  423. corresponding arguments on FunnelWeb's command line. A description of each
  424. argument and option follows.
  425. X
  426. X\narrowthing{B1$\ldots$B6: Tracedumps:}{These\xx{B}{option}
  427. six\xx{tracedump}{options}\xx{dump}{option} options have been provided to
  428. assist in the debugging and testing
  429. of FunnelWeb. They determine which of six possible trace dumps are
  430. to be written to the listing file. Only the boolean attributes
  431. of these options are ever used. The six dumps are identified by the
  432. digits \p{1..6} as
  433. follows:\xx{dump}{mapped file}
  434. X\xx{dump}{global line list}\xx{dump}{token list}
  435. X\xx{dump}{macro table}\xx{dump}{document list}\xx{dump}{times}}
  436. X
  437. X\begin{enumerate}
  438. X\item Dump a hexdump of each mapped input and include file.
  439. X\item Dump the global line list created by the scanner.
  440. X\item Dump the token list created by the scanner.
  441. X\item Dump the macro table created by the parser.
  442. X\item Dump the document list created by the parser.
  443. X\item Dump a table summarizing CPU and real time usage.
  444. X\end{enumerate}
  445. X
  446. X\narrowtext{Because these options are so closely related, a hack has been
  447. pulled to enable them to all to be controlled by the \p{B} argument.
  448. The
  449. string argument to the \p{B} argument determines which of the six options
  450. are to be affected by the sign. Examples: \p{+B134} turns on options \p{B1},
  451. X\p{B3}, and \p{B4}. \p{-B1} turns off option \p{B1}.
  452. X\p{Default:~-B123456}.}
  453. X
  454. X\narrowthing{B7: Determinism:}{If the \p{B7} option is turned on,
  455. XFunnelWeb suppresses the output of anything
  456. non-deterministic,\x{non-determinism}
  457. or machine dependent. This assists in regression testing.
  458. Only the boolean attribute is used in this option.
  459. This option is controlled by the \p{B7} argument which falls under the
  460. same argument syntax as the other \p{B} options. Examples: \p{+B7}, \p{-B7}.
  461. X\p{Default:~-B7}.}
  462. X
  463. X\narrowthing{C: Listing File Context:}{The\xx{C}{option}
  464. X\p{C}\xx{listing file}{context}
  465. option is always turned on and
  466. cannot be turned off. Its only attribute is a number which determines the
  467. number of lines of context that the lister will place around lines flagged
  468. with diagnostics in the listing file (if a listing file is written).
  469. A value of 100 indicates infinite context\xx{infinite}{context}
  470. which means that the entire
  471. listing file will be written out if a single diagnostic occurs.
  472. The value of this number can be specified by specifying it as a string of
  473. decimal digits to the \p{+C} argument. Examples: \p{+C100}, \p{+C10}.
  474. X\p{Default:~+C2}.}
  475. X
  476. X\narrowthing{D: Delete Identical Output Files:}{Only the boolean
  477. attribute of this option is used.\xx{D}{option}\xx{delete output}{option}
  478. When turned on, the option causes the suppression (deletion)
  479. of product files and documentation files
  480. X(but not listing or journal files) that
  481. are identical to the currently existing files of the same name. For example,
  482. if FunnelWeb is instructed to generate \p{stack.h} as an product file, and
  483. the text to be written to \p{stack.h} is identical to the currently existing
  484. X\p{stack.h}, then FunnelWeb will simply not write any product file, leaving the
  485. currently existing \p{stack.h} as it is (and in particular leaving the
  486. file's date attribute the same).
  487. This prevents unnecessary \p{make} propagations. For example, in a C program,
  488. if \p{stack.fw} is a
  489. XFunnelWeb input file that generates \p{stack.h} and \p{stack.c},
  490. a modification to \p{stack.fw} that affects \p{stack.c} but does not
  491. affect \p{stack.h} will not provoke the recompilation of modules
  492. that \p{\#include stack.h}, so long as the intervening FunnelWeb run has
  493. X\p{+D} set. Examples: \p{-D}, \p{+D}. \p{Default:~-D}.}
  494. X
  495. X\narrowthing{F: FunnelWeb Input File:}{If\xx{F}{option}
  496. this option is turned on, FunnelWeb\xx{input file}{option}
  497. processes the input file whose name is specified by the option string.
  498. XExamples: \p{+Fsloth.fw}, \p{+Fwalrus}, \p{-F}.
  499. X\p{Default:~-F}.}
  500. X
  501. X\narrowthing{H: Display Help Message:}{If\xx{H}{option}
  502. this option\xx{help}{option} is turned on, FunnelWeb
  503. displays the message specified by the argument string.
  504. XEach message has a name. The main help message is called \dqp{menu}
  505. and contains a list of the other help messages. Examples: \p{+Hregistration},
  506. X\p{+Hoptions}. \p{Default:~-Hmenu}.}
  507. X
  508. X\narrowthing{I: Include default file specification:}{This\xx{I}{option}
  509. option\xx{include file}{option}\xx{include}{file} is always turned
  510. on and cannot be turned off. Its string attribute is used as the default file
  511. specification for include files. Usually this option is used to specify
  512. a directory from which include files should be obtained.
  513. XExamples: \p{=I/usr/dave/includes/}. \p{Default:~+I}.}
  514. X
  515. X\narrowthing{J: Journal File:}{If\xx{J}{option} this option is turned on,
  516. XFunnelWeb generates a\xx{journal file}{option}\xx{journal}{file}
  517. journal file. A journal file contains a log of
  518. all the console input and output to FunnelWeb during a single invocation of
  519. the FunnelWeb program (Note: The \p{Q} option does not affect this.).
  520. The journal file is particularly useful for examining what happened during
  521. a FunnelWeb shell run. The string attribute is the name of the journal
  522. file. Examples: \p{+Jjournfile}, \p{-J}. \p{Default:~-J}.}
  523. X
  524. X\narrowthing{K: Keyboard:}{If\xx{K}{option}
  525. this option\xx{keyboard}{option}\xx{interactive}{option}
  526. is turned on, FunnelWeb enters an
  527. interactive mode in which the user can enter FunnelWeb shell commands
  528. interactively. The string attribute is unused.
  529. XExamples: \p{+K}, \p{-K}. \p{Default:~-K}.}
  530. X
  531. X\narrowthing{L: Listing File:}{If\xx{L}{option}
  532. this option is turned on, FunnelWeb
  533. generates a\xx{listing file}{option}\xx{listing}{file}
  534. listing file containing a summary of a run on FunnelWeb proper.
  535. The string argument is the name of the listing file to be created.
  536. XExamples: \p{+L}, \p{-L}, \p{+Llisting.lis}.
  537. X\p{Default:~-L}.}
  538. X
  539. X\narrowthing{O: Product Files:}{If this option is turned on,
  540. XFunnelWeb generates a product file for each macro in the input file
  541. that is bound to an output file. The string attribute contributes to the
  542. name of the product files. This option is controlled
  543. by the \p{O} argument
  544. because product files used to be called \dq{\b{O}utput files}).
  545. XExamples: \p{-O}, \p{+O/usr/dave/product/}. \p{Default:~+O}.}
  546. X
  547. X\narrowthing{Q: Quiet:}{If\xx{Q}{option} this option is turned on,
  548. XFunnelWeb suppresses all\xx{quiet}{option}\xx{suppress}{console output}
  549. output to the screen (standard output) unless one or more errors occur,
  550. in which case a single line summarizing the errors is sent to standard
  551. output at the end of the run. If this option is turned off, FunnelWeb
  552. writes to the console in its normal garrulous way. The string
  553. attribute is unused in this option. Examples: \p{-Q}, \p{+Q}. \p{Default:~-Q}.}
  554. X
  555. X\narrowthing{S: Screen:}{If\xx{S}{option} this option is turned on,
  556. XFunnelWeb writes all\xx{screen}{option}
  557. diagnostics to the screen (standard output)
  558. as well as to the listing file.
  559. By default, they are sent only to the listing file.
  560. This option has a single numerical attribute
  561. that can be specified as a decimal string in the string component of the
  562. X\p{S} argument. The number is the number of lines of context that should
  563. surround each diagnostic sent to the screen.\x{context}
  564. XExamples: \p{-S}, \p{+S6}, \p{+S0}. \p{Default:~-S}.}
  565. X
  566. X\narrowthing{T: Documentation file:}{If\xx{T}{option} this
  567. option\footnote{This option is controlled by the \p{T} command line
  568. argument because documentation files used to be called typesetter files.} is
  569. turned on, FunnelWeb\xx{typeset}{option}\xx{typeset}{file}
  570. generates a documentation file in \TeX{} format.
  571. The string argument contributes to the
  572. name of the documentation file to be created.
  573. By default this option is turned off, as experience has
  574. shown that most FunnelWeb runs are made during program development;
  575. documentation runs occur far more rarely. Examples: \p{-T},
  576. X\p{+Tsloth.tex}. \p{Default:~-T}.}
  577. X
  578. X\narrowthing{W: Width of Product Files:}{If\xx{W}{option}
  579. this option\xx{width}{option}\xx{product file}{width}
  580. is turned on, a limit is
  581. placed on the length of lines in product files generated during the
  582. run. Lines that breach the limit are flagged with error messages.
  583. This option has a single numerical attribute
  584. that can be specified as a decimal string in the string component of the
  585. X\p{W} argument. The number is the specified maximum width.
  586. This option is one of two limits that are placed on the width of
  587. product files. The other limit is an attribute of the input file that
  588. defaults to 80 characters,
  589. but can be raised or lowered using an output line length
  590. pragma. The width that is enforced is the lower of this value and the
  591. value of the \p{W} option (if turned on).
  592. XExamples: \p{-W}, \p{+W100}. \p{Default:~-W80}.}
  593. X
  594. X\narrowthing{X: Execute:}{If\xx{X}{option}
  595. this option\xx{execute script}{option}
  596. is turned on, FunnelWeb executes the FunnelWeb shell
  597. script file specified by the string attribute.
  598. XExamples: \p{+Xmaster}, \p{-X}.
  599. X\p{Default:~-X}.}
  600. X
  601. X\section{File Name Inheritance}
  602. X\xx{filename}{inheritance}
  603. X
  604. During a single run of FunnelWeb, FunnelWeb can produce many different
  605. output files. As it would be very tedious to have to specify the name
  606. of each of these files explicitly each time FunnelWeb is run, FunnelWeb
  607. provides a system of defaults that allows the user to specify the minimum
  608. required to successfully complete the run. To do this FunnelWeb allows
  609. file specifications to inherit fields from one another.
  610. X
  611. XFunnelWeb structures filenames into three fields\xx{filename}{fields}
  612. which are inherited
  613. independently. The fields are: \newterm{directory}, \newterm{name},
  614. and \newterm{extension}.
  615. On systems having other fields (\eg{}\i{network node}, \i{device name}),
  616. the extra fields are considered to be part of the directory field.
  617. Version numbers are
  618. ignored. A field can inherit a value if its current value is
  619. the empty string.
  620. X
  621. The following table gives the full inheritance scheme used in FunnelWeb.
  622. X
  623. X\begin{center}
  624. X\begin{tabular}{|l|l|l|l|l|l|l|}                                             \hline
  625. Script     & Input     &  Include   &  Journal   &  List      &  Document  & Product \\ \hline
  626. X           &           & \p{@i}     &            &            &            & \p{@o}  \\
  627. X\p{+x}     & \p{+f}    & \p{+i}     & \p{+j}     & \p{+l}     & \p{+t}     & \p{+o}  \\
  628. X\dqp{.fws} & \dqp{.fw} & \dqp{.fwi} & \dqp{.jrn} & \dqp{.lis} & \dqp{.tex} &         \\
  629. X           &           & \p{+f}     & \p{+f}     & \p{+f}     & \p{+f}     &         \\
  630. DefDir     & Defdir    & Defdir     & Defdir     & Defdir     & Defdir     & Defdir  \\ \hline
  631. X\end{tabular}
  632. X\end{center}
  633. X
  634. The table is arranged with items of highest priority at the top.
  635. The \dqp{+<letter>} cells refer to the file
  636. specification supplied in the given command line argument.
  637. X\dqp{+F} is the name of the input file.
  638. X\dq{Defdir} refers to the default directory
  639. specification provided by the operating system. Empty cells
  640. do not contribute.
  641. X
  642. The following example shows how the table is used.
  643. Suppose that the user invoked FunnelWeb as
  644. follows:\xx{filename inheritance}{example}
  645. X
  646. X\begin{verbatim}
  647. fw /usr/ross/work/sloth.fw +twalrus
  648. X\end{verbatim}
  649. X
  650. To work out what the documentation file should be called, FunnelWeb starts
  651. with the empty string and then works down the Document column of the table.
  652. The top entry is empty
  653. so we ignore it and proceed to the second entry which consists of \dqp{+T}.
  654. The user specified the string \dqp{walrus} as the value of this option, and
  655. as our current (empty)
  656. string does not have a name field, we insert the string
  657. X\dqp{walrus} into the name field, resulting in the string \dqp{walrus}.
  658. Moving down to the next row, we encounter the constant string \dqp{.tex}.
  659. This string consists of an empty directory and name field, but a \dqp{.tex}
  660. file extension. As our current string \dqp{walrus}, does not already
  661. have a file extension (\ie{}the file extension field of our current string
  662. is empty), we add in \dqp{.tex},
  663. resulting in the string \dqp{walrus.tex}. Next we encounter the \dqp{+F} field
  664. which is the input filename \dqp{/usr/ross/work/sloth.fw} consisting of
  665. a directory field \dqp{/usr/ross/work/}, a name field \dqp{sloth}, and a
  666. file extension field \dqp{.fw}. Our \dqp{walrus.tex} string already has
  667. name and file extension fields, but its directory field is empty, and
  668. so we add in the directory field from the input file specification,
  669. resulting in the string \dqp{/usr/ross/work/walrus.tex}. Finally, we hit
  670. the default directory specification, which is (say)
  671. X\dqp{/usr/ross/play/}. However, as the directory field of our walrus
  672. string is already full, it has no effect.
  673. X
  674. In general, there is no need to remember the exact details of FunnelWeb's
  675. filename inheritance. The important thing is to know that it exists, and to
  676. use it.
  677. X
  678. X\section{FunnelWeb Startup}
  679. X\xx{FunnelWeb}{startup}\xx{FunnelWeb}{initialization}
  680. X
  681. XFunnelWeb's command line options can be divided into two groups.
  682. X\newterm{Action options} instruct FunnelWeb to performs some sort of
  683. independent action such as processing a file. \newterm{Ordinary options}
  684. merely modify the way in which FunnelWeb executes the actions.
  685. X
  686. The four action options are: \p{+F}, \p{+K}, \p{+X}, and \p{+H}. For
  687. XFunnelWeb to be successfully invoked, at least one action option must be
  688. specified. If zero action options are specified, FunnelWeb terminates
  689. with failure status.
  690. If more than one action option is specified, FunnelWeb performs
  691. the specified actions in a predefined order.
  692. X
  693. Assuming that the user has specified at least one action, the order in which
  694. actions are executed is as follows:\xx{action execution}{order}
  695. X
  696. X\narrowthing{Initialization script:}{FunnelWeb\xx{initialization}{script}
  697. starts by
  698. looking in the current
  699. directory for a file called \dqp{fwinit.fws}.\x{fwinit.fws}
  700. If it doesn't find one, it
  701. doesn't raise any error. If it does find one, it executes it as a FunnelWeb
  702. shellscript. Initialization scripts are useful for setting up FunnelWeb
  703. options (\eg{}using the \dqp{set}
  704. command without having to type them each time).}
  705. X
  706. X\narrowthing{Execute argument script:}{If a shellscript has been specified
  707. using the \dqp{+X} option, FunnelWeb executes it.}
  708. X
  709. X\narrowthing{Process input file:}{If the user has specified an input file
  710. using the \dqp{+F} option, then this is processed next (by FunnelWeb proper).}
  711. X
  712. X\narrowthing{Display help message:}{If the user requested,
  713. using the \dqp{+H} option, that a help message be displayed,
  714. the message is displayed at this time.}
  715. X
  716. X\narrowthing{Interactive mode:}{If the user specified the
  717. X\dqp{+K} option, FunnelWeb enters interactive (keyboard) mode.}
  718. X
  719. XFunnelWeb processes these actions in the above order regardless of the
  720. order in which they appear on the command line.
  721. X
  722. It may be hard to see how some of these actions might be combined.
  723. Nevertheless, FunnelWeb allows this. For example,  a user might wish
  724. to process a batch of files as specified in a script (\dqp{+Xscript.fws}),
  725. be reminded of the interactive commands available (\dqp{+Hcommand}), and
  726. then enter interactive mode so as to be able to
  727. reprocess files for which FunnelWeb
  728. reported errors (after correcting the errors in a different
  729. workstation window).
  730. X
  731. X
  732. X\section{Scanner}
  733. X\x{scanner}
  734. X
  735. The scanner reads in the input file and produces a list of tokens
  736. which it hands onto the parser. In addition, some input constructs may cause
  737. the scanner to modify some of FunnelWeb's options.
  738. X
  739. X\subsection{Basic Input File Processing}
  740. X
  741. In order to read in an input file or include file, the scanner calls a
  742. submodule called the \newterm{mapper}
  743. that reads a file in and creates a contiguous copy of
  744. it in memory. The scanner then performs three checks on the file, the first
  745. X(file termination) of
  746. which is performed before scanning commences, and the other two of which take
  747. place during scanning before each line is scanned.
  748. X
  749. X\narrowthing{File Termination:}{The\xx{file}{termination}
  750. first check the scanner makes\xx{line}{termination}
  751. is whether
  752. the file is terminated properly. A file is considered to be properly
  753. terminated if it either contains no lines, or if the last line in the file
  754. is terminated by an end-of-line marker. If the scanner detects that an
  755. input file is not properly terminated, it adds an end-of-line marker
  756. itself (to the copy in memory only).}
  757. X
  758. X\narrowthing{Unprintable Characters:}{The second check the
  759. scanner makes is for\xx{unprintable}{characters}
  760. unprintable characters (ASCII 0--31 and 127--255
  761. X(except for EOL(10))) which it flags
  762. as errors and  replaces by question marks.}
  763. X
  764. X\narrowthing{Line Lengths:}{The third check
  765. the scanner makes is input line length.\xx{line}{length}
  766. When FunnelWeb starts up, a default maximum
  767. input line length of 80 is set. This can be changed dynamically during scanning
  768. using a \p{@p maximum\_input\_line\_length} pragma.
  769. If the number of characters on a line (not including the end of line marker)
  770. exceeds this limit, FunnelWeb generates an error.\checked{}}
  771. X
  772. X\subsection{Special Sequences}
  773. X\xx{special}{sequences}
  774. X
  775. The scanner scans the input file from top to bottom, left to right, treating
  776. the input as ordinary text (to be handed directly to the parser as a text
  777. token) unless it encounters the \newterm{special character}\footnote{This sort
  778. of character is often referred to as the \dq{escape character} or the
  779. X\dq{control character} in other
  780. systems. However, as there is great potential to confuse these names
  781. with the \dq{escape} character (ASCII 27) and ASCII \dq{control} characters,
  782. the term \dq{special} has been chosen instead. This results in the terms
  783. X\i{special character} and \i{special sequence}.} which introduces
  784. a \newterm{special sequence}. Thus, the
  785. scanner partitions the input file into ordinary text and special sequences.
  786. X
  787. X\begin{verbatim}
  788. input_file = {ordinary_text | special_sequence}
  789. X\end{verbatim}
  790. X
  791. Upon startup, the special character\xx{default}{special character}
  792. is \p{@}, but it can
  793. be changed using the $<$special$>$\p{=}$<$new\_special$>$ special sequence.
  794. Rather than using $<$special$>$ whenever the special character appears,
  795. this document uses the default special character \dqp{@} to represent the
  796. current special character.
  797. More importantly, FunnelWeb's
  798. error messages all use the default special character in their error messages
  799. even if the special character has been changed.
  800. X
  801. An occurrence of the special character in the input file introduces a
  802. special sequence. The kind of special sequence is determined by the
  803. character following the special character. Only printable characters can
  804. follow the special character.
  805. X
  806. The following list gives all the possible characters that can follow the
  807. special character, and the legality of each sequence.
  808. The first column gives the ASCII number of each ASCII character. The second
  809. column gives the special sequence for that character. The next column contains
  810. one of three characters: \dqp{-} means that the sequence is illegal. \dqp{S}
  811. indicates that the sequence is a \newterm{simple sequence} (with no attributes
  812. or side effects) that appears exactly as shown and is
  813. converted directly into a token and fed to the parser. Finally, \dqp{C}
  814. indicates that the special sequence is complex, possibly having a following
  815. syntax or producing funny side effects.
  816. X
  817. X\begin{verbatim}
  818. ASC  SEQ  COMMENT
  819. X-----------------
  820. X000       \
  821. X016        | Unprintable characters and hence illegal specials.
  822. X031       /
  823. X032  @    - Illegal (space).
  824. X033  @!   C Comment.
  825. X034  @"   S Parameter delimeter.
  826. X035  @#   C Short name sequence.
  827. X036  @$   S Start of macro definition.
  828. X037  @%   - Illegal.
  829. X038  @&   - Illegal.
  830. X039  @'   - Illegal.
  831. X040  @(   S Open parameter list.
  832. X041  @)   S Close parameter list.
  833. X042  @*   - Illegal.
  834. X043  @+   C Insert newline.
  835. X044  @,   S Parameter separator.
  836. X045  @-   C Suppress end of line marker.
  837. X046  @.   - Illegal.
  838. X047  @/   S Open or close emphasised text.
  839. X048  @0   - Illegal.
  840. X049  @1   S Formal parameter 1.
  841. X050  @2   S Formal parameter 2.
  842. X051  @3   S Formal parameter 3.
  843. X052  @4   S Formal parameter 4.
  844. X053  @5   S Formal parameter 5.
  845. X054  @6   S Formal parameter 6.
  846. X055  @7   S Formal parameter 7.
  847. X056  @8   S Formal parameter 8.
  848. X057  @9   S Formal parameter 9.
  849. X058  @:   - Illegal.
  850. X059  @;   - Illegal.
  851. X060  @<   S Open macro name.
  852. X061  @=   C Set special character.
  853. X062  @>   S Close macro name.
  854. X063  @?   - Illegal. Reserved for future use.
  855. X064  @@   C Insert special character into text.
  856. X065  @A   S New section (level 1).
  857. X066  @B   S New section (level 2).
  858. X067  @C   S New section (level 3).
  859. X068  @D   S New section (level 4).
  860. X069  @E   S New section (level 5).
  861. X070  @F   - Illegal.
  862. X071  @G   - Illegal.
  863. X072  @H   - Illegal.
  864. X073  @I   C Include file.
  865. X074  @J   - Illegal.
  866. X075  @K   - Illegal.
  867. X076  @L   - Illegal.
  868. X077  @M   S Tag macro as being allowed to be called many times.
  869. X078  @N   - Illegal.
  870. X079  @O   S New macro attached to product file. Has to be at start of line.
  871. X080  @P   C Pragma.
  872. X081  @Q   - Illegal.
  873. X082  @R   - Illegal.
  874. X083  @S   - Illegal.
  875. X084  @T   C Typesetter directive.
  876. X085  @U   - Illegal.
  877. X086  @V   - Illegal.
  878. X087  @W   - Illegal.
  879. X088  @X   - Illegal.
  880. X089  @Y   - Illegal.
  881. X090  @Z   S Tags macro as being allowed to be called zero times.
  882. X091  @[   - Illegal. Reserved for future use.
  883. X092  @\   - Illegal.
  884. X093  @]   - Illegal. Reserved for future use.
  885. X094  @^   C Insert control character into text
  886. X095  @_   - Illegal.
  887. X096  @`   - Illegal.
  888. X097  @a   \
  889. X109  @m    | Identical to @A..@Z.
  890. X122  @z   /
  891. X123  @{   S Open macro body/Open literal directive.
  892. X124  @|   - Illegal.
  893. X125  @}   S Close macro body/Close literal directive.
  894. X126  @~   - Illegal.
  895. X127 to 255 are not standard printable ASCII characters and are illegal.
  896. X\end{verbatim}
  897. X
  898. The most important thing to remember about the scanner is that \i{nothing
  899. happens unless the special character is seen.} There are no funny sequences
  900. that will cause strange things to happen. The best way to view a FunnelWeb
  901. document at the scanner level is as a body of text punctuated by special
  902. sequences that serve to structure the text at a higher level.
  903. X
  904. The remaining description of the scanner consists of a detailed description
  905. of the effect of each complex special sequence.
  906. X
  907. X\subsection{Setting the Special Character}
  908. X\xx{setting}{special character}
  909. X
  910. The special character can be set using the sequence
  911. X$<$special$>$\p{=}$<$newspecialchar$>$. For example, \p{@=\#} would change the
  912. special character to a hash (\p{\#}) character. The special character may
  913. be set to any printable ASCII character except the blank character
  914. X(\ie{}any character in the ASCII range $[33,126]$). In normal use, it
  915. should not be necessary to change the special character of FunnelWeb, and it
  916. is probably best to avoid changing the special character so as not to
  917. confuse FunnelWeb readers conditioned to the \p{@} character.
  918. However, the feature is very useful where the text being prepared contains
  919. many \p{@} characters (\eg{}a list of internet electronic mail addresses).
  920. X
  921. X\subsection{Inserting the Special Character into the Text}
  922. X\xx{special character}{inserting into text}
  923. X
  924. The special sequence $<$special$>$\p{@} inserts the special character
  925. into the text as if it were not special at all. The \p{@} of this
  926. sequence has nothing to do with the current special character. If the
  927. current special character is \p{P} then the sequence \p{P@} will insert
  928. a \p{P} into the text. Example: \p{@@\#@=\#@\#@\#=@@@} translates
  929. to \p{@\#@\#@}.
  930. X
  931. X\subsection{Inserting Arbitrary Characters into the Text}
  932. X\xx{arbitrary characters}{inserting into text}
  933. X\xx{control characters}{inserting into text}\x{@circumflex}
  934. X
  935. While FunnelWeb does not tolerate unprintable characters in the input file
  936. X(except for the end of line character),
  937. it does allow the user to specify that unprintable characters appear in the
  938. product file. The \p{@\circumflex{}} sequence inserts a single character
  939. of the user's choosing into the text.
  940. The character can be specified by giving its
  941. ASCII number in one of four bases:
  942. binary, octal, decimal, and hexadecimal. Here is the syntax:
  943. X
  944. X\begin{verbatim}
  945. control_sequence = "@^" char_spec
  946. char_spec        = binary | octal | decimal | hexadecimal
  947. binary           = ("b" | "B")             "(" {binary_digit}8  ")"
  948. octal            = ("o" | "O" | "q" | "Q") "(" {octal_digit}3   ")"
  949. decimal          = ("d" | "D")             "(" {decimal_digit}3 ")"
  950. hexadecimal      = ("h" | "H" | "x" | "X") "(" {hex_digit}2     ")"
  951. binary_digit     = "0" | "1"
  952. octal_digit      = binary_digit | "2" | "3" | "4" | "5" | "6" | "7"
  953. decimal_digit    = octal_digit | "8" | "9"
  954. hex_digit        = decimal_digit | "A" | "B" | "C" | "D" | "E" | "F"
  955. X                                 | "a" | "b" | "c" | "d" | "e" | "f"
  956. X\end{verbatim}
  957. X
  958. XExample:
  959. X
  960. X\begin{verbatim}
  961. X@! Unix Make requires that productions commence with tab characters.
  962. X@^D(009)prog.o <- prog.c
  963. X\end{verbatim}
  964. X
  965. Note that the decimal \dqp{9} is expressed with leading zeros
  966. as \dqp{009}. FunnelWeb requires
  967. a fixed number of digits for each base. Eight digits for base two, three
  968. digits for base ten, three digits for base eight and two digits for base
  969. sixteen.
  970. X
  971. XFunnelWeb treats the character resulting from a
  972. X\p{@\circumflex{}} sequence as ordinary text in every sense.
  973. If your input file contains many instances of a particular control
  974. character,
  975. you can package it up in a macro like any other text. In particular,
  976. quick names can be used to great effect:
  977. X
  978. X\begin{verbatim}
  979. X@! Unix "Make" requires that productions commence with tab characters.
  980. X@! So we define a macro with a quick name as a tab character.
  981. X$@#T@{@^D(009)@}
  982. X@! And use it in our productions.
  983. X@#Tprog.o <- prog.c
  984. X@#Ta.out <- prog.o
  985. X\end{verbatim}
  986. X
  987. Warning: If you insert a Unix\x{Unix newline}
  988. newline character (decimal 10) into the text,
  989. XFunnelWeb will treat this as an end of line sequence regardless of what
  990. the character sequence for end of line is on the machine upon which it is
  991. running. Unix EOL is FunnelWeb's internal representation for end of line.
  992. Thus, in the current version of FunnelWeb, inserting character 10 into the
  993. text is impossible unless this also happens to be
  994. the character used by the operating system to mark the end of line.
  995. X
  996. X\subsection{Comments}
  997. X\xx{comments}{FunnelWeb}
  998. X
  999. When FunnelWeb encounters the \p{@!}\x{@!}
  1000. sequence during its left-to-right scan
  1001. of the line, it throws away the rest of the line (including the EOL)
  1002. without analysing it further.
  1003. Comments can appear in any line except \dqp{@i},
  1004. X\dqp{@t}, and \dqp{@p} lines.
  1005. X
  1006. XFunnelWeb comments can be used to insert
  1007. comments into your input file that will
  1008. neither appear in the product files nor in the documentation file,
  1009. but will be
  1010. solely for the benefit of those reading and editing the input
  1011. file directly. Example:
  1012. X
  1013. X\begin{verbatim}
  1014. X@! I have used a quick macro for this definition as it will be used often.
  1015. X@$@#C@{--@}
  1016. X\end{verbatim}
  1017. X
  1018. Because comments are defined to include the end-of-line marker,
  1019. care must be taken when they are being added or removed within the text
  1020. of macro bodies. For example
  1021. the text fragment
  1022. X
  1023. X\begin{verbatim}
  1024. for (i=0;i<MAXVAL;i++)      @! Print out a[0..MAXVAL-1].
  1025. X   printf("%u\n",a[i]);
  1026. X\end{verbatim}
  1027. X
  1028. will expand to
  1029. X
  1030. X\begin{verbatim}
  1031. for (i=0;i<MAXVAL;i++)         printf("%u\n",a[i]);
  1032. X\end{verbatim}
  1033. X
  1034. This problem really has no solution; if FunnelWeb comments were defined to
  1035. omit the end of line marker, the expanded text would contain trailing blanks!
  1036. As it is, FunnelWeb comments are designed to support single line comments
  1037. which can be inserted and removed as a line without causing trouble.
  1038. XFor example:
  1039. X
  1040. X\begin{verbatim}
  1041. X@! Print out a[0..MAXVAL-1].
  1042. for (i=0;i<MAXVAL;i++)
  1043. X   printf("%u\n",a[i]);
  1044. X\end{verbatim}
  1045. X
  1046. If you want a comment construct that does not enclose the end of line
  1047. marker, combine the insert end of line construct \p{@+} with the comment
  1048. construct \p{@!} as in
  1049. X
  1050. X\begin{verbatim}
  1051. for (i=0;i<MAXVAL;i++)      @+@! Print out a[0..MAXVAL-1].
  1052. X   printf("%u\n",a[i]);
  1053. X\end{verbatim}
  1054. X
  1055. XFunnelWeb comments should really only be used to comment the FunnelWeb
  1056. constructs being used in the input file. Comments on the target code are
  1057. best placed in comments in the target language or in the documenting text
  1058. surrounding the macro definitions. In the example above, a C
  1059. comment would have been more appropriate.
  1060. X
  1061. X\subsection{Quick Names}
  1062. X\xx{quick}{names}
  1063. X
  1064. XFunnelWeb provides a \newterm{quick name} syntax as an alternative,
  1065. for macros whose name consists of a single character, to the
  1066. angle bracket syntax usually used (\eg{}\p{@<Sloth@>}).
  1067. A quick name sequence consists of \p{@\#}$x$\x{@hash}
  1068. where $x$, the name of the macro,
  1069. can be any printable character except space.
  1070. X
  1071. X\begin{verbatim}
  1072. quick_name = "@#" non_space_printable
  1073. X\end{verbatim}
  1074. X
  1075. The result is identical to the
  1076. equivalent ordinary name syntax, but is
  1077. shorter. For example, \p{@\#X} is equivalent to \p{@<X@>}.
  1078. This shorter way of writing one-character macro names is more convenient where
  1079. a macro must be used very often. For example, the macro calls in the
  1080. following fragment of an Ada program are a little clumsy.
  1081. X
  1082. X\begin{verbatim}
  1083. X@! Define @<D@> as "" to turn on debug code and "--" to turn it off.
  1084. X@$@<D@>@{--@}
  1085. X@<D@>assert(b>3);
  1086. X@<D@>if x>7 then write("error") end if
  1087. X\end{verbatim}
  1088. X
  1089. The calls can be shortened using the alternative syntax.
  1090. X
  1091. X\begin{verbatim}
  1092. X@! Define @#| as "" to turn on debug code and "--" to turn it off.
  1093. X@$@#|@{--@}
  1094. X@#|assert(b>3);
  1095. X@#|if x>7 then write("error") end if
  1096. X\end{verbatim}
  1097. X
  1098. X\subsection{Inserting End of Line Markers}
  1099. X\xx{EOL markers}{inserting}
  1100. X
  1101. An end of line marker/character can be inserted into the text
  1102. using the \p{@+}\x{@+} sequence. This is
  1103. exactly equivalent to a real end of line in the text at the point where
  1104. it occurs.
  1105. While this feature may sound rather useless,
  1106. it is very useful for laying out the input file. For
  1107. example, the following input data for a database program
  1108. X
  1109. X\begin{verbatim}
  1110. Animal = Kangaroo
  1111. Size   = Medium
  1112. Speed  = Fast
  1113. X
  1114. Animal = Sloth
  1115. Size   = Medium
  1116. Speed  = Slow
  1117. X
  1118. Animal = Walrus
  1119. Size   = Big
  1120. Speed  = Medium
  1121. X\end{verbatim}
  1122. X
  1123. can be converted into
  1124. X
  1125. X\begin{verbatim}
  1126. Animal = Kangaroo  @+Size = Medium  @+Speed = Fast    @+
  1127. Animal = Sloth     @+Size = Medium  @+Speed = Slow    @+
  1128. Animal = Walrus    @+Size = Big     @+Speed = Medium  @+
  1129. X\end{verbatim}
  1130. X
  1131. which is easier to read, and more easily allows comparisons between
  1132. records.
  1133. X
  1134. X\subsection{Suppressing End of Line Markers}
  1135. X\xx{EOL markers}{suppressing}
  1136. X
  1137. XEnd of line markers can be suppressed by the \p{@-}\x{@-}
  1138. sequence.
  1139. A single occurrence of a \p{@-} sequence serves to suppress only the end of line
  1140. marker following it and must appear \i{exactly} before the end of line marker to
  1141. be suppressed. No trailing spaces, \p{@!} comments, or any other characters
  1142. are permitted between a \p{@-} sequence and the end of line that it is
  1143. supposed to suppress. The \p{@-} sequence is useful for constructing
  1144. long output lines without them having to appear in the input.
  1145. It can also be used in the same way as the \p{@+}
  1146. was used in the previous section to assist in exposing the structure of output
  1147. text without affecting the output text itself. Finally, it is invaluable for
  1148. suppressing the EOL after the opening macro text \p{@\{} construct.
  1149. XFor example:
  1150. X
  1151. X\begin{verbatim}
  1152. X@$@<Walrus@>@{@-
  1153. I am the walrus!@}
  1154. X\end{verbatim}
  1155. X
  1156. is equivalent to
  1157. X
  1158. X\begin{verbatim}
  1159. X@$@<Walrus@>@{I am the walrus!@}
  1160. X\end{verbatim}
  1161. X
  1162. The comment construct (\p{@!}) can also be used to suppress end of lines.
  1163. However, the \p{@-} construct should be preferred for this purpose as it
  1164. makes explicit the programmer's intent to suppress the end of line.
  1165. X
  1166. X\subsection{Include Files}
  1167. X\xx{include}{files}
  1168. X
  1169. XFunnelWeb provides an include file facility with a maximum depth of 10.
  1170. When FunnelWeb sees a line of the form \p{@i <filename>},\x{@i}
  1171. it replaces the entire line (including the EOL) with the
  1172. contents of the specified include file. FunnelWeb's include file
  1173. facility is intended to operate at the line level. If the last line of the
  1174. include file is not terminated by an EOL, FunnelWeb issues a warning
  1175. and interts one (in the copy in memory).
  1176. X
  1177. The
  1178. X\p{@i} construct is illegal if it appears anywhere except
  1179. at the start of a line.
  1180. The construct must be followed by a single blank. The file
  1181. name is defined to be everything
  1182. between the blank and the end of the line (no
  1183. comments (\p{@!}) please!). Example: If the input file is
  1184. X
  1185. X\begin{verbatim}
  1186. X"Uh Oh, It's the Fuzz. We're busted!" said Baby Bear.
  1187. X@i mr_plod.txt
  1188. X"Quick! Flush the stash down the dunny and let's split." said Father Bear.
  1189. X\end{verbatim}
  1190. X
  1191. and there is a file called \p{mr\_plod.txt} containing
  1192. X
  1193. X\begin{verbatim}
  1194. X"'Ello, 'Ello, 'Ello! What's all this 'ere then?" Mr Plod exclaimed.
  1195. X\end{verbatim}
  1196. X
  1197. then the scanner translates the input file into
  1198. X
  1199. X\begin{verbatim}
  1200. X"Uh Oh, It's the Fuzz. We're busted!" said Baby Bear.
  1201. X"'Ello, 'Ello, 'Ello! What's all this 'ere then?" Mr Plod exclaimed.
  1202. X"Quick! Flush the stash down the dunny and let's split." said Father Bear.
  1203. X\end{verbatim}
  1204. X
  1205. As a point of terminology, FunnelWeb calls the original input file the
  1206. X\newterm{input file} and calls include files and their included files
  1207. X\newterm{include files}.
  1208. X
  1209. The include file construct operates at a very low level. An include
  1210. line can appear anywhere in the input file regardless of the context
  1211. of the surrounding lines.
  1212. X
  1213. XFunnelWeb sets the special character to the default (\p{@}) at the
  1214. start of each include file and restores it to its previous value at the end
  1215. of the include file. This allows macro libraries to be constructed and
  1216. included that are independent of the prevailing special character
  1217. at the point of inclusion.
  1218. The same goes for the input line length limit
  1219. which is reset to the default
  1220. value at the start of each include file and
  1221. restored to its previous value afterwards.
  1222. X
  1223. X\subsection{Pragmas}
  1224. X\x{pragmas}\xx{pragmas}{visible}\xx{pragmas}{invisible}
  1225. X
  1226. Most tools have to support some essential, but rather inelegant features.
  1227. In FunnelWeb these messy bits have all been stuffed into the
  1228. scanner's \newterm{pragma} (for \i{pragma}tic) construct.
  1229. X
  1230. A pragma consists of a single line of input (including the EOL)
  1231. commencing with \p{@p}. This
  1232. must be followed by a single space, and then the pragma verb.
  1233. This must
  1234. be followed by a sequence of zero or more arguments separated by one or
  1235. more spaces. Four pragmas are available
  1236. X
  1237. X\begin{verbatim}
  1238. pragma = pragma_ident | pragma_mill | pragma_moll | pragma_typesetter
  1239. X\end{verbatim}
  1240. The following syntax definitions assist in defining the pragmas.
  1241. X
  1242. X\begin{verbatim}
  1243. s        = {" "}+
  1244. ps       = ("@p" | "@P") " "
  1245. number   = { decimal_digit }+
  1246. numorinf = number | "infinity"
  1247. X\end{verbatim}
  1248. X
  1249. The arguments to pragmas are case-sensitive and must be specified in
  1250. lower case.
  1251. X
  1252. Pragmas are processed and consumed entirely by the scanner. The parser
  1253. never sees them and so they can play
  1254. no part in the parser level syntax. As a result, pragma lines
  1255. can appear anywhere in the entire input file regardless of the surrounding
  1256. context (\eg{}even in the middle of a macro definition).
  1257. The sole effect of a pragma is to modify some internal parameter of
  1258. XFunnelWeb. 
  1259. X
  1260. The following sections describe the four FunnelWeb pragmas.
  1261. X
  1262. X\subsubsection{Indentation}
  1263. X\label{indentationpragma}\xx{indentation}{macro expansion}
  1264. X
  1265. When FunnelWeb expands a macro, it can do so in two ways. First it can treat
  1266. the text it is processing as a one-dimensional stream of text, and merely
  1267. insert the body of the macro in place of the macro call. Second, it can
  1268. treat the text of the macro as a two dimensional object and
  1269. indent each line of the macro body by the amount that the macro
  1270. call itself was indented. Consider the following macros.
  1271. X
  1272. X\begin{verbatim}
  1273. X@$@<Loop Structure@>@{@-
  1274. i=1;
  1275. while (i<=N)
  1276. X   @<Loop body@>
  1277. endwhile
  1278. X@}
  1279. X
  1280. X@$@<Loop body@>@{@-
  1281. a[i]:=0;
  1282. i:=i+1;@}
  1283. X\end{verbatim}
  1284. X
  1285. Under the regime of \newterm{no indentation}\xx{indentation}{none}
  1286. the loop structure
  1287. macro expands to:
  1288. X
  1289. X\begin{verbatim}
  1290. i=1;
  1291. while (i<=N)
  1292. X   a[i]:=0;
  1293. i:=i+1;
  1294. endwhile
  1295. X\end{verbatim}
  1296. X
  1297. Under the regime of \newterm{blank indentation}\xx{indentation}{blank}
  1298. the loop structure macro expands to:
  1299. X
  1300. X\begin{verbatim}
  1301. i=1;
  1302. while (i<=N)
  1303. X   a[i]:=0;
  1304. X   i:=i+1;
  1305. endwhile
  1306. X\end{verbatim}
  1307. X
  1308. The \p{indentation} pragma determines which of these two regimes will be used
  1309. to expand the macros when constructing the product files. The syntax of the
  1310. pragma is:
  1311. X
  1312. X\begin{verbatim}
  1313. pragma_ident = ps "indentation" s "=" s ("blank" | "none")
  1314. X\end{verbatim}
  1315. X
  1316. Its two forms look like this:
  1317. X
  1318. X\begin{verbatim}
  1319. X@p indentation = blank
  1320. X@p indentation = none
  1321. X\end{verbatim}
  1322. X
  1323. In the current version of FunnelWeb, the indentation regime is an attribute
  1324. that is attached to an entire run of Tangle; it is not possible to bind it
  1325. to particular product files or to particular macros. As a result, it doesn't
  1326. matter where indentation pragmas occur in the input file or how many
  1327. there are so long as they are all the same. By default FunnelWeb uses
  1328. blank indentation.
  1329. X
  1330. X\subsubsection{Maximum Input Line Length}
  1331. X\label{millpragma}\xx{input}{line length}\xx{maximum}{input line length}
  1332. X
  1333. XFunnelWeb generates an error for each input line
  1334. that exceeds a certain maximum number of characters. At the start of the
  1335. processing of each input
  1336. file and each include file, this maximum is set to a default value of 80.
  1337. However,
  1338. the maximum can be changed using a maximum input line length
  1339. pragma.\xx{pragma}{input line length}
  1340. X
  1341. X\begin{verbatim}
  1342. pragma_mill = ps "maximum_input_line_length" s "=" s numorinf
  1343. X\end{verbatim}
  1344. X
  1345. The maximum input line length can be varied
  1346. X\i{dynamically} throughout the input file. Each maximum input line length
  1347. pragma's scope covers the line following the pragma through to and including
  1348. the next maximum input line length pragma, but not covering any intervening
  1349. include files. At the start of  an include file, FunnelWeb resets
  1350. the maximum input line length to the default value. It restores it to
  1351. its previous value at the end of the include file.
  1352. X
  1353. This pragma is useful for detecting text that has strayed off the
  1354. right side of the screen when editing. If you use FunnelWeb, and set the
  1355. maximum input line length to be the width of your editing window, you will
  1356. never be caught by, for example, off-screen opening comment symbols.
  1357. You can also be sure that your source text can be printed raw, if necessary,
  1358. without lines wrapping around.
  1359. X
  1360. X\subsubsection{Maximum Output File Line Length}
  1361. X\label{mollpragma}%
  1362. X\xx{maximum}{product file line length}%
  1363. X\xx{pragma}{maximum product file line length}%
  1364. X\xx{maximum}{output file line length}%
  1365. X\xx{pragma}{maximum output file line length}
  1366. X
  1367. As well as keeping an eye on input line lengths, FunnelWeb also keeps an
  1368. eye on the line lengths of product files and flags all lines longer
  1369. than a certain limit with error messages.
  1370. Unlike the
  1371. maximum input line length, which can vary dynamically throughout the input
  1372. file, the maximum product file line length remains fixed throughout the
  1373. generation
  1374. of all the product files. The maximum product file
  1375. line length pragma allows this
  1376. value to be set. If there is more than one such pragma in an input file, the
  1377. pragmas must all specify the same value.
  1378. X
  1379. X\begin{verbatim}
  1380. pragma_moll = ps "maximum_output_line_length" s "=" s numorinf
  1381. X\end{verbatim}
  1382. X
  1383. The default value is 80 characters.
  1384. X
  1385. This pragma is only one of two constraints on the length of the lines of the
  1386. product files. The \p{+W} command line option also contributes.
  1387. The actual value that FunnelWeb uses is the minimum of the limits
  1388. specified in the command line and pragmas.
  1389. X
  1390. XFunnelWeb does not monitor the length of the lines of its other output files
  1391. X(journal file, listing file, documentation file).
  1392. X
  1393. X\subsubsection{Typesetter}
  1394. X\xx{typesetter}{pragma}\xx{typesetter}{independence}
  1395. X
  1396. The \p{typesetter} pragma allows the user to specify whether the input
  1397. file is supposed to be typesetter-independent, or whether it contains
  1398. commands in a particular typesetter language. The pragma has the
  1399. following syntax.
  1400. X
  1401. X\begin{verbatim}
  1402. pragma_typesetter = ps "typesetter" s "=" s ("none" | "tex")
  1403. X\end{verbatim}
  1404. X
  1405. The two forms of the pragma look like this.
  1406. X
  1407. X\begin{verbatim}
  1408. X@ typesetter = none
  1409. X@ typesetter = tex
  1410. X\end{verbatim}
  1411. X
  1412. A source file can contain more than one typesetter pragma, but they must
  1413. all specify the same value. The default is \p{none}.
  1414. The typesetter setting affects two things:
  1415. X
  1416. X\narrowthing{Handling of free text:}{If the typesetter is not \p{none},
  1417. Weave writes the free text \i{directly}
  1418. to the documentation file without changing it whatsoever. This means that
  1419. if (say) \p{\char`\\ centerline} appears in the input file, it will copied
  1420. directly to the documentation file. If the typesetter is \p{none}, Weave
  1421. intercepts any characters or sequences that might have a special
  1422. meaning to the target typesetter and replaces them
  1423. with typesetter commands to typeset the sequences so that they will appear
  1424. as they do in the input. For example, if the typesetter is \p{none} and
  1425. the target typesetter is \TeX{}, then if
  1426. X\p{\$} (the \TeX{} \dq{mathematics mode} character)
  1427. appears in the input file, it will be
  1428. be written to the documentation file as \p{\char`\\ \$}.}
  1429. X
  1430. X\narrowthing{Restrictions on the target typesetter:}{At a later date,
  1431. different weave modules might be incorporated into FunnelWeb to cater
  1432. for a variety
  1433. of different typesetters. If this happens, it will be important to ensure
  1434. that typesetter-specific source files
  1435. X(\ie{}\p{typesetter} $\ne$ \p{none}) are not processed with different
  1436. target typesetters. For example, a user might innocently attempt to generate
  1437. a \p{troff} documentation file from a
  1438. XFunnelWeb source file containing a \p{typesetter = tex} (and by
  1439. implication \TeX{} control sequences). The pragma could also be useful
  1440. for catching typesetter clashes in source and include files. The setting
  1441. X\p{none} is special because it is guaranteed to work with any
  1442. future target typesetter.}
  1443. X
  1444. The aim of all this is
  1445. to ensure that any typesetter dependency is correctly proclaimed.
  1446. Because \p{none} is the default typesetter,
  1447. a user who creates a source file without a \p{typesetter = x} pragma
  1448. will soon find that the control sequences they are inserting into
  1449. the source document are appearing verbatim in the printed documentation!
  1450. In order to activate these sequences, they will be forced to add a
  1451. X\p{typesetter} pragma, thus making the dependency explicit.
  1452. X
  1453. It may seem strange to place the \p{typesetter} setting facility within
  1454. a pragma (\p{@p}) when there is a separate typesetting construct (\p{@t}).
  1455. This has been done to sustain the rule of thumb that says that
  1456. pragmas do not participate in the parser-level syntax, but typesetter
  1457. directives do.
  1458. X
  1459. X\subsection{Freestanding Typesetter Directives}
  1460. X\xx{typesetter}{directives}
  1461. X
  1462. XFunnelWeb provides two kinds of typesetter directive to assist the user
  1463. to produce documentation. These are \newterm{inline} and
  1464. X\newterm{freestanding}. Unlike pragmas,
  1465. each of these categories of directive participates in the parser-level
  1466. syntax and can appear only in certain contexts (see the parser section).
  1467. Inline directives are
  1468. designed to be used within paragraphs to alter the look of the enclosed
  1469. text. Freestanding typesetter directives are designed to
  1470. appear on lines of their own and have a bigger typographical impact.
  1471. X
  1472. The syntax of freestanding typesetter directives is almost identical to that
  1473. of pragmas. All the same syntax rules apply (except that the actual
  1474. keywords are different).
  1475. The following subsections describe the four typesetter directives
  1476. available.
  1477. X
  1478. X\begin{verbatim}
  1479. ftd = ftd_newpage | ftd_toc | ftd_vskip | ftd_title
  1480. ts  = "@t "
  1481. X\end{verbatim}
  1482. X
  1483. X\subsubsection{New Page}
  1484. X\x{new page}\xx{pragma}{new page}
  1485. X
  1486. The new page pragma is a typesetting pragma with the following syntax.
  1487. X
  1488. X\begin{verbatim}
  1489. ftd_newpage = ts "new_page"
  1490. X\end{verbatim}
  1491. X
  1492. It only form looks like this.
  1493. X
  1494. X\begin{verbatim}
  1495. X@t new_page
  1496. X\end{verbatim}
  1497. X
  1498. Its sole effect is to cause a \dq{skip to a new page} command to be inserted
  1499. into the documentation file.
  1500. The new page command is such that if the typesetter is already at
  1501. the top of a page, it will skip to the top of the next page.
  1502. X
  1503. X\subsubsection{Table of Contents}
  1504. X\xx{table of}{contents}\xx{pragma}{table of contents}
  1505. X
  1506. The new page pragma is a typesetting pragma with the following syntax.
  1507. X
  1508. X\begin{verbatim}
  1509. ftd_toc = ts "table_of_contents"
  1510. X\end{verbatim}
  1511. X
  1512. It only form looks like this.
  1513. X
  1514. X\begin{verbatim}
  1515. X@t table_of_contents
  1516. X\end{verbatim}
  1517. X
  1518. Its sole effect is to instruct Weave to insert a table of contents at
  1519. this point in the printed documentation.
  1520. This pragma does not skip to a top of a new page first.
  1521. X
  1522. X\subsubsection{Vertical Skip}
  1523. X\xx{vertical}{skip}\xx{pragma}{vskip}
  1524. X
  1525. The vertical skip pragma is a typesetting pragma that
  1526. instructs Weave to insert a specified amount of
  1527. vertical space into the documentation. The pragma has the following syntax.
  1528. X
  1529. X\begin{verbatim}
  1530. ftd_vskip = ts "vskip" s number s "mm"
  1531. X\end{verbatim}
  1532. X
  1533. XFor example:
  1534. X
  1535. X\begin{verbatim}
  1536. X@t vskip 26 mm
  1537. X\end{verbatim}
  1538. X
  1539. X\subsubsection{Title}
  1540. X\x{title}\xx{pragma}{title}
  1541. X
  1542. The title pragma is a typesetting pragma with the following syntax.
  1543. X
  1544. X\begin{verbatim}
  1545. ftd_title = ts "title" s font s alignment text
  1546. font      = "normalfont" | "titlefont" | "smalltitlefont"
  1547. alignment = "left" | "centre" | "right"
  1548. text      = """" {printable_char} """"
  1549. X\end{verbatim}
  1550. X
  1551. It's effect is to instruct Weave to insert a single line
  1552. into the printed documentation
  1553. containing the specified text set in the specified font
  1554. and aligned in the specified manner. The double quotes delimiting
  1555. the text are for show only; if you want to put a double quote in the string,
  1556. you don't need to double them.
  1557. X
  1558. Here is an example of the pragma.
  1559. X
  1560. X\begin{verbatim}
  1561. X@t title smalltitlefont centre "How to Flip a Bit"
  1562. X\end{verbatim}
  1563. X
  1564. X\subsection{Scanner/Parser Interface}
  1565. X
  1566. If the scanner terminates without any errors, control
  1567. is passed to the parser. The parser parses the token list generated by
  1568. the scanner. The token list consists of text scraps, freestanding
  1569. typesetter directives,
  1570. and special sequence tokens.
  1571. X
  1572. The user should bear in mind that
  1573. X\i{the scanner finishes running before the
  1574. parser starts running.} This means that the scanner cannot be influenced
  1575. in any way by higher order structures such as the parser might parse.
  1576. XFor example,
  1577. it is impossible to write a FunnelWeb macro to include a file, or insert
  1578. a \p{vskip} pragma into the input text.
  1579. X
  1580. X\section{Parser}
  1581. X\x{parser}
  1582. X
  1583. By the time the parser starts, the scanner has completely terminated.
  1584. At this point, it
  1585. is not possible for any more files  to be included, and special characters are
  1586. no longer present  to confuse things.  All that remains is a list of
  1587. X\newterm{text tokens},
  1588. X\newterm{special tokens}, and \newterm{typesetter directive tokens}.
  1589. Text  tokens consist  entirely of
  1590. sequences of  printable characters and end  of line markers. Special tokens
  1591. represent the special sequences that the scanner found in the input file.
  1592. Typesetter directive tokens represent the freestanding typesetter directives
  1593. that the scanner encountered.
  1594. The parser consumes the token list and builds a macro table that is
  1595. later used to generate product files. It also constructs
  1596. a document list that is used to generate the documentation file.
  1597. X
  1598. The syntax rules appearing in the following sections refer to the
  1599. token list.
  1600. X
  1601. X\subsection{High Level Structure}
  1602. X\xx{syntax}{high level}
  1603. X
  1604. At the highest level, the FunnelWeb parser parses the input file (token
  1605. list) into a sequence of text scraps, macro definitions,
  1606. and typesetter directives.
  1607. X
  1608. X\begin{verbatim}
  1609. input_file = {text | macro | directive}
  1610. X\end{verbatim}
  1611. X
  1612. All three of these kinds of components contribute to the documentation file,
  1613. but only macro definitions
  1614. contribute to the product files. If all the free text
  1615. and directives were removed from a FunnelWeb input file, the
  1616. product files would not be affected.
  1617. X
  1618. X\subsection{Free Text}
  1619. X\xx{free}{text}
  1620. X
  1621. X\newterm{Free text} is any text that is not part of a macro definition or a
  1622. directive. A scrap of free text consists of a sequence of items drawn
  1623. from the following list:
  1624. non-special printable characters, insert-eol special
  1625. sequences, insert special character special sequences, insert arbitrary
  1626. character special sequence.
  1627. X
  1628. X\begin{verbatim}
  1629. free_text      = ordinary_text
  1630. ordinary_text  = {ordinary_char | eol | text_special}+
  1631. text_special   = "@+" | "@@" | "@^" char_spec
  1632. ordinary_char  = " ".."~"-special
  1633. X\end{verbatim}
  1634. X
  1635. An example of some rather messy free text is as follows:
  1636. X
  1637. X\begin{verbatim}
  1638. This@@ is a very@+ messy
  1639. X@^D(009)chunk of text indeed.
  1640. But FunnelWeb still views it as
  1641. a single chunk of text.
  1642. X\end{verbatim}
  1643. X
  1644. XFunnelWeb never sees two text chunks next to each other in the input;
  1645. they are always merged into a single text token.
  1646. X
  1647. The free text in an input file
  1648. does not affect the product files. However, by default, it appears in the
  1649. printed documentation exactly as it is given in the input file, except
  1650. that it is filled and justified into paragraphs.
  1651. X
  1652. Any printable character
  1653. or particular sequence of characters
  1654. may appear in the free text of a document. FunnelWeb ensures that they
  1655. will appear exactly as given in the input file, even if they happen to be
  1656. escape characters or commands in the target typesetter.
  1657. However, FunnelWeb also provides a special mode that allows
  1658. this censoring to be
  1659. overridden. See Section~\label{typesetterpragma} for more information.
  1660. X
  1661. X\subsection{Typesetter Directives}
  1662. X\x{directives}
  1663. X
  1664. XFunnelWeb provides a variety of typesetter directives to assist the
  1665. user to typeset the document in a typesetter-independent way. These are
  1666. divided into \newterm{freestanding typesetter directives} (ftd) and
  1667. X\newterm{inline typesetter directives} (itd). The internal syntax of the
  1668. freestanding typesetter directives has already been discussed
  1669. in the scanner section. The following syntax rule defines
  1670. the context in which these constructs can appear.
  1671. X
  1672. X\begin{verbatim}
  1673. directive = ftd | itd
  1674. itd       = section | literal | emphasis
  1675. X\end{verbatim}
  1676. X
  1677. The remainder of this section describes the inline typesetter directives.
  1678. X
  1679. X\subsubsection{Section}
  1680. X\xx{section}{constructs}
  1681. X
  1682. The section directive
  1683. provides a way for the user to structure the program and documentation into
  1684. a hierarchical tree structure,\xx{tree}{structure}
  1685. just as in most large documents.
  1686. A section construct consists of a case-insensitive
  1687. identifying letter, which determines the
  1688. absolute level of the section in the document, and an optional section
  1689. name, which has exactly the same syntax as a macro name.
  1690. X
  1691. X\begin{verbatim}
  1692. section   = "@" levelchar [name]
  1693. levelchar = "A" | "B" | "C" | "D" | "E" |
  1694. X            "a" | "b" | "c" | "d" | "e" 
  1695. X\end{verbatim}
  1696. X
  1697. The section construct is not quite \dq{inline} as it must appear only
  1698. at the start of a line. However, unlike the \dqp{@i}, \dqp{@p}, and
  1699. X\dqp{@t} constructs, it does not consume the remainder of the line
  1700. X(although it would be silly to place anything on the same line anyway).
  1701. X
  1702. XFunnelWeb provides five levels of sections, ranging from the highest level
  1703. of \p{A} (like a \LaTeX{}\x{LaTeX}
  1704. chapter) to the lowest level of \p{E} (like a \LaTeX{}
  1705. subsubsubsection). FunnelWeb input files need not contain
  1706. any sections at all, but if they do, the first section must be at level \p{A},
  1707. and following sections must not skip hierarchical levels (\eg{}an \p{@D} cannot
  1708. follow an \p{@C}). FunnelWeb generates an error if a level is skipped.
  1709. X
  1710. All section \i{must} have names associated with them, but for convenience,
  1711. the section name is optional if the section contains one or more
  1712. macro definitions
  1713. X(\ie{}at least one macro definition appears between the section construct
  1714. in question and the
  1715. next section construct in the input file.). In this case, the section
  1716. X\i{inherits} the name of the first macro defined in the section. This
  1717. feature streamlines the input file, avoiding duplicate name inconsistencies.
  1718. X
  1719. Any sequence of printable characters can be used in the
  1720. section name,\xx{section}{name}
  1721. even the target typesetter's escape sequence (\eg{}in \TeX{},
  1722. X\dqp{\bs{}}).
  1723. X
  1724. The following example demonstrates the section construct.
  1725. X
  1726. X\begin{verbatim}
  1727. X@A@<Life Simulation@>
  1728. X
  1729. This is the main simulation module for planet earth, simulated down to the
  1730. molecular level. This is a REALLY big program. I mean really big. I mean,
  1731. if you thought the X-Windows source code was big, you're in for a shock...
  1732. X
  1733. X@B We start by looking at the code for six legged stick insects as they
  1734. form a good example of a typical object-oriented animal implementation.
  1735. X
  1736. X@$@<Six Legged Stick Insects@>@{@-
  1737. slsi.creep; slsi.crawl; slsi.creep;@}
  1738. X\end{verbatim}
  1739. X
  1740. In the above example, the name for the level A section is provided
  1741. explicitly, while the name for the level B section will be inherited from the
  1742. macro name.
  1743. X
  1744. X\subsubsection{Literal Directive}
  1745. X\xx{literal}{directive}
  1746. X
  1747. XExperience has shown that one of the most common typesetting requirement
  1748. is that of being able to typeset small program fragments
  1749. in the middle of the documenting free text. Typically
  1750. there is a frequent need to refer to program identifiers, and it
  1751. assists the reader to have such identifiers typeset in the same manner
  1752. as the program text in the macro definition.
  1753. XFunnelWeb~V1
  1754. defined a \TeX{} macro for this (called \p{p}) that simply typeset its
  1755. argument in \p{tt font}. This proved so
  1756. useful, that the facility has been made typesetter-independent in
  1757. XFunnelWeb~V3.
  1758. X
  1759. To specify that some text be typeset in \p{tt font},
  1760. enclose the text in curly brace special sequences as follows.
  1761. X
  1762. X\begin{verbatim}
  1763. literal = "@{" ordinary_text "@}"
  1764. X\end{verbatim}
  1765. X
  1766. As in macro names, section names, and macro bodies, the text contained
  1767. within the literal
  1768. construct is protected by FunnelWeb from any non-literal interpretation by
  1769. the typesetter and the user is
  1770. free to enclose \i{any} text covered by the definition \p{ordinary\_text}.
  1771. XFunnelWeb guarantees that, no matter what the text is, it will
  1772. be typeset in \p{tt font} exactly as it appears. However, the text will be
  1773. filled and justified into a paragraph as usual.
  1774. X
  1775. Here is an example of the use of the construct:
  1776. X
  1777. X\begin{verbatim}
  1778. X@C The @{WOMBAT@} (Waste Of Money, Brains, And Time) function
  1779. calls the @{kangaroo@} input function which has been
  1780. known to cause keybounce.
  1781. This keybounce can be dampened using the @{wet_sloth@} subsystem.
  1782. X\end{verbatim}
  1783. X
  1784. X\subsubsection{Emphasis Directive}
  1785. X\xx{emphasis}{directive}
  1786. X
  1787. The emphasis directive is very similar to the literal directive except that
  1788. it causes its argument to be typeset in an emphasised manner
  1789. X(\eg{}italics). Like the literal directive,
  1790. the emphasis directive protects its text argument.
  1791. X
  1792. X\begin{verbatim}
  1793. emphasise = "@/" ordinary_text "@/"
  1794. X\end{verbatim}
  1795. X
  1796. XExample:
  1797. X
  1798. X\begin{verbatim}
  1799. X@C What you @/really@/ need, of course, is a @/great@/, @/big@/,
  1800. network with packets just flying @/everywhere@/.
  1801. This section implements an interface
  1802. to such a @/humungeous@/ network.
  1803. X\end{verbatim}
  1804. X
  1805. X\subsection{Macros}
  1806. X\xx{macro}{definition}
  1807. X
  1808. The third category of
  1809. construct appearing at the highest syntactic level in a FunnelWeb
  1810. input file is the macro definition.
  1811. A macro definition binds a unique
  1812. X\newterm{macro name} to a \newterm{macro body} containing an
  1813. X\newterm{expression} consisting of text, calls to
  1814. other macros, and formal parameters. The syntax for a macro definition is as
  1815. follows:
  1816. X
  1817. X\begin{verbatim}
  1818. macro = ("@O" | "@$") name [formal_parameter_list]
  1819. X        ["@Z"] ["@M"] ["==" | "+="] "@{" expression "@}"
  1820. X\end{verbatim}
  1821. X
  1822. The complexity of the macro definition syntax is mostly to enable the user
  1823. to attach various attributes to the macro.\xx{macro}{attributes}
  1824. If the user chooses \p{@O},
  1825. then the macro cannot be called, but is instead
  1826. attached to a product file. If the user chooses \p{@\$}, then the macro is
  1827. an ordinary macro definition that is not attached to a file.
  1828. X
  1829. By default, a non-file macro must be invoked exactly once by one other
  1830. macro. Macros that
  1831. aren't are flagged with errors by the FunnelWeb analyser. However, if the
  1832. user uses the \p{@Z}\x{@Z} sequence in the macro definition, the macro is then
  1833. permitted to be invoked zero times, as well as once. Similarly, if the
  1834. user uses the \p{@M}\x{@M}
  1835. sequence in the macro definition, the macro is
  1836. permitted to be called many times as well as once. If both \p{@Z} and
  1837. X\p{@M} are present then the macro is permitted to be invoked zero, one,
  1838. or many times.
  1839. X
  1840. The purpose of enforcing the default \dq{exactly one call} rule is to
  1841. flag pieces of code that the user may have defined in a macro but not
  1842. hooked into the rest of the program. Experience shows that this is a
  1843. common error. Similarly, it can be dangerous to multiply invoke a
  1844. macro intended to be invoked only once. For example, it may be dangerous
  1845. to invoke a scrap of non-idempotent initialization code in two different
  1846. parts of the main function of a program! However, FunnelWeb will not
  1847. generate an error if a macro without \p{@M} is called by another
  1848. macro that is called more than once.
  1849. X
  1850. If the text string \p{==}\x{==} (or nothing) follows the macro name,
  1851. the  expression that follows
  1852. is the entire text  of the macro body. If the  text string \p{+=}\x{+=}
  1853. follows
  1854. the macro name,  then more than one  such definition is allowed
  1855. X(but not required) in the document
  1856. and  the body of
  1857. the macro consists of the concatenation of all such expressions in the order
  1858. in which they occur  in the input file. Such a macro is said to be
  1859. additive and is
  1860. X\newterm{additively defined}. Thus a macro body  can either be defined
  1861. in one place using one definition (using  \p{==}) or it can be \i{distributed}
  1862. throughout the input file in a sequence  of one or more macro definitions (using
  1863. X\p{+=}). If neither \p{==} and \p{+=} are present, FunnelWeb assumes a
  1864. default of \p{==}.
  1865. X
  1866. Macros attached to product files cannot be additively defined.
  1867. Additively defined macros can have parameter lists and \p{@Z} and \p{@M}
  1868. attributes, but these must be specified only in the first definition of the
  1869. macro. However,  \p{+=} must appear in each definition.
  1870. X
  1871. X\subsubsection{Names}
  1872. X\x{names}\xx{macro}{names}\xx{section}{names}
  1873. X
  1874. Names are used to identify macros and sections.
  1875. A name consists of a sequence of from zero to 80 printable characters,
  1876. including the blank
  1877. character. End of line characters are not permitted in names.
  1878. Names are case sensitive; two different macros are permitted to have names
  1879. that differ in case only. Like free text, names are typeset by FunnelWeb and
  1880. are safe from misinterpretation by the target typesetter. For example, it
  1881. is quite acceptable to use the macro name \p{@<\bs{}medskip@>}
  1882. even if the target typesetter is \TeX{}.
  1883. X
  1884. X\begin{verbatim}
  1885. name      = "@<" name_text "@>"
  1886. name_text = {ordinary_char | text_special}
  1887. X\end{verbatim}
  1888. X
  1889. X\subsubsection{Formal Parameter Lists}
  1890. X\xx{parameter lists}{formal}
  1891. X
  1892. XFunnelWeb allows macros to have up to nine macro parameters, named
  1893. X\p{@1},\x{@1...}
  1894. X\p{@2}, $\ldots$, \p{@9}. If a macro does not have a formal
  1895. parameter list,
  1896. it is defined to have no parameters, and an actual parameter list must not
  1897. appear at the point of call. If a macro has a formal parameter list, it
  1898. is defined to have one or more parameters, and a corresponding actual
  1899. parameter must be supplied for each formal parameter, at the point of call.
  1900. X
  1901. Because FunnelWeb parameters have predictable names, the only information
  1902. that a formal parameter list need convey is \i{how many} parameters a macro
  1903. has. For this reason a formal parameter list takes the form of the highest
  1904. numbered formal parameter desired, enclosed in parentheses sequences.
  1905. X
  1906. X\begin{verbatim}
  1907. formal_parameter_list = "@(" formal_parameter "@)".
  1908. formal_parameter = "@1" | "@2" | "@3" | "@4" | "@5" |
  1909. X                   "@6" | "@7" | "@8" | "@9"
  1910. X\end{verbatim}
  1911. X
  1912. X\subsection{Expressions}
  1913. X\xx{macro}{expressions}
  1914. X
  1915. XExpressions are FunnelWeb's most powerful form of expressing a text
  1916. string.
  1917. Macro bodies are defined as expressions. Actual parameters consist of
  1918. expressions.
  1919. X
  1920. An expression consists of a sequence of zero or more expression elements.
  1921. An expression element can be ordinary text, a macro call, or a formal
  1922. parameter of the macro \i{definition} in which the formal parameter occurs.
  1923. X
  1924. X\begin{verbatim}
  1925. expression = {ordinary_text | macro_call | formal_parameter}
  1926. X\end{verbatim}
  1927. X
  1928. X\subsection{Macro Calls}
  1929. X\xx{macro}{calls}
  1930. X
  1931. A macro  call consists  of a name optionally followed by an actual parameter 
  1932. list. The
  1933. number  of parameters  in the  actual parameter  list must  be the same as
  1934. the  number of formal parameters specified in the definition of the
  1935. macro. If the macro has no formal parameter list, its call must have no
  1936. actual parameter list.
  1937. X
  1938. X\begin{verbatim}
  1939. macro_call            = name [actual_parameter_list]
  1940. actual_parameter_list = "@(" actpar { "@," actpar } "@)"
  1941. actpar                = expression |
  1942. X                        ( whitespace "@""" expression "@""" whitespace )
  1943. whitespace            = {" " | eol}
  1944. X\end{verbatim}
  1945. X
  1946. XFunnelWeb allows parameters to be passed directly, or delimited by
  1947. special double
  1948. quotes.\xx{macro parameter}{delimiting}
  1949. XEach form is useful under different circumstances. Direct specification
  1950. is useful where the parameters are short and can be all placed on one line.
  1951. Double quoted parameters allow whitespace on either side
  1952. X(that is not considered part of the parameter) and are useful for laying out
  1953. rather messy parameters. Here are examples of the two forms.
  1954. X
  1955. X\begin{verbatim}
  1956. X@<Generic Loop@>@(
  1957. X   @"x:=1;@"  @,
  1958. X   @"x<=10;@" @,
  1959. X   @"print "x=%u, x^2=%u",x,x*x;
  1960. X   x:=x+1;@+@"
  1961. X@)
  1962. X
  1963. X@<Colours@>@(red@,green@,blue@,yellow@)
  1964. X\end{verbatim}
  1965. X
  1966. As shown, the two forms may be mixed within the same parameter list.
  1967. X
  1968. XExperience has shown that the vast majority of macros have no parameters.
  1969. X
  1970. X\subsection{Formal Parameters}
  1971. X\xx{formal}{parameters}
  1972. X
  1973. XFormal parameters can appear in the expressions forming macro bodies
  1974. in accordance with the syntax rules defined above. A formal parameter
  1975. expands to the text of the expansion of its corresponding
  1976. actual parameter. There is nothing preventing a formal
  1977. parameter being provided as part of an expression that forms an actual
  1978. parameter.
  1979. In that happens, the formal parameter is bound to the actual parameter of the
  1980. calling macro, not the called macro.
  1981. After the following definitions,
  1982. X
  1983. X\begin{verbatim}
  1984. X@$@<One@>@(@1@)=@{A walrus in @1 is a walrus in vain.@}
  1985. X@$@<Two@>@(@1@)=@{@<One@>@(S@1n@)@}
  1986. X\end{verbatim}
  1987. X
  1988. the call
  1989. X
  1990. X\begin{verbatim}
  1991. X@<Two@>@(pai@)
  1992. X\end{verbatim}
  1993. X
  1994. will result in the expansion
  1995. X
  1996. X\begin{verbatim}
  1997. A walrus in Spain is a walrus in vain.
  1998. X\end{verbatim}
  1999. X
  2000. X\subsection{Macros are Static}
  2001. X\xx{macro}{definition}\xx{macro}{expansion}\xx{macros}{static}
  2002. X
  2003. In FunnelWeb, the actions of \i{macro  definition} and  \i{macro
  2004. expansion} occur during two separate phases (parser and tangle)
  2005. and cannot be interleaved. As a result, the FunnelWeb macro facility is
  2006. completely static.
  2007. It is not possible for one macro to
  2008. define another while the first macro is being
  2009. expanded; each must be defined statically. It is not possible to define a
  2010. macro to even assist in the definition of other macros. Because the scanner,
  2011. parser, analyser, and tangler phases are all invoked sequentially, there is
  2012. no room for feedback of definitions between different levels (\eg{}the user
  2013. cannot define a macro for the \p{vskip} pragma).
  2014. X
  2015. This lack of power is fully intentional. By totally excluding the more
  2016. incomprehensible ways in which a general purpose macro preprocessor can be
  2017. used, FunnelWeb provides definite guarantees to the reader of its input files:
  2018. X
  2019. X\begin{itemize}
  2020. X\item FunnelWeb guarantees that a piece of text does not contain a macro call
  2021. unless it contains the special character followed by \p{$<$} or \p{\#}.
  2022. X\item FunnelWeb allows calls to be made to macros that are defined later
  2023. in the input file.
  2024. X\end{itemize}
  2025. X
  2026. X\section{Analyser}
  2027. X\x{analyser}\xx{checks}{macro}
  2028. X
  2029. The effect of the parser is to construct a macro table containing a
  2030. representation of all the macros defined within the document, and a document
  2031. list which contains a complete representation of the entire document.
  2032. If there are no error diagnostics (or worse) at the end of the parser
  2033. run, FunnelWeb invokes the analyser which tests for the following conditions
  2034. and flags them with errors if they arise.
  2035. X
  2036. X\begin{itemize}
  2037. X\item No macros defined in the input file.
  2038. X\item No macros connected to output files.
  2039. X\item Call of an undefined macro.
  2040. X\item Call having the wrong number of parameters.
  2041. X\item Call of a macro that is connected to an output file.
  2042. X\item No calls made to a macro without the \p{@Z} option.
  2043. X\item More than one call made to a macro without the \p{@M} option.
  2044. X\item Directly or indirectly recursively defined macros.
  2045. X\item Unnamed sections that contain no macro definitions.
  2046. X\end{itemize}
  2047. X
  2048. XFunnelWeb performs a static analysis\xx{static}{analysis} to detect
  2049. recursion.\xx{macro}{recursion}
  2050. Unfortunately, the recursion detection algorithm
  2051. flags all macros that have an infinite expansion
  2052. rather than just all macros
  2053. with a recursive definition. If A calls B, and B calls
  2054. C, and C calls B, then FunnelWeb will flag A as well
  2055. as B and C. It is hoped that this problem will be fixed in a later version.
  2056. X
  2057. Because FunnelWeb does not provide any kind of conditional feature, the
  2058. prevention of recursion does not represent a curtailment of expressive power.
  2059. X
  2060. Macros may be invoked recursively, but may not be recursive. Thus:
  2061. X
  2062. X\begin{verbatim}
  2063. X@<Sloth@>@(@<Sloth@>@(Walrus@)@)     @! LEGAL   recursive invocation.
  2064. X
  2065. X@$@<Teapot@>==@{@<Teapot@>@}         @! ILLEGAL recursive definition.
  2066. X\end{verbatim}
  2067. X
  2068. X\section{Tangle}
  2069. X\x{tangle}
  2070. X
  2071. If the scanner, parser, and analyser have successfully (\ie{}with no
  2072. errors, severe errors, or fatal errors) completed, and the Tangle option
  2073. X(\p{+O}) is turned on (it is by default), then the Tangle component of
  2074. XFunnelWeb is invoked to generate the product files specified in the \p{@O}
  2075. macros of the input file.
  2076. X
  2077. The operation of Tangle is very simple. Each \p{@O} macro is expanded and
  2078. written to a file of the same name. As there are a finite number of macros,
  2079. and the analyser guarantees that the
  2080. macro structure is non-recursive, Tangle is guaranteed to terminate.
  2081. X
  2082. Three remaining points are worth discussing.
  2083. X
  2084. X\begin{enumerate}
  2085. X
  2086. X\item Tangle expands macros using blank indentation unless the
  2087. user has specified otherwise in an indentation pragma in the
  2088. input file (see Section~\ref{indentationpragma}).
  2089. X
  2090. X\item Tangle keeps track of the
  2091. length of the lines that it is writing
  2092. and issues an error if any line of any product file that it generates is
  2093. longer than the maximum. The maximum is the minimum of a value defaulted
  2094. or specified in the input file (Section~\ref{mollpragma}),
  2095. and the value (if any) provided by the
  2096. X\p{+w} command line argument (Section~\ref{commandlineoptions}).
  2097. X
  2098. X\item It is worth the user obtaining
  2099. some understanding of the resources
  2100. that FunnelWeb requires to perform its task.
  2101. X
  2102. X\end{enumerate}
  2103. X
  2104. When FunnelWeb's scanner
  2105. executes, it reads each file into memory where it is kept for the duration
  2106. of the run. Thus, there must be room in memory for the entire
  2107. input file, including all include files. While this approach may seem
  2108. expensive in memory, it is almost necessary in order to support
  2109. forward references. To merely scan the input file, recording the macro
  2110. names, but leaving the text on disk, would require many random
  2111. access disk seeks.
  2112. X
  2113. In contrast, FunnelWeb never builds an internal representation
  2114. of the product file.
  2115. Instead, each piece of output is written immediately to the
  2116. product file. This means that as long as the input file fits in memory,
  2117. the product file can be arbitrarily large. It also means that users need
  2118. not fear to define or call macros that they know will expand to megabytes
  2119. of text. Nor need they fear placing a call to such a macro as part of
  2120. an actual parameter. FunnelWeb does not ever expand actual parameters
  2121. internally. In fact, it does not expand them until it hits the corresponding
  2122. formal parameter during its expansion of the called macro. At that point, it
  2123. looks up the \i{expression} (not the expansion of the expression) for the
  2124. corresponding actual parameter, and starts expanding it.
  2125. X
  2126. X\section{Weave}
  2127. X\x{weave}\x{typesetting}
  2128. X
  2129. If the scanner, parser, and analyser have successfully (\ie{}with no
  2130. errors, severe errors, or fatal errors) completed, and the Weave option
  2131. X(\p{+T}) is turned on (it is \i{off} by default), then the Weave component of
  2132. XFunnelWeb is invoked to generate a text file in the format of a particular
  2133. typesetter. The result, when fed through the particular typesetter and printed,
  2134. is a fully typeset representation of the entire input file complete with
  2135. cross referencing information.
  2136. X
  2137. X\subsection{Target Typesetter}
  2138. X\xx{target}{typesetter}
  2139. X
  2140. Currently, FunnelWeb produces documentation files
  2141. in the format of only one typesetter ---
  2142. X\TeX{}. However, the Weave package of FunnelWeb is fairly small, and it
  2143. is hoped that it can be rewritten so as to provide
  2144. a collection of typesetter modules from which
  2145. the user will be able to choose using a command line argument.
  2146. X
  2147. X\subsection{Cross Reference Numbering}
  2148. X\xx{cross}{referencing}\xx{cross reference}{numbering}
  2149. X\xx{section}{numbering}
  2150. X
  2151. When FunnelWeb produces its typeset documentation, it \i{numbers} each
  2152. section and each macro definition and cross references the macro definitions.
  2153. The exact scheme used has been carefully thought out. However, as it can
  2154. be a little confusing to the beginner, it is explained here in full.
  2155. X
  2156. The most important thing is that there is \i{no relation} between the
  2157. macro numbering and the section numbering. In Knuth's Web there are only
  2158. section numbers. In FunnelWeb,  the numbering of sections and macros
  2159. is separated.
  2160. X
  2161. In FunnelWeb, \i{sections} are numbered
  2162. hierarchically in ascending order. For example, the second level-C section
  2163. of the third level-B section of the first level-A section is
  2164. numbered \dq{1.3.2}. In contrast, \i{macro definitions} are numbered
  2165. sequentially in ascending order. For example, the first macro definition is
  2166. number 1, the second is number 2, and so on. Note that it is \i{macro
  2167. definitions} that are numbered, not \i{macros}. This distinction is necessary
  2168. because additive macros (\ie{}the ones with \p{+=})
  2169. can be defined by a collection
  2170. of partial definitions scattered throughout the input file. A single additive
  2171. macro may be defined in definitions 5, 67, 128, and 153.
  2172. X
  2173. X\section{FunnelWeb Shell}
  2174. X\label{commandshell}%
  2175. X\xx{FunnelWeb}{command shell}\xx{commands}{FunnelWeb}\xx{FunnelWeb}{shell}
  2176. X
  2177. X\subsection{Introduction}
  2178. X
  2179. One of the goals of FunnelWeb is
  2180. that it must be extremely portable. Huge efforts, desperate actions,
  2181. and great sacrifices were made in the name of portability.
  2182. XFor example, FunnelWeb is written in~C.
  2183. X
  2184. An equally important goal was that of correctness and reliability. To this
  2185. end, it was determined that a large automated suite of test programs be
  2186. prepared to assist in regression testing. Preparing the test suite was
  2187. tedious, but achievable. Automating it portably was more difficult.
  2188. X
  2189. The difficulty faced was that if FunnelWeb was implemented in the form of
  2190. a utility that could be
  2191. invoked from the operating system command language, the only way to set up
  2192. regression testing was in the command language of the operating system
  2193. of the target machine (shellscripts for UNIX, DCL for VMS, batch files
  2194. for MSDOS, and \i{nothing} on the Macintosh). The huge variation in these
  2195. command languages led to the conclusion that either the automation of
  2196. regression testing would have to be rewritten on each target machine, or
  2197. a small command language would have to be created within FunnelWeb. In the
  2198. end, the twin goals of portability and regression testing were considered so
  2199. important that a small command
  2200. shell was constructed inside FunnelWeb. This is called the
  2201. X\newterm{FunnelWeb command shell}, or just \dq{the shell} for short.
  2202. X
  2203. By default, when FunnelWeb is invoked, it does not enter its shell. If
  2204. just given the name of an input file, it will simple process the input file
  2205. in the normal manner and then terminate. To instruct FunnelWeb to
  2206. invoke its shell, the \p{+K} or \p{+X} command line option must be specified
  2207. when FunnelWeb is invoked from the operating system. It is also
  2208. invoked upon startup if the file \p{fwinit.fws} exists.
  2209. X
  2210. Most FunnelWeb users will never need to use the shell and need not even
  2211. know about it. There are four main uses of the shell:\xx{uses}{shell}
  2212. X
  2213. X\begin{enumerate}
  2214. X
  2215. X\item As a tool to support automated regression testing.
  2216. X
  2217. X\item As a development tool on machines that do not have a built in shell
  2218. X(\eg{}the Macintosh). The shell can be used to process whole groups of
  2219. files automatically.
  2220. X
  2221. X\item As a convenience. A user working on a multi-tasking, multi-window
  2222. workstation\x{workstation}
  2223. may wish to keep an interactive session of FunnelWeb going in
  2224. one window rather than having to run up the utility each time it is required.
  2225. X
  2226. X\item As a convenient
  2227. vehicle for enclosing utilities. The FunnelWeb shell contains
  2228. useful general purpose commands such as the
  2229. differences command \p{diff}.
  2230. X
  2231. X\end{enumerate}
  2232. X
  2233. X\subsection{Return Statuses}
  2234. X\xx{errors}{shell}\xx{status}{success}%
  2235. X\xx{status}{warning}\xx{status}{error}\xx{status}{severe}\xx{status}{fatal}%
  2236. X\xx{status}{assertion}
  2237. X
  2238. The hierarchy of diagnostics described in Section~\ref{diagnostics}
  2239. is also used in the
  2240. shell commands. Each shell command returns a status which can affect
  2241. further processing.
  2242. X
  2243. X\narrowthing{Success}{status is the normal command return status.}
  2244. X
  2245. X\narrowthing{Warning}{status is returned if some minor problem
  2246. arose with the execution of the command.}
  2247. X
  2248. X\narrowthing{Error}{status is returned if a significant problem
  2249. arises during the execution of the command.
  2250. However, unlike a severe error,
  2251. it does \i{not} cause termination of the enclosing shellscript.}
  2252. X
  2253. X\narrowthing{Severe error}{status is returned if a problem arises
  2254. during the execution of the command that prevents the command from
  2255. delivering on its \dq{promise}. A severe error causes FunnelWeb
  2256. to abort the script (and any stacked scripts) to the interactive level.
  2257. X(However, the \p{tolerate} command allows this to be temporarily
  2258. overridden).}
  2259. X
  2260. X\narrowthing{Fatal error}{status is returned if a problem arises
  2261. that is so serious that execution of FunnelWeb cannot continue.
  2262. A fatal error causes FunnelWeb to abort to the operating system level.}
  2263. X
  2264. X\narrowthing{Assertion error}{status is never returned. If an assertion
  2265. error occurs, FunnelWeb bombs out ungracefully to the operating system.
  2266. Assertion errors should never happen. If they do, then there is a bug
  2267. in FunnelWeb.}
  2268. X
  2269. To be precise, the status returned by each command
  2270. is a vector of numbers being the number of each of the different kinds of
  2271. diagnostic generated by the command. Usually only one kind
  2272. of diagnostic is generated. However, the \p{fw} command and a few of the other
  2273. commands can generate more than one kind of diagnostic.
  2274. These status vectors are summed internally where they may later be accessed
  2275. using the \p{status} command. However, the current diagnostic state
  2276. evaporates as soon as the next command is encountered.
  2277. X
  2278. X\subsection{Command Line Length}
  2279. X\xx{command}{length}
  2280. X
  2281. The maximum length of a shell command line is guaranteed to be
  2282. at least 300 characters.
  2283. X
  2284. X\subsection{String Substitution}
  2285. X\label{stringsubstitution}\xx{string}{substitution}
  2286. X
  2287. Most command shells provide some form of string substitution so
  2288. as to provide some degree of parameterization.
  2289. The FunnelWeb shell provides 36 different string variables named
  2290. X\p{\$0..\$9} and \p{\$A..\$Z} (case insensitive).
  2291. XEach variable can hold a string containing
  2292. any sequence of printable characters and can be as long as a command line.
  2293. X
  2294. The \p{define} command\xx{define}{command}
  2295. allows the user to assign a value to these variables.
  2296. The \p{define} command takes two arguments. The first is the digit or letter
  2297. of the
  2298. variable to be defined. The second is a double quote delimited string being the
  2299. string value to be assigned to the variable. If you want to include a
  2300. double quote character within the string, you don't need to double it.
  2301. X
  2302. XExamples:
  2303. X
  2304. X\begin{verbatim}
  2305. define 3 "/root/usr/usrs/users/users5/thisuser/workdir/fwdir/testdir"
  2306. define M "/user/local/rubbish/bin/fw"
  2307. define Q "You don't need to double" double quotes"
  2308. X\end{verbatim}
  2309. X
  2310. Only the identifying character of the variable being assigned
  2311. is used in the definition. This syntax is a simple way of preventing
  2312. the variable from being substituted before it has a chance to be
  2313. defined!
  2314. X
  2315. The following points clean up the remaining semantic details:
  2316. X
  2317. X\begin{itemize}
  2318. X
  2319. X\item There is only one set of variables and they are global to all
  2320. shellscripts. There are \i{no local variables}.
  2321. X
  2322. X\item When a shellscript is invoked using the \p{execute} command, the
  2323. substitution variables \p{0} through \p{9} are affected. See
  2324. Section~\ref{executecommand} for more details.
  2325. X
  2326. X\item If you want to include a dollar sign character in a command
  2327. use \dqp{\$\$}.
  2328. X
  2329. X\item FunnelWeb also defines \dqp{\$/} which translates to the character
  2330. that separates directory and file name fields in file names on the host
  2331. machine. For example: Sun=\dqp{/}, Vax=\dqp{]}, Mac=\dqp{:},
  2332. PC=\dqp{\bs{}}.
  2333. X
  2334. X\item Substitution is not performed recursively.
  2335. X
  2336. X\end{itemize}
  2337. X
  2338. X\subsection{How a Command Line is Processed}
  2339. X\xx{command line}{processing}
  2340. X
  2341. When FunnelWeb reads in a command line (from the console or a script file),
  2342. it processes it in the following sequence:
  2343. X
  2344. X\begin{enumerate}
  2345. X
  2346. X\item The command line is checked for non-printable characters. If there
  2347. are any, they are flagged with a severe error.
  2348. X
  2349. X\item All dollar string substitution variables in the command line are
  2350. replaced by their corresponding string.
  2351. The command line is processed from left to right. Substitutions are
  2352. performed non recursively.
  2353. X
  2354. X\item At this point, if the line is empty, or consists entirely of
  2355. blanks, it is ignored and the interpreter moves to the next line.
  2356. X
  2357. X\item A severe error is generated if the line at this stage begins with
  2358. a blank.
  2359. X
  2360. X\item If the first character of the line is \dqp{!}, the line is a
  2361. comment line and is ignored.
  2362. X
  2363. X\item The run of non-blanks commencing at the start of the line is
  2364. compared case-insensitively to each of the legal command verbs. If the
  2365. command is illegal, a severe error is generated, otherwise the command
  2366. is processed.
  2367. X
  2368. X\end{enumerate}
  2369. X
  2370. X\subsection{Options}
  2371. X\xx{command}{options}\xx{default}{options}
  2372. X
  2373. The FunnelWeb shell maintains three sets of command line options.
  2374. X
  2375. X\begin{enumerate}
  2376. X
  2377. X\item The set of options resulting from applying the operating system
  2378. level command line
  2379. arguments to the default option settings.
  2380. X
  2381. X\item A set of shell options that prevail during the shell invocation.
  2382. X
  2383. X\item The set of option values active during a particular invocation
  2384. of FunnelWeb proper.
  2385. X
  2386. X\end{enumerate}
  2387. X
  2388. When FunnelWeb is invoked from the operating system with just \p{+F},
  2389. only the first of these three sets comes into existence. If the user
  2390. invokes the FunnelWeb shell, the shell options come into existence and are
  2391. initialized with the value of the first set. These shell options are
  2392. used as the default for all subsequent \p{fw} commands. However,
  2393. they can be altered using the script command \p{set}. If a
  2394. X\p{fw} command executed in a shell contains additional command line options,
  2395. these override the shell options for that run, but do not change the
  2396. shell options. An example follows:
  2397. X
  2398. X\begin{verbatim}
  2399. X$ fw +k +t            ! Original invocation of FunnelWeb from OS.
  2400. X                      ! Shell options are now default with "+t".
  2401. XFunnelWeb>fw sloth    ! Equivalent to fw sloth +t.
  2402. XFunnelWeb>set -l      ! Change the l shell option.
  2403. XFunnelWeb>fw sloth +q ! Equivalent to fw sloth +t -l +q.
  2404. XFunnelWeb>fw sloth    ! Equivalent to fw sloth +t -l.
  2405. X\end{verbatim}
  2406. X
  2407. The existence of the shell option set means that the user can set up
  2408. a set of defaults to be applied to all \p{fw} commands issued within
  2409. the shell.
  2410. X
  2411. X\subsection{Shell Commands}
  2412. X\xx{shell commands}{list}\xx{commands}{shell}
  2413. X
  2414. This section describes each of the FunnelWeb shell commands. The syntax
  2415. is:
  2416. X
  2417. X\begin{verbatim}
  2418. shell_command = absent   | codify | compare | define | diff    | diffsummary |
  2419. X                diffzero | eneo   | execute | exists | fixeols | help        |
  2420. X                here     | quit   | set     | show   | skipto  | status      |
  2421. X                tolerate | trace  | write   | writeu
  2422. s = {" "}+
  2423. X\end{verbatim}
  2424. X
  2425. As a rule, FunnelWeb shell commands return severe status if their
  2426. arguments are syntactically incorrect or if they are
  2427. unable to successfully operate on argument files.
  2428. X
  2429. X\subsubsection{Absent}
  2430. X\xx{command}{absent}
  2431. X
  2432. The \p{absent} command performs no action except to return a status. If the
  2433. file specified in its argument doesn't exist
  2434. it returns success status, otherwise it returns severe status.
  2435. X
  2436. X\begin{verbatim}
  2437. Syntax : absent = "absent" s filename
  2438. XExample: absent result.out
  2439. X\end{verbatim}
  2440. X
  2441. This command is useful in regression testing
  2442. for making sure that
  2443. XFunnelWeb \i{hasn't} produced a particular output file.
  2444. X
  2445. X\subsubsection{Codify}
  2446. X\xx{command}{codify}
  2447. X
  2448. The \p{codify} command takes two arguments: an input file and an output file.
  2449. It reads each line of the input file and writes a corresponding line to the
  2450. output file. The corresponding line consists of a C macro call containing
  2451. a string containing the input line. The command converts all backslashes in
  2452. input lines to double backslashes so as to avoid unwanted interpretations by
  2453. the C compiler. It also converts double quotes in the line to backslashed
  2454. double quotes.
  2455. X
  2456. X\begin{verbatim}
  2457. Syntax : codify = "codify" s filename s filename
  2458. XExample: codify header.tex header.c
  2459. X\end{verbatim}
  2460. X
  2461. The following example demonstrates the transformation.
  2462. X
  2463. X\begin{verbatim}
  2464. Input  Line: \def\par{\leavevmode\endgraf}% A "jolly good hack".
  2465. Output Line: WX("\\def\\par{\\leavevmode\\endgraf}% A \"jolly good hack\".");
  2466. X\end{verbatim}
  2467. X
  2468. The \p{codify} command was introduced to assist in the
  2469. development of FunnelWeb.
  2470. It is used to convert longish text files
  2471. into C code to write them out. The C code is then included within
  2472. the FunnelWeb C program. For example,
  2473. the set of \TeX{} definitions that appears at the top of every
  2474. documentation file was \p{codif}ied and inserted into the
  2475. XFunnelWeb code so that FunnelWeb would not have to look for a file containing
  2476. the definitions at run time.
  2477. X
  2478. X\subsubsection{Compare}
  2479. X\xx{command}{compare}
  2480. X
  2481. The \p{compare} command takes two filename arguments and performs a binary
  2482. comparison of the two files. If the files are identical, success status
  2483. is returned. If they are different, severe status is returned. No information
  2484. about the manner in which the files differ is conveyed.
  2485. X
  2486. X\begin{verbatim}
  2487. Syntax : compare = "compare" s filename s filename
  2488. XExample: compare result.txt answer.txt
  2489. X\end{verbatim}
  2490. X
  2491. The \p{compare} command was created as the main checking mechanism for
  2492. regression testing. However, its binary output was soon found to be
  2493. unworkable and the more sophisticated \p{diff} command was added so
  2494. that the actual differences between the files could be examined.
  2495. X
  2496. X\subsubsection{Define}
  2497. X\xx{command}{define}\xx{string}{substitution}
  2498. X
  2499. The \p{define} command
  2500. assigns a value to a shell string substitution variable.
  2501. The \p{define} command takes two arguments. The first is the digit or letter
  2502. of the
  2503. variable to be defined. The second is a double quote delimited string being the
  2504. string value to be assigned to the variable. If you want to include a
  2505. double quote character within the string, you don't need to double it.
  2506. X
  2507. X\begin{verbatim}
  2508. Syntax  : define = "define" s letter s """" text """"
  2509. XExamples: define 3 "/usr/usrs/thisuser/workdir/fwdir/testdir"
  2510. X          define M "/user/local/rubbish/bin/fw"
  2511. X          define Q "You don't need to double" double quotes"
  2512. X\end{verbatim}
  2513. X
  2514. The command interpreter expands the command line before it executes the
  2515. X\p{define} command. This means that you can define string substitution
  2516. variables in terms of each other with static binding.
  2517. X
  2518. The \p{define} command was introduced to allow the parameterization
  2519. of the directories involved in regression testing.
  2520. X
  2521. See Section~\ref{stringsubstitution} for more details.
  2522. X
  2523. X\subsubsection{Diff}
  2524. X\xx{command}{diff}\xx{file}{differences}
  2525. X
  2526. The \p{diff} command reads in two text files and \i{appends} a report to a log
  2527. file containing a list of the differences between the two input
  2528. files. If the log file does not already exist, an empty one is created first.
  2529. X
  2530. X\begin{verbatim}
  2531. Syntax  : diff = "diff" s filename s filename s filename s ["ABORT"]
  2532. XExamples: diff result.tex answer.tex diff.log
  2533. X          diff $Otest23.out $Atest23.out $Ldiff.log ABORT
  2534. X\end{verbatim}
  2535. X
  2536. The \p{diff} command performs a full line-based differences operation.
  2537. It will identify different sections in a file, even if they are of differing
  2538. length.
  2539. X
  2540. The implementation of the \p{diff} command is quite complicated. To be
  2541. sure that it is at least getting its same/different proclamation right,
  2542. the \p{diff} command performs a binary comparison as an extra check.
  2543. X
  2544. The following points describe the rules for determining the result status.
  2545. X
  2546. X\begin{enumerate}
  2547. X
  2548. X\item \p{diff} aborts with a
  2549. severe error if the log file cannot be opened or
  2550. created for appending.
  2551. X
  2552. X\item An ordinary error is generated if either or both of the input files
  2553. cannot be opened.
  2554. X
  2555. X\item If, at the end of the run, the two input files have not
  2556. been proven to be identical, and the \p{ABORT} keyword is present, \p{diff}
  2557. returns severe status.
  2558. X
  2559. X\item \p{diff} returns success status if none of the above conditions
  2560. X(or similar conditions) occur, even if the two files are different.
  2561. X
  2562. X\end{enumerate}
  2563. X
  2564. The \p{diff} command \i{appends} its differences report rather than
  2565. merely writing it. This allows a regression test script to perform
  2566. a series of regression tests and produce a report for the user.
  2567. X
  2568. The \p{diff} command was added to the shell after it had become apparent
  2569. that the simpler \p{compare} command was not yielding enough information.
  2570. Whereas early on, regression testing was treated
  2571. mainly as a tool to ensure that FunnelWeb was being ported to other machines
  2572. correctly, it began to place an increasing role during development in
  2573. identifying the effects of changes made to the code. The \p{diff} command
  2574. supports this application of regression testing by pinpointing the
  2575. differences between nearly-identical text files.
  2576. X
  2577. X\subsubsection{Diffsummary}
  2578. X\xx{command}{diffsummary}
  2579. X
  2580. The \p{diffsummary} command writes a short report to the
  2581. console giving the number of
  2582. difference operations that have taken place and how many of the pairs
  2583. of files compared were identical. Counting starts at the most recent
  2584. execution of a \p{diffzero} command, or if there has been none, when
  2585. XFunnelWeb started up.
  2586. X
  2587. X\begin{verbatim}
  2588. Syntax  : diffsummary = "diffsummary"
  2589. XExamples: diffsummary
  2590. X\end{verbatim}
  2591. X
  2592. The \p{diffsummary} command was added so as to allow regression testing
  2593. scripts to display a summary of the results of the test. If the summary
  2594. indicates that no pair of files differed, then there is no need to look
  2595. in the \p{diff} log file.
  2596. X
  2597. X\subsubsection{Diffzero}
  2598. X\xx{command}{diffzero}
  2599. X
  2600. The \p{diffzero} command zeros the different summary counters used by the
  2601. X\p{diff} and \p{diffsummary} commands.
  2602. X
  2603. X\begin{verbatim}
  2604. Syntax  : diffzero = "diffzero"
  2605. XExamples: diffzero
  2606. X\end{verbatim}
  2607. X
  2608. The \p{diffzero} command was added so as to allow regression testing
  2609. shellscripts to zero their differences counters at the start of a run.
  2610. This allows testers to invoke the same regression testing script
  2611. twice in one interactive session without receiving an inflated
  2612. differences summary.
  2613. X
  2614. X\subsubsection{Eneo}
  2615. X\xx{command}{eneo}
  2616. X
  2617. The \p{eneo} command takes one filename argument. If the file does
  2618. not exist, no action is taken. If the file does exist, it is deleted.
  2619. In both cases success status is returned. However, if the file exists
  2620. and cannot be deleted, \p{eneo} returns severe status.
  2621. X
  2622. X\begin{verbatim}
  2623. Syntax  : eneo = "eneo" s filename
  2624. XExamples: eneo result.out
  2625. X\end{verbatim}
  2626. X
  2627. The \p{eneo} command was added so as to allow regression testing scripts
  2628. to ensure that existing output files were not present before proceeding
  2629. with a test run. If FunnelWeb were to fail to generate an output file, it
  2630. would be
  2631. extremely undesirable for the old version to be used.
  2632. X
  2633. XENEO stands for \b{E}stablish the \b{N}on \b{E}xistence \b{O}f.
  2634. Most operating systems provide a command to delete files. Typically
  2635. these commands are verbs such as \dq{delete}, \dq{remove}, and \dq{kill}.
  2636. As a consequence, the designers of delete commands usually
  2637. consider the command to have failed if it fails to find the file to be
  2638. deleted. However, in my experience, the most common use
  2639. for the delete command
  2640. is to \i{establish the non-existence of} one or more files. Typically, a
  2641. script is starting up and needs to clear the air before getting started.
  2642. If the files are there, they should be deleted; if they are not, then that's
  2643. OK too.\footnote{As far as I know, the \p{eneo} command is original.}
  2644. X
  2645. X\subsubsection{Execute}
  2646. X\label{executecommand}\xx{command}{execute}
  2647. X
  2648. The \p{execute} command causes a specified text file to be
  2649. executed as a FunnelWeb shellscript. The first argument is the
  2650. name of the script file.
  2651. The remaining arguments are assigned to the substitution
  2652. variables \p{\$1}, \p{\$2}, $\ldots$, \p{\$9}.
  2653. Substitution variables in the range
  2654. X\p{\$1} to \p{\$9} that do not correspond to an argument are set to
  2655. the empty string \p{""}. \p{\$0} is set to the empty string regardless.
  2656. The execute command can be used recursively, allowing shell scripts to
  2657. invoke each other. A file extension default of \dqp{.fws}
  2658. X(FunnelWeb Script) applies to script files.
  2659. X
  2660. X\begin{verbatim}
  2661. Syntax  : execute = "execute" s filename {argument_string}
  2662. XExamples: execute megatest.fws /usr/users/ross/fwtest !
  2663. X          execute sloth
  2664. X\end{verbatim}
  2665. X
  2666. The first example above will result in the following substitution variable
  2667. assignments.
  2668. X
  2669. X\begin{verbatim}
  2670. X$0 = ""
  2671. X$1 = "/usr/users/ross/fwtest"
  2672. X$2 = "!"
  2673. X$3 = ""
  2674. X...
  2675. X$9 = ""
  2676. X\end{verbatim}
  2677. X
  2678. It should be stressed that there are no local variables in the FunnelWeb
  2679. command language; the variables above are globally modified.
  2680. X
  2681. The \p{execute} command was added to allow the creation of sub-scripts
  2682. to test FunnelWeb in particular ways.
  2683. X
  2684. X\subsubsection{Exists}
  2685. X\xx{command}{exists}
  2686. X
  2687. The \p{exists} command performs no action except to return a status. If the
  2688. file specified in its argument exists
  2689. it returns success status, otherwise it returns severe status.
  2690. X
  2691. X\begin{verbatim}
  2692. Syntax : exists = "exists" s filename
  2693. XExample: exists test6.fw
  2694. X\end{verbatim}
  2695. X
  2696. This command is useful in regression testing
  2697. for ensuring that
  2698. XFunnelWeb has produced a particular output file.
  2699. X
  2700. X\subsubsection{Fixeols}
  2701. X\xx{command}{fixeols}
  2702. X
  2703. The \p{fixeols} command takes two filename arguments: an input file and
  2704. an output file. It reads in the input file and writes it to the output file
  2705. changing all the end of line control character
  2706. sequences to the local format. It can also take one filename argument, in
  2707. which case it replaces the target file with its transformation.
  2708. X
  2709. X\begin{verbatim}
  2710. Syntax  : fixeols = "fixeols" s filename [s filename]
  2711. XExamples: fixeols imported.hak result.kln
  2712. X          fixeols sloth.dat
  2713. X\end{verbatim}
  2714. X
  2715. The \p{fixeols} command works by parsing the input file into alternating
  2716. runs of
  2717. printable characters (ASCII 20 to ASCII 126) and runs of non-printable
  2718. characters (all the others).
  2719. It then\xx{non-printable}{characters}
  2720. parses each run of non-printable characters from left to right into
  2721. subruns of non-printables not containing the same character twice.
  2722. It then replaces each subrun with a native EOL.\footnote{Note: A native
  2723. XEOL can be inserted into a text file in a portable manner
  2724. simply by writing \dqp{\bs{}n} to the text output stream.}
  2725. XFor example,
  2726. if a native EOL is \p{X}, and \p{ABCD} are non-printable characters, and
  2727. the file to be converted is
  2728. X
  2729. X\begin{verbatim}
  2730. thisABisABCDanABABexampleABCCCof the conversion.
  2731. X\end{verbatim}
  2732. X
  2733. then \p{fixeols} would produce
  2734. X
  2735. X\begin{verbatim}
  2736. thisXisXanXXexampleXXXof the conversion.
  2737. X\end{verbatim}
  2738. X
  2739. The \p{fixeols} command was devised to solve the problem created sometimes
  2740. when text files are moved from one machine to another
  2741. X(\eg{}with the kermit program)
  2742. using a binary transfer mode rather than a text transfer mode.
  2743. If such a transfer is made, and the text file line termination conventions
  2744. differ on the two machines, one can wind up with a set of
  2745. text files with improperly terminated lines. This can cause problems
  2746. on a number of fronts, but in particular affects regression testing
  2747. which relies heavily on exact comparisons between files. The \p{fixeols}
  2748. command provides a solution to this problem by providing a portable way
  2749. to \dq{purify} text files whose end of lines have become incorrect.
  2750. The regression testing scripts all apply \p{fixeols} to their input and
  2751. output files before each test.
  2752. X
  2753. X\subsubsection{Fw}
  2754. X\xx{command}{fw}
  2755. X
  2756. The \p{fw} command allows FunnelWeb proper to be invoked from a shell
  2757. script. The syntax is almost identical to the syntax with which FunnelWeb is
  2758. invoked from the operating system.
  2759. X
  2760. X\begin{verbatim}
  2761. Syntax  : fw = "fw" s ordinary_funnelweb_command_line
  2762. XExamples: fw sloth +t +d
  2763. X          fw -l walrus
  2764. X\end{verbatim}
  2765. X
  2766. Some important points about this \p{fw} command are:
  2767. X
  2768. X\begin{itemize}
  2769. X\item Options are inherited from the default shell options.
  2770. X\item The \p{F} (input file option) must be turned on.
  2771. X\item The \p{K}, \p{H}, and \p{X} options must be turned off.
  2772. X\item The \p{J} option must be turned off.
  2773. X\item The options specified in a \p{fw} command do not affect the default
  2774. shell options.
  2775. X\item This command performs no action in the VAX VMS version of FunnelWeb.
  2776. X\end{itemize}
  2777. X
  2778. X\subsubsection{Help}
  2779. X\xx{command}{help}
  2780. X
  2781. The \p{help} command provides online help from within the FunnelWeb shell.
  2782. It provides access to all of the same messages that the \p{+H} command
  2783. line option does.
  2784. X
  2785. X\begin{verbatim}
  2786. Syntax  : help = "help" [s help_message_name]
  2787. XExamples: help
  2788. X          help commands
  2789. X\end{verbatim}
  2790. X
  2791. If no message name is given, the default message is displayed. It contains
  2792. a list of the other help messages and their names. The actual messages
  2793. themselves are not listed here.
  2794. X
  2795. X\subsubsection{Here}
  2796. X\xx{command}{here}
  2797. X
  2798. The \p{here} command acts as a target for the \p{skipto} command. When
  2799. the shell interpreter encounters a \p{skipto} command, it ignores all
  2800. the following commands until it encounters a \p{here} command.
  2801. X
  2802. X\begin{verbatim}
  2803. Syntax : here = "here"
  2804. XExample: here
  2805. X\end{verbatim}
  2806. X
  2807. The \p{skipto}/\p{here} mechanism was created to allow groups of
  2808. regression tests to be skipped during debugging without having to comment
  2809. them out. For more information, see Section~\ref{skiptocommand}.
  2810. X
  2811. X\subsubsection{Quit}
  2812. X\xx{command}{quit}
  2813. X
  2814. The \p{quit} command terminates FunnelWeb immediately and returns
  2815. control to the operating system. This applies regardless of the depth
  2816. of the script being executed.
  2817. X
  2818. X\begin{verbatim}
  2819. Syntax : quit = "quit"
  2820. XExample: quit
  2821. X\end{verbatim}
  2822. X
  2823. X\subsubsection{Set}
  2824. X\xx{command}{set}
  2825. X
  2826. The \p{set} command modifies the default shell options.
  2827. XFor example, \p{set +t} sets the \p{+t} option for all subsequent
  2828. XFunnelWeb runs within the shell until another set command
  2829. sets \p{-t}.
  2830. X
  2831. X\begin{verbatim}
  2832. Syntax  : set = "set" s ordinary_funnelweb_command_line
  2833. XExamples: set sloth +t +d
  2834. X          set -lwalrus
  2835. X\end{verbatim}
  2836. X
  2837. The restrictions on the \p{set} command are identical to those on the
  2838. X\p{fw} command except that, in addition,
  2839. the \p{+F} option cannot be turned on in the \p{set} command.
  2840. X
  2841. The set command is useful for setting option defaults before a long run
  2842. of regression tests. It could also be useful to set default options in
  2843. a FunnelWeb shell kept by a user in a workstation window.
  2844. X
  2845. X\subsubsection{Show}
  2846. X\xx{command}{show}
  2847. X
  2848. The \p{show} command displays the current default shell options.
  2849. These options are the options that subsequent \p{fw} commands will
  2850. inherit.
  2851. X
  2852. X\begin{verbatim}
  2853. Syntax : show = "show"
  2854. XExample: show
  2855. X\end{verbatim}
  2856. X
  2857. X\subsubsection{Skipto}
  2858. X\label{skiptocommand}\xx{command}{skipto}
  2859. X
  2860. The \p{skipto} command causes the shell to ignore all subsequent commands
  2861. until a \p{here} command is encountered.
  2862. X
  2863. X\begin{verbatim}
  2864. Syntax  : skipto = "skipto"
  2865. XExamples: skipto
  2866. X\end{verbatim}
  2867. X
  2868. The \p{skipto}/\p{here} mechanism was created to allow groups of
  2869. regression tests to be skipped during debugging without having to comment
  2870. them out. It is like a cut price \p{goto}.
  2871. XFor example, supposing that there were eight tests and that
  2872. you had debugged the first five. You might want to skip the first five
  2873. tests so that you can concentrate on the next three. The following
  2874. code shows how this can be done.
  2875. X
  2876. X\begin{verbatim}
  2877. skipto
  2878. execute test infile1
  2879. execute test infile2
  2880. execute test infile3
  2881. execute test infile4
  2882. execute test infile5
  2883. here
  2884. execute test infile6
  2885. execute test infile7
  2886. execute test infile8
  2887. X\end{verbatim}
  2888. X
  2889. It should be stressed that FunnelWeb performs full command line processing
  2890. including the dollar substitutions before testing the line to see if
  2891. it is \p{here}. This can lead to non-obvious problems. For example.
  2892. X
  2893. X\begin{verbatim}
  2894. skipto
  2895. X! Test the Parser
  2896. X! ---------------
  2897. define X "execute parsertest.fws"
  2898. X$X infile1
  2899. X$X infile2
  2900. X$X infile3
  2901. X$X infile4
  2902. X$X infile5
  2903. here
  2904. X\end{verbatim}
  2905. X
  2906. The above looks correct, but, because the \p{define} command isn't executed
  2907. X(and \p{\$X} is not defined) the subsequent \p{\$X} lines result in a
  2908. leading blanks error. The problem can be corrected by defining \p{\$X}
  2909. before the \p{skipto} command.
  2910. X
  2911. X\subsubsection{Status}
  2912. X\xx{command}{status}
  2913. X
  2914. The \p{status} command takes two forms. In its first form in which
  2915. no arguments are given, it writes out the number of warnings, errors
  2916. and severe errors that 1) were generated by the previous command
  2917. and 2) have been generated during the entire shell invocation.
  2918. In its second form it takes from one to three arguments each of which
  2919. specifies a diagnostic severity and a number. The \p{status} command
  2920. compares each of these numbers with the number of that diagnostic
  2921. generated by the previous command and generates a severe error if
  2922. they differ.
  2923. X
  2924. X\begin{verbatim}
  2925. Syntax  : status = "status" {s ("w"|"e"|"s") num}0..3
  2926. XExamples: status
  2927. X          status w1 e5 s1
  2928. X          status w4
  2929. X          status s1 e2
  2930. X\end{verbatim}
  2931. X
  2932. The \p{status} command was introduced to test the status results of
  2933. commands during their debugging. It is also useful for checking to see that
  2934. the right number of diagnostics have been generated at particular points
  2935. in test scripts.
  2936. X
  2937. X\subsubsection{Tolerate}
  2938. X\xx{command}{tolerate}
  2939. X
  2940. The \p{tolerate} command instructs the shell not to abort processing
  2941. of the script if the next command generates one or more warnings, errors,
  2942. or severe errors. For the purposes of this command, a blank line counts
  2943. as a command, so be sure to place the \p{tolerate} command immediately
  2944. above the command about which you wish to be tolerant.
  2945. X
  2946. X\begin{verbatim}
  2947. Syntax : tolerate = "tolerate"
  2948. XExample: tolerate
  2949. X\end{verbatim}
  2950. X
  2951. The tolerate command was introduced to allow FunnelWeb (\ie{}the
  2952. X\p{fw} command) to be tested
  2953. in a script under conditions which would normally cause it to abort the
  2954. script.
  2955. X
  2956. X\subsubsection{Trace}
  2957. X\xx{command}{trace}
  2958. X
  2959. The \p{trace} command turns on or off command tracing during script
  2960. execution. By default, tracing is turned off.
  2961. X
  2962. X\begin{verbatim}
  2963. Syntax  : trace = "trace" [s ("on" | "off")]
  2964. XExamples: trace on
  2965. X          trace off
  2966. X\end{verbatim}
  2967. X
  2968. The \p{trace} command was introduced to assist in the debugging of
  2969. regression test scripts.
  2970. X
  2971. X\subsubsection{Write}
  2972. X\xx{command}{write}
  2973. X
  2974. The \p{write} command accepts a double-quoted argument and writes it followed
  2975. by an EOL to the console (standard output).
  2976. There is no need to double any double quotes
  2977. occurring within the string.
  2978. X
  2979. X\begin{verbatim}
  2980. Syntax  : write = "write" s string
  2981. XExamples: write "Now about to start the next test."
  2982. X          write "You don't need to " double enclosed double quotes."
  2983. X\end{verbatim}
  2984. X
  2985. The \p{write} command was added so as to allow regression testing scripts
  2986. to inform the user of their progress.
  2987. X
  2988. X\subsubsection{Writeu}
  2989. X\xx{command}{writeu}
  2990. X
  2991. The \p{writeu} command is identical to the \p{write} command except that it
  2992. underlines the text on an additional following output line.
  2993. X
  2994. X\begin{verbatim}
  2995. Syntax  : writeu = "writeu" s string
  2996. XExamples: writeu "Test 6"
  2997. X\end{verbatim}
  2998. X
  2999. X\section{Concluding Remarks}
  3000. X
  3001. This chapter defines the semantics of the FunnelWeb program. As stated
  3002. at the start of this chapter, this document takes precedence over the
  3003. XFunnelWeb program. While the
  3004. definition of FunnelWeb in this chapter is reasonably solid, it is far
  3005. from watertight, and it is hoped that it can be tightened further in
  3006. future versions. All constructive criticism will be gratefully received
  3007. by the author Ross Williams (\p{ross@spam.adelaide.edu.au}).
  3008. X
  3009. X%==============================================================================%
  3010. X%                               End of Ch3.tex                                 %
  3011. X%==============================================================================%
  3012. END_OF_FILE
  3013. if test 117966 -ne `wc -c <'userman/u_ch3.tex'`; then
  3014.     echo shar: \"'userman/u_ch3.tex'\" unpacked with wrong size!
  3015. fi
  3016. # end of 'userman/u_ch3.tex'
  3017. fi
  3018. echo shar: End of archive 20 \(of 20\).
  3019. cp /dev/null ark20isdone
  3020. MISSING=""
  3021. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
  3022.     if test ! -f ark${I}isdone ; then
  3023.     MISSING="${MISSING} ${I}"
  3024.     fi
  3025. done
  3026. if test "${MISSING}" = "" ; then
  3027.     echo You have unpacked all 20 archives.
  3028.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  3029. else
  3030.     echo You still need to unpack the following archives:
  3031.     echo "        " ${MISSING}
  3032. fi
  3033. ##  End of shell archive.
  3034. exit 0
  3035.