\input mcwebmac
% This file is part of mCWEB.
% This program by Markus Öllinger is based on
% CWEB 3.4 by Silvio Levy and Donald E. Knuth which in turn
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
% Version 1.1 --- October 1998

% Copyright (C) 1996-1998 Markus Öllinger

% Permission is granted to make and distribute verbatim copies of this
% document provided that the copyright notice and this permission notice
% are preserved on all copies.

% Permission is granted to copy and distribute modified versions of this
% document under the conditions for verbatim copying, provided that the
% entire resulting derived work is given a different name and distributed
% under the terms of a permission notice identical to this one.

% Here is TeX material that gets inserted after \input mcwebmac
\def\hang{\hangindent 3em\indent\ignorespaces}
\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
\def\v{\char'174} % vertical (|) in typewriter font
\def\dleft{[\![} \def\dright{]\!]} % double brackets
\mathchardef\RA="3221 % right arrow
\mathchardef\BA="3224 % double arrow
\def\({} % ) kludge for alphabetizing certain section names
\def\TeXxstring{\\{\TEX/\_string}}
\def\skipxTeX{\\{skip\_\TEX/}}
\def\copyxTeX{\\{copy\_\TEX/}}

\def\title{mCWEAVE (Version 1.1)}
\def\topofcontents{\null\vfill
  \centerline{\titlefont The {\ttitlefont mCWEAVE} processor}
  \vskip 15pt
  \centerline{(Version 1.1)}
  \vfill}
\def\botofcontents{\vfill\titlefalse}
\def\contentspagenumber{201}
%\def\title{APPENDIX F: CWEAVE}
%\let\K=\leftarrow
\pageno=\contentspagenumber \advance\pageno by 1
\let\maybe=\iftrue


\N{0}{1}Introduction.
This is the \.{mCWEAVE} program which is an extension to
\.{CWEB} by Silvio Levy and Donald E. Knuth,
based on \.{WEAVE} by Knuth.
I am thankful to Thomas \"Ollinger for his constructive criticism and %"
his help with the \TeX\ macros, and everbody who has contributed to
the original \.{CWEB}: Silvio Levy, D.~E.~Knuth, Steve Avery,
Nelson Beebe, Hans-Hermann Bode (to whom the \CPLUSPLUS/ adaptation is due),
Klaus Guntermann, Norman Ramsey, Tomas Rokicki, Joachim Schnitter,
Joachim Schrod, Lee Wittenberg, and others who have contributed improvements.

The ``banner line'' defined here should be changed whenever \.{mCWEAVE}
is modified.

\Y\B\4\D$\\{banner}$ \5
\.{"This\ is\ mCWEAVE\ (Ve}\)\.{rsion\ 1.1)\\n"}\par
\Y\B\X7:Include files\X\6
\ATH\6
\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X\6
\X19:Typedef declarations\X\6
\X18:Global variables\X\6
\X2:Predeclaration of procedures\X\par
\fi

\M{2}We predeclare several standard system functions here instead of including
their system header files, because the names of the header files are not as
standard as the names of the functions. (For example, some \CEE/ environments
have \.{<string.h>} where others have \.{<strings.h>}.)

\Y\B\4\X2:Predeclaration of procedures\X${}\E{}$\6
\&{extern} \&{int} \\{strlen}(\,);\C{ length of string }\6
\&{extern} \&{int} \\{strcmp}(\,);\C{ compare strings lexicographically }\6
\&{extern} \&{char} ${}{*}\\{strcpy}(\,){}$;\C{ copy one string to another }\6
\&{extern} \&{int} \\{strncmp}(\,);\C{ compare up to $n$ string characters }\6
\&{extern} \&{char} ${}{*}\\{strncpy}(\,){}$;\C{ copy up to $n$ string
characters }\6
\&{extern} \&{char} ${}{*}\\{strrchr}(\,){}$;\C{ find last occurrence of
character in string }\6
\&{extern} \&{char} ${}{*}\\{strchr}(\,){}$;\C{ find first occurrence of
character in string }\par
\As37, 42, 58, 62, 65, 71, 82, 88, 93, 96, 104, 127, 147, 200, 203, 209, 220,
231, 240, 249, 253, 265, 270, 279, 281, 287, 300, 309, 312, 315, 319, 321, 323,
327, 331, 334, 347, 353, 356, 360, 362, 372, 378\ETs387.
\U1.\fi

\M{3}\.{CWEAVE} has a fairly straightforward outline.  It operates in
three phases: First it inputs the source file and stores cross-reference
data, then it inputs the source once again and produces the \TEX/ output
file, finally it sorts and outputs the index.

Please read the documentation for \.{mcommon}, the set of routines common
to \.{CTANGLE} and \.{CWEAVE}, before proceeding further.

\Y\B\&{int} ${}\\{main}(\\{ac},\39\\{av}){}$\1\1\6
\&{int} \\{ac};\C{ argument count }\6
\&{char} ${}{*}{*}\\{av}{}$;\C{ argument values }\2\2\6
${}\{{}$\1\6
${}\\{argc}\K\\{ac};{}$\6
${}\\{argv}\K\\{av};{}$\6
${}\\{program}\K\\{cweave};{}$\6
${}\\{make\_xrefs}\K\\{force\_lines}\K\T{1}{}$;\C{ controlled by command-line
options }\6
${}\\{show\_banner}\K\\{show\_happiness}\K\\{show\_progress}\K\T{1};{}$\6
\\{scan\_args}(\,);\6
\&{if} (\\{show\_banner})\1\5
\\{printf}(\\{banner});\C{ print a ``banner line'' }\2\6
${}\\{argc}\K\\{ac};{}$\6
${}\\{argv}\K\\{av};{}$\6
\X369:Initialize at the very beginning\X;\6
\X337:Check for book file\X;\6
\&{return} \\{weave\_file}(\,);\6
\4${}\}{}$\2\par
\fi

\M{4}\.{mCWEAVE} should be able to handle both, old style web files and
new style web books. Books can be recognized by their \.{prg} or
\.{lib} extension. Every chapter of the book gets weaved separatly
like if \.{CWEAVE} was called with every chapter as an argument.

The following function weaves a file and assumes that the command line
arguments have been scanned so that global variables like
\PB{\\{web\_file\_name}}, \PB{\\{change\_file\_name}}, \PB{\\{tex\_file\_name}}
and the like
already have the corresponding values.
\Y\B\&{int} \\{weave\_file}(\,)\1\1\2\2\6
${}\{{}$\1\6
\\{common\_init}(\,);\6
\X21:Set initial values\X;\6
\X29:Store all the reserved words\X;\6
\\{phase\_one}(\,);\C{ read all the user's text and store the cross-references
}\6
\\{phase\_two}(\,);\C{ read all the text again and translate it to \TEX/ form }%
\6
\\{phase\_three}(\,);\C{ output the cross-reference index }\6
\&{return} \\{wrap\_up}(\,);\C{ and exit gracefully }\6
\4${}\}{}$\2\par
\fi

\M{5}The following parameters were sufficient in the original \.{WEAVE} to
handle \TEX/, so they should be sufficient for most applications of \.{CWEAVE}.
If you change \PB{\\{max\_bytes}}, \PB{\\{max\_names}}, \PB{\\{hash\_size}} or %
\PB{\\{buf\_size}}
you have to change them also in the file \PB{\.{"mcommon.w"}}.

\Y\B\4\D$\\{max\_bytes}$ \5
\T{90000}\C{ the number of bytes in identifiers,   index entries, and section
names }\par
\B\4\D$\\{max\_names}$ \5
\T{10000}\C{ number of identifiers, strings, section names;   must be less than
10240; used in \PB{\.{"mcommon.w"}} }\par
\B\4\D$\\{max\_sections}$ \5
\T{2000}\C{ greater than the total number of sections }\par
\B\4\D$\\{hash\_size}$ \5
\T{353}\C{ should be prime }\par
\B\4\D$\\{buf\_size}$ \5
\T{256}\C{ maximum length of input line, plus one }\par
\B\4\D$\\{longest\_name}$ \5
\T{1000}\C{ section names and strings shouldn't be longer than this }\par
\B\4\D$\\{long\_buf\_size}$ \5
$(\\{buf\_size}+\\{longest\_name}{}$)\par
\B\4\D$\\{line\_length}$ \5
\T{80}\C{ lines of \TEX/ output have at most this many characters;   should be
less than 256 }\par
\B\4\D$\\{max\_refs}$ \5
\T{20000}\C{ number of cross-references; must be less than 65536 }\par
\B\4\D$\\{max\_toks}$ \5
\T{60000}\C{ number of symbols in \CEE/ texts being parsed;   must be less than
65536 }\par
\B\4\D$\\{max\_texts}$ \5
\T{10000}\C{ number of phrases in \CEE/ texts being parsed;   must be less than
10240 }\par
\B\4\D$\\{max\_scraps}$ \5
\T{40000}\C{ number of tokens in \CEE/ texts being parsed }\par
\B\4\D$\\{stack\_size}$ \5
\T{400}\C{ number of simultaneous output levels }\par
\fi

\M{6}The next few sections contain stuff from \PB{\.{"mcommon.w"}} that must
be included in both \PB{\.{"mctangle.w"}} and \PB{\.{"mcweave.w"}}. It appears
in
file \PB{\.{"mcommon.h"}}, which needs to be updated when \PB{\.{"mcommon.w"}}
changes.

% This file is part of mCWEB.
% This program by Markus Öllinger is based on
% CWEB 3.4 by Silvio Levy and Donald E. Knuth which in turn
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
% Version 1.1 --- October 1998

% Copyright (C) 1996-1998 Markus Öllinger

% Permission is granted to make and distribute verbatim copies of this
% document provided that the copyright notice and this permission notice
% are preserved on all copies.

% Permission is granted to copy and distribute modified versions of this
% document under the conditions for verbatim copying, provided that the
% entire resulting derived work is distributed under the terms of a
% permission notice identical to this one.

% Please send comments, suggestions, etc. to moell@ist.tu-graz.ac.at.

% The next few sections contain stuff from the file \PB{\.{"common.w"}} that
%has
% to be included in both \PB{\.{"ctangle.w"}} and \PB{\.{"cweave.w"}}. It
%appears in this
% file \PB{\.{"common.h"}}, which needs to be updated when \PB{\.{"common.w"}}
%changes.

First comes general stuff:

\Y\B\4\D$\\{ctangle}$ \5
\T{0}\par
\B\4\D$\\{cweave}$ \5
\T{1}\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\E{}$\6
\&{typedef} \&{short} \&{boolean};\6
\&{typedef} \&{char} \&{unsigned} \&{eight\_bits};\6
\&{extern} \&{boolean} \\{program};\C{ \.{CWEAVE} or \.{CTANGLE}? }\6
\&{extern} \&{int} \\{phase};\C{ which phase are we in? }\par
\As8, 9, 10, 11, 12, 13, 14, 15\ETs16.
\U1.\fi

\M{7}\B\X7:Include files\X${}\E{}$\6
\8\#\&{include} \.{<stdio.h>}\par
\A41.
\U1.\fi

\M{8}Code related to the character set:

\Y\B\4\D$\\{and\_and}$ \5
\T{\~4}\C{ `\.{\&\&}'\,; corresponds to MIT's {\tentex\char'4} }\par
\B\4\D$\\{lt\_lt}$ \5
\T{\~20}\C{ `\.{<<}'\,;  corresponds to MIT's {\tentex\char'20} }\par
\B\4\D$\\{gt\_gt}$ \5
\T{\~21}\C{ `\.{>>}'\,;  corresponds to MIT's {\tentex\char'21} }\par
\B\4\D$\\{plus\_plus}$ \5
\T{\~13}\C{ `\.{++}'\,;  corresponds to MIT's {\tentex\char'13} }\par
\B\4\D$\\{minus\_minus}$ \5
\T{\~1}\C{ `\.{--}'\,;  corresponds to MIT's {\tentex\char'1} }\par
\B\4\D$\\{minus\_gt}$ \5
\T{\~31}\C{ `\.{->}'\,;  corresponds to MIT's {\tentex\char'31} }\par
\B\4\D$\\{not\_eq}$ \5
\T{\~32}\C{ `\.{!=}'\,;  corresponds to MIT's {\tentex\char'32} }\par
\B\4\D$\\{lt\_eq}$ \5
\T{\~34}\C{ `\.{<=}'\,;  corresponds to MIT's {\tentex\char'34} }\par
\B\4\D$\\{gt\_eq}$ \5
\T{\~35}\C{ `\.{>=}'\,;  corresponds to MIT's {\tentex\char'35} }\par
\B\4\D$\\{eq\_eq}$ \5
\T{\~36}\C{ `\.{==}'\,;  corresponds to MIT's {\tentex\char'36} }\par
\B\4\D$\\{or\_or}$ \5
\T{\~37}\C{ `\.{\v\v}'\,;  corresponds to MIT's {\tentex\char'37} }\par
\B\4\D$\\{dot\_dot\_dot}$ \5
\T{\~16}\C{ `\.{...}'\,;  corresponds to MIT's {\tentex\char'16} }\par
\B\4\D$\\{colon\_colon}$ \5
\T{\~6}\C{ `\.{::}'\,;  corresponds to MIT's {\tentex\char'6} }\par
\B\4\D$\\{period\_ast}$ \5
\T{\~26}\C{ `\.{.*}'\,;  corresponds to MIT's {\tentex\char'26} }\par
\B\4\D$\\{minus\_gt\_ast}$ \5
\T{\~27}\C{ `\.{->*}'\,;  corresponds to MIT's {\tentex\char'27} }\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{char} ${}\\{section\_text}[\\{longest\_name}+\T{1}]{}$;\C{ name being sought
for }\6
\&{char} ${}{*}\\{section\_text\_end}\K\\{section\_text}+\\{longest\_name}{}$;%
\C{ end of \PB{\\{section\_text}} }\6
\&{char} ${}{*}\\{id\_first}{}$;\C{ where the current identifier begins in the
buffer }\6
\&{char} ${}{*}\\{id\_loc}{}$;\C{ just after the current identifier in the
buffer }\par
\fi

\M{9}Code related to input routines:

\Y\B\4\D$\\{xisalpha}(\|c)$ \5
$(\\{isalpha}(\|c)\W{}$((\&{eight\_bits}) \|c${}<\T{\~200}){}$)\par
\B\4\D$\\{xisdigit}(\|c)$ \5
$(\\{isdigit}(\|c)\W{}$((\&{eight\_bits}) \|c${}<\T{\~200}){}$)\par
\B\4\D$\\{xisspace}(\|c)$ \5
$(\\{isspace}(\|c)\W{}$((\&{eight\_bits}) \|c${}<\T{\~200}){}$)\par
\B\4\D$\\{xislower}(\|c)$ \5
$(\\{islower}(\|c)\W{}$((\&{eight\_bits}) \|c${}<\T{\~200}){}$)\par
\B\4\D$\\{xisupper}(\|c)$ \5
$(\\{isupper}(\|c)\W{}$((\&{eight\_bits}) \|c${}<\T{\~200}){}$)\par
\B\4\D$\\{xisxdigit}(\|c)$ \5
$(\\{isxdigit}(\|c)\W{}$((\&{eight\_bits}) \|c${}<\T{\~200}){}$)\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{extern} \&{char} \\{buffer}[\,];\C{ where each line of input goes }\6
\&{extern} \&{char} ${}{*}\\{buffer\_end}{}$;\C{ end of \PB{\\{buffer}} }\6
\&{extern} \&{char} ${}{*}\\{loc}{}$;\C{ points to the next character to be
read from the buffer}\6
\&{extern} \&{char} ${}{*}\\{limit}{}$;\C{ points to the last character in the
buffer }\par
\fi

\M{10}Code related to identifier and section name storage:
\Y\B\4\D$\\{length}(\|c)$ \5
$(\|c+\T{1})\MG\\{byte\_start}-(\|c)\MG{}$\\{byte\_start}\C{ the length of a
name }\par
\B\4\D$\\{print\_id}(\|c)$ \5
$\\{term\_write}((\|c)\MG\\{byte\_start},\39\\{length}((\|c)){}$)\C{ print
identifier }\par
\B\4\D$\\{llink}$ \5
\\{link}\C{ left link in binary search tree for section names }\par
\B\4\D$\\{rlink}$ \5
$\\{dummy}.{}$\\{Rlink}\C{ right link in binary search tree for section names }%
\par
\B\4\D$\\{root}$ \5
$\\{name\_dir}\MG{}$\\{rlink}\C{ the root of the binary search tree   for
section names }\par
\B\4\D$\\{chunk\_marker}$ \5
\T{0}\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{typedef} \&{struct} \&{name\_info} ${}\{{}$\1\6
\&{char} ${}{*}\\{byte\_start}{}$;\C{ beginning of the name in \PB{\\{byte%
\_mem}} }\6
\&{struct} \&{name\_info} ${}{*}\\{link};{}$\6
\&{union} ${}\{{}$\1\6
\&{struct} \&{name\_info} ${}{*}\\{Rlink}{}$;\C{ right link in binary search
tree for section       names }\6
\&{char} \\{Ilk};\C{ used by identifiers in \.{CWEAVE} only }\2\6
${}\}{}$ \\{dummy};\6
\&{char} ${}{*}\\{equiv\_or\_xref}{}$;\C{ info corresponding to names }\2\6
${}\}{}$ \&{name\_info};\C{ contains information about an identifier or section
name }\6
\&{typedef} \&{name\_info} ${}{*}\&{name\_pointer}{}$;\C{ pointer into array of
\&{name\_info}s }\6
\&{typedef} \&{name\_pointer} ${}{*}\&{hash\_pointer};{}$\6
\&{extern} \&{char} \\{byte\_mem}[\,];\C{ characters of names }\6
\&{extern} \&{char} ${}{*}\\{byte\_mem\_end}{}$;\C{ end of \PB{\\{byte\_mem}} }%
\6
\&{extern} \&{name\_info} \\{name\_dir}[\,];\C{ information about names }\6
\&{extern} \&{name\_pointer} \\{name\_dir\_end};\C{ end of \PB{\\{name\_dir}} }%
\6
\&{extern} \&{name\_pointer} \\{name\_ptr};\C{ first unused position in \PB{%
\\{byte\_start}} }\6
\&{extern} \&{char} ${}{*}\\{byte\_ptr}{}$;\C{ first unused position in \PB{%
\\{byte\_mem}} }\6
\&{extern} \&{name\_pointer} \\{hash}[\,];\C{ heads of hash lists }\6
\&{extern} \&{hash\_pointer} \\{hash\_end};\C{ end of \PB{\\{hash}} }\6
\&{extern} \&{hash\_pointer} \|h;\C{ index into hash-head array }\6
\&{extern} \&{name\_pointer} \\{id\_lookup}(\,);\C{ looks up a string in the
identifier table }\6
\&{extern} \&{name\_pointer} \\{section\_lookup}(\,);\C{ finds section name }\6
\&{extern} \&{void} \\{print\_section\_name}(\,)${},{}$ \\{sprint\_section%
\_name}(\,);\par
\fi

\M{11}Code related to error handling:
\Y\B\4\D$\\{spotless}$ \5
\T{0}\C{ \PB{\\{history}} value for normal jobs }\par
\B\4\D$\\{harmless\_message}$ \5
\T{1}\C{ \PB{\\{history}} value when non-serious info was printed }\par
\B\4\D$\\{error\_message}$ \5
\T{2}\C{ \PB{\\{history}} value when an error was noted }\par
\B\4\D$\\{fatal\_message}$ \5
\T{3}\C{ \PB{\\{history}} value when we had to stop prematurely }\par
\B\4\D$\\{mark\_harmless}$ \6
${}\{{}$\1\6
\&{if} ${}(\\{history}\E\\{spotless}){}$\1\5
${}\\{history}\K\\{harmless\_message};{}$\2\6
\4${}\}{}$\2\par
\B\4\D$\\{mark\_error}$ \5
$\\{history}\K{}$\\{error\_message}\par
\B\4\D$\\{confusion}(\|s)$ \5
$\\{fatal}(\.{"!\ This\ can't\ happen}\)\.{:\ "},\39\|s{}$)\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{extern} \\{history};\C{ indicates how bad this run was }\6
\&{extern} \\{err\_print}(\,);\C{ print error message and context }\6
\&{extern} \\{wrap\_up}(\,);\C{ indicate \PB{\\{history}} and exit }\6
\&{extern} \&{void} \\{fatal}(\,);\C{ issue error message and die }\6
\&{extern} \&{void} \\{overflow}(\,);\C{ succumb because a table has overflowed
}\par
\fi

\M{12}Code related to file handling:
\Y\B\F\\{line} \5
\|x\C{ make \PB{\\{line}} an unreserved word }\par
\B\4\D$\\{max\_file\_name\_length}$ \5
\T{128}\par
\B\4\D$\\{cur\_file}$ \5
\\{file}[\\{include\_depth}]\C{ current file }\par
\B\4\D$\\{cur\_file\_name}$ \5
\\{file\_name}[\\{include\_depth}]\C{ current file name }\par
\B\4\D$\\{web\_file\_name}$ \5
\\{file\_name}[\T{0}]\C{ main source file name }\par
\B\4\D$\\{cur\_line}$ \5
\\{line}[\\{include\_depth}]\C{ number of current line in current file }\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{extern} \\{include\_depth};\C{ current level of nesting }\6
\&{extern} \&{FILE} ${}{*}\\{file}[\,]{}$;\C{ stack of non-change files }\6
\&{extern} \&{FILE} ${}{*}\\{change\_file}{}$;\C{ change file }\6
\&{extern} \&{char} \\{C\_file\_name}[\,];\C{ name of \PB{\\{C\_file}} }\6
\&{extern} \&{char} \\{tex\_file\_name}[\,];\C{ name of \PB{\\{tex\_file}} }\6
\&{extern} \&{char} \\{idx\_file\_name}[\,];\C{ name of \PB{\\{idx\_file}} }\6
\&{extern} \&{char} \\{scn\_file\_name}[\,];\C{ name of \PB{\\{scn\_file}} }\6
\&{extern} \&{char} \\{file\_name}[\,][\\{max\_file\_name\_length}];\C{ stack
of non-change file names }\6
\&{extern} \&{char} \\{change\_file\_name}[\,];\C{ name of change file }\6
\&{extern} \\{line}[\,];\C{ number of current line in the stacked files }\6
\&{extern} \\{change\_line};\C{ number of current line in change file }\6
\&{extern} \&{boolean} \\{input\_has\_ended};\C{ if there is no more input }\6
\&{extern} \&{boolean} \\{changing};\C{ if the current line is from \PB{%
\\{change\_file}} }\6
\&{extern} \&{boolean} \\{web\_file\_open};\C{ if the web file is being read }\6
\&{extern} \\{reset\_input}(\,);\C{ initialize to read the web file and change
file }\6
\&{extern} \\{get\_line}(\,);\C{ inputs the next line }\6
\&{extern} \\{check\_complete}(\,);\C{ checks that all changes were picked up }%
\par
\fi

\M{13}Code related to section numbers:
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{typedef} \&{unsigned} \&{short} \&{sixteen\_bits};\6
\&{extern} \&{sixteen\_bits} \\{section\_count};\C{ the current section number
}\6
\&{extern} \&{boolean} \\{changed\_section}[\,];\C{ is the section changed? }\6
\&{extern} \&{boolean} \\{change\_pending};\C{ is a decision about change still
unclear? }\6
\&{extern} \&{boolean} \\{print\_where};\C{ tells \.{CTANGLE} to print line and
file info }\par
\fi

\M{14}Code related to command line arguments:
\Y\B\4\D$\\{show\_banner}$ \5
\\{flags}[\.{'b'}]\C{ should the banner line be printed? }\par
\B\4\D$\\{show\_progress}$ \5
\\{flags}[\.{'p'}]\C{ should progress reports be printed? }\par
\B\4\D$\\{show\_happiness}$ \5
\\{flags}[\.{'h'}]\C{ should lack of errors be announced? }\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{extern} \&{int} \\{argc};\C{ copy of \PB{\\{ac}} parameter to \PB{\\{main}}
}\6
\&{extern} \&{char} ${}{*}{*}\\{argv}{}$;\C{ copy of \PB{\\{av}} parameter to %
\PB{\\{main}} }\6
\&{extern} \&{boolean} \\{flags}[\,];\C{ an option for each 7-bit code }\par
\fi

\M{15}Code relating to output:
\Y\B\4\D$\\{update\_terminal}$ \5
\\{fflush}(\\{stdout})\C{ empty the terminal output buffer }\par
\B\4\D$\\{new\_line}$ \5
\\{putchar}(\.{'\\n'})\par
\B\4\D$\\{putxchar}$ \5
\\{putchar}\par
\B\4\D$\\{term\_write}(\|a,\|b)$ \5
$\\{fflush}(\\{stdout}),\39\\{fwrite}(\|a,\39\&{sizeof}(\&{char}),\39\|b,\39%
\\{stdout}{}$)\par
\B\4\D$\\{C\_printf}(\|c,\|a)$ \5
$\\{fprintf}(\\{C\_file},\39\|c,\39\|a{}$)\par
\B\4\D$\\{C\_putc}(\|c)$ \5
$\\{putc}(\|c,\39\\{C\_file}{}$)\par
\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{extern} \&{FILE} ${}{*}\\{C\_file}{}$;\C{ where output of \.{CTANGLE} goes }%
\6
\&{extern} \&{FILE} ${}{*}\\{tex\_file}{}$;\C{ where output of \.{CWEAVE} goes
}\6
\&{extern} \&{FILE} ${}{*}\\{idx\_file}{}$;\C{ where index from \.{CWEAVE} goes
}\6
\&{extern} \&{FILE} ${}{*}\\{scn\_file}{}$;\C{ where list of sections from %
\.{CWEAVE} goes }\6
\&{extern} \&{FILE} ${}{*}\\{active\_file}{}$;\C{ currently active file for %
\.{CWEAVE} output }\par
\fi

\M{16}The procedure that gets everything rolling:

\Y\B\4\X6:Common code for \.{CWEAVE} and \.{CTANGLE}\X${}\mathrel+\E{}$\6
\&{extern} \&{void} \\{common\_init}(\,);\par
\fi

\N{1}{17}Data structures exclusive to {\tt CWEAVE}.
As explained in \.{mcommon.w}, the field of a \PB{\&{name\_info}} structure
that contains the \PB{\\{rlink}} of a section name is used for a completely
different purpose in the case of identifiers.  It is then called the
\PB{\\{ilk}} of the identifier, and it is used to
distinguish between various types of identifiers, as follows:

\yskip\hang \PB{\\{normal}} identifiers are part of the \CEE/ program and
will appear in italic type.

\yskip\hang \PB{\\{roman}} identifiers are index entries that appear after
\.{@\^} in the \.{CWEB} file.

\yskip\hang \PB{\\{wildcard}} identifiers are index entries that appear after
\.{@:} in the \.{CWEB} file.

\yskip\hang \PB{\\{typewriter}} identifiers are index entries that appear after
\.{@.} in the \.{CWEB} file.

\yskip\hang \PB{\\{else\_like}}, \dots, \PB{\\{typedef\_like}}
identifiers are \CEE/ reserved words whose \PB{\\{ilk}} explains how they are
to be treated when \CEE/ code is being formatted.

\Y\B\4\D$\\{ilk}$ \5
$\\{dummy}.{}$\\{Ilk}\par
\B\4\D$\\{normal}$ \5
\T{0}\C{ ordinary identifiers have \PB{\\{normal}} ilk }\par
\B\4\D$\\{roman}$ \5
\T{1}\C{ normal index entries have \PB{\\{roman}} ilk }\par
\B\4\D$\\{wildcard}$ \5
\T{2}\C{ user-formatted index entries have \PB{\\{wildcard}} ilk }\par
\B\4\D$\\{typewriter}$ \5
\T{3}\C{ `typewriter type' entries have \PB{\\{typewriter}} ilk }\par
\B\4\D$\\{abnormal}(\|a)$ \5
$(\|a\MG\\{ilk}>\\{typewriter}{}$)\C{ tells if a name is special }\par
\B\4\D$\\{custom}$ \5
\T{4}\C{ identifiers with user-given control sequence }\par
\B\4\D$\\{unindexed}(\|a)$ \5
$(\|a\MG\\{ilk}>\\{custom}{}$)\C{ tells if uses of a name are to be indexed }%
\par
\B\4\D$\\{quoted}$ \5
\T{5}\C{ \.{NULL} }\par
\B\4\D$\\{else\_like}$ \5
\T{26}\C{ \&{else} }\par
\B\4\D$\\{public\_like}$ \5
\T{40}\C{ \&{public}, \&{private}, \&{protected} }\par
\B\4\D$\\{operator\_like}$ \5
\T{41}\C{ \&{operator} }\par
\B\4\D$\\{new\_like}$ \5
\T{42}\C{ \&{new} }\par
\B\4\D$\\{catch\_like}$ \5
\T{43}\C{ \&{catch} }\par
\B\4\D$\\{for\_like}$ \5
\T{45}\C{ \.{for}, \&{switch}, \&{while} }\par
\B\4\D$\\{do\_like}$ \5
\T{46}\C{ \&{do} }\par
\B\4\D$\\{if\_like}$ \5
\T{47}\C{ \&{if}, \&{ifdef}, \&{endif}, \&{pragma}, \dots }\par
\B\4\D$\\{raw\_rpar}$ \5
\T{48}\C{ `\.)' or `\.]' when looking for \&{const} following }\par
\B\4\D$\\{raw\_unorbin}$ \5
\T{49}\C{ `\.\&' or `\.*' when looking for \&{const} following }\par
\B\4\D$\\{const\_like}$ \5
\T{50}\C{ \&{const}, \&{volatile} }\par
\B\4\D$\\{raw\_int}$ \5
\T{51}\C{ \&{int}, \&{char}, \&{extern}, \dots  }\par
\B\4\D$\\{int\_like}$ \5
\T{52}\C{ same, when not followed by left parenthesis }\par
\B\4\D$\\{case\_like}$ \5
\T{53}\C{ \&{case}, \&{return}, \&{goto}, \&{break}, \&{continue} }\par
\B\4\D$\\{sizeof\_like}$ \5
\T{54}\C{ \&{sizeof} }\par
\B\4\D$\\{struct\_like}$ \5
\T{55}\C{ \&{struct}, \&{union}, \&{enum}, \&{class} }\par
\B\4\D$\\{typedef\_like}$ \5
\T{56}\C{ \&{typedef} }\par
\B\4\D$\\{define\_like}$ \5
\T{57}\C{ \&{define} }\par
\fi

\M{18}We keep track of the current section number in \PB{\\{section\_count}},
which
is the total number of sections that have started.  Sections which have
been altered by a change file entry have their \PB{\\{changed\_section}} flag
turned on during the first phase.

\Y\B\4\X18:Global variables\X${}\E{}$\6
\&{boolean} \\{change\_exists};\C{ has any section changed? }\par
\As20, 26, 30, 34, 40, 44, 46, 61, 67, 76, 81, 85, 91, 92, 110, 117, 121, 146,
185, 207, 213, 217, 233, 244, 255, 257, 261, 263, 274, 276, 291, 298, 307, 314,
318, 326, 335, 336, 340, 350, 363, 368, 375, 383\ETs385.
\U1.\fi

\M{19}%modified
The other large memory area in \.{CWEAVE} keeps the cross-reference data.
All uses of the name \PB{\|p} are recorded in a linked list beginning at
\PB{$\|p\MG\\{xref}$}, which points into the \PB{\\{xmem}} array. The elements
of \PB{\\{xmem}}
are structures consisting of an integer, \PB{\\{num}}, and a pointer \PB{%
\\{xlink}}
to another element of \PB{\\{xmem}}.  If \PB{$\|x\K\|p\MG\\{xref}$} is a
pointer into \PB{\\{xmem}},
the value of \PB{$\|x\MG\\{num}$} is either a section number where \PB{\|p} is
used,
or \PB{\\{cite\_flag}} plus a section number where \PB{\|p} is mentioned,
or \PB{\\{def\_flag}} plus a section number where \PB{\|p} is defined;
and \PB{$\|x\MG\\{xlink}$} points to the next such cross-reference for \PB{%
\|p},
if any. This list of cross-references is in decreasing order by
section number. The next unused slot in \PB{\\{xmem}} is \PB{\\{xref\_ptr}}.
The linked list ends at \PB{${\AND}\\{xmem}[\T{0}]$}.

The global variable \PB{\\{xref\_switch}} is set either to \PB{\\{def\_flag}}
or to zero,
depending on whether the next cross-reference to an identifier is to be
underlined or not in the index. This switch is set to \PB{\\{def\_flag}} when
\.{@!} or \.{@d} is scanned, and it is cleared to zero when
the next identifier or index entry cross-reference has been made.
Similarly, the global variable \PB{\\{section\_xref\_switch}} is either
\PB{\\{def\_flag}} or \PB{\\{cite\_flag}} or zero, depending
on whether a section name is being defined, cited or used in \CEE/ text.

In case of an external reference to a chapter of another book
\PB{\\{ext\_ref}} is a pointer to an \PB{\\{external\_reference}} structure
which
contains the name and chapter number of the referenced book.
There are two special values for \PB{\\{ext\_ref}}, \PB{\\{own\_shared}} and %
\PB{\\{own\_export}}
which denote the chapter's own shared and export file, respectively.
\Y\B\4\D$\\{own\_shared}$ \5
((\&{struct} \\{external\_reference} ${}{*}){}$ ${}{-}\T{1\$L}{}$)\par
\B\4\D$\\{own\_export}$ \5
((\&{struct} \\{external\_reference} ${}{*}){}$ ${}{-}\T{2\$L}{}$)\par
\Y\B\4\X19:Typedef declarations\X${}\E{}$\6
\&{typedef} \&{struct} \&{xref\_info} ${}\{{}$\1\6
\&{sixteen\_bits} \\{num};\C{ section number plus zero or \PB{\\{def\_flag}} }\6
\&{struct} \&{xref\_info} ${}{*}\\{xlink}{}$;\C{ pointer to the previous
cross-reference }\6
\&{struct} \\{external\_reference} ${}{*}\\{ext\_ref}{}$;\C{ pointer to book
name and chapter number }\2\6
${}\}{}$ \&{xref\_info};\6
\&{typedef} \&{xref\_info} ${}{*}\&{xref\_pointer}{}$;\par
\As25, 116, 212, 297, 306, 366, 367\ETs384.
\U1.\fi

\M{20}\B\X18:Global variables\X${}\mathrel+\E{}$\6
\&{xref\_info} \\{xmem}[\\{max\_refs}];\C{ contains cross-reference information
}\6
\&{xref\_pointer} \\{xmem\_end}${}\K\\{xmem}+\\{max\_refs}-\T{1};{}$\6
\&{xref\_pointer} \\{xref\_ptr};\C{ the largest occupied position in \PB{%
\\{xmem}} }\6
\&{sixteen\_bits} \\{xref\_switch}${},{}$ \\{section\_xref\_switch};\C{ either
zero or \PB{\\{def\_flag}} }\par
\fi

\M{21}A section that is used for multi-file output (with the \.{@(} feature)
has a special first cross-reference whose \PB{\\{num}} field is \PB{\\{file%
\_flag}}.

\Y\B\4\D$\\{file\_flag}$ \5
$(\T{3}*\\{cite\_flag}{}$)\par
\B\4\D$\\{def\_flag}$ \5
$(\T{2}*\\{cite\_flag}{}$)\par
\B\4\D$\\{cite\_flag}$ \5
\T{10240}\C{ must be strictly larger than \PB{\\{max\_sections}} }\par
\B\4\D$\\{xref}$ \5
\\{equiv\_or\_xref}\par
\Y\B\4\X21:Set initial values\X${}\E{}$\6
$\\{memset}(\\{xmem},\39\T{0},\39{}$\&{sizeof} (\\{xmem}));\6
${}\\{xref\_ptr}\K\\{xmem};{}$\6
${}\\{name\_dir}\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xmem};\6
${}\\{xref\_switch}\K\T{0};{}$\6
${}\\{section\_xref\_switch}\K\T{0};{}$\6
${}\\{xmem}\MG\\{num}\K\T{0}{}$;\C{ sentinel value }\par
\As27, 35, 55, 68, 90, 95, 111, 118, 208, 214, 234, 262, 264, 277, 292, 299,
308\ETs386.
\Us4\ET337.\fi

\M{22}A new cross-reference for an identifier is formed by calling \PB{\\{new%
\_xref}},
which discards duplicate entries and ignores non-underlined references
to one-letter identifiers or \CEE/'s reserved words.

If the user has sent the \PB{\\{no\_xref}} flag (the \.{-x} option of the
command line),
it is unnecessary to keep track of cross-references for identifiers.
If one were careful, one could probably make more changes around section
100 to avoid a lot of identifier looking up.

\Y\B\4\D$\\{append\_xref}(\|c)$ \6
\&{if} ${}(\\{xref\_ptr}\E\\{xmem\_end}){}$\1\5
\\{overflow}(\.{"cross-reference"});\2\6
\&{else}\1\5
${}(\PP\\{xref\_ptr})\MG\\{num}\K\|c{}$;\2\par
\B\4\D$\\{no\_xref}$ \5
$(\\{flags}[\.{'x'}]\E\T{0}{}$)\par
\B\4\D$\\{make\_xrefs}$ \5
\\{flags}[\.{'x'}]\C{ should cross references be output? }\par
\B\4\D$\\{is\_tiny}(\|p)$ \5
$((\|p+\T{1})\MG\\{byte\_start}\E(\|p)\MG\\{byte\_start}+\T{1}{}$)\par
\Y\B\&{void} \\{new\_xref}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \|q;\C{ pointer to previous cross-reference }\6
\&{sixteen\_bits} \|m${},{}$ \|n;\C{ new and previous cross-reference value }\7
\&{if} ${}(\\{no\_xref}\V\\{section\_count}\E\T{0}\V\\{is\_adoc}){}$\1\5
\&{return};\2\6
\&{if} ${}((\\{unindexed}(\|p)\V\\{is\_tiny}(\|p))\W\\{xref\_switch}\E\T{0}){}$%
\1\5
\&{return};\2\6
${}\|m\K\\{section\_count}+\\{xref\_switch};{}$\6
${}\\{xref\_switch}\K\T{0};{}$\6
${}\|q\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$\6
\&{if} ${}(\|q\I\\{xmem}){}$\5
${}\{{}$\1\6
${}\|n\K\|q\MG\\{num};{}$\6
\&{if} ${}(\|q\MG\\{ext\_ref}\E\\{ext\_ref}\V\|q\MG\\{ext\_ref}\E\NULL\W(\\{ext%
\_ref}\E\\{own\_shared}\V\\{ext\_ref}\E\\{own\_export})\V\\{ext\_ref}\E\NULL\W(%
\|q\MG\\{ext\_ref}\E\\{own\_shared}\V\|q\MG\\{ext\_ref}\E\\{own\_export})){}$\5
${}\{{}$\C{ reference to same book or reference to own files }\1\6
\&{if} ${}(\|n\E\|m\V\|n\E\|m+\\{def\_flag}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\|q\MG\\{ext\_ref}){}$\1\5
${}\|q\MG\\{ext\_ref}\K\\{ext\_ref};{}$\2\6
\&{return};\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|m\E\|n+\\{def\_flag}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\|q\MG\\{ext\_ref}){}$\1\5
${}\|q\MG\\{ext\_ref}\K\\{ext\_ref};{}$\2\6
${}\|q\MG\\{num}\K\|m;{}$\6
\&{return};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{append\_xref}(\|m);\6
${}\\{xref\_ptr}\MG\\{xlink}\K\|q;{}$\6
${}\|p\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xref\_ptr};\6
${}\\{xref\_ptr}\MG\\{ext\_ref}\K\\{ext\_ref}{}$;\C{ current external reference
or \PB{$\NULL$} }\6
\&{return};\6
\4${}\}{}$\2\par
\fi

\M{23}The cross-reference lists for section names are slightly different.
Suppose that a section name is defined in sections $m_1$, \dots,
$m_k$, cited in sections $n_1$, \dots, $n_l$, and used in sections
$p_1$, \dots, $p_j$.  Then its list will contain $m_1+\PB{\\{def\_flag}}$,
\dots, $m_k+\PB{\\{def\_flag}}$, $n_1+\PB{\\{cite\_flag}}$, \dots,
$n_l+\PB{\\{cite\_flag}}$, $p_1$, \dots, $p_j$, in this order.

Although this method of storage take quadratic time on the length of
the list, under foreseeable uses of \.{CWEAVE} this inefficiency is
insignificant.

\Y\B\&{void} \\{new\_section\_xref}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \|q${},{}$ \|r;\C{ pointers to previous cross-references }\7
${}\|q\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$\6
${}\|r\K\\{xmem};{}$\6
\&{if} ${}(\|q>\\{xmem}){}$\1\6
\&{while} ${}(\|q\MG\\{num}>\\{section\_xref\_switch}){}$\5
${}\{{}$\1\6
${}\|r\K\|q;{}$\6
${}\|q\K\|q\MG\\{xlink};{}$\6
\4${}\}{}$\2\2\6
\&{if} ${}(\|r\MG\\{num}\E\\{section\_count}+\\{section\_xref\_switch}){}$\1\5
\&{return};\C{ don't duplicate entries }\2\6
${}\\{append\_xref}(\\{section\_count}+\\{section\_xref\_switch});{}$\6
${}\\{xref\_ptr}\MG\\{xlink}\K\|q;{}$\6
${}\\{section\_xref\_switch}\K\T{0};{}$\6
\&{if} ${}(\|r\E\\{xmem}){}$\1\5
${}\|p\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xref\_ptr};\2\6
\&{else}\1\5
${}\|r\MG\\{xlink}\K\\{xref\_ptr};{}$\2\6
\4${}\}{}$\2\par
\fi

\M{24}The cross-reference list for a section name may also begin with
\PB{\\{file\_flag}}. Here's how that flag gets put~in.

\Y\B\&{void} \\{set\_file\_flag}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \|q;\7
${}\|q\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$\6
\&{if} ${}(\|q\MG\\{num}\E\\{file\_flag}){}$\1\5
\&{return};\2\6
\\{append\_xref}(\\{file\_flag});\6
${}\\{xref\_ptr}\MG\\{xlink}\K\|q;{}$\6
${}\|p\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xref\_ptr};\6
\4${}\}{}$\2\par
\fi

\M{25}A third large area of memory is used for sixteen-bit `tokens', which
appear
in short lists similar to the strings of characters in \PB{\\{byte\_mem}}.
Token lists
are used to contain the result of \CEE/ code translated into \TEX/ form;
further details about them will be explained later. A \PB{\&{text\_pointer}}
variable
is an index into \PB{\\{tok\_start}}.

\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{typedef} \&{sixteen\_bits} \&{token};\6
\&{typedef} \&{token} ${}{*}\&{token\_pointer};{}$\6
\&{typedef} \&{token\_pointer} ${}{*}\&{text\_pointer}{}$;\par
\fi

\M{26}The first position of \PB{\\{tok\_mem}}
that is unoccupied by replacement text is called \PB{\\{tok\_ptr}}, and the
first
unused location of \PB{\\{tok\_start}} is called \PB{\\{text\_ptr}}.
Thus, we usually have \PB{${*}\\{text\_ptr}\E\\{tok\_ptr}$}.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{token} \\{tok\_mem}[\\{max\_toks}];\C{ tokens }\6
\&{token\_pointer} \\{tok\_mem\_end}${}\K\\{tok\_mem}+\\{max\_toks}-\T{1}{}$;%
\C{ end of \PB{\\{tok\_mem}} }\6
\&{token\_pointer} \\{tok\_start}[\\{max\_texts}];\C{ directory into \PB{\\{tok%
\_mem}} }\6
\&{token\_pointer} \\{tok\_ptr};\C{ first unused position in \PB{\\{tok\_mem}}
}\6
\&{text\_pointer} \\{text\_ptr};\C{ first unused position in \PB{\\{tok%
\_start}} }\6
\&{text\_pointer} \\{tok\_start\_end}${}\K\\{tok\_start}+\\{max\_texts}-%
\T{1}{}$;\C{ end of \PB{\\{tok\_start}} }\6
\&{token\_pointer} \\{max\_tok\_ptr};\C{ largest value of \PB{\\{tok\_ptr}} }\6
\&{text\_pointer} \\{max\_text\_ptr};\C{ largest value of \PB{\\{text\_ptr}} }%
\par
\fi

\M{27}\B\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{tok\_ptr}\K\\{tok\_mem}+\T{1};{}$\6
${}\\{text\_ptr}\K\\{tok\_start}+\T{1};{}$\6
${}\\{tok\_start}[\T{0}]\K\\{tok\_mem}+\T{1};{}$\6
${}\\{tok\_start}[\T{1}]\K\\{tok\_mem}+\T{1};{}$\6
${}\\{max\_tok\_ptr}\K\\{tok\_mem}+\T{1};{}$\6
${}\\{max\_text\_ptr}\K\\{tok\_start}+\T{1}{}$;\par
\fi

\M{28}Here are the three procedures needed to complete \PB{\\{id\_lookup}}:
\Y\B\&{int} ${}\\{names\_match}(\|p,\39\\{first},\39\|l,\39\|t){}$\1\1\6
\&{name\_pointer} \|p;\C{ points to the proposed match }\6
\&{char} ${}{*}\\{first}{}$;\C{ position of first character of string }\6
\&{int} \|l;\C{ length of identifier }\6
\&{eight\_bits} \|t;\C{ desired ilk }\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{length}(\|p)\I\|l){}$\1\5
\&{return} \T{0};\2\6
\&{if} ${}(\|p\MG\\{ilk}\I\|t\W\R(\|t\E\\{normal}\W\\{abnormal}(\|p))){}$\1\5
\&{return} \T{0};\2\6
\&{return} ${}\R\\{strncmp}(\\{first},\39\|p\MG\\{byte\_start},\39\|l);{}$\6
\4${}\}{}$\2\7
\&{void} ${}\\{init\_p}(\|p,\39\|t){}$\1\1\6
\&{name\_pointer} \|p;\6
\&{eight\_bits} \|t;\2\2\6
${}\{{}$\1\6
${}\|p\MG\\{ilk}\K\|t;{}$\6
${}\|p\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xmem};\6
\4${}\}{}$\2\7
\&{void} \\{init\_node}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
${}\|p\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xmem};\6
\4${}\}{}$\2\par
\fi

\M{29}We have to get \CEE/'s
reserved words into the hash table, and the simplest way to do this is
to insert them every time \.{CWEAVE} is run.  Fortunately there are relatively
few reserved words. (Some of these are not strictly ``reserved,'' but
are defined in header files of the ISO Standard \CEE/ Library.)

\Y\B\4\X29:Store all the reserved words\X${}\E{}$\6
$\\{id\_lookup}(\.{"asm"},\39\NULL,\39\\{sizeof\_like});{}$\6
${}\\{id\_lookup}(\.{"auto"},\39\NULL,\39\\{int\_like});{}$\6
${}\\{id\_lookup}(\.{"break"},\39\NULL,\39\\{case\_like});{}$\6
${}\\{id\_lookup}(\.{"case"},\39\NULL,\39\\{case\_like});{}$\6
${}\\{id\_lookup}(\.{"catch"},\39\NULL,\39\\{catch\_like});{}$\6
${}\\{id\_lookup}(\.{"char"},\39\NULL,\39\\{raw\_int});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"class"},\39\NULL,\39\\{struct\_like});{}$\2\6
${}\\{id\_lookup}(\.{"clock\_t"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"const"},\39\NULL,\39\\{const\_like});{}$\6
${}\\{id\_lookup}(\.{"continue"},\39\NULL,\39\\{case\_like});{}$\6
${}\\{id\_lookup}(\.{"default"},\39\NULL,\39\\{case\_like});{}$\6
${}\\{id\_lookup}(\.{"define"},\39\NULL,\39\\{define\_like});{}$\6
${}\\{id\_lookup}(\.{"defined"},\39\NULL,\39\\{sizeof\_like});{}$\6
${}\\{id\_lookup}(\.{"delete"},\39\NULL,\39\\{sizeof\_like});{}$\6
${}\\{id\_lookup}(\.{"div\_t"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"do"},\39\NULL,\39\\{do\_like});{}$\6
${}\\{id\_lookup}(\.{"double"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"elif"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"else"},\39\NULL,\39\\{else\_like});{}$\6
${}\\{id\_lookup}(\.{"endif"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"enum"},\39\NULL,\39\\{struct\_like});{}$\6
${}\\{id\_lookup}(\.{"error"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"extern"},\39\NULL,\39\\{int\_like});{}$\6
${}\\{id\_lookup}(\.{"FILE"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"float"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"for"},\39\NULL,\39\\{for\_like});{}$\6
${}\\{id\_lookup}(\.{"fpos\_t"},\39\NULL,\39\\{raw\_int});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"friend"},\39\NULL,\39\\{int\_like});{}$\2\6
${}\\{id\_lookup}(\.{"goto"},\39\NULL,\39\\{case\_like});{}$\6
${}\\{id\_lookup}(\.{"if"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"ifdef"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"ifndef"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"include"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"inline"},\39\NULL,\39\\{int\_like});{}$\6
${}\\{id\_lookup}(\.{"int"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"jmp\_buf"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"ldiv\_t"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"line"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"long"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"new"},\39\NULL,\39\\{new\_like});{}$\6
${}\\{id\_lookup}(\.{"NULL"},\39\NULL,\39\\{quoted});{}$\6
${}\\{id\_lookup}(\.{"offsetof"},\39\NULL,\39\\{sizeof\_like});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"operator"},\39\NULL,\39\\{operator\_like});{}$\2\6
${}\\{id\_lookup}(\.{"pragma"},\39\NULL,\39\\{if\_like});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"private"},\39\NULL,\39\\{public\_like});{}$\2\6
${}\\{id\_lookup}(\.{"protected"},\39\NULL,\39\\{public\_like});{}$\6
${}\\{id\_lookup}(\.{"ptrdiff\_t"},\39\NULL,\39\\{raw\_int});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"public"},\39\NULL,\39\\{public\_like});{}$\2\6
${}\\{id\_lookup}(\.{"register"},\39\NULL,\39\\{int\_like});{}$\6
${}\\{id\_lookup}(\.{"return"},\39\NULL,\39\\{case\_like});{}$\6
${}\\{id\_lookup}(\.{"short"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"sig\_atomic\_t"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"signed"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"size\_t"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"sizeof"},\39\NULL,\39\\{sizeof\_like});{}$\6
${}\\{id\_lookup}(\.{"static"},\39\NULL,\39\\{int\_like});{}$\6
${}\\{id\_lookup}(\.{"struct"},\39\NULL,\39\\{struct\_like});{}$\6
${}\\{id\_lookup}(\.{"switch"},\39\NULL,\39\\{for\_like});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"template"},\39\NULL,\39\\{int\_like});{}$\2\6
${}\\{id\_lookup}(\.{"TeX"},\39\NULL,\39\\{custom});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"this"},\39\NULL,\39\\{quoted});{}$\2\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"throw"},\39\NULL,\39\\{case\_like});{}$\2\6
${}\\{id\_lookup}(\.{"time\_t"},\39\NULL,\39\\{raw\_int});{}$\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"try"},\39\NULL,\39\\{else\_like});{}$\2\6
${}\\{id\_lookup}(\.{"typedef"},\39\NULL,\39\\{typedef\_like});{}$\6
${}\\{id\_lookup}(\.{"undef"},\39\NULL,\39\\{if\_like});{}$\6
${}\\{id\_lookup}(\.{"union"},\39\NULL,\39\\{struct\_like});{}$\6
${}\\{id\_lookup}(\.{"unsigned"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"va\_dcl"},\39\NULL,\39\\{decl}){}$;\C{ Berkeley's
variable-arg-list convention }\6
${}\\{id\_lookup}(\.{"va\_list"},\39\NULL,\39\\{raw\_int}){}$;\C{ ditto }\6
\&{if} (\\{Cxx})\1\5
${}\\{id\_lookup}(\.{"virtual"},\39\NULL,\39\\{int\_like});{}$\2\6
${}\\{id\_lookup}(\.{"void"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"volatile"},\39\NULL,\39\\{const\_like});{}$\6
${}\\{id\_lookup}(\.{"wchar\_t"},\39\NULL,\39\\{raw\_int});{}$\6
${}\\{id\_lookup}(\.{"while"},\39\NULL,\39\\{for\_like});{}$\6
\X31:Store all special command identifiers\X;\par
\U4.\fi

\M{30}In addition, the special commands introduced by '\.{@\_}' are stored
in the symbol table and pointers to them are kept in the following variables:
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{name\_pointer} \\{id\_import};\6
\&{name\_pointer} \\{id\_from};\6
\&{name\_pointer} \\{id\_chapter};\6
\&{name\_pointer} \\{id\_program};\6
\&{name\_pointer} \\{id\_library};\6
\&{name\_pointer} \\{id\_transitively};\6
\&{name\_pointer} \\{id\_global};\6
\&{name\_pointer} \\{id\_shared};\6
\&{name\_pointer} \\{id\_export};\6
\&{name\_pointer} \\{id\_mark};\6
\&{name\_pointer} \\{id\_copy};\6
\&{name\_pointer} \\{id\_paste};\par
\fi

\M{31}
\Y\B\4\X31:Store all special command identifiers\X${}\E{}$\6
$\\{id\_import}\K\\{id\_lookup}(\.{"import"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_from}\K\\{id\_lookup}(\.{"from"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_chapter}\K\\{id\_lookup}(\.{"chapter"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_program}\K\\{id\_lookup}(\.{"program"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_library}\K\\{id\_lookup}(\.{"library"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_transitively}\K\\{id\_lookup}(\.{"transitively"},\39\NULL,\39%
\\{normal});{}$\6
${}\\{id\_global}\K\\{id\_lookup}(\.{"global"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_shared}\K\\{id\_lookup}(\.{"shared"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_export}\K\\{id\_lookup}(\.{"export"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_mark}\K\\{id\_lookup}(\.{"mark"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_copy}\K\\{id\_lookup}(\.{"copy"},\39\NULL,\39\\{normal});{}$\6
${}\\{id\_paste}\K\\{id\_lookup}(\.{"paste"},\39\NULL,\39\\{normal}){}$;\par
\U29.\fi

\N{1}{32}Lexical scanning.
Let us now consider the subroutines that read the \.{CWEB} source file
and break it into meaningful units. There are four such procedures:
One simply skips to the next `\.{@\ }' or `\.{@*}' that begins a
section; another passes over the \TEX/ text at the beginning of a
section; the third passes over the \TEX/ text in a \CEE/ comment;
and the last, which is the most interesting, gets the next token of
a \CEE/ text.  They all use the pointers \PB{\\{limit}} and \PB{\\{loc}} into
the line of input currently being studied.

\fi

\M{33}Control codes in \.{CWEB}, which begin with `\.{@}', are converted
into a numeric code designed to simplify \.{CWEAVE}'s logic; for example,
larger numbers are given to the control codes that denote more significant
milestones, and the code of \PB{\\{new\_section}} should be the largest of
all. Some of these numeric control codes take the place of \PB{\&{char}}
control codes that will not otherwise appear in the output of the
scanning routines.

\Y\B\4\D$\\{ignore}$ \5
\T{\~0}\C{ control code of no interest to \.{CWEAVE} }\par
\B\4\D$\\{verbatim}$ \5
\T{\~2}\C{ takes the place of extended ASCII \.{\char2} }\par
\B\4\D$\\{begin\_short\_comment}$ \5
\T{\~3}\C{ \CPLUSPLUS/ short comment }\par
\B\4\D$\\{begin\_comment}$ \5
\.{'\\t'}\C{ tab marks will not appear }\par
\B\4\D$\\{underline}$ \5
\.{'\\n'}\C{ this code will be intercepted without confusion }\par
\B\4\D$\\{noop}$ \5
\T{\~177}\C{ takes the place of ASCII delete }\par
\B\4\D$\\{xref\_roman}$ \5
\T{\~203}\C{ control code for `\.{@\^}' }\par
\B\4\D$\\{xref\_wildcard}$ \5
\T{\~204}\C{ control code for `\.{@:}' }\par
\B\4\D$\\{xref\_typewriter}$ \5
\T{\~205}\C{ control code for `\.{@.}' }\par
\B\4\D$\TeXxstring$ \5
\T{\~206}\C{ control code for `\.{@t}' }\par
\B\F\\{TeX\_string} \5
\\{TeX}\par
\B\4\D$\\{ord}$ \5
\T{\~207}\C{ control code for `\.{@'}' }\par
\B\4\D$\\{join}$ \5
\T{\~210}\C{ control code for `\.{@\&}' }\par
\B\4\D$\\{thin\_space}$ \5
\T{\~211}\C{ control code for `\.{@,}' }\par
\B\4\D$\\{math\_break}$ \5
\T{\~212}\C{ control code for `\.{@\v}' }\par
\B\4\D$\\{line\_break}$ \5
\T{\~213}\C{ control code for `\.{@/}' }\par
\B\4\D$\\{big\_line\_break}$ \5
\T{\~214}\C{ control code for `\.{@\#}' }\par
\B\4\D$\\{no\_line\_break}$ \5
\T{\~215}\C{ control code for `\.{@+}' }\par
\B\4\D$\\{pseudo\_semi}$ \5
\T{\~216}\C{ control code for `\.{@;}' }\par
\B\4\D$\\{special\_command}$ \5
\T{\~220}\C{ control code for '\.{@$\_$}' }\par
\B\4\D$\\{macro\_arg\_open}$ \5
\T{\~221}\C{ control code for `\.{@[}' }\par
\B\4\D$\\{macro\_arg\_close}$ \5
\T{\~222}\C{ control code for `\.{@]}' }\par
\B\4\D$\\{trace}$ \5
\T{\~223}\C{ control code for `\.{@0}', `\.{@1}' and `\.{@2}' }\par
\B\4\D$\\{translit\_code}$ \5
\T{\~224}\C{ control code for `\.{@l}' }\par
\B\4\D$\\{output\_defs\_code}$ \5
\T{\~225}\C{ control code for `\.{@h}' }\par
\B\4\D$\\{autodoc\_code}$ \5
\T{\~226}\C{ control code for '\.{@a}' }\par
\B\4\D$\\{example\_code}$ \5
\T{\~227}\C{ control code for '\.{@e}' }\par
\B\4\D$\\{format\_code}$ \5
\T{\~230}\C{ control code for `\.{@f}' and `\.{@s}' }\par
\B\4\D$\\{definition}$ \5
\T{\~231}\C{ control code for `\.{@d}' }\par
\B\4\D$\\{begin\_C}$ \5
\T{\~232}\C{ control code for `\.{@c}' }\par
\B\4\D$\\{section\_name}$ \5
\T{\~233}\C{ control code for `\.{@<}' }\par
\B\4\D$\\{new\_section}$ \5
\T{\~234}\C{ control code for `\.{@\ }' and `\.{@*}' }\par
\fi

\M{34}Control codes are converted to \.{CWEAVE}'s internal
representation by means of the table \PB{\\{ccode}}.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{eight\_bits} \\{ccode}[\T{256}];\C{ meaning of a char following \.{@} }\par
\fi

\M{35}\B\X21:Set initial values\X${}\mathrel+\E{}$\6
${}\{{}$\1\6
\&{int} \|c;\7
\&{for} ${}(\|c\K\T{0};{}$ ${}\|c<\T{256};{}$ ${}\|c\PP){}$\1\5
${}\\{ccode}[\|c]\K\T{0};{}$\2\6
\4${}\}{}$\2\6
${}\\{ccode}[\.{'\ '}]\K\\{ccode}[\.{'\\t'}]\K\\{ccode}[\.{'\\n'}]\K\\{ccode}[%
\.{'\\v'}]\K\\{ccode}[\.{'\\r'}]\K\\{ccode}[\.{'\\f'}]\K\\{ccode}[\.{'*'}]\K%
\\{new\_section};{}$\6
${}\\{ccode}[\.{'@'}]\K\.{'@'}{}$;\C{ `quoted' at sign }\6
${}\\{ccode}[\.{'='}]\K\\{verbatim};{}$\6
${}\\{ccode}[\.{'a'}]\K\\{ccode}[\.{'A'}]\K\\{autodoc\_code};{}$\6
${}\\{ccode}[\.{'d'}]\K\\{ccode}[\.{'D'}]\K\\{definition};{}$\6
${}\\{ccode}[\.{'e'}]\K\\{ccode}[\.{'E'}]\K\\{example\_code};{}$\6
${}\\{ccode}[\.{'f'}]\K\\{ccode}[\.{'F'}]\K\\{ccode}[\.{'s'}]\K\\{ccode}[%
\.{'S'}]\K\\{format\_code};{}$\6
${}\\{ccode}[\.{'c'}]\K\\{ccode}[\.{'C'}]\K\\{ccode}[\.{'p'}]\K\\{ccode}[%
\.{'P'}]\K\\{begin\_C};{}$\6
${}\\{ccode}[\.{'t'}]\K\\{ccode}[\.{'T'}]\K\TeXxstring;{}$\6
${}\\{ccode}[\.{'l'}]\K\\{ccode}[\.{'L'}]\K\\{translit\_code};{}$\6
${}\\{ccode}[\.{'q'}]\K\\{ccode}[\.{'Q'}]\K\\{noop};{}$\6
${}\\{ccode}[\.{'h'}]\K\\{ccode}[\.{'H'}]\K\\{output\_defs\_code};{}$\6
${}\\{ccode}[\.{'\&'}]\K\\{join};{}$\6
${}\\{ccode}[\.{'<'}]\K\\{ccode}[\.{'('}]\K\\{section\_name};{}$\6
${}\\{ccode}[\.{'!'}]\K\\{underline};{}$\6
${}\\{ccode}[\.{'\^'}]\K\\{xref\_roman};{}$\6
${}\\{ccode}[\.{':'}]\K\\{xref\_wildcard};{}$\6
${}\\{ccode}[\.{'.'}]\K\\{xref\_typewriter};{}$\6
${}\\{ccode}[\.{','}]\K\\{thin\_space};{}$\6
${}\\{ccode}[\.{'|'}]\K\\{math\_break};{}$\6
${}\\{ccode}[\.{'/'}]\K\\{line\_break};{}$\6
${}\\{ccode}[\.{'\#'}]\K\\{big\_line\_break};{}$\6
${}\\{ccode}[\.{'+'}]\K\\{no\_line\_break};{}$\6
${}\\{ccode}[\.{';'}]\K\\{pseudo\_semi};{}$\6
${}\\{ccode}[\.{'['}]\K\\{macro\_arg\_open};{}$\6
${}\\{ccode}[\.{']'}]\K\\{macro\_arg\_close};{}$\6
${}\\{ccode}[\.{'\\''}]\K\\{ord};{}$\6
${}\\{ccode}[\.{'\_'}]\K\\{special\_command};{}$\6
\X36:Special control codes for debugging\X\par
\fi

\M{36}Users can write
\.{@2}, \.{@1}, and \.{@0} to turn tracing fully on, partly on,
and off, respectively.

\Y\B\4\X36:Special control codes for debugging\X${}\E{}$\6
$\\{ccode}[\.{'0'}]\K\\{ccode}[\.{'1'}]\K\\{ccode}[\.{'2'}]\K\\{trace}{}$;\par
\U35.\fi

\M{37}The \PB{\\{skip\_limbo}} routine is used on the first pass to skip
through
portions of the input that are not in any sections, i.e., that precede
the first section. After this procedure has been called, the value of
\PB{\\{input\_has\_ended}} will tell whether or not a section has actually been
found.

There's a complication that we will postpone until later: If the \.{@s}
operation appears in limbo, we want to use it to adjust the default
interpretation of identifiers.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{skip\_limbo}(\,);\par
\fi

\M{38}\B\&{void} \\{skip\_limbo}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}\W\\{get\_line}(\,)\E\T{0}){}$\1\5
\&{return};\2\6
${}{*}(\\{limit}+\T{1})\K\.{'@'};{}$\6
\&{while} ${}({*}\\{loc}\I\.{'@'}){}$\1\5
${}\\{loc}\PP{}$;\C{ look for '@', then skip two chars }\2\6
\&{if} ${}(\\{loc}\PP\Z\\{limit}){}$\5
${}\{{}$\1\6
\&{int} \|c${}\K{}$\\{ccode}[(\&{eight\_bits}) ${}{*}\\{loc}\PP];{}$\7
\&{if} ${}(\|c\E\\{new\_section}){}$\1\5
\&{return};\2\6
\&{if} ${}(\|c\E\\{noop}){}$\1\5
\\{skip\_restricted}(\,);\2\6
\&{else} \&{if} ${}(\|c\E\\{format\_code}){}$\1\5
\X79:Process simple format in limbo\X;\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{39}The \PB{$\skipxTeX$} routine is used on the first pass to skip through
the \TEX/ code at the beginning of a section. It returns the next
control code or `\.{\v}' found in the input. A \PB{\\{new\_section}} is
assumed to exist at the very end of the file.

\Y\B\F\\{skip\_TeX} \5
\\{TeX}\par
\Y\B\&{unsigned} ${}\skipxTeX{}$(\,)\C{ skip past pure \TEX/ code }\6
${}\{{}$\1\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}\W\\{get\_line}(\,)\E\T{0}){}$\1\5
\&{return} (\\{new\_section});\2\6
${}{*}(\\{limit}+\T{1})\K\.{'@'};{}$\6
\&{while} ${}({*}\\{loc}\I\.{'@'}\W{*}\\{loc}\I\.{'|'}){}$\1\5
${}\\{loc}\PP;{}$\2\6
\&{if} ${}({*}\\{loc}\PP\E\.{'|'}){}$\1\5
\&{return} (\.{'|'});\2\6
\&{if} ${}(\\{loc}\Z\\{limit}){}$\1\5
\&{return} (\\{ccode}[(\&{eight\_bits}) ${}{*}(\\{loc}\PP)]);{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\N{2}{40}Inputting the next token.
As stated above, \.{CWEAVE}'s most interesting lexical scanning routine is the
\PB{\\{get\_next}} function that inputs the next token of \CEE/ input. However,
\PB{\\{get\_next}} is not especially complicated.

The result of \PB{\\{get\_next}} is either a \PB{\&{char}} code for some
special character,
or it is a special code representing a pair of characters (e.g., `\.{!=}'),
or it is the numeric value computed by the \PB{\\{ccode}}
table, or it is one of the following special codes:

\yskip\hang \PB{\\{identifier}}: In this case the global variables \PB{\\{id%
\_first}} and
\PB{\\{id\_loc}} will have been set to the beginning and ending-plus-one
locations
in the buffer, as required by the \PB{\\{id\_lookup}} routine.

\yskip\hang \PB{\\{string}}: The string will have been copied into the array
\PB{\\{section\_text}}; \PB{\\{id\_first}} and \PB{\\{id\_loc}} are set as
above (now they are
pointers into \PB{\\{section\_text}}).

\yskip\hang \PB{\\{constant}}: The constant is copied into \PB{\\{section%
\_text}}, with
slight modifications; \PB{\\{id\_first}} and \PB{\\{id\_loc}} are set.

\yskip\noindent Furthermore, some of the control codes cause
\PB{\\{get\_next}} to take additional actions:

\yskip\hang \PB{\\{xref\_roman}}, \PB{\\{xref\_wildcard}}, \PB{\\{xref%
\_typewriter}}, \PB{$\TeXxstring$},
\PB{\\{verbatim}}: The values of \PB{\\{id\_first}} and \PB{\\{id\_loc}} will
have been set to
the beginning and ending-plus-one locations in the buffer.

\yskip\hang \PB{\\{section\_name}}: In this case the global variable \PB{\\{cur%
\_section}} will
point to the \PB{\\{byte\_start}} entry for the section name that has just been
scanned.
The value of \PB{\\{cur\_section\_char}} will be \PB{\.{'('}} if the section
name was
preceded by \.{@(} instead of \.{@<}.

\yskip\noindent If \PB{\\{get\_next}} sees `\.{@!}'
it sets \PB{\\{xref\_switch}} to \PB{\\{def\_flag}} and goes on to the next
token.

\Y\B\4\D$\\{constant}$ \5
\T{\~200}\C{ \CEE/ constant }\par
\B\4\D$\\{string}$ \5
\T{\~201}\C{ \CEE/ string }\par
\B\4\D$\\{identifier}$ \5
\T{\~202}\C{ \CEE/ identifier or reserved word }\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{name\_pointer} \\{cur\_section};\C{ name of section just scanned }\6
\&{char} \\{cur\_section\_char};\C{ the character just before that name }\par
\fi

\M{41}\B\X7:Include files\X${}\mathrel+\E{}$\6
\8\#\&{include} \.{<ctype.h>}\C{ definition of \PB{\\{isalpha}}, \PB{%
\\{isdigit}} and so on }\6
\8\#\&{include} \.{<stdlib.h>}\C{ definition of \PB{\\{exit}} }\6
\8\#\&{include} \.{<sys/stat.h>}\par
\fi

\M{42}As one might expect, \PB{\\{get\_next}} consists mostly of a big switch
that branches to the various special cases that can arise.

\Y\B\4\D$\\{isxalpha}(\|c)$ \5
$((\|c)\E\.{'\_'}{}$)\C{ non-alpha character allowed in identifier }\par
\B\4\D$\\{ishigh}(\|c)$ \5
((\&{eight\_bits}) (\|c)${}>\T{\~177}{}$)\par
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{eight\_bits} \\{get\_next}(\,);\par
\fi

\M{43}\B\&{eight\_bits} \\{get\_next}(\,)\C{ produces the next input token }\6
${}\{{}$\5
\1\&{eight\_bits} \|c;\C{ the current character }\7
\&{while} (\T{1})\5
${}\{{}$\1\6
\X48:Check if we're at the end of a preprocessor command\X;\6
\&{if} ${}(\\{loc}>\\{limit}\W\\{get\_line}(\,)\E\T{0}){}$\1\5
\&{return} (\\{new\_section});\2\6
${}\|c\K{*}(\\{loc}\PP);{}$\6
\&{if} ${}(\\{xisdigit}(\|c)\V\|c\E\.{'\\\\'}\V\|c\E\.{'.'}){}$\1\5
\X51:Get a constant\X\2\6
\&{else} \&{if} ${}(\|c\E\.{'\\''}\V\|c\E\.{'"'}\V(\|c\E\.{'L'}\W({*}\\{loc}\E%
\.{'\\''}\V{*}\\{loc}\E\.{'"'}))\3{-1}\V(\|c\E\.{'<'}\W\\{sharp\_include\_line}%
\E\T{1})){}$\1\5
\X52:Get a string\X\2\6
\&{else} \&{if} ${}(\\{xisalpha}(\|c)\V\\{isxalpha}(\|c)\V\\{ishigh}(\|c)){}$\1%
\5
\X50:Get an identifier\X\2\6
\&{else} \&{if} ${}(\|c\E\.{'@'}){}$\1\5
\X53:Get control code and possible section name\X\2\6
\&{else} \&{if} (\\{xisspace}(\|c))\1\5
\&{continue};\C{ ignore spaces and tabs }\2\6
\&{if} ${}(\|c\E\.{'\#'}\W\\{loc}\E\\{buffer}+\T{1}){}$\1\5
\X45:Raise preprocessor flag\X;\2\6
\4\\{mistake}:\5
\X49:Compress two-symbol operator\X\6
\&{return} (\|c);\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{44}Because preprocessor commands do not fit in with the rest of the syntax
of \CEE/,
we have to deal with them separately.  One solution is to enclose such
commands between special markers.  Thus, when a \.\# is seen as the
first character of a line, \PB{\\{get\_next}} returns a special code
\PB{\\{left\_preproc}} and raises a flag \PB{\\{preprocessing}}.

We can use the same internal code number for \PB{\\{left\_preproc}} as we do
for \PB{\\{ord}}, since \PB{\\{get\_next}} changes \PB{\\{ord}} into a string.

\Y\B\4\D$\\{left\_preproc}$ \5
\\{ord}\C{ begins a preprocessor command }\par
\B\4\D$\\{right\_preproc}$ \5
\T{\~217}\C{ ends a preprocessor command }\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{boolean} \\{preprocessing}${}\K\T{0}{}$;\C{ are we scanning a preprocessor
command? }\par
\fi

\M{45}\B\X45:Raise preprocessor flag\X${}\E{}$\6
${}\{{}$\1\6
${}\\{preprocessing}\K\T{1};{}$\6
\X47:Check if next token is \PB{\&{include}}\X;\6
\&{return} (\\{left\_preproc});\6
\4${}\}{}$\2\par
\U43.\fi

\M{46}An additional complication is the freakish use of \.< and \.> to delimit
a file name in lines that start with \.{\#include}.  We must treat this file
name as a string.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{boolean} \\{sharp\_include\_line}${}\K\T{0}{}$;\C{ are we scanning a \PB{$%
\#$ \&{include}} line? }\par
\fi

\M{47}\B\X47:Check if next token is \PB{\&{include}}\X${}\E{}$\6
\&{while} ${}(\\{loc}\Z\\{buffer\_end}-\T{7}\W\\{xisspace}({*}\\{loc})){}$\1\5
${}\\{loc}\PP;{}$\2\6
\&{if} ${}(\\{loc}\Z\\{buffer\_end}-\T{6}\W\\{strncmp}(\\{loc},\39%
\.{"include"},\39\T{7})\E\T{0}){}$\1\5
${}\\{sharp\_include\_line}\K\T{1}{}$;\2\par
\U45.\fi

\M{48}When we get to the end of a preprocessor line,
we lower the flag and send a code \PB{\\{right\_preproc}}, unless
the last character was a \.\\.

\Y\B\4\X48:Check if we're at the end of a preprocessor command\X${}\E{}$\6
\&{while} ${}(\\{loc}\E\\{limit}-\T{1}\W\\{preprocessing}\W{*}\\{loc}\E\.{'%
\\\\'}){}$\1\6
\&{if} ${}(\\{get\_line}(\,)\E\T{0}){}$\1\5
\&{return} (\\{new\_section});\C{ still in preprocessor mode }\2\2\6
\&{if} ${}(\\{loc}\G\\{limit}\W\\{preprocessing}){}$\5
${}\{{}$\1\6
${}\\{preprocessing}\K\\{sharp\_include\_line}\K\T{0};{}$\6
\&{return} (\\{right\_preproc});\6
\4${}\}{}$\2\par
\U43.\fi

\M{49}The following code assigns values to the combinations \.{++},
\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{\v\v}, and
\.{\&\&}, and to the \CPLUSPLUS/
combinations \.{...}, \.{::}, \.{.*} and \.{->*}.
The compound assignment operators (e.g., \.{+=}) are
treated as separate tokens.

%corrected by moell <= -> <
\Y\B\4\D$\\{compress}(\|c)$ \5
\&{if} ${}(\\{loc}\PP<\\{limit})$ \&{return} (\|c)\par
\Y\B\4\X49:Compress two-symbol operator\X${}\E{}$\6
\&{switch} (\|c)\5
${}\{{}$\1\6
\4\&{case} \.{'/'}:\6
\&{if} ${}({*}\\{loc}\E\.{'*'}){}$\5
${}\{{}$\1\6
\\{compress}(\\{begin\_comment});\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}({*}\\{loc}\E\.{'/'}){}$\1\5
\\{compress}(\\{begin\_short\_comment});\2\6
\&{break};\6
\4\&{case} \.{'+'}:\6
\&{if} ${}({*}\\{loc}\E\.{'+'}){}$\1\5
\\{compress}(\\{plus\_plus});\2\6
\&{break};\6
\4\&{case} \.{'-'}:\6
\&{if} ${}({*}\\{loc}\E\.{'-'}){}$\5
${}\{{}$\1\6
\\{compress}(\\{minus\_minus});\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}({*}\\{loc}\E\.{'>'}){}$\1\6
\&{if} ${}({*}(\\{loc}+\T{1})\E\.{'*'}){}$\5
${}\{{}$\1\6
${}\\{loc}\PP;{}$\6
\\{compress}(\\{minus\_gt\_ast});\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{compress}(\\{minus\_gt});\2\2\6
\&{break};\6
\4\&{case} \.{'.'}:\6
\&{if} ${}({*}\\{loc}\E\.{'*'}){}$\5
${}\{{}$\1\6
\\{compress}(\\{period\_ast});\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}({*}\\{loc}\E\.{'.'}\W{*}(\\{loc}+\T{1})\E\.{'.'}){}$\5
${}\{{}$\1\6
${}\\{loc}\PP;{}$\6
\\{compress}(\\{dot\_dot\_dot});\6
\4${}\}{}$\2\6
\&{break};\6
\4\&{case} \.{':'}:\6
\&{if} ${}({*}\\{loc}\E\.{':'}){}$\1\5
\\{compress}(\\{colon\_colon});\2\6
\&{break};\6
\4\&{case} \.{'='}:\6
\&{if} ${}({*}\\{loc}\E\.{'='}){}$\1\5
\\{compress}(\\{eq\_eq});\2\6
\&{break};\6
\4\&{case} \.{'>'}:\6
\&{if} ${}({*}\\{loc}\E\.{'='}){}$\5
${}\{{}$\1\6
\\{compress}(\\{gt\_eq});\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}({*}\\{loc}\E\.{'>'}){}$\1\5
\\{compress}(\\{gt\_gt});\2\6
\&{break};\6
\4\&{case} \.{'<'}:\6
\&{if} ${}({*}\\{loc}\E\.{'='}){}$\5
${}\{{}$\1\6
\\{compress}(\\{lt\_eq});\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}({*}\\{loc}\E\.{'<'}){}$\1\5
\\{compress}(\\{lt\_lt});\2\6
\&{break};\6
\4\&{case} \.{'\&'}:\6
\&{if} ${}({*}\\{loc}\E\.{'\&'}){}$\1\5
\\{compress}(\\{and\_and});\2\6
\&{break};\6
\4\&{case} \.{'|'}:\6
\&{if} ${}({*}\\{loc}\E\.{'|'}){}$\1\5
\\{compress}(\\{or\_or});\2\6
\&{break};\6
\4\&{case} \.{'!'}:\6
\&{if} ${}({*}\\{loc}\E\.{'='}){}$\1\5
\\{compress}(\\{not\_eq});\2\6
\&{break};\6
\4${}\}{}$\2\par
\U43.\fi

\M{50}\B\X50:Get an identifier\X${}\E{}$\6
${}\{{}$\1\6
${}\\{id\_first}\K\MM\\{loc};{}$\6
\&{while} ${}(\\{isalpha}({*}\PP\\{loc})\V\\{isdigit}({*}\\{loc})\V%
\\{isxalpha}({*}\\{loc})\V\\{ishigh}({*}\\{loc})){}$\1\5
;\2\6
${}\\{id\_loc}\K\\{loc};{}$\6
\&{return} (\\{identifier});\6
\4${}\}{}$\2\par
\U43.\fi

\M{51}Different conventions are followed by \TEX/ and \CEE/ to express octal
and hexadecimal numbers; it is reasonable to stick to each convention
within its realm.  Thus the \CEE/ part of a \.{CWEB} file has octals
introduced by \.0 and hexadecimals by \.{0x}, but \.{CWEAVE} will print
in italics or typewriter font, respectively, and introduced by single
or double quotes.  In order to simplify the \TEX/ macro used to print
such constants, we replace some of the characters.

Notice that in this section and the next, \PB{\\{id\_first}} and \PB{\\{id%
\_loc}}
are pointers into the array \PB{\\{section\_text}}, not into \PB{\\{buffer}}.

\Y\B\4\X51:Get a constant\X${}\E{}$\6
${}\{{}$\1\6
${}\\{id\_first}\K\\{id\_loc}\K\\{section\_text}+\T{1};{}$\6
\&{if} ${}({*}(\\{loc}-\T{1})\E\.{'\\\\'}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\PP\K\.{'\~'};{}$\6
\&{while} ${}(\\{xisdigit}({*}\\{loc})){}$\1\5
${}{*}\\{id\_loc}\PP\K{*}\\{loc}\PP;{}$\2\6
\4${}\}{}$\C{ octal constant }\2\6
\&{else} \&{if} ${}({*}(\\{loc}-\T{1})\E\.{'0'}){}$\5
${}\{{}$\1\6
\&{if} ${}({*}\\{loc}\E\.{'x'}\V{*}\\{loc}\E\.{'X'}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\PP\K\.{'\^'};{}$\6
${}\\{loc}\PP;{}$\6
\&{while} ${}(\\{xisxdigit}({*}\\{loc})){}$\1\5
${}{*}\\{id\_loc}\PP\K{*}\\{loc}\PP;{}$\2\6
\4${}\}{}$\C{ hex constant }\2\6
\&{else} \&{if} ${}(\\{xisdigit}({*}\\{loc})){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\PP\K\.{'\~'};{}$\6
\&{while} ${}(\\{xisdigit}({*}\\{loc})){}$\1\5
${}{*}\\{id\_loc}\PP\K{*}\\{loc}\PP;{}$\2\6
\4${}\}{}$\C{ octal constant }\2\6
\&{else}\1\5
\&{goto} \\{dec};\C{ decimal constant }\2\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\C{ decimal constant }\1\6
\&{if} ${}({*}(\\{loc}-\T{1})\E\.{'.'}\W\R\\{xisdigit}({*}\\{loc})){}$\1\5
\&{goto} \\{mistake};\C{ not a constant }\2\6
\4\\{dec}:\5
${}{*}\\{id\_loc}\PP\K{*}(\\{loc}-\T{1});{}$\6
\&{while} ${}(\\{xisdigit}({*}\\{loc})\V{*}\\{loc}\E\.{'.'}){}$\1\5
${}{*}\\{id\_loc}\PP\K{*}\\{loc}\PP;{}$\2\6
\&{if} ${}({*}\\{loc}\E\.{'e'}\V{*}\\{loc}\E\.{'E'}){}$\5
${}\{{}$\C{ float constant }\1\6
${}{*}\\{id\_loc}\PP\K\.{'\_'};{}$\6
${}\\{loc}\PP;{}$\6
\&{if} ${}({*}\\{loc}\E\.{'+'}\V{*}\\{loc}\E\.{'-'}){}$\1\5
${}{*}\\{id\_loc}\PP\K{*}\\{loc}\PP;{}$\2\6
\&{while} ${}(\\{xisdigit}({*}\\{loc})){}$\1\5
${}{*}\\{id\_loc}\PP\K{*}\\{loc}\PP;{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{while} ${}({*}\\{loc}\E\.{'u'}\V{*}\\{loc}\E\.{'U'}\V{*}\\{loc}\E\.{'l'}%
\V{*}\\{loc}\E\.{'L'}\V{*}\\{loc}\E\.{'f'}\V{*}\\{loc}\E\.{'F'}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\PP\K\.{'\$'};{}$\6
${}{*}\\{id\_loc}\PP\K\\{toupper}({*}\\{loc});{}$\6
${}\\{loc}\PP;{}$\6
\4${}\}{}$\2\6
\&{return} (\\{constant});\6
\4${}\}{}$\2\par
\U43.\fi

\M{52}\CEE/ strings and character constants, delimited by double and single
quotes, respectively, can contain newlines or instances of their own
delimiters if they are protected by a backslash.  We follow this
convention, but do not allow the string to be longer than \PB{\\{longest%
\_name}}.

\Y\B\4\X52:Get a string\X${}\E{}$\6
${}\{{}$\1\6
\&{char} \\{delim}${}\K\|c{}$;\C{ what started the string }\7
${}\\{id\_first}\K\\{section\_text}+\T{1};{}$\6
${}\\{id\_loc}\K\\{section\_text};{}$\6
\&{if} ${}(\\{delim}\E\.{'\\''}\W{*}(\\{loc}-\T{2})\E\.{'@'}){}$\5
${}\{{}$\1\6
${}{*}\PP\\{id\_loc}\K\.{'@'};{}$\6
${}{*}\PP\\{id\_loc}\K\.{'@'};{}$\6
\4${}\}{}$\2\6
${}{*}\PP\\{id\_loc}\K\\{delim};{}$\6
\&{if} ${}(\\{delim}\E\.{'L'}){}$\5
${}\{{}$\C{ wide character constant }\1\6
${}\\{delim}\K{*}\\{loc}\PP;{}$\6
${}{*}\PP\\{id\_loc}\K\\{delim};{}$\6
\4${}\}{}$\2\6
\&{if} ${}(\\{delim}\E\.{'<'}){}$\1\5
${}\\{delim}\K\.{'>'}{}$;\C{ for file names in \PB{$\#$ \&{include}} lines }\2\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\5
${}\{{}$\1\6
\&{if} ${}({*}(\\{limit}-\T{1})\I\.{'\\\\'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ String\ didn't\ end}\)\.{"});\6
${}\\{loc}\K\\{limit};{}$\6
\&{break};\6
\4${}\}{}$\2\6
\&{if} ${}(\\{get\_line}(\,)\E\T{0}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Input\ ended\ in\ mi}\)\.{ddle\ of\ string"});\6
${}\\{loc}\K\\{buffer};{}$\6
\&{break};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}((\|c\K{*}\\{loc}\PP)\E\\{delim}){}$\5
${}\{{}$\1\6
\&{if} ${}(\PP\\{id\_loc}\Z\\{section\_text\_end}){}$\1\5
${}{*}\\{id\_loc}\K\|c;{}$\2\6
\&{break};\6
\4${}\}{}$\2\6
\&{if} ${}(\|c\E\.{'\\\\'}){}$\1\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\1\5
\&{continue};\2\6
\&{else} \&{if} ${}(\PP\\{id\_loc}\Z\\{section\_text\_end}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\K\.{'\\\\'};{}$\6
${}\|c\K{*}\\{loc}\PP;{}$\6
\4${}\}{}$\2\2\6
\&{if} ${}(\PP\\{id\_loc}\Z\\{section\_text\_end}){}$\1\5
${}{*}\\{id\_loc}\K\|c;{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\\{id\_loc}\G\\{section\_text\_end}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\n!\ String\ too\ long}\)\.{:\ "});\6
${}\\{term\_write}(\\{section\_text}+\T{1},\39\T{25});{}$\6
\\{printf}(\.{"..."});\6
\\{mark\_error};\6
\4${}\}{}$\2\6
${}\\{id\_loc}\PP;{}$\6
\&{if} ${}(\\{sharp\_include\_line}\W(\\{phase}\E\T{1}\V\\{parsing\_exp%
\_file})){}$\1\5
\\{remember\_include\_file}(\,);\C{ string is an include file name }\2\6
\&{return} (\\{string});\6
\4${}\}{}$\2\par
\Us43\ET53.\fi

\M{53}After an \.{@} sign has been scanned, the next character tells us
whether there is more work to do.

\Y\B\4\X53:Get control code and possible section name\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{parsing\_exp\_file})\C{ this is an ordinary \CEE/ file, no control
codes }\1\6
\&{return} \.{'@'};\2\6
${}\|c\K{*}\\{loc}\PP;{}$\6
\&{switch} (\\{ccode}[(\&{eight\_bits}) \|c])\5
${}\{{}$\1\6
\4\&{case} \\{translit\_code}:\5
\\{err\_print}(\.{"!\ Use\ @l\ in\ limbo\ o}\)\.{nly"});\6
\&{continue};\6
\4\&{case} \\{underline}:\5
${}\\{xref\_switch}\K\\{def\_flag};{}$\6
\&{continue};\6
\4\&{case} \\{trace}:\5
${}\\{tracing}\K\|c-\.{'0'};{}$\6
\&{continue};\6
\4\&{case} \\{xref\_roman}:\5
\&{case} \\{xref\_wildcard}:\5
\&{case} \\{xref\_typewriter}:\5
\&{case} \\{noop}:\5
\&{case} ${}\TeXxstring:{}$\5
${}\|c\K\\{ccode}[\|c];{}$\6
\\{skip\_restricted}(\,);\6
\&{return} (\|c);\6
\4\&{case} \\{section\_name}:\5
\X54:Scan the section name and make \PB{\\{cur\_section}} point to it\X;\6
\4\&{case} \\{verbatim}:\5
\X60:Scan a verbatim string\X;\6
\4\&{case} \\{ord}:\5
\X52:Get a string\X;\6
\4\&{default}:\5
\&{return} (\\{ccode}[(\&{eight\_bits}) \|c]);\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U43.\fi

\M{54}The occurrence of a section name sets \PB{\\{xref\_switch}} to zero,
because the section name might (for example) follow \&{int}.

\Y\B\4\X54:Scan the section name and make \PB{\\{cur\_section}} point to it%
\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\|k{}$;\C{ pointer into \PB{\\{section\_text}} }\7
${}\\{cur\_section\_char}\K{*}(\\{loc}-\T{1});{}$\6
\X56:Put section name into \PB{\\{section\_text}}\X;\6
\&{if} ${}(\|k-\\{section\_text}>\T{3}\W\\{strncmp}(\|k-\T{2},\39\.{"..."},\39%
\T{3})\E\T{0}){}$\1\5
${}\\{cur\_section}\K\\{section\_lookup}(\\{section\_text}+\T{1},\39\|k-\T{3},%
\39\T{1}){}$;\C{ 1 indicates a prefix }\2\6
\&{else}\1\5
${}\\{cur\_section}\K\\{section\_lookup}(\\{section\_text}+\T{1},\39\|k,\39%
\T{0});{}$\2\6
${}\\{xref\_switch}\K\T{0};{}$\6
\&{return} (\\{section\_name});\6
\4${}\}{}$\2\par
\U53.\fi

\M{55}Section names are placed into the \PB{\\{section\_text}} array with
consecutive spaces,
tabs, and carriage-returns replaced by single spaces. There will be no
spaces at the beginning or the end. (We set \PB{$\\{section\_text}[\T{0}]\K\.{'%
\ '}$} to facilitate
this, since the \PB{\\{section\_lookup}} routine uses \PB{\\{section\_text}[%
\T{1}]} as the first
character of the name.)

\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{section\_text}[\T{0}]\K\.{'\ '}{}$;\par
\fi

\M{56}\B\X56:Put section name into \PB{\\{section\_text}}\X${}\E{}$\6
$\|k\K\\{section\_text};{}$\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}\W\\{get\_line}(\,)\E\T{0}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Input\ ended\ in\ se}\)\.{ction\ name"});\6
${}\\{loc}\K\\{buffer}+\T{1};{}$\6
\&{break};\6
\4${}\}{}$\2\6
${}\|c\K{*}\\{loc};{}$\6
\X57:If end of name or erroneous control code, \PB{\&{break}}\X;\6
${}\\{loc}\PP;{}$\6
\&{if} ${}(\|k<\\{section\_text\_end}){}$\1\5
${}\|k\PP;{}$\2\6
\&{if} (\\{xisspace}(\|c))\5
${}\{{}$\1\6
${}\|c\K\.{'\ '};{}$\6
\&{if} ${}({*}(\|k-\T{1})\E\.{'\ '}){}$\1\5
${}\|k\MM;{}$\2\6
\4${}\}{}$\2\6
${}{*}\|k\K\|c;{}$\6
\4${}\}{}$\2\6
\&{if} ${}(\|k\G\\{section\_text\_end}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\n!\ Section\ name\ to}\)\.{o\ long:\ "});\6
${}\\{term\_write}(\\{section\_text}+\T{1},\39\T{25});{}$\6
\\{printf}(\.{"..."});\6
\\{mark\_harmless};\6
\4${}\}{}$\2\6
\&{if} ${}({*}\|k\E\.{'\ '}\W\|k>\\{section\_text}){}$\1\5
${}\|k\MM{}$;\2\par
\U54.\fi

\M{57}\B\X57:If end of name or erroneous control code, \PB{\&{break}}\X${}\E{}$%
\6
\&{if} ${}(\|c\E\.{'@'}){}$\5
${}\{{}$\1\6
${}\|c\K{*}(\\{loc}+\T{1});{}$\6
\&{if} ${}(\|c\E\.{'>'}){}$\5
${}\{{}$\1\6
${}\\{loc}\MRL{+{\K}}\T{2};{}$\6
\&{break};\6
\4${}\}{}$\2\6
\&{if} (\\{ccode}[(\&{eight\_bits}) \|c]${}\E\\{new\_section}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Section\ name\ didn}\)\.{'t\ end"});\6
\&{break};\6
\4${}\}{}$\2\6
\&{if} ${}(\|c\I\.{'@'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Control\ codes\ are}\)\.{\ forbidden\ in\ sectio}\)\.{n\
name"});\6
\&{break};\6
\4${}\}{}$\2\6
${}{*}(\PP\|k)\K\.{'@'};{}$\6
${}\\{loc}\PP{}$;\C{ now \PB{$\|c\E{*}\\{loc}$} again }\6
\4${}\}{}$\2\par
\U56.\fi

\M{58}This function skips over a restricted context at relatively high speed.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{skip\_restricted}(\,);\par
\fi

\M{59}\B\&{void} \\{skip\_restricted}(\,)\1\1\2\2\6
${}\{{}$\1\6
${}\\{id\_first}\K\\{loc};{}$\6
${}{*}(\\{limit}+\T{1})\K\.{'@'};{}$\6
\4\\{false\_alarm}:\6
\&{while} ${}({*}\\{loc}\I\.{'@'}){}$\1\5
${}\\{loc}\PP;{}$\2\6
${}\\{id\_loc}\K\\{loc};{}$\6
\&{if} ${}(\\{loc}\PP>\\{limit}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Control\ text\ didn}\)\.{'t\ end"});\6
${}\\{loc}\K\\{limit};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} ${}({*}\\{loc}\E\.{'@'}\W\\{loc}\Z\\{limit}){}$\5
${}\{{}$\1\6
${}\\{loc}\PP;{}$\6
\&{goto} \\{false\_alarm};\6
\4${}\}{}$\2\6
\&{if} ${}({*}\\{loc}\PP\I\.{'>'}){}$\1\5
\\{err\_print}(\.{"!\ Control\ codes\ are}\)\.{\ forbidden\ in\ contro}\)\.{l\
text"});\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{60}At the present point in the program we
have \PB{${*}(\\{loc}-\T{1})\E\\{verbatim}$}; we set \PB{\\{id\_first}} to the
beginning
of the string itself, and \PB{\\{id\_loc}} to its ending-plus-one location in
the
buffer.  We also set \PB{\\{loc}} to the position just after the ending
delimiter.

\Y\B\4\X60:Scan a verbatim string\X${}\E{}$\6
${}\{{}$\1\6
${}\\{id\_first}\K\\{loc}\PP;{}$\6
${}{*}(\\{limit}+\T{1})\K\.{'@'};{}$\6
${}{*}(\\{limit}+\T{2})\K\.{'>'};{}$\6
\&{while} ${}({*}\\{loc}\I\.{'@'}\V{*}(\\{loc}+\T{1})\I\.{'>'}){}$\1\5
${}\\{loc}\PP;{}$\2\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\1\5
\\{err\_print}(\.{"!\ Verbatim\ string\ d}\)\.{idn't\ end"});\2\6
${}\\{id\_loc}\K\\{loc};{}$\6
${}\\{loc}\MRL{+{\K}}\T{2};{}$\6
\&{return} (\\{verbatim});\6
\4${}\}{}$\2\par
\U53.\fi

\N{0}{61}Phase one processing.
We now have accumulated enough subroutines to make it possible to carry out
\.{CWEAVE}'s first pass over the source file. If everything works right,
both phase one and phase two of \.{CWEAVE} will assign the same numbers to
sections, and these numbers will agree with what \.{CTANGLE} does.

The global variable \PB{\\{next\_control}} often contains the most recent
output of
\PB{\\{get\_next}}; in interesting cases, this will be the control code that
ended a section or part of a section.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{eight\_bits} \\{next\_control};\C{ control code waiting to be acting upon }%
\par
\fi

\M{62}The overall processing strategy in phase one has the following
straightforward outline.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{phase\_one}(\,);\par
\fi

\M{63}\B\&{void} \\{phase\_one}(\,)\1\1\2\2\6
${}\{{}$\1\6
${}\\{phase}\K\T{1};{}$\6
\\{reset\_input}(\,);\6
${}\\{section\_count}\K\T{0};{}$\6
\\{skip\_limbo}(\,);\6
${}\\{change\_exists}\K\T{0};{}$\6
\&{while} ${}(\R\\{input\_has\_ended}){}$\1\5
\X64:Store cross-reference data for the current section\X;\2\6
${}\\{changed\_section}[\\{section\_count}]\K\\{change\_exists}{}$;\C{ the
index changes if anything does }\6
${}\\{phase}\K\T{2}{}$;\C{ prepare for second phase }\6
\X84:Print error messages about unused or undefined section names\X;\6
\\{remember\_export\_file}(\,);\6
\\{process\_imported\_files}(\,);\6
\4${}\}{}$\2\par
\fi

\M{64}\B\X64:Store cross-reference data for the current section\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\PP\\{section\_count}\E\\{max\_sections}){}$\1\5
\\{overflow}(\.{"section\ number"});\2\6
${}\\{changed\_section}[\\{section\_count}]\K\\{changing}{}$;\C{ it will become
1 if any line changes }\6
\&{if} ${}({*}(\\{loc}-\T{1})\E\.{'*'}\W\\{show\_progress}){}$\5
${}\{{}$\1\6
${}\\{printf}(\.{"*\%d"},\39\\{section\_count});{}$\6
\\{update\_terminal};\C{ print a progress report }\6
\4${}\}{}$\2\6
\X73:Store cross-references in the \TEX/ part of a section\X;\6
\X77:Store cross-references in the definition part of a section\X;\6
\X80:Store cross-references in the \CEE/ part of a section\X;\6
\&{if} (\\{changed\_section}[\\{section\_count}])\1\5
${}\\{change\_exists}\K\T{1};{}$\2\6
\4${}\}{}$\2\par
\U63.\fi

\M{65}The \PB{\\{C\_xref}} subroutine stores references to identifiers in
\CEE/ text material beginning with the current value of \PB{\\{next\_control}}
and continuing until \PB{\\{next\_control}} is `\.\{' or `\.{\v}', or until the
next
``milestone'' is passed (i.e., \PB{$\\{next\_control}\G\\{format\_code}$}). If
\PB{$\\{next\_control}\G\\{format\_code}$} when \PB{\\{C\_xref}} is called,
nothing will happen;
but if \PB{$\\{next\_control}\E\.{'|'}$} upon entry, the procedure assumes that
this is
the `\.{\v}' preceding \CEE/ text that is to be processed.

The parameter \PB{\\{spec\_ctrl}} is used to change this behavior. In most
cases
\PB{\\{C\_xref}} is called with \PB{$\\{spec\_ctrl}\E\\{ignore}$}, which
triggers the default
processing described above. If \PB{$\\{spec\_ctrl}\E\\{section\_name}$},
section names will
be gobbled. This is used when \CEE/ text in the \TEX/ part or inside comments
is parsed: It allows for section names to appear in \pb, but these
strings will not be entered into the cross reference lists since they are not
definitions of section names.

The program uses the fact that our internal code numbers satisfy
the relations \PB{$\\{xref\_roman}\E\\{identifier}+\\{roman}$} and \PB{$\\{xref%
\_wildcard}\E\\{identifier}+\\{wildcard}$} and \PB{$\\{xref\_typewriter}\E%
\\{identifier}+\\{typewriter}$} and \PB{$\\{normal}\E\T{0}$}.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{C\_xref}(\,);\par
\fi

\M{66}\B\&{void} \\{C\_xref}(\\{spec\_ctrl})\C{ makes cross-references for %
\CEE/ identifiers }\1\1\6
\&{eight\_bits} \\{spec\_ctrl};\2\2\6
${}\{{}$\1\6
\&{static} \&{int} \\{bal}${}\K\T{0},{}$ \\{par}${}\K\T{0}{}$;\C{
brace/paranthesis balance in \CEE/ code }\6
\&{static} \&{name\_pointer} \\{typedef\_name};\C{ the name of a new type }\6
\&{name\_pointer} \|p;\7
\&{while} ${}(\\{next\_control}<\\{format\_code}\V\\{next\_control}\E\\{spec%
\_ctrl}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{next\_control}\G\\{identifier}\W\\{next\_control}\Z\\{xref%
\_typewriter}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{next\_control}>\\{identifier}){}$\5
${}\{{}$\1\6
\X74:Replace \PB{\.{"@@"}} by \PB{\.{"@"}}\X\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{next\_control}-%
\\{identifier});{}$\6
\\{new\_xref}(\|p);\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{next\_control}-%
\\{identifier});{}$\6
\\{new\_xref}(\|p);\6
\X69:Examine identifier to find out new types\X;\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\\{special\_command}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{spec\_ctrl}\E\\{ignore}){}$\5
${}\{{}$\C{ if not enclosed in '\.{\v}' }\1\6
\X293:Special command seen in phase one\X;\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\5
\&{goto} \\{got\_next\_one};\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'\{'}){}$\1\5
${}\\{bal}\PP;{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'\}'}){}$\1\5
${}\\{bal}\MM;{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'('}){}$\1\5
${}\\{par}\PP;{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{')'}){}$\1\5
${}\\{par}\MM;{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{';'}\W\R\\{bal}\W\\{typedefing}){}$\5
${}\{{}$\C{ typedefing ends }\1\6
\X70:end of \PB{\&{typedef}} construct reached\X;\6
\4${}\}{}$\2\6
\&{if} ${}(\\{next\_control}\E\\{section\_name}){}$\5
${}\{{}$\1\6
${}\\{section\_xref\_switch}\K\\{cite\_flag};{}$\6
\\{new\_section\_xref}(\\{cur\_section});\6
\4${}\}{}$\2\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4\\{got\_next\_one}:\6
\&{if} ${}(\\{next\_control}\E\.{'|'}\V\\{next\_control}\E\\{begin\_comment}\V%
\\{next\_control}\E\\{begin\_short\_comment}){}$\1\5
\&{return};\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{67}The following flag says, that we are scanning a \PB{\&{typedef}}
construct.
We keep the flag raised until we found a '\.{;}' outside of all braces
or we encountered the type name enclosed in paranthesis.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{static} \&{int} \\{typedefing};\par
\fi

\M{68}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{typedefing}\K\T{0}{}$;\par
\fi

\M{69}The original version of \.{CWEAVE} only knew user defined types from
the point on the definition occurred. We now want to find all types in
phase one so that we can print them properly in phase two.

There are two different kinds of things we want to be of ilk \PB{\\{raw\_int}}
rather than \PB{\\{normal}}. The first are identifiers following a \PB{%
\\{struct\_like}}
name. Since they immediatly follow the \PB{\\{struct\_like}} keyword, this is
easy.
As we distinguish between \CEE/ and \CPLUSPLUS/ now, we will only do that
if \PB{\\{Cxx}} is \PB{\\{true}}.

The other case is type definitions using \PB{\&{typedef}}. If we encounter a
\PB{\\{typedef\_like}} keyword, we raise the \PB{\\{typedefing}} flag.
In order to find the name of the new type keyword, we have to scan
the following identifiers. If we find one enclosed in '\.{()}', then we
can assume it's the the new type keyword and change its ilk to \PB{\\{raw%
\_int}}.
Otherwise, we change the ilk of the last identifier before the final
'\.{;}' of the \PB{\&{typedef}} construct.
\Y\B\4\D$\\{Cxx}$ \5
\\{flags}[\.{'+'}]\par
\Y\B\4\X69:Examine identifier to find out new types\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \\{label\_ilk};\7
\&{if} ${}(\\{typedefing}\W\R\\{bal}\W\R\\{preprocessing}){}$\5
${}\{{}$\C{ identifier outside of braces }\1\6
\&{if} (\\{par})\5
${}\{{}$\C{ \.{(} open: a function pointer like \PB{\&{typedef} \&{void} (\,);}
}\1\6
${}\\{typedefing}\K\T{0};{}$\6
${}\|p\MG\\{ilk}\K\\{raw\_int};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{typedef\_name}\K\|p{}$;\C{ remember last identifier }\2\6
\4${}\}{}$\2\6
\&{if} ${}(\|p\MG\\{ilk}\E\\{struct\_like}){}$\5
${}\{{}$\C{ if followed by identifier, make its ilk \PB{\\{raw\_int}} }\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
\&{if} (\\{Cxx})\1\5
${}\\{label\_ilk}\K\\{raw\_int}{}$;\C{ only if \CEE/++ is true }\2\6
\&{else}\1\5
${}\\{label\_ilk}\K\\{normal};{}$\2\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{label\_ilk});{}$\6
\4${}\}{}$\2\6
\&{goto} \\{got\_next\_one};\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\MG\\{ilk}\E\\{typedef\_like}\W\\{spec\_ctrl}\E%
\\{ignore}){}$\5
${}\{{}$\1\6
${}\\{typedefing}\K\T{1};{}$\6
${}\\{par}\K\\{bal}\K\T{0}{}$;\C{ count braces/paranthesis starting from here }%
\6
${}\\{typedef\_name}\K\NULL;{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U66.\fi

\M{70}At the end of the \PB{\&{typedef}} construct, \PB{\\{typedef\_name}}
holds the
last identifier seen. We change its ilk to \PB{\\{raw\_int}}.
\Y\B\4\X70:end of \PB{\&{typedef}} construct reached\X${}\E{}$\6
${}\{{}$\1\6
\&{if} (\\{typedef\_name})\C{ if we found the name of a type, change its ilk }%
\1\6
${}\\{typedef\_name}\MG\\{ilk}\K\\{raw\_int};{}$\2\6
${}\\{typedefing}\K\T{0};{}$\6
\4${}\}{}$\2\par
\U66.\fi

\M{71}The \PB{\\{outer\_xref}} subroutine is like \PB{\\{C\_xref}} except that
it begins
with \PB{$\\{next\_control}\I\.{'|'}$} and ends with \PB{$\\{next\_control}\G%
\\{format\_code}$}. Thus, it
handles \CEE/ text with embedded comments.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{outer\_xref}(\,);\par
\fi

\M{72}\B\&{void} \\{outer\_xref}(\,)\C{ extension of \PB{\\{C\_xref}} }\6
${}\{{}$\1\6
\&{int} \\{bal};\C{ brace level in comment }\7
${}\\{typedefing}\K\T{0};{}$\6
\&{while} ${}(\\{next\_control}<\\{format\_code}){}$\1\6
\&{if} ${}(\\{next\_control}\I\\{begin\_comment}\W\\{next\_control}\I\\{begin%
\_short\_comment}){}$\1\5
\\{C\_xref}(\\{ignore});\2\6
\&{else}\5
${}\{{}$\1\6
\&{boolean} \\{is\_long\_comment}${}\K(\\{next\_control}\E\\{begin%
\_comment});{}$\7
${}\\{bal}\K\\{copy\_comment}(\\{is\_long\_comment},\39\T{1});{}$\6
${}\\{next\_control}\K\.{'|'};{}$\6
\&{while} ${}(\\{bal}>\T{0}){}$\5
${}\{{}$\1\6
\\{C\_xref}(\\{section\_name});\C{ do not reference section names in comments }%
\6
\&{if} ${}(\\{next\_control}\E\.{'|'}){}$\1\5
${}\\{bal}\K\\{copy\_comment}(\\{is\_long\_comment},\39\\{bal});{}$\2\6
\&{else}\1\5
${}\\{bal}\K\T{0}{}$;\C{ an error message will occur in phase two }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\2\6
\4${}\}{}$\2\par
\fi

\M{73}In the \TEX/ part of a section, cross-reference entries are made only for
the identifiers in \CEE/ texts enclosed in \pb, or for control texts
enclosed in \.{@\^}$\,\ldots\,$\.{@>} or \.{@.}$\,\ldots\,$\.{@>}
or \.{@:}$\,\ldots\,$\.{@>}.

\Y\B\4\X73:Store cross-references in the \TEX/ part of a section\X${}\E{}$\6
$\\{is\_example}\K\T{0};{}$\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{switch} ${}(\\{next\_control}\K\skipxTeX(\,)){}$\5
${}\{{}$\1\6
\4\&{case} \\{translit\_code}:\5
\\{err\_print}(\.{"!\ Use\ @l\ in\ limbo\ o}\)\.{nly"});\6
\&{continue};\6
\4\&{case} \\{underline}:\5
${}\\{xref\_switch}\K\\{def\_flag};{}$\6
\&{continue};\6
\4\&{case} \\{trace}:\5
${}\\{tracing}\K{*}(\\{loc}-\T{1})-\.{'0'};{}$\6
\&{continue};\6
\4\&{case} \.{'|'}:\5
${}\\{typedefing}\K\T{0};{}$\6
\\{C\_xref}(\\{section\_name});\6
\&{break};\6
\4\&{case} \\{xref\_roman}:\5
\&{case} \\{xref\_wildcard}:\5
\&{case} \\{xref\_typewriter}:\5
\&{case} \\{noop}:\5
\&{case} \\{section\_name}:\5
${}\\{loc}\MRL{-{\K}}\T{2};{}$\6
${}\\{next\_control}\K\\{get\_next}(\,){}$;\C{ scan to \.{@>} }\6
\&{if} ${}(\\{next\_control}\G\\{xref\_roman}\W\\{next\_control}\Z\\{xref%
\_typewriter}){}$\5
${}\{{}$\1\6
\X74:Replace \PB{\.{"@@"}} by \PB{\.{"@"}}\X\6
${}\\{new\_xref}(\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{next%
\_control}-\\{identifier}));{}$\6
\4${}\}{}$\2\6
\&{break};\6
\4\&{case} \\{special\_command}:\5
\X75:Special command seen in \TeX{} part (phase one)\X;\6
\&{break};\6
\4\&{case} \\{example\_code}:\5
${}\\{is\_example}\K\R\\{is\_example};{}$\6
\&{break};\6
\4\&{case} \\{autodoc\_code}:\5
\X382:Skip autodoc in phase one\X;\6
\&{break};\6
\4${}\}{}$\2\6
\&{if} ${}(\\{next\_control}\E\\{definition}\W\\{is\_example}){}$\1\5
\&{continue};\2\6
\&{if} ${}(\\{next\_control}\G\\{format\_code}){}$\1\5
\&{break};\2\6
\4${}\}{}$\2\par
\U64.\fi

\M{74}\B\X74:Replace \PB{\.{"@@"}} by \PB{\.{"@"}}\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{src}\K\\{id\_first},{}$ ${}{*}\\{dst}\K\\{id\_first};{}$\7
\&{while} ${}(\\{src}<\\{id\_loc}){}$\5
${}\{{}$\1\6
\&{if} ${}({*}\\{src}\E\.{'@'}){}$\1\5
${}\\{src}\PP;{}$\2\6
${}{*}\\{dst}\PP\K{*}\\{src}\PP;{}$\6
\4${}\}{}$\2\6
${}\\{id\_loc}\K\\{dst};{}$\6
\&{while} ${}(\\{dst}<\\{src}){}$\1\5
${}{*}\\{dst}\PP\K\.{'\ '}{}$;\C{ clean up in case of error message display }\2%
\6
\4${}\}{}$\2\par
\Us66\ET73.\fi

\M{75}Special commands are commands introduced by '\.{@$\_$}' followed by an
identifier giving the name of the command.
\Y\B\4\X75:Special command seen in \TeX{} part (phase one)\X${}\E{}$\6
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
\&{name\_pointer} \|p${}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39%
\\{normal});{}$\7
\&{if} ${}(\|p\E\\{id\_mark}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\K\T{0};{}$\6
\\{mark}(\\{id\_first});\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{err\_print}(\.{"!\ Name\ of\ copy\ buff}\)\.{er\ expected"});\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_copy}){}$\1\5
\\{copy}(\,);\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\Us73\ET382.\fi

\M{76}During the definition and \CEE/ parts of a section, cross-references
are made for all identifiers except reserved words. However, the right
identifier in a format definition is not referenced, and the left
identifier is referenced only if it has been explicitly
underlined (preceded by \.{@!}).
The \TEX/ code in comments is, of course, ignored, except for
\CEE/ portions enclosed in \pb; the text of a section name is skipped
entirely, even if it contains \pb\ constructions.

The variables \PB{\\{lhs}} and \PB{\\{rhs}} point to the respective identifiers
involved
in a format definition.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{name\_pointer} \\{lhs}${},{}$ \\{rhs};\C{ pointers to \PB{\\{byte\_start}}
for format identifiers }\par
\fi

\M{77}When we get to the following code we have \PB{$\\{next\_control}\G%
\\{format\_code}$}.

\Y\B\4\X77:Store cross-references in the definition part of a section\X${}\E{}$%
\6
\&{while} ${}(\\{next\_control}\Z\\{definition}){}$\5
${}\{{}$\C{ \PB{\\{format\_code}} or \PB{\\{definition}} }\1\6
\&{if} ${}(\\{next\_control}\E\\{definition}){}$\5
${}\{{}$\1\6
${}\\{xref\_switch}\K\\{def\_flag}{}$;\C{ implied \.{@!} }\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
\X78:Process a format definition\X;\2\6
\\{outer\_xref}(\,);\6
\4${}\}{}$\2\par
\U64.\fi

\M{78}Error messages for improper format definitions will be issued in phase
two. Our job in phase one is to define the \PB{\\{ilk}} of a properly formatted
identifier, and to remove cross-references to identifiers that we now
discover should be unindexed.

\Y\B\4\X78:Process a format definition\X${}\E{}$\6
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\\{lhs}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
${}\\{lhs}\MG\\{ilk}\K\\{normal};{}$\6
\&{if} (\\{xref\_switch})\1\5
\\{new\_xref}(\\{lhs});\2\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\\{rhs}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
${}\\{lhs}\MG\\{ilk}\K\\{rhs}\MG\\{ilk};{}$\6
\&{if} (\\{unindexed}(\\{lhs}))\5
${}\{{}$\C{ retain only underlined entries }\1\6
\&{xref\_pointer} \|q${},{}$ \|r${}\K\NULL;{}$\7
\&{for} ${}(\|q\K{}$(\&{xref\_pointer}) \\{lhs}${}\MG\\{xref};{}$ ${}\|q>%
\\{xmem};{}$ ${}\|q\K\|q\MG\\{xlink}){}$\1\6
\&{if} ${}(\|q\MG\\{num}<\\{def\_flag}){}$\1\6
\&{if} (\|r)\1\5
${}\|r\MG\\{xlink}\K\|q\MG\\{xlink};{}$\2\6
\&{else}\1\5
${}\\{lhs}\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \|q${}\MG\\{xlink};{}$\2\2\6
\&{else}\1\5
${}\|r\K\|q;{}$\2\2\6
\4${}\}{}$\2\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U77.\fi

\M{79}A much simpler processing of format definitions occurs when the
definition is found in limbo.

\Y\B\4\X79:Process simple format in limbo\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\\{get\_next}(\,)\I\\{identifier}){}$\1\5
\\{err\_print}(\.{"!\ Missing\ left\ iden}\)\.{tifier\ of\ @s"});\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{lhs}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\\{get\_next}(\,)\I\\{identifier}){}$\1\5
\\{err\_print}(\.{"!\ Missing\ right\ ide}\)\.{ntifier\ of\ @s"});\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{rhs}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
${}\\{lhs}\MG\\{ilk}\K\\{rhs}\MG\\{ilk};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U38.\fi

\M{80}Finally, when the \TEX/ and definition parts have been treated, we have
\PB{$\\{next\_control}\G\\{begin\_C}$}.

\Y\B\4\X80:Store cross-references in the \CEE/ part of a section\X${}\E{}$\6
\&{if} ${}(\\{next\_control}\Z\\{section\_name}){}$\5
${}\{{}$\C{ \PB{\\{begin\_C}} or \PB{\\{section\_name}} }\1\6
\&{if} ${}(\\{next\_control}\E\\{begin\_C}){}$\1\5
${}\\{section\_xref\_switch}\K\T{0};{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{section\_xref\_switch}\K\\{def\_flag};{}$\6
\&{if} ${}(\\{cur\_section\_char}\E\.{'('}\W\\{cur\_section}\I\\{name\_dir}){}$%
\1\5
\\{set\_file\_flag}(\\{cur\_section});\2\6
\4${}\}{}$\2\6
\&{do}\5
${}\{{}$\1\6
\&{if} ${}(\\{next\_control}\E\\{section\_name}\W\\{cur\_section}\I\\{name%
\_dir}){}$\1\5
\\{new\_section\_xref}(\\{cur\_section});\2\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\\{outer\_xref}(\,);\6
\4${}\}{}$\2\5
\&{while} ${}(\\{next\_control}\Z\\{section\_name});{}$\6
\4${}\}{}$\2\par
\U64.\fi

\M{81}After phase one has looked at everything, we want to check that each
section name was both defined and used.  The variable \PB{\\{cur\_xref}} will
point
to cross-references for the current section name of interest.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{xref\_pointer} \\{cur\_xref};\C{ temporary cross-reference pointer }\6
\&{boolean} \\{an\_output};\C{ did \PB{\\{file\_flag}} precede \PB{\\{cur%
\_xref}}? }\par
\fi

\M{82}The following recursive procedure
walks through the tree of section names and prints out anomalies.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{section\_check}(\,);\par
\fi

\M{83}\B\&{void} \\{section\_check}(\|p)\1\1\6
\&{name\_pointer} \|p;\C{ print anomalies in subtree \PB{\|p} }\2\2\6
${}\{{}$\1\6
\&{if} (\|p)\5
${}\{{}$\1\6
${}\\{section\_check}(\|p\MG\\{llink});{}$\6
${}\\{cur\_xref}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\E\\{file\_flag}){}$\5
${}\{{}$\1\6
${}\\{an\_output}\K\T{1};{}$\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{an\_output}\K\T{0};{}$\2\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}<\\{def\_flag}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\n!\ Never\ defined:\ }\)\.{<"});\6
\\{print\_section\_name}(\|p);\6
\\{putchar}(\.{'>'});\6
\\{mark\_harmless};\6
\4${}\}{}$\2\6
\&{while} ${}(\\{cur\_xref}\MG\\{num}\G\\{cite\_flag}){}$\1\5
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\2\6
\&{if} ${}(\\{cur\_xref}\E\\{xmem}\W\R\\{an\_output}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\n!\ Never\ used:\ <"});\6
\\{print\_section\_name}(\|p);\6
\\{putchar}(\.{'>'});\6
\\{mark\_harmless};\6
\4${}\}{}$\2\6
${}\\{section\_check}(\|p\MG\\{rlink});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{84}\B\X84:Print error messages about unused or undefined section names\X${}%
\E{}$\6
\\{section\_check}(\\{root})\par
\U63.\fi

\N{1}{85}Low-level output routines.
The \TEX/ output is supposed to appear in lines at most \PB{\\{line\_length}}
characters long, so we place it into an output buffer. During the output
process, \PB{\\{out\_line}} will hold the current line number of the line about
to
be output.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} ${}\\{out\_buf}[\\{line\_length}+\T{1}]{}$;\C{ assembled characters }\6
\&{char} ${}{*}\\{out\_ptr}{}$;\C{ just after last character in \PB{\\{out%
\_buf}} }\6
\&{char} ${}{*}\\{out\_buf\_end}\K\\{out\_buf}+\\{line\_length}{}$;\C{ end of %
\PB{\\{out\_buf}} }\6
\&{int} \\{out\_line};\C{ number of next line to be output }\par
\fi

\M{86}The \PB{\\{flush\_buffer}} routine empties the buffer up to a given
breakpoint,
and moves any remaining characters to the beginning of the next line.
If the \PB{\\{per\_cent}} parameter is 1 a \PB{\.{'\%'}} is appended to the
line
that is being output; in this case the breakpoint \PB{\|b} should be strictly
less than \PB{\\{out\_buf\_end}}. If the \PB{\\{per\_cent}} parameter is \PB{%
\T{0}},
trailing blanks are suppressed.
The characters emptied from the buffer form a new line of output;
if the \PB{\\{carryover}} parameter is true, a \PB{\.{"\%"}} in that line will
be
carried over to the next line (so that \TEX/ will ignore the completion
of commented-out text).

\Y\B\4\D$\\{c\_line\_write}(\|c)$ \5
$\\{fflush}(\\{active\_file}),\39\\{fwrite}(\\{out\_buf}+\T{1},\39\&{sizeof}(%
\&{char}),\39\|c,\39\\{active\_file}{}$)\par
\B\4\D$\\{tex\_putc}(\|c)$ \5
$\\{putc}(\|c,\39\\{active\_file}{}$)\par
\B\4\D$\\{tex\_new\_line}$ \5
$\\{putc}(\.{'\\n'},\39\\{active\_file}{}$)\par
\B\4\D$\\{tex\_printf}(\|c)$ \5
$\\{fprintf}(\\{active\_file},\39\|c{}$)\par
\Y\B\&{void} ${}\\{flush\_buffer}(\|b,\39\\{per\_cent},\39\\{carryover}){}$\1\1%
\6
\&{char} ${}{*}\|b{}$;\C{ outputs from \PB{$\\{out\_buf}+\T{1}$} to \PB{%
\|b},where \PB{$\|b\Z\\{out\_ptr}$} }\6
\&{boolean} \\{per\_cent}${},{}$ \\{carryover};\2\2\6
${}\{{}$\1\6
\&{char} ${}{*}\|j;{}$\7
${}\|j\K\|b{}$;\C{ pointer into \PB{\\{out\_buf}} }\6
\&{if} ${}(\R\\{per\_cent}{}$)\C{ remove trailing blanks }\1\6
\&{while} ${}(\|j>\\{out\_buf}\W{*}\|j\E\.{'\ '}){}$\1\5
${}\|j\MM;{}$\2\2\6
\&{if} (\\{is\_adoc})\5
${}\{{}$\1\6
\X87:Flush buffer to autodoc section\X;\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{c\_line\_write}(\|j-\\{out\_buf});{}$\6
\&{if} (\\{per\_cent})\1\5
\\{tex\_putc}(\.{'\%'});\2\6
\\{tex\_new\_line};\6
${}\\{out\_line}\PP;{}$\6
\4${}\}{}$\2\6
\&{if} (\\{carryover})\1\6
\&{while} ${}(\|j>\\{out\_buf}){}$\1\6
\&{if} ${}({*}\|j\MM\E\.{'\%'}\W(\|j\E\\{out\_buf}\V{*}\|j\I\.{'\\\\'})){}$\5
${}\{{}$\1\6
${}{*}\|b\MM\K\.{'\%'};{}$\6
\&{break};\6
\4${}\}{}$\2\2\2\6
\&{if} ${}(\|b<\\{out\_ptr}){}$\1\5
${}\\{strncpy}(\\{out\_buf}+\T{1},\39\|b+\T{1},\39\\{out\_ptr}-\|b);{}$\2\6
${}\\{out\_ptr}\MRL{-{\K}}\|b-\\{out\_buf};{}$\6
\4${}\}{}$\2\par
\fi

\M{87}Autodoc sections are one of the new features of \.{mCWEAVE}.
If we are processing an autodoc section, we want to output our
buffer to the autodoc memory rather than to the \TeX{} file.
See sections related to Autodocs.
\Y\B\4\X87:Flush buffer to autodoc section\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \|i;\7
\&{for} ${}(\|i\K\T{1};{}$ ${}\|i\Z\|j-\\{out\_buf};{}$ ${}\|i\PP){}$\1\5
\\{app\_adoc}(\\{out\_buf}[\|i]);\2\6
\&{if} (\\{per\_cent})\1\5
\\{app\_adoc}(\.{'\%'});\2\6
\\{app\_adoc}(\.{'\\n'});\6
\4${}\}{}$\2\par
\U86.\fi

\M{88}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{finish\_line}(\,);\par
\fi

\M{89}When we are copying \TEX/ source material, we retain line breaks
that occur in the input, except that an empty line is not
output when the \TEX/ source line was nonempty. For example, a line
of the \TEX/ file that contains only an index cross-reference entry
will not be copied. The \PB{\\{finish\_line}} routine is called just before
\PB{\\{get\_line}} inputs a new line, and just after a line break token has
been emitted during the output of translated \CEE/ text.

\Y\B\&{void} \\{finish\_line}(\,)\C{ do this at the end of a line }\6
${}\{{}$\1\6
\&{char} ${}{*}\|k{}$;\C{ pointer into \PB{\\{buffer}} }\7
\&{if} ${}(\\{out\_ptr}>\\{out\_buf}){}$\1\5
${}\\{flush\_buffer}(\\{out\_ptr},\39\T{0},\39\T{0});{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{for} ${}(\|k\K\\{buffer};{}$ ${}\|k\Z\\{limit};{}$ ${}\|k\PP){}$\1\6
\&{if} ${}(\R(\\{xisspace}({*}\|k))){}$\1\5
\&{return};\2\2\6
${}\\{flush\_buffer}(\\{out\_buf},\39\T{0},\39\T{0});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{90}In particular, the \PB{\\{finish\_line}} procedure is called near the
very
beginning of phase two. We initialize the output variables in a slightly
tricky way so that the first line of the output file will be
`\.{\BS input mcwebmac}'.

\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{out\_ptr}\K\\{out\_buf}+\T{1};{}$\6
${}\\{out\_line}\K\T{1};{}$\6
${}\\{active\_file}\K\\{tex\_file};{}$\6
\&{if} ${}(\\{book\_type}\W{*}\\{chapter\_name}){}$\5
${}\{{}$\C{ it is a chapter }\1\6
\&{char} ${}{*}\\{cp};{}$\7
${}\\{strcpy}(\\{a\_file\_name},\39\\{tex\_file\_name});{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
${}{*}\\{out\_ptr}\K\.{'\}'};{}$\6
\\{tex\_printf}(\.{"\\\\def\\\\curjob\{"});\6
\\{tex\_printf}(\\{a\_file\_name});\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\C{ it's the book }\1\6
${}\\{sprintf}(\\{a\_file\_name},\39\.{"\\\\input\ \%smcwebma"},\39\\{mcwebmac%
\_prefix});{}$\6
${}{*}\\{out\_ptr}\K\.{'c'};{}$\6
\\{tex\_printf}(\\{a\_file\_name});\6
\4${}\}{}$\2\par
\fi

\M{91}The prefix that should be prepended to {\tt mcwebmac.tex} is stored in
the following string array. This makes it possible to use localized versions
of {\tt mcwebmac}.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{extern} \&{char} \\{mcwebmac\_prefix}[\,];\par
\fi

\M{92}General purpose buffer for filenames that are not needed for a long time.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} \\{a\_file\_name}[\\{max\_file\_name\_length}];\C{ file name buffer
for various purposes }\par
\fi

\M{93}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{out\_str}(\,);\par
\fi

\M{94}When we wish to append one character \PB{\|c} to the output buffer, we
write
`\PB{\\{out}(\|c)}'; this will cause the buffer to be emptied if it was already
full.  If we want to append more than one character at once, we say
\PB{\\{out\_str}(\|s)}, where \PB{\|s} is a string containing the characters.

A line break will occur at a space or after a single-nonletter
\TEX/ control sequence.

\Y\B\4\D$\\{out}(\|c)$ \6
${}\{{}$\1\6
\&{if} ${}(\\{out\_ptr}\G\\{out\_buf\_end}){}$\1\5
\\{break\_out}(\,);\2\6
${}{*}(\PP\\{out\_ptr})\K\|c;{}$\6
\4${}\}{}$\2\par
\Y\B\&{void} \\{out\_str}(\|s)\C{ output characters from \PB{\|s} to end of
string }\1\1\6
\&{char} ${}{*}\|s;\2\2{}$\6
${}\{{}$\1\6
\&{while} ${}({*}\|s){}$\1\5
${}\\{out}({*}\|s\PP);{}$\2\6
\4${}\}{}$\2\par
\fi

\M{95}The \PB{\\{break\_out}} routine is called just before the output buffer
is about
to overflow. To make this routine a little faster, we initialize position
0 of the output buffer to `\.\\'; this character isn't really output.

\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{out\_buf}[\T{0}]\K\.{'\\\\'}{}$;\par
\fi

\M{96}A long line is broken at a blank space or just before a backslash that
isn't
preceded by another backslash. In the latter case, a \PB{\.{'\%'}} is output at
the break.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{break\_out}(\,);\par
\fi

\M{97}\B\&{void} \\{break\_out}(\,)\C{ finds a way to break the output line }\6
${}\{{}$\1\6
\&{char} ${}{*}\|k\K\\{out\_ptr}{}$;\C{ pointer into \PB{\\{out\_buf}} }\7
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\|k\E\\{out\_buf}){}$\1\5
\X98:Print warning message, break the line, \PB{\&{return}}\X;\2\6
\&{if} ${}({*}\|k\E\.{'\ '}){}$\5
${}\{{}$\1\6
${}\\{flush\_buffer}(\|k,\39\T{0},\39\T{1});{}$\6
\&{return};\6
\4${}\}{}$\2\6
\&{if} ${}({*}(\|k\MM)\E\.{'\\\\'}\W{*}\|k\I\.{'\\\\'}){}$\5
${}\{{}$\C{ we've decreased \PB{\|k} }\1\6
${}\\{flush\_buffer}(\|k,\39\T{1},\39\T{1});{}$\6
\&{return};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{98}We get to this section only in the unusual case that the entire output
line
consists of a string of backslashes followed by a string of nonblank
non-backslashes. In such cases it is almost always safe to break the
line by putting a \PB{\.{'\%'}} just before the last character.

\Y\B\4\X98:Print warning message, break the line, \PB{\&{return}}\X${}\E{}$\6
${}\{{}$\1\6
${}\\{printf}(\.{"\\n!\ Line\ had\ to\ be\ }\)\.{broken\ (output\ l.\ \%d}\)%
\.{):\\n"},\39\\{out\_line});{}$\6
${}\\{term\_write}(\\{out\_buf}+\T{1},\39\\{out\_ptr}-\\{out\_buf}-\T{1});{}$\6
\\{new\_line};\6
\\{mark\_harmless};\6
${}\\{flush\_buffer}(\\{out\_ptr}-\T{1},\39\T{1},\39\T{1});{}$\6
\&{return};\6
\4${}\}{}$\2\par
\U97.\fi

\M{99}Here is a macro that outputs a section number in decimal notation.
The number to be converted by \PB{\\{out\_section}} is known to be less than
\PB{\\{def\_flag}}, so it cannot have more than five decimal digits.  If
the section is changed, we output `\.{\\*}' just after the number.

\Y\B\&{void} \\{out\_section}(\|n)\1\1\6
\&{sixteen\_bits} \|n;\2\2\6
${}\{{}$\1\6
\&{char} \|s[\T{6}];\7
${}\\{sprintf}(\|s,\39\.{"\%d"},\39\|n);{}$\6
\\{out\_str}(\|s);\6
\&{if} (\\{changed\_section}[\|n])\1\5
\\{out\_str}(\.{"\\\\*"});\2\6
\4${}\}{}$\2\par
\fi

\M{100}The \PB{\\{out\_name}} procedure is used to output an identifier or
index
entry, enclosing it in braces.

\Y\B\&{void} \\{out\_name}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{char} ${}{*}\|k,{}$ ${}{*}\\{k\_end}\K(\|p+\T{1})\MG\\{byte\_start}{}$;\C{
pointers into \PB{\\{byte\_mem}} }\7
\\{out}(\.{'\{'});\6
\&{for} ${}(\|k\K\|p\MG\\{byte\_start};{}$ ${}\|k<\\{k\_end};{}$ ${}\|k\PP){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{isxalpha}({*}\|k)){}$\1\5
\\{out}(\.{'\\\\'});\2\6
${}\\{out}({*}\|k);{}$\6
\4${}\}{}$\2\6
\\{out}(\.{'\}'});\6
\4${}\}{}$\2\par
\fi

\N{1}{101}Routines that copy \TEX/ material.
During phase two, we use subroutines \PB{\\{copy\_limbo}}, \PB{$\copyxTeX$},
and
\PB{\\{copy\_comment}} in place of the analogous \PB{\\{skip\_limbo}}, \PB{$%
\skipxTeX$}, and
\PB{\\{skip\_comment}} that were used in phase one. (Well, \PB{\\{copy%
\_comment}}
was actually written in such a way that it functions as \PB{\\{skip\_comment}}
in phase one.)

The \PB{\\{copy\_limbo}} routine, for example, takes \TEX/ material that is not
part of any section and transcribes it almost verbatim to the output file.
The use of `\.{@}' signs is severely restricted in such material:
`\.{@@}' pairs are replaced by singletons; `\.{@l}' and `\.{@q}' and
`\.{@s}' are interpreted.

\Y\B\&{void} \\{copy\_limbo}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{char} \|c${},{}$ ${}{*}\\{cp};{}$\7
\&{if} (\\{book\_type})\5
${}\{{}$\1\6
${}\\{strcpy}(\\{out\_file\_name},\39\\{tex\_file\_name});{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{out\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
\4${}\}{}$\2\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}\W(\\{finish\_line}(\,),\39\\{get\_line}(\,)\E%
\T{0})){}$\1\5
\&{return};\2\6
${}{*}(\\{limit}+\T{1})\K\.{'@'};{}$\6
\&{while} ${}({*}\\{loc}\I\.{'@'}){}$\1\5
${}\\{out}({*}(\\{loc}\PP));{}$\2\6
\&{if} ${}(\\{loc}\PP\Z\\{limit}){}$\5
${}\{{}$\1\6
${}\|c\K{*}\\{loc}\PP;{}$\6
\&{if} (\\{ccode}[(\&{eight\_bits}) \|c]${}\E\\{new\_section}){}$\1\5
\&{break};\2\6
\&{switch} (\\{ccode}[(\&{eight\_bits}) \|c])\5
${}\{{}$\1\6
\4\&{case} \\{translit\_code}:\5
\\{out\_str}(\.{"\\\\ATL"});\6
\&{break};\6
\4\&{case} \.{'@'}:\5
\\{out}(\.{'@'});\6
\&{break};\6
\4\&{case} \\{noop}:\5
\\{skip\_restricted}(\,);\6
\&{break};\6
\4\&{case} \\{format\_code}:\6
\&{if} ${}(\\{get\_next}(\,)\E\\{identifier}){}$\1\5
\\{get\_next}(\,);\2\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\1\5
\\{get\_line}(\,);\C{ avoid blank lines in output }\2\6
\&{break};\C{ the operands of \.{@s} are ignored on this pass }\6
\4\&{default}:\5
\\{err\_print}(\.{"!\ Double\ @\ should\ b}\)\.{e\ used\ in\ limbo"});\6
\\{out}(\.{'@'});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{102}The \PB{$\copyxTeX$} routine processes the \TEX/ code at the beginning
of a
section; for example, the words you are now reading were copied in this
way. It returns the next control code or `\.{\v}' found in the input.
We don't copy spaces or tab marks into the beginning of a line. This
makes the test for empty lines in \PB{\\{finish\_line}} work.

\fi

\M{103}\B\F\\{copy\_TeX} \5
\\{TeX}\par
\Y\B\&{eight\_bits} ${}\copyxTeX(\,){}$\1\1\2\2\6
${}\{{}$\1\6
\&{char} \|c;\C{ current character being copied }\7
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}\W(\\{finish\_line}(\,),\39\\{get\_line}(\,)\E%
\T{0})){}$\1\5
\&{return} (\\{new\_section});\2\6
${}{*}(\\{limit}+\T{1})\K\.{'@'};{}$\6
\&{while} ${}((\|c\K{*}(\\{loc}\PP))\I\.{'|'}\W\|c\I\.{'@'}){}$\5
${}\{{}$\1\6
\\{out}(\|c);\6
\&{if} ${}(\\{out\_ptr}\E\\{out\_buf}+\T{1}\W(\\{xisspace}(\|c))){}$\1\5
${}\\{out\_ptr}\MM;{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\|c\E\.{'|'}){}$\1\5
\&{return} (\.{'|'});\2\6
\&{if} ${}(\\{loc}\Z\\{limit}){}$\1\5
\&{return} (\\{ccode}[(\&{eight\_bits}) ${}{*}(\\{loc}\PP)]);{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{104}The \PB{\\{copy\_comment}} function issues a warning if more braces are
opened than
closed, and in the case of a more serious error it supplies enough
braces to keep \TEX/ from complaining about unbalanced braces.
Instead of copying the \TEX/ material
into the output buffer, this function copies it into the token memory
(in phase two only).
The abbreviation \PB{\\{app\_tok}(\|t)} is used to append token \PB{\|t} to the
current
token list, and it also makes sure that it is possible to append at least
one further token without overflow.

\Y\B\4\D$\\{app\_tok}(\|c)$ \6
${}\{{}$\1\6
\&{if} ${}(\\{tok\_ptr}+\T{2}>\\{tok\_mem\_end}){}$\1\5
\\{overflow}(\.{"token"});\2\6
${}{*}(\\{tok\_ptr}\PP)\K\|c;{}$\6
\4${}\}{}$\2\par
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{int} \\{copy\_comment}(\,);\par
\fi

\M{105}\B\&{int} ${}\\{copy\_comment}(\\{is\_long\_comment},\39\\{bal}{}$)\C{
copies \TEX/ code in comments }\1\1\6
\&{boolean} \\{is\_long\_comment};\C{ is this a traditional \CEE/ comment? }\6
\&{int} \\{bal};\C{ brace balance }\2\2\6
${}\{{}$\1\6
\&{char} \|c;\C{ current character being copied }\7
\&{while} (\T{1})\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}){}$\5
${}\{{}$\1\6
\&{if} (\\{is\_long\_comment})\5
${}\{{}$\1\6
\&{if} ${}(\\{get\_line}(\,)\E\T{0}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Input\ ended\ in\ mi}\)\.{d-comment"});\6
${}\\{loc}\K\\{buffer}+\T{1};{}$\6
\&{goto} \\{done};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} ${}(\\{bal}>\T{1}){}$\1\5
\\{err\_print}(\.{"!\ Missing\ \}\ in\ comm}\)\.{ent"});\2\6
\&{goto} \\{done};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
${}\|c\K{*}(\\{loc}\PP);{}$\6
\&{if} ${}(\|c\E\.{'|'}){}$\1\5
\&{return} (\\{bal});\2\6
\&{if} (\\{is\_long\_comment})\1\5
\X106:Check for end of comment\X;\2\6
\&{if} ${}(\\{phase}\E\T{2}){}$\5
${}\{{}$\1\6
\&{if} (\\{ishigh}(\|c))\1\5
\\{app\_tok}(\\{quoted\_char});\2\6
\\{app\_tok}(\|c);\6
\4${}\}{}$\2\6
\X107:Copy special things when \PB{$\|c\E\.{'@'},\.{'\\\\'}$}\X;\6
\&{if} ${}(\|c\E\.{'\{'}){}$\1\5
${}\\{bal}\PP;{}$\2\6
\&{else} \&{if} ${}(\|c\E\.{'\}'}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{bal}>\T{1}){}$\1\5
${}\\{bal}\MM;{}$\2\6
\&{else}\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Extra\ \}\ in\ commen}\)\.{t"});\6
\&{if} ${}(\\{phase}\E\T{2}){}$\1\5
${}\\{tok\_ptr}\MM;{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4\\{done}:\5
\X108:Clear \PB{\\{bal}} and \PB{\&{return}}\X;\6
\4${}\}{}$\2\par
\fi

\M{106}\B\X106:Check for end of comment\X${}\E{}$\6
\&{if} ${}(\|c\E\.{'*'}\W{*}\\{loc}\E\.{'/'}){}$\5
${}\{{}$\1\6
${}\\{loc}\PP;{}$\6
\&{if} ${}(\\{bal}>\T{1}){}$\1\5
\\{err\_print}(\.{"!\ Missing\ \}\ in\ comm}\)\.{ent"});\2\6
\&{goto} \\{done};\6
\4${}\}{}$\2\par
\U105.\fi

\M{107}\B\X107:Copy special things when \PB{$\|c\E\.{'@'},\.{'\\\\'}$}\X${}%
\E{}$\6
\&{if} ${}(\|c\E\.{'@'}){}$\5
${}\{{}$\1\6
\&{if} ${}({*}(\\{loc}\PP)\I\.{'@'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Illegal\ use\ of\ @\ }\)\.{in\ comment"});\6
${}\\{loc}\MRL{-{\K}}\T{2};{}$\6
\&{if} ${}(\\{phase}\E\T{2}){}$\1\5
${}{*}(\\{tok\_ptr}-\T{1})\K\.{'\ '};{}$\2\6
\&{goto} \\{done};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|c\E\.{'\\\\'}\W{*}\\{loc}\I\.{'@'})$ \&{if} ${}(\\{phase}%
\E\T{2})$ $\\{app\_tok}({*}(\\{loc}\PP))$ \6
\&{else}\1\5
${}\\{loc}\PP{}$;\2\par
\U105.\fi

\M{108}We output
enough right braces to keep \TEX/ happy.

\Y\B\4\X108:Clear \PB{\\{bal}} and \PB{\&{return}}\X${}\E{}$\6
\&{if} ${}(\\{phase}\E\T{2}){}$\1\6
\&{while} ${}(\\{bal}\MM>\T{0}){}$\1\5
\\{app\_tok}(\.{'\}'});\2\2\6
\&{return} (\T{0});\par
\U105.\fi

\N{0}{109}Parsing.
The most intricate part of \.{CWEAVE} is its mechanism for converting
\CEE/-like code into \TEX/ code, and we might as well plunge into this
aspect of the program now. A ``bottom up'' approach is used to parse the
\CEE/-like material, since \.{CWEAVE} must deal with fragmentary
constructions whose overall ``part of speech'' is not known.

At the lowest level, the input is represented as a sequence of entities
that we shall call {\it scraps}, where each scrap of information consists
of two parts, its {\it category} and its {\it translation}. The category
is essentially a syntactic class, and the translation is a token list that
represents \TEX/ code. Rules of syntax and semantics tell us how to
combine adjacent scraps into larger ones, and if we are lucky an entire
\CEE/ text that starts out as hundreds of small scraps will join
together into one gigantic scrap whose translation is the desired \TEX/
code. If we are unlucky, we will be left with several scraps that don't
combine; their translations will simply be output, one by one.

The combination rules are given as context-sensitive productions that are
applied from left to right. Suppose that we are currently working on the
sequence of scraps $s_1\,s_2\ldots s_n$. We try first to find the longest
production that applies to an initial substring $s_1\,s_2\ldots\,$; but if
no such productions exist, we try to find the longest production
applicable to the next substring $s_2\,s_3\ldots\,$; and if that fails, we
try to match $s_3\,s_4\ldots\,$, etc.

A production applies if the category codes have a given pattern. For
example, one of the productions (see rule~3) is
$$\hbox{\PB{\\{exp}} }\left\{\matrix{\hbox{\PB{\\{binop}}}\cr\hbox{\PB{%
\\{unorbinop}}}}\right\}
\hbox{ \PB{\\{exp}} }\RA\hbox{ \PB{\\{exp}}}$$
and it means that three consecutive scraps whose respective categories are
\PB{\\{exp}}, \PB{\\{binop}} (or \PB{\\{unorbinop}}),
and \PB{\\{exp}} are converted to one scrap whose category
is \PB{\\{exp}}.  The translations of the original
scraps are simply concatenated.  The case of
$$\hbox{\PB{\\{exp}} \PB{\\{comma}} \PB{\\{exp}} $\RA$ \PB{\\{exp}}} %
\hskip4emE_1C\,\\{opt}9\,E_2$$
(rule 4) is only slightly more complicated:
Here the resulting \PB{\\{exp}} translation
consists not only of the three original translations, but also of the
tokens \PB{\\{opt}} and 9 between the translations of the
\PB{\\{comma}} and the following \PB{\\{exp}}.
In the \TEX/ file, this will specify an optional line break after the
comma, with penalty 90.

At each opportunity the longest possible production is applied.  For
example, if the current sequence of scraps is \PB{\\{int\_like}} \PB{\\{cast}}
\PB{\\{lbrace}}, rule 31 is applied; but if the sequence is \PB{\\{int\_like}} %
\PB{\\{cast}}
followed by anything other than \PB{\\{lbrace}}, rule 32 takes effect.

Translation rules such as `$E_1C\,\\{opt}9\,E_2$' above use subscripts
to distinguish between translations of scraps whose categories have the
same initial letter; these subscripts are assigned from left to right.

\fi

\M{110}Here is a list of the category codes that scraps can have.
(A few others, like \PB{\\{int\_like}}, have already been defined; the
\PB{\\{cat\_name}} array contains a complete list.)

\Y\B\4\D$\\{exp}$ \5
\T{1}\C{ denotes an expression, including perhaps a single identifier }\par
\B\4\D$\\{unop}$ \5
\T{2}\C{ denotes a unary operator }\par
\B\4\D$\\{binop}$ \5
\T{3}\C{ denotes a binary operator }\par
\B\4\D$\\{unorbinop}$ \5
\T{4}\C{ denotes an operator that can be unary or binary, depending on context
}\par
\B\4\D$\\{cast}$ \5
\T{5}\C{ denotes a cast }\par
\B\4\D$\\{question}$ \5
\T{6}\C{ denotes a question mark and possibly the expressions flanking it }\par
\B\4\D$\\{lbrace}$ \5
\T{7}\C{ denotes a left brace }\par
\B\4\D$\\{rbrace}$ \5
\T{8}\C{ denotes a right brace }\par
\B\4\D$\\{decl\_head}$ \5
\T{9}\C{ denotes an incomplete declaration }\par
\B\4\D$\\{comma}$ \5
\T{10}\C{ denotes a comma }\par
\B\4\D$\\{lpar}$ \5
\T{11}\C{ denotes a left parenthesis or left bracket }\par
\B\4\D$\\{rpar}$ \5
\T{12}\C{ denotes a right parenthesis or right bracket }\par
\B\4\D$\\{prelangle}$ \5
\T{13}\C{ denotes `$<$' before we know what it is }\par
\B\4\D$\\{prerangle}$ \5
\T{14}\C{ denotes `$>$' before we know what it is }\par
\B\4\D$\\{langle}$ \5
\T{15}\C{ denotes `$<$' when it's used as angle bracket in a template }\par
\B\4\D$\\{colcol}$ \5
\T{18}\C{ denotes `::' }\par
\B\4\D$\\{base}$ \5
\T{19}\C{ denotes a colon that introduces a base specifier }\par
\B\4\D$\\{decl}$ \5
\T{20}\C{ denotes a complete declaration }\par
\B\4\D$\\{struct\_head}$ \5
\T{21}\C{ denotes the beginning of a structure specifier }\par
\B\4\D$\\{stmt}$ \5
\T{23}\C{ denotes a complete statement }\par
\B\4\D$\\{function}$ \5
\T{24}\C{ denotes a complete function }\par
\B\4\D$\\{fn\_decl}$ \5
\T{25}\C{ denotes a function declarator }\par
\B\4\D$\\{semi}$ \5
\T{27}\C{ denotes a semicolon }\par
\B\4\D$\\{colon}$ \5
\T{28}\C{ denotes a colon }\par
\B\4\D$\\{tag}$ \5
\T{29}\C{ denotes a statement label }\par
\B\4\D$\\{if\_head}$ \5
\T{30}\C{ denotes the beginning of a compound conditional }\par
\B\4\D$\\{else\_head}$ \5
\T{31}\C{ denotes a prefix for a compound statement }\par
\B\4\D$\\{if\_clause}$ \5
\T{32}\C{ pending \.{if} together with a condition }\par
\B\4\D$\\{lproc}$ \5
\T{35}\C{ begins a preprocessor command }\par
\B\4\D$\\{rproc}$ \5
\T{36}\C{ ends a preprocessor command }\par
\B\4\D$\\{insert}$ \5
\T{37}\C{ a scrap that gets combined with its neighbor }\par
\B\4\D$\\{section\_scrap}$ \5
\T{38}\C{ section name }\par
\B\4\D$\\{dead}$ \5
\T{39}\C{ scrap that won't combine }\par
\B\4\D$\\{begin\_arg}$ \5
\T{58}\C{ \.{@[} }\par
\B\4\D$\\{end\_arg}$ \5
\T{59}\C{ \.{@]} }\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} \\{cat\_name}[\T{256}][\T{12}];\6
\&{eight\_bits} \\{cat\_index};\par
\fi

\M{111}\B\X21:Set initial values\X${}\mathrel+\E{}$\6
\&{for} ${}(\\{cat\_index}\K\T{0};{}$ ${}\\{cat\_index}<\T{255};{}$ ${}\\{cat%
\_index}\PP){}$\1\5
${}\\{strcpy}(\\{cat\_name}[\\{cat\_index}],\39\.{"UNKNOWN"});{}$\2\6
${}\\{strcpy}(\\{cat\_name}[\\{exp}],\39\.{"exp"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{unop}],\39\.{"unop"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{binop}],\39\.{"binop"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{unorbinop}],\39\.{"unorbinop"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{cast}],\39\.{"cast"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{question}],\39\.{"?"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{lbrace}],\39\.{"\{"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{rbrace}],\39\.{"\}"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{decl\_head}],\39\.{"decl\_head"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{comma}],\39\.{","});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{lpar}],\39\.{"("});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{rpar}],\39\.{")"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{prelangle}],\39\.{"<"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{prerangle}],\39\.{">"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{langle}],\39\.{"\\\\<"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{colcol}],\39\.{"::"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{base}],\39\.{"\\\\:"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{decl}],\39\.{"decl"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{struct\_head}],\39\.{"struct\_head"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{stmt}],\39\.{"stmt"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{function}],\39\.{"function"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{fn\_decl}],\39\.{"fn\_decl"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{else\_like}],\39\.{"else\_like"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{semi}],\39\.{";"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{colon}],\39\.{":"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{tag}],\39\.{"tag"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{if\_head}],\39\.{"if\_head"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{else\_head}],\39\.{"else\_head"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{if\_clause}],\39\.{"if()"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{lproc}],\39\.{"\#\{"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{rproc}],\39\.{"\#\}"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{insert}],\39\.{"insert"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{section\_scrap}],\39\.{"section"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{dead}],\39\.{"@d"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{public\_like}],\39\.{"public"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{operator\_like}],\39\.{"operator"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{new\_like}],\39\.{"new"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{catch\_like}],\39\.{"catch"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{for\_like}],\39\.{"for"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{do\_like}],\39\.{"do"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{if\_like}],\39\.{"if"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{raw\_rpar}],\39\.{")?"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{raw\_unorbin}],\39\.{"unorbinop?"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{const\_like}],\39\.{"const"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{raw\_int}],\39\.{"raw"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{int\_like}],\39\.{"int"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{case\_like}],\39\.{"case"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{sizeof\_like}],\39\.{"sizeof"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{struct\_like}],\39\.{"struct"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{typedef\_like}],\39\.{"typedef"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{define\_like}],\39\.{"define"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{begin\_arg}],\39\.{"@["});{}$\6
${}\\{strcpy}(\\{cat\_name}[\\{end\_arg}],\39\.{"@]"});{}$\6
${}\\{strcpy}(\\{cat\_name}[\T{0}],\39\.{"zero"}){}$;\par
\fi

\M{112}This code allows \.{CWEAVE} to display its parsing steps.

\Y\B\&{void} \\{print\_cat}(\|c)\C{ symbolic printout of a category }\1\1\6
\&{eight\_bits} \|c;\2\2\6
${}\{{}$\1\6
\\{printf}(\\{cat\_name}[\|c]);\6
\4${}\}{}$\2\par
\fi

\M{113}The token lists for translated \TEX/ output contain some special control
symbols as well as ordinary characters. These control symbols are
interpreted by \.{CWEAVE} before they are written to the output file.

\yskip\hang \PB{\\{break\_space}} denotes an optional line break or an en
space;

\yskip\hang \PB{\\{force}} denotes a line break;

\yskip\hang \PB{\\{big\_force}} denotes a line break with additional vertical
space;

\yskip\hang \PB{\\{preproc\_line}} denotes that the line will be printed flush
left;

\yskip\hang \PB{\\{opt}} denotes an optional line break (with the continuation
line indented two ems with respect to the normal starting position)---this
code is followed by an integer \PB{\|n}, and the break will occur with penalty
$10n$;

\yskip\hang \PB{\\{backup}} denotes a backspace of one em;

\yskip\hang \PB{\\{cancel}} obliterates any \PB{\\{break\_space}}, \PB{%
\\{opt}}, \PB{\\{force}}, or
\PB{\\{big\_force}} tokens that immediately precede or follow it and also
cancels any
\PB{\\{backup}} tokens that follow it;

\yskip\hang \PB{\\{indent}} causes future lines to be indented one more em;

\yskip\hang \PB{\\{outdent}} causes future lines to be indented one less em.

\yskip\noindent All of these tokens are removed from the \TEX/ output that
comes from \CEE/ text between \pb\ signs; \PB{\\{break\_space}} and \PB{%
\\{force}} and
\PB{\\{big\_force}} become single spaces in this mode. The translation of other
\CEE/ texts results in \TEX/ control sequences \.{\\1}, \.{\\2},
\.{\\3}, \.{\\4}, \.{\\5}, \.{\\6}, \.{\\7}, \.{\\8}
corresponding respectively to
\PB{\\{indent}}, \PB{\\{outdent}}, \PB{\\{opt}}, \PB{\\{backup}}, \PB{\\{break%
\_space}}, \PB{\\{force}},
\PB{\\{big\_force}} and \PB{\\{preproc\_line}}.
However, a sequence of consecutive `\.\ ', \PB{\\{break\_space}},
\PB{\\{force}}, and/or \PB{\\{big\_force}} tokens is first replaced by a single
token
(the maximum of the given ones).

The token \PB{\\{math\_rel}} will be translated into
\.{\\MRL\{}, and it will get a matching \.\} later.
Other control sequences in the \TEX/ output will be
`\.{\\\\\{}$\,\ldots\,$\.\}'
surrounding identifiers, `\.{\\\&\{}$\,\ldots\,$\.\}' surrounding
reserved words, `\.{\\.\{}$\,\ldots\,$\.\}' surrounding strings,
`\.{\\C\{}$\,\ldots\,$\.\}$\,$\PB{\\{force}}' surrounding comments, and
`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding section names, where
\PB{\|n} is the section number.

\Y\B\4\D$\\{math\_rel}$ \5
\T{\~206}\par
\B\4\D$\\{big\_cancel}$ \5
\T{\~210}\C{ like \PB{\\{cancel}}, also overrides spaces }\par
\B\4\D$\\{cancel}$ \5
\T{\~211}\C{ overrides \PB{\\{backup}}, \PB{\\{break\_space}}, \PB{\\{force}}, %
\PB{\\{big\_force}} }\par
\B\4\D$\\{indent}$ \5
\T{\~212}\C{ one more tab (\.{\\1}) }\par
\B\4\D$\\{outdent}$ \5
\T{\~213}\C{ one less tab (\.{\\2}) }\par
\B\4\D$\\{opt}$ \5
\T{\~214}\C{ optional break in mid-statement (\.{\\3}) }\par
\B\4\D$\\{backup}$ \5
\T{\~215}\C{ stick out one unit to the left (\.{\\4}) }\par
\B\4\D$\\{break\_space}$ \5
\T{\~216}\C{ optional break between statements (\.{\\5}) }\par
\B\4\D$\\{force}$ \5
\T{\~217}\C{ forced break between statements (\.{\\6}) }\par
\B\4\D$\\{big\_force}$ \5
\T{\~220}\C{ forced break with additional space (\.{\\7}) }\par
\B\4\D$\\{preproc\_line}$ \5
\T{\~221}\C{ begin line without indentation (\.{\\8}) }\par
\B\4\D$\\{quoted\_char}$ \5
\T{\~222}\C{ introduces a character token in the range \PB{\T{\~200}}--\PB{\T{%
\~377}} }\par
\B\4\D$\\{end\_translation}$ \5
\T{\~223}\C{ special sentinel token at end of list }\par
\B\4\D$\\{inserted}$ \5
\T{\~224}\C{ sentinel to mark translations of inserts }\par
\fi

\M{114}The raw input is converted into scraps according to the following table,
which gives category codes followed by the translations.
\def\stars {\.{**}}%
The symbol `\stars' stands for `\.{\\\&\{{\rm identifier}\}}',
i.e., the identifier itself treated as a reserved word.
The right-hand column is the so-called \PB{\\{mathness}}, which is explained
further below.

An identifier \PB{\|c} of length 1 is translated as \.{\\\v c} instead of
as \.{\\\\\{c\}}. An identifier \.{CAPS} in all caps is translated as
\.{\\.\{CAPS\}} instead of as \.{\\\\\{CAPS\}}. An identifier that has
become a reserved word via \PB{\&{typedef}} is translated with \.{\\\&}
replacing
\.{\\\\} and \PB{\\{raw\_int}} replacing \PB{\\{exp}}.

A string of length greater than 20 is broken into pieces of size at most~20
with discretionary breaks in between.

\yskip\halign{\quad#\hfil&\quad#\hfil&\quad\hfil#\hfil\cr
\.{!=}&\PB{\\{binop}}: \.{\\I}&yes\cr
\.{<=}&\PB{\\{binop}}: \.{\\Z}&yes\cr
\.{>=}&\PB{\\{binop}}: \.{\\G}&yes\cr
\.{==}&\PB{\\{binop}}: \.{\\E}&yes\cr
\.{\&\&}&\PB{\\{binop}}: \.{\\W}&yes\cr
\.{\v\v}&\PB{\\{binop}}: \.{\\V}&yes\cr
\.{++}&\PB{\\{binop}}: \.{\\PP}&yes\cr
\.{--}&\PB{\\{binop}}: \.{\\MM}&yes\cr
\.{->}&\PB{\\{binop}}: \.{\\MG}&yes\cr
\.{>>}&\PB{\\{binop}}: \.{\\GG}&yes\cr
\.{<<}&\PB{\\{binop}}: \.{\\LL}&yes\cr
\.{::}&\PB{\\{colcol}}: \.{\\DC}&maybe\cr
\.{.*}&\PB{\\{binop}}: \.{\\PA}&yes\cr
\.{->*}&\PB{\\{binop}}: \.{\\MGA}&yes\cr
\.{...}&\PB{\\{exp}}: \.{\\,\\ldots\\,}&yes\cr
\."string\."&\PB{\\{exp}}: \.{\\.\{}string with special characters quoted\.%
\}&maybe\cr
\.{@=}string\.{@>}&\PB{\\{exp}}: \.{\\vb\{}string with special characters
quoted\.\}&maybe\cr
\.{@'7'}&\PB{\\{exp}}: \.{\\.\{@'7'\}}&maybe\cr
\.{077} or \.{\\77}&\PB{\\{exp}}: \.{\\T\{\\\~77\}}&maybe\cr
\.{0x7f}&\PB{\\{exp}}: \.{\\T\{\\\^7f\}}&maybe\cr
\.{77}&\PB{\\{exp}}: \.{\\T\{77\}}&maybe\cr
\.{77L}&\PB{\\{exp}}: \.{\\T\{77\\\$L\}}&maybe\cr
\.{0.1E5}&\PB{\\{exp}}: \.{\\T\{0.1\\\_5\}}&maybe\cr
\.+&\PB{\\{unorbinop}}: \.+&yes\cr
\.-&\PB{\\{unorbinop}}: \.-&yes\cr
\.*&\PB{\\{raw\_unorbin}}: \.*&yes\cr
\./&\PB{\\{binop}}: \./&yes\cr
\.<&\PB{\\{prelangle}}: \.{\\langle}&yes\cr
\.=&\PB{\\{binop}}: \.{\\K}&yes\cr
\.>&\PB{\\{prerangle}}: \.{\\rangle}&yes\cr
\..&\PB{\\{binop}}: \..&yes\cr
\.{\v}&\PB{\\{binop}}: \.{\\OR}&yes\cr
\.\^&\PB{\\{binop}}: \.{\\XOR}&yes\cr
\.\%&\PB{\\{binop}}: \.{\\MOD}&yes\cr
\.?&\PB{\\{question}}: \.{\\?}&yes\cr
\.!&\PB{\\{unop}}: \.{\\R}&yes\cr
\.\~&\PB{\\{unop}}: \.{\\CM}&yes\cr
\.\&&\PB{\\{raw\_unorbin}}: \.{\\AND}&yes\cr
\.(&\PB{\\{lpar}}: \.(&maybe\cr
\.[&\PB{\\{lpar}}: \.[&maybe\cr
\.)&\PB{\\{raw\_rpar}}: \.)&maybe\cr
\.]&\PB{\\{raw\_rpar}}: \.]&maybe\cr
\.\{&\PB{\\{lbrace}}: \.\{&yes\cr
\.\}&\PB{\\{lbrace}}: \.\}&yes\cr
\.,&\PB{\\{comma}}: \.,&yes\cr
\.;&\PB{\\{semi}}: \.;&maybe\cr
\.:&\PB{\\{colon}}: \.:&maybe\cr
\.\# (within line)&\PB{\\{unorbinop}}: \.{\\\#}&yes\cr
\.\# (at beginning)&\PB{\\{lproc}}:  \PB{\\{force}} \PB{\\{preproc\_line}} \.{%
\\\#}&no\cr
end of \.\# line&\PB{\\{rproc}}:  \PB{\\{force}}&no\cr
identifier&\PB{\\{exp}}: \.{\\\\\{}identifier with underlines quoted\.\}&maybe%
\cr
\.{asm}&\PB{\\{sizeof\_like}}: \stars&maybe\cr
\.{auto}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{break}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{case}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{catch}&\PB{\\{catch\_like}}: \stars&maybe\cr
\.{char}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{class}&\PB{\\{struct\_like}}: \stars&maybe\cr
\.{clock\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{const}&\PB{\\{const\_like}}: \stars&maybe\cr
\.{continue}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{default}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{define}&\PB{\\{define\_like}}: \stars&maybe\cr
\.{defined}&\PB{\\{sizeof\_like}}: \stars&maybe\cr
\.{delete}&\PB{\\{sizeof\_like}}: \stars&maybe\cr
\.{div\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{do}&\PB{\\{do\_like}}: \stars&maybe\cr
\.{double}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{elif}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{else}&\PB{\\{else\_like}}: \stars&maybe\cr
\.{endif}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{enum}&\PB{\\{struct\_like}}: \stars&maybe\cr
\.{error}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{extern}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{FILE}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{float}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{for}&\PB{\\{for\_like}}: \stars&maybe\cr
\.{fpos\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{friend}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{goto}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{if}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{ifdef}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{ifndef}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{include}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{inline}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{int}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{jmp\_buf}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{ldiv\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{line}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{long}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{new}&\PB{\\{new\_like}}: \stars&maybe\cr
\.{NULL}&\PB{\\{exp}}: \.{\\NULL}&yes\cr
\.{offsetof}&\PB{\\{sizeof\_like}}: \stars&maybe\cr
\.{operator}&\PB{\\{operator\_like}}: \stars&maybe\cr
\.{pragma}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{private}&\PB{\\{public\_like}}: \stars&maybe\cr
\.{protected}&\PB{\\{public\_like}}: \stars&maybe\cr
\.{ptrdiff\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{public}&\PB{\\{public\_like}}: \stars&maybe\cr
\.{register}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{return}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{short}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{sig\_atomic\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{signed}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{size\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{sizeof}&\PB{\\{sizeof\_like}}: \stars&maybe\cr
\.{static}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{struct}&\PB{\\{struct\_like}}: \stars&maybe\cr
\.{switch}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{template}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{TeX}&\PB{\\{exp}}: \.{\\TeX}&yes\cr
\.{this}&\PB{\\{exp}}: \.{\\this}&yes\cr
\.{throw}&\PB{\\{case\_like}}: \stars&maybe\cr
\.{time\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{try}&\PB{\\{else\_like}}: \stars&maybe\cr
\.{typedef}&\PB{\\{typedef\_like}}: \stars&maybe\cr
\.{undef}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{union}&\PB{\\{struct\_like}}: \stars&maybe\cr
\.{unsigned}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{va\_dcl}&\PB{\\{decl}}: \stars&maybe\cr
\.{va\_list}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{virtual}&\PB{\\{int\_like}}: \stars&maybe\cr
\.{void}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{volatile}&\PB{\\{const\_like}}: \stars&maybe\cr
\.{wchar\_t}&\PB{\\{raw\_int}}: \stars&maybe\cr
\.{while}&\PB{\\{if\_like}}: \stars&maybe\cr
\.{@,}&\PB{\\{insert}}: \.{\\,}&maybe\cr
\.{@\v}&\PB{\\{insert}}:  \PB{\\{opt}} \.0&maybe\cr
\.{@/}&\PB{\\{insert}}:  \PB{\\{force}}&no\cr
\.{@\#}&\PB{\\{insert}}:  \PB{\\{big\_force}}&no\cr
\.{@+}&\PB{\\{insert}}:  \PB{\\{big\_cancel}} \.{\{\}} \PB{\\{break\_space}}
\.{\{\}} \PB{\\{big\_cancel}}&no\cr
\.{@;}&\PB{\\{semi}}: &maybe\cr
\.{@[}&\PB{\\{begin\_arg}}: &maybe\cr
\.{@]}&\PB{\\{end\_arg}}: &maybe\cr
\.{@\&}&\PB{\\{insert}}: \.{\\J}&maybe\cr
\.{@h}&\PB{\\{insert}}: \PB{\\{force}} \.{\\ATH} \PB{\\{force}}&no\cr
\.{@<}\thinspace section name\thinspace\.{@>}&\PB{\\{section\_scrap}}:
\.{\\X}$n$\.:translated section name\.{\\X}&maybe\cr
\.{@(}\thinspace section name\thinspace\.{@>}&\PB{\\{section\_scrap}}:
\.{\\X}$n$\.{:\\.\{}section name with special characters
quoted\.{\ \}\\X}&maybe\cr
\.{/*}comment\.{*/}&\PB{\\{insert}}: \PB{\\{cancel}}
\.{\\C\{}translated comment\.\} \PB{\\{force}}&no\cr
\.{//}comment&\PB{\\{insert}}: \PB{\\{cancel}}
\.{\\SHC\{}translated comment\.\} \PB{\\{force}}&no\cr
}

The construction \.{@t}\thinspace stuff\/\thinspace\.{@>} contributes
\.{\\hbox\{}\thinspace  stuff\/\thinspace\.\} to the following scrap.

% This file is part of mCWEB.
% This program by Markus Öllinger is based on
% CWEB 3.4 by Silvio Levy and Donald E. Knuth which in turn
% is based on a program by Knuth.
% It is distributed WITHOUT ANY WARRANTY, express or implied.
% Version 1.0 --- June 1996
%
\fi

\M{115}
\def\v{\char'174}
\mathchardef\RA="3221 % right arrow
\mathchardef\BA="3224 % double arrow
Here is a table of all the productions.  Each production that
combines two or more consecutive scraps implicitly inserts a {\tt \$}
where necessary, that is, between scraps whose abutting boundaries
have different \PB{\\{mathness}}.  In this way we never get double {\tt\$\$}.

A translation is provided when the resulting scrap is not merely a
juxtaposition of the scraps it comes from.  An asterisk$^*$ next to a scrap
means that its first identifier gets an underlined entry in the index,
via the function \PB{\\{make\_underlined}}.  Two asterisks$^{**}$ means that
both
\PB{\\{make\_underlined}} and \PB{\\{make\_reserved}} are called; that is, the
identifier's ilk becomes \PB{\\{raw\_int}}.  A dagger \dag\ before the
production number refers to the notes at the end of this section,
which deal with various exceptional cases.

We use \\{in}, \\{out}, \\{back} and
\\{bsp} as shorthands for \PB{\\{indent}}, \PB{\\{outdent}}, \PB{\\{backup}}
and
\PB{\\{break\_space}}, respectively.

\begingroup \lineskip=4pt
\def\alt #1 #2
{$\displaystyle\Bigl\{\!\matrix{\strut\hbox{#1}\cr
\strut\hbox{#2}\cr}\!\Bigr\}$ }
\def\altt #1 #2 #3
{$\displaystyle\Biggl\{\!\matrix{\strut\hbox{#1}\cr\hbox{#2}\cr
\strut\hbox{#3}\cr}\!\Biggr\}$ }
\def\malt #1 #2
{$\displaystyle\matrix{\strut\hbox{#1}\hfill\cr\strut\hbox{#2}\hfill\cr}$}
\def\maltt #1 #2 #3
{$\displaystyle\matrix{\strut\hbox{#1}\hfill\cr\hbox{#2}\hfill\cr
\strut\hbox{#3}\hfill\cr}$}
\yskip\newcount\prodno\prodno=0
\newdimen\midcol \midcol=2.5in
\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
\def\+#1&#2&#3&#4\cr{\def\next{#1}%
\line{\hbox to 2em{\hss
\ifx\next\empty\theprodno\else\next\fi}\strut
\ignorespaces#2\hfil\hbox to\midcol{$\RA$
\ignorespaces#3\hfil}\quad \hbox to1.45in{\ignorespaces#4\hfil}}}
\+\relax & LHS & RHS \hfill Translation & Example\cr
\yskip
\+& \altt\\{any} {\\{any} \\{any}} {\\{any} \\{any} \\{any}}
\PB{\\{insert}} & \altt\\{any} {\\{any} \\{any}} {\\{any} \\{any} \\{any}}
& stmt; \ /$\ast\,$comment$\,*$/\cr
\+& \PB{\\{exp}} \altt\PB{\\{lbrace}} \PB{\\{int\_like}} \PB{\\{decl}}
& \PB{\\{fn\_decl}} \altt\PB{\\{lbrace}} \PB{\\{int\_like}} \PB{\\{decl}}
\hfill $F=E^*\,\PB{\\{in}}\,\PB{\\{in}}$ & \malt {\\{main}()$\{$}
{\\{main}$(\\{ac},\\{av})$ \&{int} \\{ac};} \cr
\+& \PB{\\{exp}} \PB{\\{unop}} & \PB{\\{exp}} & \PB{$\|x\PP$}\cr
\+& \PB{\\{exp}} \alt \PB{\\{binop}} \PB{\\{unorbinop}} \PB{\\{exp}} & \PB{%
\\{exp}} & \malt {\PB{$\|x/\|y$}} {\PB{$\|x+\|y$}} \cr
\+& \PB{\\{exp}} \PB{\\{comma}} \PB{\\{exp}} & \PB{\\{exp}} \hfill $EC\,\PB{%
\\{opt}}9\,E$& \PB{$\|f(\|x,\|y)$}\cr
\+& \PB{\\{exp}} \alt \PB{\\{exp}} \PB{\\{cast}} & \PB{\\{exp}} & \PB{\\{time}(%
\,)}\cr
\+& \PB{\\{exp}} \PB{\\{semi}} & \PB{\\{stmt}} & \PB{$\|x\K\T{0};$}\cr
\+& \PB{\\{exp}} \PB{\\{colon}} & \PB{\\{tag}} \hfill $E^*C$ & \PB{\\{found}:}%
\cr
\+& \PB{\\{exp}} \PB{\\{base}} \PB{\\{int\_like}} \PB{\\{comma}} & \PB{%
\\{base}} \hfill $B\.\ IC$\,\PB{\\{opt}}9
& \&D : \&C,\cr
\+& \PB{\\{exp}} \PB{\\{base}} \PB{\\{int\_like}} \PB{\\{lbrace}} & \PB{%
\\{exp}} \PB{\\{lbrace}} \hfill
$E=E\.\ B\.\ I$ & \&D : \&C $\{$\cr
\+& \PB{\\{exp}} \PB{\\{rbrace}} & \PB{\\{stmt}} \PB{\\{rbrace}} & end of %
\&{enum} list\cr
\+& \PB{\\{lpar}} \alt \PB{\\{exp}} \PB{\\{unorbinop}} \PB{\\{rpar}} & \PB{%
\\{exp}} & \malt{\PB{(\|x)}} {\PB{$(*)$}} \cr
\+& \PB{\\{lpar}} \PB{\\{rpar}} & \PB{\\{exp}} \hfill $L\.{\\,}R$ & functions,
declarations\cr
\+& \PB{\\{lpar}} \alt \PB{\\{decl\_head}} \PB{\\{int\_like}} \PB{\\{rpar}} & %
\PB{\\{cast}} & \PB{(\&{char} ${}{*})$}\cr
\+& \PB{\\{lpar}} \altt \PB{\\{decl\_head}} \PB{\\{int\_like}} \PB{\\{exp}} %
\PB{\\{comma}} & \PB{\\{lpar}} \hfill
$L$\,\altt $D$ $I$ $E$ C\,\PB{\\{opt}}9 & \PB{$(\&{int},$}\cr
\+& \PB{\\{lpar}} \alt \PB{\\{stmt}} \PB{\\{decl}} & \PB{\\{lpar}} \hfill \alt
{$LS\.\ $} {$LD\.\ $} &
\alt {\PB{$(\|k\K\T{5};{}$ }} {\PB{(\&{int} \|k${}\K\T{5};{}$ }} \cr
\+& \PB{\\{question}} \PB{\\{exp}} \PB{\\{colon}} & \PB{\\{binop}} & \PB{$\?%
\|x:$}\cr
\+& \PB{\\{unop}} \alt \PB{\\{exp}} \PB{\\{int\_like}} & \alt \PB{\\{exp}} \PB{%
\\{int\_like}} &
\malt \PB{$\R\|x$} \PB{$\CM$}\&C \cr
\+& \PB{\\{unorbinop}} \alt\PB{\\{exp}} \PB{\\{int\_like}} & \alt\PB{\\{exp}} %
\PB{\\{int\_like}} \hfill
$\.\{U\.\}E$ & \PB{${*}\|x$}\cr
\+& \PB{\\{unorbinop}} \PB{\\{binop}} & \PB{\\{binop}} \hfill $\PB{\\{math%
\_rel}}\,U\.\{B\.\}\.\}$ & \PB{$\MRL{*{\K}}$}\cr
\+& \PB{\\{binop}} \PB{\\{binop}} & \PB{\\{binop}} \hfill
$\PB{\\{math\_rel}}\,\.\{B_1\.\}\.\{B_2\.\}\.\}$ & \PB{$\MRL{{\GG}{\K}}$}\cr
\+& \PB{\\{cast}} \PB{\\{exp}} & \PB{\\{exp}} \hfill $C\.\ E$ & \PB{(%
\&{double}) \|x}\cr
\+& \PB{\\{cast}} \PB{\\{semi}} & \PB{\\{exp}} \PB{\\{semi}} & \PB{(\&{int});}%
\cr
\+& \PB{\\{sizeof\_like}} \PB{\\{cast}} & \PB{\\{exp}} & \PB{\&{sizeof}(%
\&{double})}\cr
\+& \PB{\\{sizeof\_like}} \PB{\\{exp}} & \PB{\\{exp}} \hfill $S\.\ E$ & \PB{%
\&{sizeof} \|x}\cr
\+& \PB{\\{int\_like}} \alt\PB{\\{int\_like}} \PB{\\{struct\_like}} &
\alt\PB{\\{int\_like}} \PB{\\{struct\_like}} \hfill $I\.\ $\alt $I$ $S$
\unskip& \PB{\&{extern} \&{char}}\cr
\+& \PB{\\{int\_like}} \PB{\\{exp}} \alt\PB{\\{raw\_int}} \PB{\\{struct\_like}}
&
\PB{\\{int\_like}} \alt\PB{\\{int\_like}} \PB{\\{struct\_like}} & \PB{%
\&{extern}\.{"Ada"} \&{int}}\cr
\+& \PB{\\{int\_like}} \altt\PB{\\{exp}} \PB{\\{unorbinop}} \PB{\\{semi}} & %
\PB{\\{decl\_head}}
\altt\PB{\\{exp}} \PB{\\{unorbinop}} \PB{\\{semi}} \hfill
$D=I$\altt{\.\ } {\.\ } {} \unskip & \PB{\&{int} \|x}\cr
\+& \PB{\\{int\_like}} \PB{\\{colon}} & \PB{\\{decl\_head}} \PB{\\{colon}} %
\hfill $D=I\.\ $ & \PB{\&{unsigned}  :}\cr
\+& \PB{\\{int\_like}} \PB{\\{prelangle}} & \PB{\\{int\_like}} \PB{\\{langle}}
& \&C$\langle$\cr
\+& \PB{\\{int\_like}} \PB{\\{colcol}} \alt \PB{\\{exp}} \PB{\\{int\_like}} & %
\alt \PB{\\{exp}} \PB{\\{int\_like}} &
\malt {\&C\DC$x$} {\&C\DC\&B} \cr
\+& \PB{\\{int\_like}} \PB{\\{cast}} \PB{\\{lbrace}} & \PB{\\{fn\_decl}} \PB{%
\\{lbrace}} \hfill $IC\,\PB{\\{in}}\,\PB{\\{in}}$&
\&C$\langle\&{void}\ast\rangle\{$\cr
\+& \PB{\\{int\_like}} \PB{\\{cast}} & \PB{\\{int\_like}} & \&C$\langle%
\&{class}\ \&T\rangle$\cr
\+& \PB{\\{decl\_head}} \PB{\\{comma}} & \PB{\\{decl\_head}} \hfill $DC\.\ $ & %
\PB{\&{int} \|x${},{}$ }\cr
\+& \PB{\\{decl\_head}} \PB{\\{unorbinop}} & \PB{\\{decl\_head}} \hfill $D\.\{U%
\.\}$ & \PB{\&{int} ${}{*}$}\cr
\+\dag\theprodno& \PB{\\{decl\_head}} \PB{\\{exp}} & \PB{\\{decl\_head}} \hfill
$DE^*$ & \PB{\&{int} \|x}\cr
\+& \PB{\\{decl\_head}} \alt\PB{\\{binop}} \PB{\\{colon}} \PB{\\{exp}} \altt%
\PB{\\{comma}} \PB{\\{semi}} \PB{\\{rpar}} &
\PB{\\{decl\_head}} \altt\PB{\\{comma}} \PB{\\{semi}} \PB{\\{rpar}} \hfill
$D=D$\alt $B$ $C$ \unskip$E$ & \maltt initialization {fields or}
{default argument} \cr
\+& \PB{\\{decl\_head}} \PB{\\{cast}} & \PB{\\{decl\_head}} & \PB{\&{int} \|f(%
\&{int})}\cr
\+\dag\theprodno& \PB{\\{decl\_head}} \altt\PB{\\{int\_like}} \PB{\\{lbrace}} %
\PB{\\{decl}} & \PB{\\{fn\_decl}}
\altt\PB{\\{int\_like}} \PB{\\{lbrace}} \PB{\\{decl}} \hfill $F=D\,\PB{\\{in}}%
\,\PB{\\{in}}$
& \PB{\&{long} \\{time}(\,) $\{$}\cr
\+& \PB{\\{decl\_head}} \PB{\\{semi}} & \PB{\\{decl}} & \PB{\&{int} \|n;}\cr
\+& \PB{\\{decl}} \PB{\\{decl}} & \PB{\\{decl}} \hfill $D\,\PB{\\{force}}\,D$ &
\PB{\&{int} \|n; \&{double} \|x;}\cr
\+& \PB{\\{decl}} \alt\PB{\\{stmt}} \PB{\\{function}} & \alt\PB{\\{stmt}} \PB{%
\\{function}}
\hfill $D\,\PB{\\{big\_force}}\,$\alt $S$ $F$ \unskip& \&{extern} $n$;
\\{main} ()\PB{$\{\,\}$}\cr
\+\dag\theprodno& \PB{\\{typedef\_like}} \PB{\\{decl\_head}} \alt\PB{\\{exp}} %
\PB{\\{int\_like}} &
\PB{\\{typedef\_like}} \PB{\\{decl\_head}} \hfill $D=D$\alt $E^{**}$ $I^{**}$ %
\unskip &
\&{typedef} \&{char} \&{ch};\cr
\+& \PB{\\{typedef\_like}} \PB{\\{decl\_head}} \PB{\\{semi}} & \PB{\\{decl}} %
\hfill $T\.\ D$ &
\&{typedef} \&{int} $\&x,\&y$;\cr
\+& \PB{\\{struct\_like}} \PB{\\{lbrace}} & \PB{\\{struct\_head}} \hfill $S\.\
L$ & \PB{\&{struct} ${}\{$}\cr
\+& \PB{\\{struct\_like}} \alt\PB{\\{exp}} \PB{\\{int\_like}} \PB{\\{semi}} & %
\PB{\\{decl\_head}}
\hfill $S\.\ $\alt $E^{**}$ $I^{**}$ & \&{struct} \&{forward};\cr
\+& \PB{\\{struct\_like}} \alt\PB{\\{exp}} \PB{\\{int\_like}} \PB{\\{lbrace}} &
\PB{\\{struct\_head}} \hfill
$S\.\ $\alt $E^{**}$ $I^{**}$ \unskip $\.\ L$ &
\&{struct} \&{name\_info} $\{$\cr
\+& \PB{\\{struct\_like}} \alt\PB{\\{exp}} \PB{\\{int\_like}} \PB{\\{colon}} &
\PB{\\{struct\_like}} \alt\PB{\\{exp}} \PB{\\{int\_like}} \PB{\\{base}} & \PB{%
\\{class}} \&C :\cr
\+\dag\theprodno& \PB{\\{struct\_like}} \alt\PB{\\{exp}} \PB{\\{int\_like}} & %
\PB{\\{int\_like}}
\hfill $S\.\ $\alt$E$ $I$ & \&{struct} \&{name\_info} $z$;\cr
\+& \PB{\\{struct\_head}} \altt\PB{\\{decl}} \PB{\\{stmt}} \PB{\\{function}} %
\PB{\\{rbrace}} & \PB{\\{int\_like}}\hfill
$S\,\\{in}\,\PB{\\{force}}\,D\,\\{out}\,\PB{\\{force}}\,R$ &
\PB{\&{struct} ${}\{$} declaration \PB{$\}$}\cr
\+& \PB{\\{struct\_head}} \PB{\\{rbrace}} & \PB{\\{int\_like}}\hfill $S\.{%
\\,}R$ & \PB{\\{class}\|C ${}\{\,\}$}\cr
\+& \PB{\\{fn\_decl}} \PB{\\{decl}} & \PB{\\{fn\_decl}} \hfill $F\,\PB{%
\\{force}}\,D$
& $f(z)$ \&{double} $z$; \cr
\+& \PB{\\{fn\_decl}} \PB{\\{stmt}} & \PB{\\{function}} \hfill $F\,\PB{\\{out}}%
\,\PB{\\{out}}\,\PB{\\{force}}\,S$
& \\{main}() {\dots}\cr
\+& \PB{\\{function}} \altt\PB{\\{stmt}} \PB{\\{decl}} \PB{\\{function}} & %
\altt \PB{\\{stmt}} \PB{\\{decl}} \PB{\\{function}}
\hfill $F\,\PB{\\{big\_force}}\,$\altt $S$ $D$ $F$ & outer block\cr
\+& \PB{\\{lbrace}} \PB{\\{rbrace}} & \PB{\\{stmt}} \hfill $L\.{\\,}R$ & empty
statement\cr
\advance\midcol35pt
\+& \PB{\\{lbrace}} \altt\PB{\\{stmt}} \PB{\\{decl}} \PB{\\{function}} \PB{%
\\{rbrace}} & \PB{\\{stmt}} \hfill
$\PB{\\{force}}\,L\,\\{in}\,\PB{\\{force}}\,S\,
\PB{\\{force}}\,\\{back}\,R\,\\{out}\,\PB{\\{force}}$ & compound statement\cr
\advance\midcol-20pt
\+& \PB{\\{lbrace}} \PB{\\{exp}} [\PB{\\{comma}}] \PB{\\{rbrace}} & \PB{%
\\{exp}} & initializer\cr
\+& \PB{\\{if\_like}} \PB{\\{exp}} & \PB{\\{if\_clause}} \hfill $I\.{\ }E$ & %
\PB{\&{if} (\|z)}\cr
\+& \PB{\\{for\_like}} \PB{\\{exp}} & \PB{\\{else\_like}} \hfill $F\.{\ }E$ & %
\PB{\&{while} (\T{1})}\cr
\+& \PB{\\{else\_like}} \PB{\\{lbrace}} & \PB{\\{else\_head}} \PB{\\{lbrace}} &
\&{else} $\{$\cr
\+& \PB{\\{else\_like}} \PB{\\{stmt}} & \PB{\\{stmt}} \hfill
$\PB{\\{force}}\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,\PB{\\{force}}$ & \PB{ %
\&{else} ${}\|x\K\T{0};{}$}\cr
\+& \PB{\\{else\_head}} \alt\PB{\\{stmt}} \PB{\\{exp}}  & \PB{\\{stmt}} \hfill
$\PB{\\{force}}\,E\,\\{bsp}\,\PB{\\{noop}}\,\PB{\\{cancel}}\,S\,\\{bsp}$ & \PB{
\&{else} ${}\{{}$ ${}\|x\K\T{0};{}$ ${}\}{}$}\cr
\+& \PB{\\{if\_clause}} \PB{\\{lbrace}} & \PB{\\{if\_head}} \PB{\\{lbrace}} & %
\PB{\&{if} (\|x) $\{$}\cr
\+& \PB{\\{if\_clause}} \PB{\\{stmt}} \PB{\\{else\_like}} \PB{\\{if\_like}} & %
\PB{\\{if\_like}} \hfill
$\PB{\\{force}}\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,\PB{\\{force}}\,E\,\.\ I$ &
\PB{ \&{if} (\|x) \|y; \&{else} \&{if}}\cr
\+& \PB{\\{if\_clause}} \PB{\\{stmt}} \PB{\\{else\_like}} & \PB{\\{else\_like}}
\hfill
$\PB{\\{force}}\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,\PB{\\{force}}\,E$ &
\PB{ \&{if} (\|x) \|y; \&{else}}\cr
\+& \PB{\\{if\_clause}} \PB{\\{stmt}} & \PB{\\{else\_like}} \PB{\\{stmt}} & %
\PB{\&{if} (\|x)}\cr
\+& \PB{\\{if\_head}} \alt\PB{\\{stmt}} \PB{\\{exp}} \PB{\\{else\_like}} \PB{%
\\{if\_like}} & \PB{\\{if\_like}} \hfill
$\PB{\\{force}}\,I\,\\{bsp}\,\PB{\\{noop}}\,\PB{\\{cancel}}\,S\,\PB{\\{force}}%
\,E\,\.\ I$ &
\PB{ \&{if} (\|x) ${}\{{}$ \|y; ${}\}{}$ \&{else} \&{if}}\cr
\+& \PB{\\{if\_head}} \alt\PB{\\{stmt}} \PB{\\{exp}} \PB{\\{else\_like}} & \PB{%
\\{else\_like}} \hfill
$\PB{\\{force}}\,I\,\\{bsp}\,\PB{\\{noop}}\,\PB{\\{cancel}}\,S\,\PB{\\{force}}%
\,E$ &
\PB{ \&{if} (\|x) ${}\{{}$ \|y; ${}\}{}$ \&{else}}\cr
\+& \PB{\\{if\_head}} \alt\PB{\\{stmt}} \PB{\\{exp}} & \PB{\\{else\_head}} \alt%
\PB{\\{stmt}} \PB{\\{exp}} & \PB{ \&{if} (\|x) ${}\{{}$ \|y; ${}\}{}$}\cr
\advance\midcol20pt
\+& \PB{\\{do\_like}} \PB{\\{stmt}} \PB{\\{else\_like}} \PB{\\{semi}} & \PB{%
\\{stmt}} \hfill
$D\,\\{bsp}\,\PB{\\{noop}}\,\PB{\\{cancel}}\,S\,\PB{\\{cancel}}\,\PB{\\{noop}}%
\,\\{bsp}\,ES$%
&       \PB{\&{do} \|f(\|x); \&{while} (\|g(\|x));}\cr
\advance\midcol-20pt
\+& \PB{\\{case\_like}} \PB{\\{semi}} & \PB{\\{stmt}} & \PB{\&{return};}\cr
\+& \PB{\\{case\_like}} \PB{\\{colon}} & \PB{\\{tag}} & \PB{\&{default}:}\cr
\+& \PB{\\{case\_like}} \PB{\\{exp}} \PB{\\{semi}} & \PB{\\{stmt}} \hfill $C\.\
ES$ & \PB{\&{return} \T{0};}\cr
\+& \PB{\\{case\_like}} \PB{\\{exp}} \PB{\\{colon}} & \PB{\\{tag}} \hfill $C\.\
EC$ & \PB{\&{case} \T{0}:}\cr
\+& \PB{\\{tag}} \PB{\\{tag}} & \PB{\\{tag}} \hfill $T_1\,\\{bsp}\,T_2$ & \PB{%
\&{case} \T{0}: \&{case} \T{1}:}\cr
\+& \PB{\\{tag}} \altt\PB{\\{stmt}} \PB{\\{decl}} \PB{\\{function}} & \altt\PB{%
\\{stmt}} \PB{\\{decl}} \PB{\\{function}}
\hfill $\PB{\\{force}}\,\\{back}\,T\,\\{bsp}\,S$ & \PB{ \&{case} \T{0}: ${}\|z%
\K\T{0};$}\cr
\+\dag\theprodno& \PB{\\{stmt}} \altt\PB{\\{stmt}} \PB{\\{decl}} \PB{%
\\{function}} &
\altt\PB{\\{stmt}} \PB{\\{decl}} \PB{\\{function}}
\hfill $S\,$\altt$\PB{\\{force}}\,S$ $\PB{\\{big\_force}}\,D$ $\PB{\\{big%
\_force}}\,F$ &
\PB{$\|x\K\T{1};{}$ ${}\|y\K\T{2};$}\cr
\+& \PB{\\{semi}} & \PB{\\{stmt}} \hfill \.\ $S$& empty statement\cr
\+\dag\theprodno& \PB{\\{lproc}} \altt \PB{\\{if\_like}} \PB{\\{else\_like}} %
\PB{\\{define\_like}} & \PB{\\{lproc}} &
\maltt {{\bf \#include}} {\bf\#else} {\bf\#define} \cr
\+& \PB{\\{lproc}} \PB{\\{rproc}} & \PB{\\{insert}} & {\bf\#endif} \cr
\+& \PB{\\{lproc}} \alt {\PB{\\{exp}} [\PB{\\{exp}}]} \PB{\\{function}} \PB{%
\\{rproc}} & \PB{\\{insert}} \hfill
$I$\.\ \alt {$E{[\.{\ \\5}E]}$} {$F$} &
\malt{{\bf\#define} $a$\enspace 1} {{\bf\#define} $a$\enspace$\{\,b;\,\}$} \cr
\+& \PB{\\{section\_scrap}} \PB{\\{semi}} & \PB{\\{stmt}}\hfill $MS$ \PB{%
\\{force}}
&$\langle\,$section name$\,\rangle$;\cr
\+& \PB{\\{section\_scrap}} & \PB{\\{exp}} &$\langle\,$section name$\,\rangle$%
\cr
\+& \PB{\\{insert}} \PB{\\{any}} & \PB{\\{any}} & \.{\v\#include\v}\cr
\+& \PB{\\{prelangle}} & \PB{\\{binop}} \hfill \.< & $<$ not in template\cr
\+& \PB{\\{prerangle}} & \PB{\\{binop}} \hfill \.> & $>$ not in template\cr
\+& \PB{\\{langle}} \PB{\\{exp}} \PB{\\{prerangle}} & \PB{\\{cast}} & $\langle%
\,0\,\rangle$\cr
\+& \PB{\\{langle}} \PB{\\{prerangle}} & \PB{\\{cast}} \hfill $L\.{\\,}P$ & $%
\langle\,\rangle$\cr
\+& \PB{\\{langle}} \alt\PB{\\{decl\_head}} \PB{\\{int\_like}} \PB{%
\\{prerangle}} & \PB{\\{cast}} &
$\langle\&{class}\,\&C\rangle$\cr
\+& \PB{\\{langle}} \alt\PB{\\{decl\_head}} \PB{\\{int\_like}} \PB{\\{comma}} &
\PB{\\{langle}} \hfill
$L$\,\alt $D$ $I$ C\,\PB{\\{opt}}9 & $\langle\&{class}\,\&C,$\cr
\+& \PB{\\{public\_like}} \PB{\\{colon}} & \PB{\\{tag}} & \&{private}:\cr
\+& \PB{\\{public\_like}} & \PB{\\{int\_like}} & \&{private}\cr
\+& \PB{\\{colcol}} \alt\PB{\\{exp}} \PB{\\{int\_like}} & \alt\PB{\\{exp}} \PB{%
\\{int\_like}} & \PB{\DC\|x}\cr
\+\dag\theprodno&
\PB{\\{new\_like}} \alt\PB{\\{exp}} \PB{\\{raw\_int}} & \PB{\\{new\_like}} %
\hfill $N\.\ E$ & \PB{\&{new} (\T{1})}\cr
\+& \PB{\\{new\_like}} \alt\PB{\\{raw\_unorbin}} \PB{\\{colcol}} & \PB{\\{new%
\_like}} & \PB{$\&{new}\DC*$}\cr
\+& \PB{\\{new\_like}} \PB{\\{cast}} & \PB{\\{exp}} & \PB{\&{new} ${}(*)$}\cr
\+\dag\theprodno& \PB{\\{new\_like}} & \PB{\\{exp}} & \PB{\&{new}}\cr
\+\dag\theprodno& \PB{\\{operator\_like}} \altt\PB{\\{binop}} \PB{\\{unop}} %
\PB{\\{unorbinop}} & \PB{\\{exp}}
\hfill $O$\.\{\altt $B$ $U$ $U$\unskip \.\} & \PB{\\{operator} $+$}\cr
\+& \PB{\\{operator\_like}} \alt\PB{\\{new\_like}} \PB{\\{sizeof\_like}} & \PB{%
\\{exp}} \hfill $O\.\ N$
& \PB{\\{operator} \&{delete}}\cr
\+& \PB{\\{operator\_like}} & \PB{\\{new\_like}} & conversion operator\cr
\+& \PB{\\{catch\_like}} \alt\PB{\\{cast}} \PB{\\{exp}} & \PB{\\{fn\_decl}} %
\hfill $CE\,\\{in}\,\\{in}$ &
\PB{$\&{catch}(\,\ldots\,){}$}\cr
\+& \PB{\\{base}} \PB{\\{public\_like}} \PB{\\{exp}} \PB{\\{comma}} & \PB{%
\\{base}} \hfill $BP\.\ EC$ &
: \&{public} $a$,\cr
\+& \PB{\\{base}} \PB{\\{public\_like}} \PB{\\{exp}} & \PB{\\{base}} \PB{\\{int%
\_like}} \hfill $I=P\.\ E$ &
: \&{public} $a$\cr
\+\dag\theprodno& \PB{\\{raw\_rpar}} \PB{\\{const\_like}} & \PB{\\{raw\_rpar}} %
\hfill $R\.\ C$ &
) \&{const};\cr
\+& \PB{\\{raw\_rpar}} & \PB{\\{rpar}} & );\cr
\+& \PB{\\{raw\_unorbin}} \PB{\\{const\_like}} & \PB{\\{raw\_unorbin}} \hfill
$RC$\.{\\\ }
& $*$\&{const} \PB{\|x}\cr
\+& \PB{\\{raw\_unorbin}} & \PB{\\{unorbinop}} & $*$ \PB{\|x}\cr
\+& \PB{\\{const\_like}} & \PB{\\{int\_like}} & \&{const} \PB{\|x}\cr
\+& \PB{\\{raw\_int}} \PB{\\{lpar}} & \PB{\\{exp}} & \&{complex}$(x,y)$\cr
\+& \PB{\\{raw\_int}} & \PB{\\{int\_like}}   & \&{complex} \PB{\|z}\cr
\+& \PB{\\{begin\_arg}} \PB{\\{end\_arg}} & \PB{\\{exp}} & \.{@[}\&{char}$*$%
\.{@]}\cr
\+& \PB{\\{any\_other}} \PB{\\{end\_arg}} & \PB{\\{end\_arg}} &    \&{char}$*$%
\.{@]}\cr
\+& \PB{\\{typedef\_like}} \PB{\\{exp}} \PB{\\{cast}} \PB{\\{semi}} & \PB{%
\\{decl}}\hfill$T\.\ EC$ &
\&{typedef} \&{int}$(*x)()$\cr
\+& \PB{\\{typedef\_like}} \PB{\\{int\_like}} \PB{\\{decl}} & \PB{\\{decl}}%
\hfill$T\. ID$ &
\&{typedef} \&{int} $(*x)(\&{\#if}$\cr
\+& \PB{\\{typedef\_like}} \PB{\\{exp}} \PB{\\{exp}} \PB{\\{lpar}} & \PB{%
\\{exp}} \PB{\\{lpar}}\hfill$T\.\ E\.\ E$  &
\&{typedef} \&{void} $(*x)(\,)$\cr
\+& \PB{\\{int\_like}} \PB{\\{base}} \PB{\\{int\_like}} \PB{\\{lbrace}} & \PB{%
\\{exp}} \PB{\\{lbrace}}\hfill
$E=I\.\ B\.\ I$ & \&D : \&C $\{$\cr
\+& \PB{\\{int\_like}} \PB{\\{lproc}} & \PB{\\{lproc}}\hfill & \&{shared} {\bf%
\#include}\cr
\yskip
\yskip
\yskip
\parindent=0pt
\dag{\bf Notes}
\yskip
Rule 35: The \PB{\\{exp}} must not be immediately followed by \PB{\\{lpar}} or~%
\PB{\\{exp}}.

Rule 38: The \PB{\\{int\_like}} must not be immediately followed by \PB{%
\\{colcol}}.

Rule 42: The \PB{\\{exp}} must not be immediately followed by \PB{\\{lpar}} or~%
\PB{\\{exp}}.

Rule 48: The \PB{\\{exp}} or \PB{\\{int\_like}} must not be immediately
followed by \PB{\\{base}}.

Rule 76: The \PB{\\{force}} in the \PB{\\{stmt}} line becomes \\{bsp} if %
\.{CWEAVE} has
been invoked with the \.{-f} option.

Rule 78: The \PB{\\{define\_like}} case calls \PB{\\{make\_underlined}} on the
following scrap.

Rule 93: The \PB{\\{raw\_int}} must not be immediately followed by
\PB{\\{prelangle}} or \PB{\\{langle}}.

Rule 96: The \PB{\\{new\_like}} must not be immediately followed by \PB{%
\\{lpar}},
\PB{\\{raw\_int}}, or \PB{\\{struct\_like}}.

Rule 97: The operator after \PB{\\{operator\_like}}
must not be immediately followed by a \PB{\\{binop}}.

Rule 103: The operator after \PB{\\{const\_like}} must be \PB{\\{semi}}, \PB{%
\\{lbrace}}, \PB{\\{comma}},
\PB{\\{binop}}, or \PB{\\{const\_like}}.

\endgroup

\fi

\N{1}{116}Implementing the productions.
More specifically, a scrap is a structure consisting of a category
\PB{\\{cat}} and a \PB{\&{text\_pointer}} \PB{\\{trans}}, which points to the
translation in
\PB{\\{tok\_start}}.  When \CEE/ text is to be processed with the grammar
above,
we form an array \PB{\\{scrap\_info}} containing the initial scraps.
Our production rules have the nice property that the right-hand side is never
longer than the left-hand side. Therefore it is convenient to use sequential
allocation for the current sequence of scraps. Five pointers are used to
manage the parsing:

\yskip\hang \PB{\\{pp}} is a pointer into \PB{\\{scrap\_info}}.  We will try to
match
the category codes \PB{$\\{pp}\MG\\{cat},\,\,(\\{pp}+\T{1})\MG\\{cat}$}$,\,\,%
\ldots\,$
to the left-hand sides of productions.

\yskip\hang \PB{\\{scrap\_base}}, \PB{\\{lo\_ptr}}, \PB{\\{hi\_ptr}}, and \PB{%
\\{scrap\_ptr}} are such that
the current sequence of scraps appears in positions \PB{\\{scrap\_base}}
through
\PB{\\{lo\_ptr}} and \PB{\\{hi\_ptr}} through \PB{\\{scrap\_ptr}}, inclusive,
in the \PB{\\{cat}} and
\PB{\\{trans}} arrays. Scraps located between \PB{\\{scrap\_base}} and \PB{%
\\{lo\_ptr}} have
been examined, while those in positions \PB{$\G$ \\{hi\_ptr}} have not yet been
looked at by the parsing process.

\yskip\noindent Initially \PB{\\{scrap\_ptr}} is set to the position of the
final
scrap to be parsed, and it doesn't change its value. The parsing process
makes sure that \PB{$\\{lo\_ptr}\G\\{pp}+\T{3}$}, since productions have as
many as four terms,
by moving scraps from \PB{\\{hi\_ptr}} to \PB{\\{lo\_ptr}}. If there are
fewer than \PB{$\\{pp}+\T{3}$} scraps left, the positions up to \PB{$\\{pp}+%
\T{3}$} are filled with
blanks that will not match in any productions. Parsing stops when
\PB{$\\{pp}\E\\{lo\_ptr}+\T{1}$} and \PB{$\\{hi\_ptr}\E\\{scrap\_ptr}+\T{1}$}.

Since the \PB{\\{scrap}} structure will later be used for other purposes, we
declare its second element as unions.

\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{typedef} \&{struct} ${}\{{}$\1\6
\&{eight\_bits} \\{cat};\6
\&{eight\_bits} \\{mathness};\6
\&{union} ${}\{{}$\1\6
\&{text\_pointer} \\{Trans};\7
\X260:Rest of \PB{\\{trans\_plus}} union\X\2\6
${}\}{}$ \\{trans\_plus};\2\6
${}\}{}$ \&{scrap};\6
\&{typedef} \&{scrap} ${}{*}\&{scrap\_pointer}{}$;\par
\fi

\M{117}\B\D$\\{trans}$ \5
$\\{trans\_plus}.{}$\\{Trans}\C{ translation texts of scraps }\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{scrap} \\{scrap\_info}[\\{max\_scraps}];\C{ memory array for scraps }\6
\&{scrap\_pointer} \\{scrap\_info\_end}${}\K\\{scrap\_info}+\\{max\_scraps}-%
\T{1}{}$;\C{ end of \PB{\\{scrap\_info}} }\6
\&{scrap\_pointer} \\{pp};\C{ current position for reducing productions }\6
\&{scrap\_pointer} \\{scrap\_base};\C{ beginning of the current scrap sequence
}\6
\&{scrap\_pointer} \\{scrap\_ptr};\C{ ending of the current scrap sequence }\6
\&{scrap\_pointer} \\{lo\_ptr};\C{ last scrap that has been examined }\6
\&{scrap\_pointer} \\{hi\_ptr};\C{ first scrap that has not been examined }\6
\&{scrap\_pointer} \\{max\_scr\_ptr};\C{ largest value assumed by \PB{\\{scrap%
\_ptr}} }\par
\fi

\M{118}\B\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{scrap\_base}\K\\{scrap\_info}+\T{1};{}$\6
${}\\{max\_scr\_ptr}\K\\{scrap\_ptr}\K\\{scrap\_info}{}$;\par
\fi

\M{119}Token lists in \PB{\\{tok\_mem}} are composed of the following kinds of
items for \TEX/ output.

\yskip\item{$\bullet$}Character codes and special codes like \PB{\\{force}} and
\PB{\\{math\_rel}} represent themselves;

\item{$\bullet$}\PB{$\\{id\_flag}+\|p$} represents \.{\\\\\{{\rm identifier
$p$}\}};

\item{$\bullet$}\PB{$\\{res\_flag}+\|p$} represents \.{\\\&\{{\rm identifier
$p$}\}};

\item{$\bullet$}\PB{$\\{section\_flag}+\|p$} represents section name \PB{\|p};

\item{$\bullet$}\PB{$\\{tok\_flag}+\|p$} represents token list number \PB{\|p};

\item{$\bullet$}\PB{$\\{inner\_tok\_flag}+\|p$} represents token list number %
\PB{\|p}, to be
translated without line-break controls.

\Y\B\4\D$\\{id\_flag}$ \5
\T{10240}\C{ signifies an identifier }\par
\B\4\D$\\{res\_flag}$ \5
$\T{2}*{}$\\{id\_flag}\C{ signifies a reserved word }\par
\B\4\D$\\{section\_flag}$ \5
$\T{3}*{}$\\{id\_flag}\C{ signifies a section name }\par
\B\4\D$\\{tok\_flag}$ \5
$\T{4}*{}$\\{id\_flag}\C{ signifies a token list }\par
\B\4\D$\\{inner\_tok\_flag}$ \5
$\T{5}*{}$\\{id\_flag}\C{ signifies a token list in `\pb' }\par
\Y\B\&{void} \\{print\_text}(\|p)\C{ prints a token list for debugging; not
used in \PB{\\{main}} }\1\1\6
\&{text\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{token\_pointer} \|j;\C{ index into \PB{\\{tok\_mem}} }\6
\&{sixteen\_bits} \|r;\C{ remainder of token after the flag has been stripped
off }\7
\&{if} ${}(\|p\G\\{text\_ptr}){}$\1\5
\\{printf}(\.{"BAD"});\2\6
\&{else}\1\6
\&{for} ${}(\|j\K{*}\|p;{}$ ${}\|j<{*}(\|p+\T{1});{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
${}\|r\K{*}\|j\MOD\\{id\_flag};{}$\6
\&{switch} ${}({*}\|j/\\{id\_flag}){}$\5
${}\{{}$\1\6
\4\&{case} \T{1}:\5
\\{printf}(\.{"\\\\\\\\\{"});\6
${}\\{print\_id}((\\{name\_dir}+\|r));{}$\6
\\{printf}(\.{"\}"});\6
\&{break};\C{ \PB{\\{id\_flag}} }\6
\4\&{case} \T{2}:\5
\\{printf}(\.{"\\\\\&\{"});\6
${}\\{print\_id}((\\{name\_dir}+\|r));{}$\6
\\{printf}(\.{"\}"});\6
\&{break};\C{ \PB{\\{res\_flag}} }\6
\4\&{case} \T{3}:\5
\\{printf}(\.{"<"});\6
${}\\{print\_section\_name}((\\{name\_dir}+\|r));{}$\6
\\{printf}(\.{">"});\6
\&{break};\C{ \PB{\\{section\_flag}} }\6
\4\&{case} \T{4}:\5
${}\\{printf}(\.{"[[\%d]]"},\39\|r);{}$\6
\&{break};\C{ \PB{\\{tok\_flag}} }\6
\4\&{case} \T{5}:\5
${}\\{printf}(\.{"|[[\%d]]|"},\39\|r);{}$\6
\&{break};\C{ \PB{\\{inner\_tok\_flag}} }\6
\4\&{default}:\5
\X120:Print token \PB{\|r} in symbolic form\X;\6
\4${}\}{}$\2\6
\4${}\}{}$\2\2\6
\\{fflush}(\\{stdout});\6
\4${}\}{}$\2\par
\fi

\M{120}\B\X120:Print token \PB{\|r} in symbolic form\X${}\E{}$\6
\&{switch} (\|r)\5
${}\{{}$\1\6
\4\&{case} \\{math\_rel}:\5
\\{printf}(\.{"\\\\mathrel\{"});\6
\&{break};\6
\4\&{case} \\{big\_cancel}:\5
\\{printf}(\.{"[ccancel]"});\6
\&{break};\6
\4\&{case} \\{cancel}:\5
\\{printf}(\.{"[cancel]"});\6
\&{break};\6
\4\&{case} \\{indent}:\5
\\{printf}(\.{"[indent]"});\6
\&{break};\6
\4\&{case} \\{outdent}:\5
\\{printf}(\.{"[outdent]"});\6
\&{break};\6
\4\&{case} \\{backup}:\5
\\{printf}(\.{"[backup]"});\6
\&{break};\6
\4\&{case} \\{opt}:\5
\\{printf}(\.{"[opt]"});\6
\&{break};\6
\4\&{case} \\{break\_space}:\5
\\{printf}(\.{"[break]"});\6
\&{break};\6
\4\&{case} \\{force}:\5
\\{printf}(\.{"[force]"});\6
\&{break};\6
\4\&{case} \\{big\_force}:\5
\\{printf}(\.{"[fforce]"});\6
\&{break};\6
\4\&{case} \\{preproc\_line}:\5
\\{printf}(\.{"[preproc]"});\6
\&{break};\6
\4\&{case} \\{quoted\_char}:\5
${}\|j\PP;{}$\6
${}\\{printf}(\.{"[\%o]"},\39{}$(\&{unsigned}) ${}{*}\|j);{}$\6
\&{break};\6
\4\&{case} \\{end\_translation}:\5
\\{printf}(\.{"[quit]"});\6
\&{break};\6
\4\&{case} \\{inserted}:\5
\\{printf}(\.{"[inserted]"});\6
\&{break};\6
\4\&{default}:\5
\\{putxchar}(\|r);\6
\4${}\}{}$\2\par
\U119.\fi

\M{121}The production rules listed above are embedded directly into \.{CWEAVE},
since it is easier to do this than to write an interpretive system
that would handle production systems in general. Several macros are defined
here so that the program for each production is fairly short.

All of our productions conform to the general notion that some \PB{\|k}
consecutive scraps starting at some position \PB{\|j} are to be replaced by a
single scrap of some category \PB{\|c} whose translation is composed from the
translations of the disappearing scraps. After this production has been
applied, the production pointer \PB{\\{pp}} should change by an amount \PB{%
\|d}. Such
a production can be represented by the quadruple \PB{$(\|j,\|k,\|c,\|d)$}. For
example,
the production `\PB{\\{exp}\,\\{comma}\,\\{exp}} $\RA$ \PB{\\{exp}}' would be
represented by
`\PB{$(\\{pp},\T{3},\\{exp},{-}\T{2})$}'; in this case the pointer \PB{\\{pp}}
should decrease by 2
after the production has been applied, because some productions with
\PB{\\{exp}} in their second or third positions might now match,
but no productions have
\PB{\\{exp}} in the fourth position of their left-hand sides. Note that
the value of \PB{\|d} is determined by the whole collection of productions, not
by an individual one.
The determination of \PB{\|d} has been
done by hand in each case, based on the full set of productions but not on
the grammar of \CEE/ or on the rules for constructing the initial
scraps.

We also attach a serial number to each production, so that additional
information is available when debugging. For example, the program below
contains the statement `\PB{$\\{reduce}(\\{pp},\T{3},\\{exp},{-}\T{2},\T{4})$}'
when it implements
the production just mentioned.

Before calling \PB{\\{reduce}}, the program should have appended the tokens of
the new translation to the \PB{\\{tok\_mem}} array. We commonly want to append
copies of several existing translations, and macros are defined to
simplify these common cases. For example, \\{app2}\PB{(\\{pp})} will append the
translations of two consecutive scraps, \PB{$\\{pp}\MG\\{trans}$} and \PB{$(%
\\{pp}+\T{1})\MG\\{trans}$}, to
the current token list. If the entire new translation is formed in this
way, we write `\PB{$\\{squash}(\|j,\|k,\|c,\|d,\|n)$}' instead of `\PB{$%
\\{reduce}(\|j,\|k,\|c,\|d,\|n)$}'. For
example, `\PB{$\\{squash}(\\{pp},\T{3},\\{exp},{-}\T{2},\T{3})$}' is an
abbreviation for `\\{app3}\PB{(\\{pp}); $\\{reduce}(\\{pp},\T{3},\\{exp},{-}%
\T{2},\T{3})$}'.

A couple more words of explanation:
Both \PB{\\{big\_app}} and \PB{\\{app}} append a token (while \PB{\\{big%
\_app1}} to \PB{\\{big\_app4}}
append the specified number of scrap translations) to the current token list.
The difference between \PB{\\{big\_app}} and \PB{\\{app}} is simply that \PB{%
\\{big\_app}}
checks whether there can be a conflict between math and non-math
tokens, and intercalates a `\.{\$}' token if necessary.  When in
doubt what to use, use \PB{\\{big\_app}}.

The \PB{\\{mathness}} is an attribute of scraps that says whether they are
to be printed in a math mode context or not.  It is separate from the
``part of speech'' (the \PB{\\{cat}}) because to make each \PB{\\{cat}} have
a fixed \PB{\\{mathness}} (as in the original \.{WEAVE}) would multiply the
number of necessary production rules.

The low two bits (i.e. \PB{$\\{mathness}\MOD\T{4}$}) control the left boundary.
(We need two bits because we allow cases \PB{\\{yes\_math}}, \PB{\\{no\_math}}
and
\PB{\\{maybe\_math}}, which can go either way.)
The next two bits (i.e. \PB{$\\{mathness}/\T{4}$}) control the right boundary.
If we combine two scraps and the right boundary of the first has
a different mathness from the left boundary of the second, we
insert a \.{\$} in between.  Similarly, if at printing time some
irreducible scrap has a \PB{\\{yes\_math}} boundary the scrap gets preceded
or followed by a \.{\$}. The left boundary is \PB{\\{maybe\_math}} if and
only if the right boundary is.

The code below is an exact translation of the production rules into
\CEE/, using such macros, and the reader should have no difficulty
understanding the format by comparing the code with the symbolic
productions as they were listed earlier.

\Y\B\4\D$\\{no\_math}$ \5
\T{2}\C{ should be in horizontal mode }\par
\B\4\D$\\{yes\_math}$ \5
\T{1}\C{ should be in math mode }\par
\B\4\D$\\{maybe\_math}$ \5
\T{0}\C{ works in either horizontal or math mode }\par
\B\4\D$\\{big\_app2}(\|a)$ \5
\\{big\_app1}(\|a); $\\{big\_app1}(\|a+\T{1}{}$)\par
\B\4\D$\\{big\_app3}(\|a)$ \5
\\{big\_app2}(\|a); $\\{big\_app1}(\|a+\T{2}{}$)\par
\B\4\D$\\{big\_app4}(\|a)$ \5
\\{big\_app3}(\|a); $\\{big\_app1}(\|a+\T{3}{}$)\par
\B\4\D$\\{app}(\|a)$ \5
${*}(\\{tok\_ptr}\PP)\K{}$\|a\par
\B\4\D$\\{app1}(\|a)$ \5
${*}(\\{tok\_ptr}\PP)\K\\{tok\_flag}+{}$(\&{int}) ${}((\|a)\MG\\{trans}-\\{tok%
\_start}{}$)\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{int} \\{cur\_mathness}${},{}$ \\{init\_mathness};\par
\fi

\M{122}\B\&{void} \\{app\_str}(\|s)\1\1\6
\&{char} ${}{*}\|s;\2\2{}$\6
${}\{{}$\1\6
\&{while} ${}({*}\|s){}$\1\5
${}\\{app\_tok}({*}(\|s\PP));{}$\2\6
\4${}\}{}$\2\7
\&{void} \\{big\_app}(\|a)\1\1\6
\&{token} \|a;\2\2\6
${}\{{}$\1\6
\&{if} ${}(\|a\E\.{'\ '}\V(\|a\G\\{big\_cancel}\W\|a\Z\\{big\_force}){}$)\C{
non-math token }\6
${}\{{}$\1\6
\&{if} ${}(\\{cur\_mathness}\E\\{maybe\_math}){}$\1\5
${}\\{init\_mathness}\K\\{no\_math};{}$\2\6
\&{else} \&{if} ${}(\\{cur\_mathness}\E\\{yes\_math}){}$\1\5
\\{app\_str}(\.{"\{\}\$"});\2\6
${}\\{cur\_mathness}\K\\{no\_math};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} ${}(\\{cur\_mathness}\E\\{maybe\_math}){}$\1\5
${}\\{init\_mathness}\K\\{yes\_math};{}$\2\6
\&{else} \&{if} ${}(\\{cur\_mathness}\E\\{no\_math}){}$\1\5
\\{app\_str}(\.{"\$\{\}"});\2\6
${}\\{cur\_mathness}\K\\{yes\_math};{}$\6
\4${}\}{}$\2\6
\\{app}(\|a);\6
\4${}\}{}$\2\7
\&{void} \\{big\_app1}(\|a)\1\1\6
\&{scrap\_pointer} \|a;\2\2\6
${}\{{}$\1\6
\&{switch} ${}(\|a\MG\\{mathness}\MOD\T{4}){}$\5
${}\{{}$\C{ left boundary }\1\6
\4\&{case} (\\{no\_math}):\6
\&{if} ${}(\\{cur\_mathness}\E\\{maybe\_math}){}$\1\5
${}\\{init\_mathness}\K\\{no\_math};{}$\2\6
\&{else} \&{if} ${}(\\{cur\_mathness}\E\\{yes\_math}){}$\1\5
\\{app\_str}(\.{"\{\}\$"});\2\6
${}\\{cur\_mathness}\K\|a\MG\\{mathness}/\T{4}{}$;\C{ right boundary }\6
\&{break};\6
\4\&{case} (\\{yes\_math}):\6
\&{if} ${}(\\{cur\_mathness}\E\\{maybe\_math}){}$\1\5
${}\\{init\_mathness}\K\\{yes\_math};{}$\2\6
\&{else} \&{if} ${}(\\{cur\_mathness}\E\\{no\_math}){}$\1\5
\\{app\_str}(\.{"\$\{\}"});\2\6
${}\\{cur\_mathness}\K\|a\MG\\{mathness}/\T{4}{}$;\C{ right boundary }\6
\&{break};\6
\4\&{case} (\\{maybe\_math}):\C{ no changes }\6
\&{break};\6
\4${}\}{}$\2\6
${}\\{app}(\\{tok\_flag}+{}$(\&{int}) ${}((\|a)\MG\\{trans}-\\{tok%
\_start}));{}$\6
\4${}\}{}$\2\par
\fi

\M{123}Let us consider the big switch for productions now, before looking
at its context. We want to design the program so that this switch
works, so we might as well not keep ourselves in suspense about exactly what
code needs to be provided with a proper environment.

\Y\B\4\D$\\{cat1}$ \5
$(\\{pp}+\T{1})\MG{}$\\{cat}\par
\B\4\D$\\{cat2}$ \5
$(\\{pp}+\T{2})\MG{}$\\{cat}\par
\B\4\D$\\{cat3}$ \5
$(\\{pp}+\T{3})\MG{}$\\{cat}\par
\B\4\D$\\{lhs\_not\_simple}$ \5
$(\\{pp}\MG\\{cat}\I\\{semi}\W\\{pp}\MG\\{cat}\I\\{raw\_int}\W\\{pp}\MG\\{cat}%
\I\\{raw\_unorbin}\W\\{pp}\MG\\{cat}\I\\{raw\_rpar}\W\\{pp}\MG\\{cat}\I\\{const%
\_like}{}$)\par
\Y\B\4\X123:Match a production at \PB{\\{pp}}, or increase \PB{\\{pp}} if there
is no match\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\\{cat1}\E\\{end\_arg}\W\\{lhs\_not\_simple}){}$\1\6
\&{if} ${}(\\{pp}\MG\\{cat}\E\\{begin\_arg}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{110});{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{end\_arg},\39{-}\T{1},\39\T{111});{}$\2\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{insert}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{pp}\MG\\{cat},\39{-}\T{2},\39\T{0});{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{insert}){}$\1\5
${}\\{squash}(\\{pp}+\T{1},\39\T{2},\39(\\{pp}+\T{1})\MG\\{cat},\39{-}\T{1},\39%
\T{0});{}$\2\6
\&{else} \&{if} ${}(\\{cat3}\E\\{insert}){}$\1\5
${}\\{squash}(\\{pp}+\T{2},\39\T{2},\39(\\{pp}+\T{2})\MG\\{cat},\39\T{0},\39%
\T{0});{}$\2\6
\&{else}\1\6
\&{switch} ${}(\\{pp}\MG\\{cat}){}$\5
${}\{{}$\1\6
\4\&{case} \\{exp}:\5
\X130:Cases for \PB{\\{exp}}\X;\5
\&{break};\6
\4\&{case} \\{lpar}:\5
\X131:Cases for \PB{\\{lpar}}\X;\5
\&{break};\6
\4\&{case} \\{question}:\5
\X132:Cases for \PB{\\{question}}\X;\5
\&{break};\6
\4\&{case} \\{unop}:\5
\X133:Cases for \PB{\\{unop}}\X;\5
\&{break};\6
\4\&{case} \\{unorbinop}:\5
\X134:Cases for \PB{\\{unorbinop}}\X;\5
\&{break};\6
\4\&{case} \\{binop}:\5
\X135:Cases for \PB{\\{binop}}\X;\5
\&{break};\6
\4\&{case} \\{cast}:\5
\X136:Cases for \PB{\\{cast}}\X;\5
\&{break};\6
\4\&{case} \\{sizeof\_like}:\5
\X137:Cases for \PB{\\{sizeof\_like}}\X;\5
\&{break};\6
\4\&{case} \\{int\_like}:\5
\X138:Cases for \PB{\\{int\_like}}\X;\5
\&{break};\6
\4\&{case} \\{decl\_head}:\5
\X139:Cases for \PB{\\{decl\_head}}\X;\5
\&{break};\6
\4\&{case} \\{decl}:\5
\X140:Cases for \PB{\\{decl}}\X;\5
\&{break};\6
\4\&{case} \\{typedef\_like}:\5
\X141:Cases for \PB{\\{typedef\_like}}\X;\5
\&{break};\6
\4\&{case} \\{struct\_like}:\5
\X142:Cases for \PB{\\{struct\_like}}\X;\5
\&{break};\6
\4\&{case} \\{struct\_head}:\5
\X143:Cases for \PB{\\{struct\_head}}\X;\5
\&{break};\6
\4\&{case} \\{fn\_decl}:\5
\X144:Cases for \PB{\\{fn\_decl}}\X;\5
\&{break};\6
\4\&{case} \\{function}:\5
\X150:Cases for \PB{\\{function}}\X;\5
\&{break};\6
\4\&{case} \\{lbrace}:\5
\X151:Cases for \PB{\\{lbrace}}\X;\5
\&{break};\6
\4\&{case} \\{do\_like}:\5
\X158:Cases for \PB{\\{do\_like}}\X;\5
\&{break};\6
\4\&{case} \\{if\_like}:\5
\X152:Cases for \PB{\\{if\_like}}\X;\5
\&{break};\6
\4\&{case} \\{for\_like}:\5
\X153:Cases for \PB{\\{for\_like}}\X;\5
\&{break};\6
\4\&{case} \\{else\_like}:\5
\X154:Cases for \PB{\\{else\_like}}\X;\5
\&{break};\6
\4\&{case} \\{if\_clause}:\5
\X156:Cases for \PB{\\{if\_clause}}\X;\5
\&{break};\6
\4\&{case} \\{if\_head}:\5
\X157:Cases for \PB{\\{if\_head}}\X;\5
\&{break};\6
\4\&{case} \\{else\_head}:\5
\X155:Cases for \PB{\\{else\_head}}\X;\5
\&{break};\6
\4\&{case} \\{case\_like}:\5
\X159:Cases for \PB{\\{case\_like}}\X;\5
\&{break};\6
\4\&{case} \\{stmt}:\5
\X161:Cases for \PB{\\{stmt}}\X;\5
\&{break};\6
\4\&{case} \\{tag}:\5
\X160:Cases for \PB{\\{tag}}\X;\5
\&{break};\6
\4\&{case} \\{semi}:\5
\X162:Cases for \PB{\\{semi}}\X;\5
\&{break};\6
\4\&{case} \\{lproc}:\5
\X163:Cases for \PB{\\{lproc}}\X;\5
\&{break};\6
\4\&{case} \\{section\_scrap}:\5
\X164:Cases for \PB{\\{section\_scrap}}\X;\5
\&{break};\6
\4\&{case} \\{insert}:\5
\X165:Cases for \PB{\\{insert}}\X;\5
\&{break};\6
\4\&{case} \\{prelangle}:\5
\X166:Cases for \PB{\\{prelangle}}\X;\5
\&{break};\6
\4\&{case} \\{prerangle}:\5
\X167:Cases for \PB{\\{prerangle}}\X;\5
\&{break};\6
\4\&{case} \\{langle}:\5
\X168:Cases for \PB{\\{langle}}\X;\5
\&{break};\6
\4\&{case} \\{public\_like}:\5
\X169:Cases for \PB{\\{public\_like}}\X;\5
\&{break};\6
\4\&{case} \\{colcol}:\5
\X170:Cases for \PB{\\{colcol}}\X;\5
\&{break};\6
\4\&{case} \\{new\_like}:\5
\X171:Cases for \PB{\\{new\_like}}\X;\5
\&{break};\6
\4\&{case} \\{operator\_like}:\5
\X172:Cases for \PB{\\{operator\_like}}\X;\5
\&{break};\6
\4\&{case} \\{catch\_like}:\5
\X173:Cases for \PB{\\{catch\_like}}\X;\5
\&{break};\6
\4\&{case} \\{base}:\5
\X174:Cases for \PB{\\{base}}\X;\5
\&{break};\6
\4\&{case} \\{raw\_rpar}:\5
\X175:Cases for \PB{\\{raw\_rpar}}\X;\5
\&{break};\6
\4\&{case} \\{raw\_unorbin}:\5
\X176:Cases for \PB{\\{raw\_unorbin}}\X;\5
\&{break};\6
\4\&{case} \\{const\_like}:\5
\X177:Cases for \PB{\\{const\_like}}\X;\5
\&{break};\6
\4\&{case} \\{raw\_int}:\5
\X178:Cases for \PB{\\{raw\_int}}\X;\5
\&{break};\6
\4${}\}{}$\2\2\6
${}\\{pp}\PP{}$;\C{ if no match was found, we move to the right }\6
\4${}\}{}$\2\par
\U183.\fi

\M{124}In \CEE/, new specifier names can be defined via \PB{\&{typedef}}, and
we want
to make the parser recognize future occurrences of the identifier thus
defined as specifiers.  This is done by the procedure \PB{\\{make\_reserved}},
which changes the \PB{\\{ilk}} of the relevant identifier.

We first need a procedure to recursively seek the first
identifier in a token list, because the identifier might
be enclosed in parentheses, as when one defines a function
returning a pointer.

\Y\B\4\D$\\{no\_ident\_found}$ \5
\T{0}\C{ distinct from any identifier token }\par
\Y\B\&{token\_pointer} \\{find\_first\_ident}(\|p)\1\1\6
\&{text\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{token\_pointer} \|q;\C{ token to be returned }\6
\&{token\_pointer} \|j;\C{ token being looked at }\6
\&{sixteen\_bits} \|r;\C{ remainder of token after the flag has been stripped
off }\7
\&{if} ${}(\|p\G\\{text\_ptr}){}$\1\5
\\{confusion}(\.{"find\_first\_ident"});\2\6
\&{for} ${}(\|j\K{*}\|p;{}$ ${}\|j<{*}(\|p+\T{1});{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
${}\|r\K{*}\|j\MOD\\{id\_flag};{}$\6
\&{switch} ${}({*}\|j/\\{id\_flag}){}$\5
${}\{{}$\1\6
\4\&{case} \T{1}:\5
\&{case} \T{2}:\6
\&{if} ${}(\|j[\T{1}]\E\.{'\\\\'}\W\|j[\T{2}]\E\.{'D'}\W\|j[\T{3}]\E\.{'C'}{}$)%
\C{ identifier followed by \PB{\.{"::"}} }\1\6
\&{break};\2\6
\&{return} \|j;\6
\4\&{case} \T{4}:\5
\&{case} \T{5}:\C{ \PB{\\{tok\_flag}} or \PB{\\{inner\_tok\_flag}} }\6
\&{if} ${}((\|q\K\\{find\_first\_ident}(\\{tok\_start}+\|r))\I\\{no\_ident%
\_found}){}$\1\5
\&{return} \|q;\2\6
\4\&{default}:\5
;\C{ char, \PB{\\{section\_flag}}, fall thru: move on to next token }\6
\&{if} ${}({*}\|j\E\\{inserted}){}$\1\5
\&{return} \\{no\_ident\_found};\C{ ignore inserts }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{return} \\{no\_ident\_found};\6
\4${}\}{}$\2\par
\fi

\M{125}The scraps currently being parsed must be inspected for any
occurrence of the identifier that we're making reserved; hence
the \PB{\&{for}} loop below.

\Y\B\&{void} \\{make\_reserved}(\|p)\C{ make the first identifier in \PB{$\|p%
\MG\\{trans}$} like \PB{\&{int}} }\1\1\6
\&{scrap\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{sixteen\_bits} \\{tok\_value};\C{ the name of this identifier, plus its
flag}\6
\&{token\_pointer} \\{tok\_loc};\C{ pointer to \PB{\\{tok\_value}} }\7
\&{if} ${}((\\{tok\_loc}\K\\{find\_first\_ident}(\|p\MG\\{trans}))\E\\{no%
\_ident\_found}){}$\1\5
\&{return};\C{ this should not happen }\2\6
${}\\{tok\_value}\K{*}\\{tok\_loc};{}$\6
\&{for} ( ; ${}\|p\Z\\{scrap\_ptr};{}$ ${}\|p\E\\{lo\_ptr}\?\|p\K\\{hi\_ptr}:%
\|p\PP){}$\5
${}\{{}$\1\6
\&{if} ${}(\|p\MG\\{cat}\E\\{exp}){}$\5
${}\{{}$\1\6
\&{if} ${}({*}{*}(\|p\MG\\{trans})\E\\{tok\_value}){}$\5
${}\{{}$\1\6
${}\|p\MG\\{cat}\K\\{raw\_int};{}$\6
${}{*}{*}(\|p\MG\\{trans})\K\\{tok\_value}\MOD\\{id\_flag}+\\{res\_flag};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
${}(\\{name\_dir}+{}$(\&{sixteen\_bits}) ${}(\\{tok\_value}\MOD\\{id\_flag}))%
\MG\\{ilk}\K\\{raw\_int};{}$\6
${}{*}\\{tok\_loc}\K\\{tok\_value}\MOD\\{id\_flag}+\\{res\_flag};{}$\6
\4${}\}{}$\2\par
\fi

\M{126}In the following situations we want to mark the occurrence of
an identifier as a definition: when \PB{\\{make\_reserved}} is just about to be
used; after a specifier, as in \PB{\&{char} ${}{*}{*}\\{argv}$};
before a colon, as in \\{found}:; and in the declaration of a function,
as in \\{main}()$\{\ldots;\}$.  This is accomplished by the invocation
of \PB{\\{make\_underlined}} at appropriate times.  Notice that, in the
declaration
of a function, we only find out that the identifier is being defined after
it has been swallowed up by an \PB{\\{exp}}.

\Y\B\&{void} \\{make\_underlined}(\|p)\C{ underline the entry for the first
identifier in \PB{$\|p\MG\\{trans}$} }\1\1\6
\&{scrap\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{token\_pointer} \\{tok\_loc};\C{ where the first identifier appears }\7
\&{if} ${}((\\{tok\_loc}\K\\{find\_first\_ident}(\|p\MG\\{trans}))\E\\{no%
\_ident\_found}){}$\1\5
\&{return};\C{ this happens after parsing the \PB{(\,)} in \PB{\&{double} \|f(%
\,);} }\2\6
\&{if} (\\{parsing\_exp\_file})\1\5
${}\\{section\_count}\K\\{section\_of\_token}(\\{tok\_loc});{}$\2\6
${}\\{xref\_switch}\K\\{def\_flag};{}$\6
${}\\{underline\_xref}({*}\\{tok\_loc}\MOD\\{id\_flag}+\\{name\_dir});{}$\6
\4${}\}{}$\2\par
\fi

\M{127}We cannot use \PB{\\{new\_xref}} to underline a cross-reference at this
point
because this would just make a new cross-reference at the end of the list.
We actually have to search through the list for the existing
cross-reference.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{underline\_xref}(\,);\par
\fi

\M{128}\B\&{void} \\{underline\_xref}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \|q${}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref}{}$;\C{
pointer to cross-reference being examined }\6
\&{xref\_pointer} \|r;\C{ temporary pointer for permuting cross-references }\6
\&{sixteen\_bits} \|m;\C{ cross-reference value to be installed }\6
\&{sixteen\_bits} \|n;\C{ cross-reference value being examined }\7
\&{if} ${}(\\{no\_xref}\V\R\\{section\_count}\V\\{is\_adoc}){}$\1\5
\&{return};\2\6
${}\|m\K\\{section\_count}+\\{xref\_switch};{}$\6
\&{while} ${}(\|q\I\\{xmem}){}$\5
${}\{{}$\1\6
${}\|n\K\|q\MG\\{num};{}$\6
\&{if} ${}(\|q\MG\\{ext\_ref}\E\\{ext\_ref}\V\|q\MG\\{ext\_ref}\E\NULL\W(\\{ext%
\_ref}\E\\{own\_shared}\V\\{ext\_ref}\E\\{own\_export})\V\\{ext\_ref}\E\NULL\W(%
\|q\MG\\{ext\_ref}\E\\{own\_shared}\V\|q\MG\\{ext\_ref}\E\\{own\_export})){}$\5
${}\{{}$\1\6
\&{if} ${}(\|n\E\|m){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\|q\MG\\{ext\_ref}){}$\1\5
${}\|q\MG\\{ext\_ref}\K\\{ext\_ref};{}$\2\6
\&{return};\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|m\E\|n+\\{def\_flag}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\|q\MG\\{ext\_ref}){}$\1\5
${}\|q\MG\\{ext\_ref}\K\\{ext\_ref};{}$\2\6
${}\|q\MG\\{num}\K\|m;{}$\6
\&{return};\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|n\G\\{def\_flag}\W\|n<\|m){}$\1\5
\&{break};\2\6
\4${}\}{}$\2\6
${}\|q\K\|q\MG\\{xlink};{}$\6
\4${}\}{}$\2\6
\X129:Insert new cross-reference at \PB{\|q}, not at beginning of list\X;\6
\4${}\}{}$\2\par
\fi

\M{129}We get to this section only when the identifier is one letter long,
so it didn't get a non-underlined entry during phase one.  But it may
have got some explicitly underlined entries in later sections, so in order
to preserve the numerical order of the entries in the index, we have
to insert the new cross-reference not at the beginning of the list
(namely, at \PB{$\|p\MG\\{xref}$}), but rather right before \PB{\|q}.

\Y\B\4\X129:Insert new cross-reference at \PB{\|q}, not at beginning of list%
\X${}\E{}$\6
\\{append\_xref}(\T{0});\C{ this number doesn't matter }\6
${}\\{xref\_ptr}\MG\\{xlink}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$\6
${}\|r\K\\{xref\_ptr};{}$\6
${}\|p\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xref\_ptr};\6
\&{while} ${}(\|r\MG\\{xlink}\I\|q){}$\5
${}\{{}$\1\6
${}\|r\MG\\{num}\K\|r\MG\\{xlink}\MG\\{num};{}$\6
${}\|r\MG\\{ext\_ref}\K\|r\MG\\{xlink}\MG\\{ext\_ref};{}$\6
${}\|r\K\|r\MG\\{xlink};{}$\6
\4${}\}{}$\2\6
${}\|r\MG\\{num}\K\|m{}$;\C{ everything from \PB{\|q} on is left undisturbed }\6
${}\|r\MG\\{ext\_ref}\K\\{ext\_ref}{}$;\par
\U128.\fi

\M{130}Now comes the code that tries to match each production starting
with a particular type of scrap. Whenever a match is discovered,
the \PB{\\{squash}} or \PB{\\{reduce}} macro will cause the appropriate action
to be performed, followed by \PB{\&{goto} \\{found}}.

\Y\B\4\X130:Cases for \PB{\\{exp}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{lbrace}\V\\{cat1}\E\\{int\_like}\V\\{cat1}\E%
\\{decl}){}$\5
${}\{{}$\1\6
\\{make\_underlined}(\\{pp});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{app}(\\{indent});\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{fn\_decl},\39\T{0},\39\T{1});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{unop}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{2});{}$\2\6
\&{else} \&{if} ${}((\\{cat1}\E\\{binop}\V\\{cat1}\E\\{unorbinop})\W\\{cat2}\E%
\\{exp}){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{2},\39\T{3});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{comma}\W\\{cat2}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{app}(\\{opt});\6
\\{app}(\.{'9'});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{2},\39\T{4});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{cast}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{5});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{semi}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{stmt},\39{-}\T{1},\39\T{6});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{colon}){}$\5
${}\{{}$\1\6
\\{make\_underlined}(\\{pp});\6
${}\\{squash}(\\{pp},\39\T{2},\39\\{tag},\39\T{0},\39\T{7});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{base}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{int\_like}\W\\{cat3}\E\\{comma}){}$\5
${}\{{}$\1\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app2}(\\{pp}+\T{2});{}$\6
\\{app}(\\{opt});\6
\\{app}(\.{'9'});\6
${}\\{reduce}(\\{pp}+\T{1},\39\T{3},\39\\{base},\39\T{0},\39\T{8});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{int\_like}\W\\{cat3}\E\\{lbrace}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{1},\39\T{9});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{rbrace}){}$\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{stmt},\39{-}\T{1},\39\T{10}){}$;\2\par
\U123.\fi

\M{131}\B\X131:Cases for \PB{\\{lpar}}\X${}\E{}$\6
\&{if} ${}((\\{cat1}\E\\{exp}\V\\{cat1}\E\\{unorbinop})\W\\{cat2}\E\\{rpar}){}$%
\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{2},\39\T{11});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{rpar}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{app}(\.{'\\\\'});\6
\\{app}(\.{','});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{12});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{decl\_head}\V\\{cat1}\E\\{int\_like}\V\\{cat1}%
\E\\{exp}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{rpar}){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{cast},\39{-}\T{2},\39\T{13});{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{comma}){}$\5
${}\{{}$\1\6
\\{big\_app3}(\\{pp});\6
\\{app}(\\{opt});\6
\\{app}(\.{'9'});\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{lpar},\39\T{0},\39\T{14});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{decl}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{lpar},\39\T{0},\39\T{15});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{132}\B\X132:Cases for \PB{\\{question}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}\W\\{cat2}\E\\{colon}){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{binop},\39{-}\T{2},\39\T{16}){}$;\2\par
\U123.\fi

\M{133}\B\X133:Cases for \PB{\\{unop}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{int\_like}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{cat1},\39{-}\T{2},\39\T{17}){}$;\2\par
\U123.\fi

\M{134}\B\X134:Cases for \PB{\\{unorbinop}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{int\_like}){}$\5
${}\{{}$\1\6
\\{big\_app}(\.{'\{'});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\}'});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cat1},\39{-}\T{2},\39\T{18});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{binop}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{math\_rel});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\{'});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\}'});\6
\\{big\_app}(\.{'\}'});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{binop},\39{-}\T{1},\39\T{19});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{135}\B\X135:Cases for \PB{\\{binop}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{binop}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{math\_rel});\6
\\{big\_app}(\.{'\{'});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\}'});\6
\\{big\_app}(\.{'\{'});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\}'});\6
\\{big\_app}(\.{'\}'});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{binop},\39{-}\T{1},\39\T{20});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{136}\B\X136:Cases for \PB{\\{cast}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{21});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{semi}){}$\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{exp},\39{-}\T{2},\39\T{22}){}$;\2\par
\U123.\fi

\M{137}\B\X137:Cases for \PB{\\{sizeof\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{cast}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{23});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{24});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{138}\B\X138:Cases for \PB{\\{int\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{int\_like}\V\\{cat1}\E\\{struct\_like}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cat1},\39{-}\T{2},\39\T{25});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\W(\\{cat2}\E\\{raw\_int}\V\\{cat2}\E%
\\{struct\_like})){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{int\_like},\39{-}\T{2},\39\T{26});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{unorbinop}\V\\{cat1}\E%
\\{semi}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\&{if} ${}(\\{cat1}\I\\{semi}){}$\1\5
\\{big\_app}(\.{'\ '});\2\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{decl\_head},\39{-}\T{1},\39\T{27});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{colon}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{decl\_head},\39\T{0},\39\T{28});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{prelangle}){}$\1\5
${}\\{squash}(\\{pp}+\T{1},\39\T{1},\39\\{langle},\39\T{1},\39\T{29});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{colcol}\W(\\{cat2}\E\\{exp}\V\\{cat2}\E\\{int%
\_like})){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{cat2},\39{-}\T{2},\39\T{30});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{cast}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{lbrace}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{big\_app}(\\{indent});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{fn\_decl},\39\T{1},\39\T{31});{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{int\_like},\39{-}\T{2},\39\T{32});{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{base}\W\\{cat2}\E\\{int\_like}\W\\{cat3}\E%
\\{lbrace}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{1},\39\T{115});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{lproc}\W\\{cat2}\E\\{if\_like}\W\\{cat3}\E%
\\{exp}){}$\5
${}\{{}$\1\6
${}\\{squash}(\\{pp},\39\T{2},\39\\{lproc},\39\T{0},\39\T{116});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{139}\B\X139:Cases for \PB{\\{decl\_head}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{comma}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{decl\_head},\39{-}\T{1},\39\T{33});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{unorbinop}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\{'});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\}'});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{decl\_head},\39{-}\T{1},\39\T{34});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\W\\{cat2}\I\\{lpar}\W\\{cat2}\I%
\\{exp}){}$\5
${}\{{}$\1\6
${}\\{make\_underlined}(\\{pp}+\T{1});{}$\6
${}\\{squash}(\\{pp},\39\T{2},\39\\{decl\_head},\39{-}\T{1},\39\T{35});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}((\\{cat1}\E\\{binop}\V\\{cat1}\E\\{colon})\W\\{cat2}\E%
\\{exp}\W(\\{cat3}\E\\{comma}\V\\{cat3}\E\\{semi}\V\\{cat3}\E\\{rpar})){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{decl\_head},\39{-}\T{1},\39\T{36});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{cast}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{decl\_head},\39{-}\T{1},\39\T{37});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{lbrace}\V(\\{cat1}\E\\{int\_like}\W\\{cat2}\I%
\\{colcol})\V\\{cat1}\E\\{decl}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{app}(\\{indent});\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{fn\_decl},\39\T{0},\39\T{38});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{semi}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{decl},\39{-}\T{2},\39\T{39}){}$;\2\par
\U123.\fi

\M{140}\B\X140:Cases for \PB{\\{decl}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{decl}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{decl},\39{-}\T{2},\39\T{40});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{function}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{big\_force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cat1},\39{-}\T{1},\39\T{41});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{141}\B\X141:Cases for \PB{\\{typedef\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{decl\_head}){}$\5
${}\{{}$\1\6
\&{if} ${}((\\{cat2}\E\\{exp}\W\\{cat3}\I\\{lpar}\W\\{cat3}\I\\{exp})\V\\{cat2}%
\E\\{int\_like}){}$\5
${}\{{}$\1\6
${}\\{make\_underlined}(\\{pp}+\T{2});{}$\6
${}\\{make\_reserved}(\\{pp}+\T{2});{}$\6
${}\\{big\_app2}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp}+\T{1},\39\T{2},\39\\{decl\_head},\39\T{0},\39\T{42});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{semi}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app2}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{decl},\39{-}\T{2},\39\T{43});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\W\\{cat2}\E\\{cast}\W\\{cat3}\E%
\\{semi}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app3}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{4},\39\\{decl},\39{-}\T{2},\39\T{112});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{int\_like}\W\\{cat2}\E\\{decl}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app2}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{decl},\39{-}\T{2},\39\T{113});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\W\\{cat2}\E\\{exp}\W\\{cat3}\E%
\\{lpar}){}$\5
${}\{{}$\1\6
${}\\{make\_underlined}(\\{pp}+\T{2});{}$\6
${}\\{make\_reserved}(\\{pp}+\T{2});{}$\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\ '});\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{2},\39\T{114});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{142}\B\X142:Cases for \PB{\\{struct\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{lbrace}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{struct\_head},\39\T{0},\39\T{44});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{int\_like}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{lbrace}\V\\{cat2}\E\\{semi}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{lbrace}{}$)\C{ only if real definition }\1\6
${}\\{make\_underlined}(\\{pp}+\T{1});{}$\2\6
\&{if} (\\{Cxx})\C{ only if \CEE/++, make structure label a reserved word }\1\6
${}\\{make\_reserved}(\\{pp}+\T{1});{}$\2\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\&{if} ${}(\\{cat2}\E\\{semi}){}$\1\5
${}\\{reduce}(\\{pp},\39\T{2},\39\\{decl\_head},\39\T{0},\39\T{45});{}$\2\6
\&{else}\5
${}\{{}$\1\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{struct\_head},\39\T{0},\39\T{46});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{colon}){}$\1\5
${}\\{squash}(\\{pp}+\T{2},\39\T{1},\39\\{base},\39{-}\T{1},\39\T{47});{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\I\\{base}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{int\_like},\39{-}\T{2},\39\T{48});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{143}\B\X143:Cases for \PB{\\{struct\_head}}\X${}\E{}$\6
\&{if} ${}((\\{cat1}\E\\{decl}\V\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{function})\W%
\\{cat2}\E\\{rbrace}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{outdent});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{int\_like},\39{-}\T{2},\39\T{49});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{rbrace}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{app\_str}(\.{"\\\\,"});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{int\_like},\39{-}\T{2},\39\T{50});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{144}\B\X144:Cases for \PB{\\{fn\_decl}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{decl}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{fn\_decl},\39\T{0},\39\T{51});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{stmt}){}$\5
${}\{{}$\1\6
\X145:Don't export formal parameters\X;\6
\\{big\_app1}(\\{pp});\6
\\{app}(\\{outdent});\6
\\{app}(\\{outdent});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{function},\39{-}\T{1},\39\T{52});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{145}%mine
If we have an exported function definition with formal parameters,
we don't want them to appear in the export index, since they are no
real definitions. Therefore, we go through the scraps and set all
\PB{\\{ext\_ref}}s but the first one to \PB{$\NULL$}. The first \PB{$\\{ext%
\_ref}\I\NULL$} corresponds
to the function name which should stay in the export index, all others are
parameters.
\Y\B\4\X145:Don't export formal parameters\X${}\E{}$\6
${}\{{}$\1\6
${}\\{ext\_ref\_seen}\K\T{0}{}$;\C{ no \PB{\\{ext\_ref}} seen yet }\6
${}\\{struct\_like\_seen}\K\T{0};{}$\6
${}\\{reset\_ext\_refs}(\\{pp}\MG\\{trans});{}$\6
\4${}\}{}$\2\par
\U144.\fi

\M{146}
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{boolean} \\{ext\_ref\_seen}${},{}$ \\{struct\_like\_seen};\par
\fi

\M{147}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{reset\_ext\_refs}(\,);\6
\&{xref\_pointer} \\{defined\_here}(\,);\par
\fi

\M{148}%mine
Remove all but the first external definition of the given \PB{\\{text}\|p}
by setting the \PB{\\{ext\_ref}} field of the corresponding \PB{\\{xref}} to %
\PB{$\NULL$}.
\Y\B\&{void} \\{reset\_ext\_refs}(\|p)\1\1\6
\&{text\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{token\_pointer} \|j;\C{ token being looked at }\6
\&{sixteen\_bits} \|r;\C{ remainder of token after the flag has been stripped
off }\6
\&{xref\_pointer} \\{xp};\C{ cross reference where name defined name found }\7
\&{if} ${}(\|p\G\\{text\_ptr}){}$\1\5
\\{confusion}(\.{"find\_first\_ident"});\2\6
\&{for} ${}(\|j\K{*}\|p;{}$ ${}\|j<{*}(\|p+\T{1});{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
${}\|r\K{*}\|j\MOD\\{id\_flag};{}$\6
\&{switch} ${}({*}\|j/\\{id\_flag}){}$\5
${}\{{}$\1\6
\4\&{case} \T{1}:\6
\&{if} ${}(\|j[\T{1}]\E\.{'\\\\'}\W\|j[\T{2}]\E\.{'D'}\W\|j[\T{3}]\E\.{'C'}{}$)%
\C{ identifier followed by \PB{\.{"::"}} }\1\6
\&{break};\2\6
\&{if} (\\{struct\_like\_seen})\1\5
${}\\{struct\_like\_seen}\K\T{0}{}$;\C{ ignore this identifier }\2\6
\&{else} \&{if} ${}(\\{xp}\K\\{defined\_here}(\\{name\_dir}+\|r)){}$\5
${}\{{}$\1\6
\&{if} (\\{ext\_ref\_seen})\1\5
${}\\{xp}\MG\\{ext\_ref}\K\NULL;{}$\2\6
\&{else}\1\5
${}\\{ext\_ref\_seen}\K\T{1};{}$\2\6
\4${}\}{}$\2\6
\&{break};\6
\4\&{case} \T{2}:\6
\&{if} ${}(\\{name\_dir}[\|r].\\{ilk}\E\\{struct\_like}\W\|j<{*}(\|p+\T{1})\W%
\|j[\T{1}]/\\{id\_flag}\E\T{1}){}$\1\5
${}\\{struct\_like\_seen}\K\T{1}{}$;\C{ ignore next identifier }\2\6
\&{break};\6
\4\&{case} \T{4}:\5
\&{case} \T{5}:\C{ \PB{\\{tok\_flag}} or \PB{\\{inner\_tok\_flag}} }\6
${}\\{reset\_ext\_refs}(\\{tok\_start}+\|r);{}$\6
\4\&{default}:\5
;\C{ char, \PB{\\{section\_flag}}, fall thru: move on to next token }\6
\&{if} ${}({*}\|j\E\\{inserted}){}$\1\5
\&{return};\C{ ignore inserts }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{149}%mine
Checks if the name \PB{\|p} is defined in the current section \PB{\\{section%
\_count}}
and, if so, returns the \PB{\\{xref}}.
\Y\B\&{xref\_pointer} \\{defined\_here}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \\{xp};\7
\&{for} ${}(\\{xp}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$ ${}\\{xp}\I{%
\AND}\\{xmem}[\T{0}];{}$ ${}\\{xp}\K\\{xp}\MG\\{xlink}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{xp}\MG\\{num}\E\\{section\_count}+\\{def\_flag}){}$\1\5
\&{return} \\{xp};\2\6
\4${}\}{}$\2\6
\&{return} ${}\NULL;{}$\6
\4${}\}{}$\2\par
\fi

\M{150}\B\X150:Cases for \PB{\\{function}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{function}\V\\{cat1}\E\\{decl}\V\\{cat1}\E\\{stmt}){}$\5
${}\{{}$\1\6
\&{int} \\{shift}${}\K{-}\T{1};{}$\7
\&{if} ${}(\\{cat1}\E\\{decl}){}$\1\5
${}\\{shift}\K{-}\T{2};{}$\2\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{big\_force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cat1},\39\\{shift},\39\T{53});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{151}\B\X151:Cases for \PB{\\{lbrace}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{rbrace}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{app}(\.{'\\\\'});\6
\\{app}(\.{','});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{stmt},\39{-}\T{1},\39\T{54});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}((\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{decl}\V\\{cat1}\E%
\\{function})\W\\{cat2}\E\\{rbrace}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{force});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{force});\6
\\{big\_app}(\\{backup});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
\\{big\_app}(\\{outdent});\6
\\{big\_app}(\\{force});\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{stmt},\39{-}\T{1},\39\T{55});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{rbrace}){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{exp},\39{-}\T{2},\39\T{56});{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{comma}\W\\{cat3}\E\\{rbrace}){}$\1\5
${}\\{squash}(\\{pp},\39\T{4},\39\\{exp},\39{-}\T{2},\39\T{56});{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{152}\B\X152:Cases for \PB{\\{if\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{if\_clause},\39\T{0},\39\T{57});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{153}\B\X153:Cases for \PB{\\{for\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{else\_like},\39{-}\T{2},\39\T{58});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{154}\B\X154:Cases for \PB{\\{else\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{lbrace}){}$\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{else\_head},\39\T{0},\39\T{59});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{stmt}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{force});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{big\_app}(\\{break\_space});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{outdent});\6
\\{big\_app}(\\{force});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{stmt},\39{-}\T{1},\39\T{60});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{155}\B\X155:Cases for \PB{\\{else\_head}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{force});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{break\_space});\6
\\{app}(\\{noop});\6
\\{big\_app}(\\{cancel});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{force});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{stmt},\39{-}\T{1},\39\T{61});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{156}\B\X156:Cases for \PB{\\{if\_clause}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{lbrace}){}$\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{if\_head},\39\T{0},\39\T{62});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{stmt}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{else\_like}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{force});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{big\_app}(\\{break\_space});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{outdent});\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
\&{if} ${}(\\{cat3}\E\\{if\_like}){}$\5
${}\{{}$\1\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{3});{}$\6
${}\\{reduce}(\\{pp},\39\T{4},\39\\{if\_like},\39\T{0},\39\T{63});{}$\6
\4${}\}{}$\5
\2\&{else}\1\5
${}\\{reduce}(\\{pp},\39\T{3},\39\\{else\_like},\39\T{0},\39\T{64});{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{else\_like},\39\T{0},\39\T{65});{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{157}\B\X157:Cases for \PB{\\{if\_head}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{else\_like}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{force});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{break\_space});\6
\\{app}(\\{noop});\6
\\{big\_app}(\\{cancel});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{force});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
\&{if} ${}(\\{cat3}\E\\{if\_like}){}$\5
${}\{{}$\1\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{3});{}$\6
${}\\{reduce}(\\{pp},\39\T{4},\39\\{if\_like},\39\T{0},\39\T{66});{}$\6
\4${}\}{}$\5
\2\&{else}\1\5
${}\\{reduce}(\\{pp},\39\T{3},\39\\{else\_like},\39\T{0},\39\T{67});{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{else\_head},\39\T{0},\39\T{68});{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{158}\B\X158:Cases for \PB{\\{do\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{stmt}\W\\{cat2}\E\\{else\_like}\W\\{cat3}\E\\{semi}){}$%
\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{break\_space});\6
\\{app}(\\{noop});\6
\\{big\_app}(\\{cancel});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\\{cancel});\6
\\{app}(\\{noop});\6
\\{big\_app}(\\{break\_space});\6
${}\\{big\_app2}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{4},\39\\{stmt},\39{-}\T{1},\39\T{69});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{159}\B\X159:Cases for \PB{\\{case\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{semi}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{stmt},\39{-}\T{1},\39\T{70});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{colon}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{tag},\39{-}\T{1},\39\T{71});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{semi}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{stmt},\39{-}\T{1},\39\T{72});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{colon}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{tag},\39{-}\T{1},\39\T{73});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{160}\B\X160:Cases for \PB{\\{tag}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{tag}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{break\_space});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{tag},\39{-}\T{1},\39\T{74});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{decl}\V\\{cat1}\E%
\\{function}){}$\5
${}\{{}$\1\6
\&{int} \\{shift}${}\K{-}\T{1};{}$\7
\&{if} ${}(\\{cat1}\E\\{decl}){}$\1\5
${}\\{shift}\K{-}\T{2};{}$\2\6
\\{big\_app}(\\{force});\6
\\{big\_app}(\\{backup});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\\{break\_space});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cat1},\39\\{shift},\39\T{75});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{161}The user can decide at run-time whether short statements should be
grouped together on the same line.

\Y\B\4\D$\\{force\_lines}$ \5
\\{flags}[\.{'f'}]\C{ should each statement be on its own line? }\par
\Y\B\4\X161:Cases for \PB{\\{stmt}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{stmt}\V\\{cat1}\E\\{decl}\V\\{cat1}\E\\{function}){}$\5
${}\{{}$\1\6
\&{int} \\{shift}${}\K{-}\T{1};{}$\7
\\{big\_app1}(\\{pp});\6
\&{if} ${}(\\{cat1}\E\\{function}){}$\1\5
\\{big\_app}(\\{big\_force});\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{decl}){}$\5
${}\{{}$\1\6
\\{big\_app}(\\{big\_force});\6
${}\\{shift}\K{-}\T{2};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} (\\{force\_lines})\1\5
\\{big\_app}(\\{force});\2\6
\&{else}\1\5
\\{big\_app}(\\{break\_space});\2\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cat1},\39\\{shift},\39\T{76});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{162}\B\X162:Cases for \PB{\\{semi}}\X${}\E{}$\6
\\{big\_app}(\.{'\ '});\6
\\{big\_app1}(\\{pp});\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{stmt},\39{-}\T{1},\39\T{77}){}$;\par
\U123.\fi

\M{163}\B\X163:Cases for \PB{\\{lproc}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{define\_like}){}$\1\5
${}\\{make\_underlined}(\\{pp}+\T{2});{}$\2\6
\&{if} ${}(\\{cat1}\E\\{else\_like}\V\\{cat1}\E\\{if\_like}\V\\{cat1}\E%
\\{define\_like}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{lproc},\39\T{0},\39\T{78});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{rproc}){}$\5
${}\{{}$\1\6
\\{app}(\\{inserted});\6
\\{big\_app2}(\\{pp});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{insert},\39{-}\T{1},\39\T{79});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{function}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{rproc}){}$\5
${}\{{}$\1\6
\\{app}(\\{inserted});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app2}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{insert},\39{-}\T{1},\39\T{80});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{exp}\W\\{cat3}\E\\{rproc}\W\\{cat1}\E%
\\{exp}){}$\5
${}\{{}$\1\6
\\{app}(\\{inserted});\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{app\_str}(\.{"\ \\\\5"});\6
${}\\{big\_app2}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{4},\39\\{insert},\39{-}\T{1},\39\T{80});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{164}\B\X164:Cases for \PB{\\{section\_scrap}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{semi}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{big\_app}(\\{force});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{stmt},\39{-}\T{2},\39\T{81});{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{exp},\39{-}\T{2},\39\T{82}){}$;\2\par
\U123.\fi

\M{165}\B\X165:Cases for \PB{\\{insert}}\X${}\E{}$\6
\&{if} (\\{cat1})\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{cat1},\39\T{0},\39\T{83}){}$;\2\par
\U123.\fi

\M{166}\B\X166:Cases for \PB{\\{prelangle}}\X${}\E{}$\6
$\\{init\_mathness}\K\\{cur\_mathness}\K\\{yes\_math};{}$\6
\\{app}(\.{'<'});\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{binop},\39{-}\T{2},\39\T{84}){}$;\par
\U123.\fi

\M{167}\B\X167:Cases for \PB{\\{prerangle}}\X${}\E{}$\6
$\\{init\_mathness}\K\\{cur\_mathness}\K\\{yes\_math};{}$\6
\\{app}(\.{'>'});\6
${}\\{reduce}(\\{pp},\39\T{1},\39\\{binop},\39{-}\T{2},\39\T{85}){}$;\par
\U123.\fi

\M{168}\B\X168:Cases for \PB{\\{langle}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}\W\\{cat2}\E\\{prerangle}){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{cast},\39{-}\T{1},\39\T{86});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{prerangle}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{app}(\.{'\\\\'});\6
\\{app}(\.{','});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{cast},\39{-}\T{1},\39\T{87});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{decl\_head}\V\\{cat1}\E\\{int\_like}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{prerangle}){}$\1\5
${}\\{squash}(\\{pp},\39\T{3},\39\\{cast},\39{-}\T{1},\39\T{88});{}$\2\6
\&{else} \&{if} ${}(\\{cat2}\E\\{comma}){}$\5
${}\{{}$\1\6
\\{big\_app3}(\\{pp});\6
\\{app}(\\{opt});\6
\\{app}(\.{'9'});\6
${}\\{reduce}(\\{pp},\39\T{3},\39\\{langle},\39\T{0},\39\T{89});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{169}\B\X169:Cases for \PB{\\{public\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{colon}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{tag},\39{-}\T{1},\39\T{90});{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{int\_like},\39{-}\T{2},\39\T{91}){}$;\2\par
\U123.\fi

\M{170}\B\X170:Cases for \PB{\\{colcol}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}\V\\{cat1}\E\\{int\_like}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{cat1},\39{-}\T{2},\39\T{92}){}$;\2\par
\U123.\fi

\M{171}\B\X171:Cases for \PB{\\{new\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{exp}\V(\\{cat1}\E\\{raw\_int}\W\\{cat2}\I\\{prelangle}%
\W\\{cat2}\I\\{langle})){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{new\_like},\39\T{0},\39\T{93});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{raw\_unorbin}\V\\{cat1}\E\\{colcol}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{new\_like},\39\T{0},\39\T{94});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{cast}){}$\1\5
${}\\{squash}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{95});{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\I\\{lpar}\W\\{cat1}\I\\{raw\_int}\W\\{cat1}\I%
\\{struct\_like}){}$\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{exp},\39{-}\T{2},\39\T{96}){}$;\2\par
\U123.\fi

\M{172}\B\X172:Cases for \PB{\\{operator\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{binop}\V\\{cat1}\E\\{unop}\V\\{cat1}\E\\{unorbinop}){}$%
\5
${}\{{}$\1\6
\&{if} ${}(\\{cat2}\E\\{binop}){}$\1\5
\&{break};\2\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\{'});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\}'});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{97});{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cat1}\E\\{new\_like}\V\\{cat1}\E\\{sizeof\_like}){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{exp},\39{-}\T{2},\39\T{98});{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{new\_like},\39\T{0},\39\T{99}){}$;\2\par
\U123.\fi

\M{173}\B\X173:Cases for \PB{\\{catch\_like}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{cast}\V\\{cat1}\E\\{exp}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{big\_app}(\\{indent});\6
\\{big\_app}(\\{indent});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{fn\_decl},\39\T{0},\39\T{100});{}$\6
\4${}\}{}$\2\par
\U123.\fi

\M{174}\B\X174:Cases for \PB{\\{base}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{public\_like}\W\\{cat2}\E\\{exp}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cat3}\E\\{comma}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app2}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp},\39\T{4},\39\\{base},\39\T{0},\39\T{101});{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{2});{}$\6
${}\\{reduce}(\\{pp}+\T{1},\39\T{2},\39\\{int\_like},\39{-}\T{1},\39%
\T{102});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U123.\fi

\M{175}\B\X175:Cases for \PB{\\{raw\_rpar}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{const\_like}\W\3{-1}(\\{cat2}\E\\{semi}\V\\{cat2}\E%
\\{lbrace}\V\\{cat2}\E\\{comma}\V\\{cat2}\E\\{binop}\V\\{cat2}\E\\{const%
\_like})){}$\5
${}\{{}$\1\6
\\{big\_app1}(\\{pp});\6
\\{big\_app}(\.{'\ '});\6
${}\\{big\_app1}(\\{pp}+\T{1});{}$\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{raw\_rpar},\39\T{0},\39\T{103});{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{rpar},\39{-}\T{3},\39\T{104}){}$;\2\par
\U123.\fi

\M{176}\B\X176:Cases for \PB{\\{raw\_unorbin}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{const\_like}){}$\5
${}\{{}$\1\6
\\{big\_app2}(\\{pp});\6
\\{app\_str}(\.{"\\\\\ "});\6
${}\\{reduce}(\\{pp},\39\T{2},\39\\{raw\_unorbin},\39\T{0},\39\T{105});{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{unorbinop},\39{-}\T{2},\39\T{106}){}$;\2\par
\U123.\fi

\M{177}\B\X177:Cases for \PB{\\{const\_like}}\X${}\E{}$\6
$\\{squash}(\\{pp},\39\T{1},\39\\{int\_like},\39{-}\T{2},\39\T{107}){}$;\par
\U123.\fi

\M{178}\B\X178:Cases for \PB{\\{raw\_int}}\X${}\E{}$\6
\&{if} ${}(\\{cat1}\E\\{lpar}){}$\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{exp},\39{-}\T{2},\39\T{108});{}$\2\6
\&{else}\1\5
${}\\{squash}(\\{pp},\39\T{1},\39\\{int\_like},\39{-}\T{3},\39\T{109}){}$;\2\par
\U123.\fi

\M{179}The `\PB{\\{freeze\_text}}' macro is used to give official status to a
token list.
Before saying \PB{\\{freeze\_text}}, items are appended to the current token
list,
and we know that the eventual number of this token list will be the current
value of \PB{\\{text\_ptr}}. But no list of that number really exists as yet,
because no ending point for the current list has been
stored in the \PB{\\{tok\_start}} array. After saying \PB{\\{freeze\_text}},
the
old current token list becomes legitimate, and its number is the current
value of \PB{$\\{text\_ptr}-\T{1}$} since \PB{\\{text\_ptr}} has been
increased. The new
current token list is empty and ready to be appended to.
Note that \PB{\\{freeze\_text}} does not check to see that \PB{\\{text\_ptr}}
hasn't gotten
too large, since it is assumed that this test was done beforehand.

\Y\B\4\D$\\{freeze\_text}$ \5
${*}(\PP\\{text\_ptr})\K{}$\\{tok\_ptr}\par
\fi

\M{180}Here's the \PB{\\{reduce}} procedure used in our code for productions:

\Y\B\&{void} ${}\\{reduce}(\|j,\39\|k,\39\|c,\39\|d,\39\|n){}$\1\1\6
\&{scrap\_pointer} \|j;\6
\&{eight\_bits} \|c;\6
\&{short} \|k${},{}$ \|d${},{}$ \|n;\2\2\6
${}\{{}$\1\6
\&{scrap\_pointer} \|i${},{}$ \\{i1};\C{ pointers into scrap memory }\7
${}\|j\MG\\{cat}\K\|c;{}$\6
${}\|j\MG\\{trans}\K\\{text\_ptr};{}$\6
${}\|j\MG\\{mathness}\K\T{4}*\\{cur\_mathness}+\\{init\_mathness};{}$\6
\\{freeze\_text};\6
\&{if} ${}(\|k>\T{1}){}$\5
${}\{{}$\1\6
\&{for} ${}(\|i\K\|j+\|k,\39\\{i1}\K\|j+\T{1};{}$ ${}\|i\Z\\{lo\_ptr};{}$ ${}%
\|i\PP,\39\\{i1}\PP){}$\5
${}\{{}$\1\6
${}\\{i1}\MG\\{cat}\K\|i\MG\\{cat};{}$\6
${}\\{i1}\MG\\{trans}\K\|i\MG\\{trans};{}$\6
${}\\{i1}\MG\\{mathness}\K\|i\MG\\{mathness};{}$\6
\4${}\}{}$\2\6
${}\\{lo\_ptr}\K\\{lo\_ptr}-\|k+\T{1};{}$\6
\4${}\}{}$\2\6
\X181:Change \PB{\\{pp}} to $\max(\PB{\\{scrap\_base}},\PB{\\{pp}}+d)$\X;\6
\X186:Print a snapshot of the scrap list if debugging\X;\6
${}\\{pp}\MM{}$;\C{ we next say \PB{$\\{pp}\PP$} }\6
\4${}\}{}$\2\par
\fi

\M{181}\B\X181:Change \PB{\\{pp}} to $\max(\PB{\\{scrap\_base}},\PB{\\{pp}}+d)$%
\X${}\E{}$\6
\&{if} ${}(\\{pp}+\|d\G\\{scrap\_base}){}$\1\5
${}\\{pp}\K\\{pp}+\|d;{}$\2\6
\&{else}\1\5
${}\\{pp}\K\\{scrap\_base}{}$;\2\par
\Us180\ET182.\fi

\M{182}Here's the \PB{\\{squash}} procedure, which
takes advantage of the simplification that occurs when \PB{$\|k\E\T{1}$}.

\Y\B\&{void} ${}\\{squash}(\|j,\39\|k,\39\|c,\39\|d,\39\|n){}$\1\1\6
\&{scrap\_pointer} \|j;\6
\&{eight\_bits} \|c;\6
\&{short} \|k${},{}$ \|d${},{}$ \|n;\2\2\6
${}\{{}$\1\6
\&{scrap\_pointer} \|i;\C{ pointers into scrap memory }\7
\&{if} ${}(\|k\E\T{1}){}$\5
${}\{{}$\1\6
${}\|j\MG\\{cat}\K\|c;{}$\6
\X181:Change \PB{\\{pp}} to $\max(\PB{\\{scrap\_base}},\PB{\\{pp}}+d)$\X;\6
\X186:Print a snapshot of the scrap list if debugging\X;\6
${}\\{pp}\MM{}$;\C{ we next say \PB{$\\{pp}\PP$} }\6
\&{return};\6
\4${}\}{}$\2\6
\&{for} ${}(\|i\K\|j;{}$ ${}\|i<\|j+\|k;{}$ ${}\|i\PP){}$\1\5
\\{big\_app1}(\|i);\2\6
${}\\{reduce}(\|j,\39\|k,\39\|c,\39\|d,\39\|n);{}$\6
\4${}\}{}$\2\par
\fi

\M{183}Here now is the code that applies productions as long as possible.
Before applying the production mechanism, we must make sure
it has good input (at least four scraps, the length of the lhs of the
longest rules), and that there is enough room in the memory arrays
to hold the appended tokens and texts.  Here we use a very
conservative test: it's more important to make sure the program
will still work if we change the production rules (within reason)
than to squeeze the last bit of space from the memory arrays.

\Y\B\4\D$\\{safe\_tok\_incr}$ \5
\T{20}\par
\B\4\D$\\{safe\_text\_incr}$ \5
\T{10}\par
\B\4\D$\\{safe\_scrap\_incr}$ \5
\T{10}\par
\Y\B\4\X183:Reduce the scraps using the productions until no more rules apply%
\X${}\E{}$\6
\&{while} (\T{1})\5
${}\{{}$\1\6
\X184:Make sure the entries \PB{\\{pp}} through \PB{$\\{pp}+\T{3}$} of \PB{%
\\{cat}} are defined\X;\6
\&{if} ${}(\\{tok\_ptr}+\\{safe\_tok\_incr}>\\{tok\_mem\_end}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{tok\_ptr}>\\{max\_tok\_ptr}){}$\1\5
${}\\{max\_tok\_ptr}\K\\{tok\_ptr};{}$\2\6
\\{overflow}(\.{"token"});\6
\4${}\}{}$\2\6
\&{if} ${}(\\{text\_ptr}+\\{safe\_text\_incr}>\\{tok\_start\_end}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{text\_ptr}>\\{max\_text\_ptr}){}$\1\5
${}\\{max\_text\_ptr}\K\\{text\_ptr};{}$\2\6
\\{overflow}(\.{"text"});\6
\4${}\}{}$\2\6
\&{if} ${}(\\{pp}>\\{lo\_ptr}){}$\1\5
\&{break};\2\6
${}\\{init\_mathness}\K\\{cur\_mathness}\K\\{maybe\_math};{}$\6
\X123:Match a production at \PB{\\{pp}}, or increase \PB{\\{pp}} if there is no
match\X;\6
\4${}\}{}$\2\par
\U187.\fi

\M{184}If we get to the end of the scrap list, category codes equal to zero are
stored, since zero does not match anything in a production.

\Y\B\4\X184:Make sure the entries \PB{\\{pp}} through \PB{$\\{pp}+\T{3}$} of %
\PB{\\{cat}} are defined\X${}\E{}$\6
\&{if} ${}(\\{lo\_ptr}<\\{pp}+\T{3}){}$\5
${}\{{}$\1\6
\&{while} ${}(\\{hi\_ptr}\Z\\{scrap\_ptr}\W\\{lo\_ptr}\I\\{pp}+\T{3}){}$\5
${}\{{}$\1\6
${}(\PP\\{lo\_ptr})\MG\\{cat}\K\\{hi\_ptr}\MG\\{cat};{}$\6
${}\\{lo\_ptr}\MG\\{mathness}\K(\\{hi\_ptr})\MG\\{mathness};{}$\6
${}\\{lo\_ptr}\MG\\{trans}\K(\\{hi\_ptr}\PP)\MG\\{trans};{}$\6
\4${}\}{}$\2\6
\&{for} ${}(\|i\K\\{lo\_ptr}+\T{1};{}$ ${}\|i\Z\\{pp}+\T{3};{}$ ${}\|i\PP){}$\1%
\5
${}\|i\MG\\{cat}\K\T{0};{}$\2\6
\4${}\}{}$\2\par
\U183.\fi

\M{185}If \.{CWEAVE} is being run in debugging mode, the production numbers and
current stack categories will be printed out when \PB{\\{tracing}} is set to 2;
a sequence of two or more irreducible scraps will be printed out when
\PB{\\{tracing}} is set to 1.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{int} \\{tracing};\C{ can be used to show parsing details }\par
\fi

\M{186}\B\X186:Print a snapshot of the scrap list if debugging\X${}\E{}$\6
${}\{{}$\1\6
\&{scrap\_pointer} \|k;\C{ pointer into \PB{\\{scrap\_info}} }\7
\&{if} ${}(\\{tracing}\E\T{2}){}$\5
${}\{{}$\1\6
${}\\{printf}(\.{"\\n\%d:"},\39\|n);{}$\6
\&{for} ${}(\|k\K\\{scrap\_base};{}$ ${}\|k\Z\\{lo\_ptr};{}$ ${}\|k\PP){}$\5
${}\{{}$\1\6
\&{if} ${}(\|k\E\\{pp}){}$\1\5
\\{putxchar}(\.{'*'});\2\6
\&{else}\1\5
\\{putxchar}(\.{'\ '});\2\6
\&{if} ${}(\|k\MG\\{mathness}\MOD\T{4}\E\\{yes\_math}){}$\1\5
\\{putchar}(\.{'+'});\2\6
\&{else} \&{if} ${}(\|k\MG\\{mathness}\MOD\T{4}\E\\{no\_math}){}$\1\5
\\{putchar}(\.{'-'});\2\6
${}\\{print\_cat}(\|k\MG\\{cat});{}$\6
\&{if} ${}(\|k\MG\\{mathness}/\T{4}\E\\{yes\_math}){}$\1\5
\\{putchar}(\.{'+'});\2\6
\&{else} \&{if} ${}(\|k\MG\\{mathness}/\T{4}\E\\{no\_math}){}$\1\5
\\{putchar}(\.{'-'});\2\6
\4${}\}{}$\2\6
\&{if} ${}(\\{hi\_ptr}\Z\\{scrap\_ptr}){}$\1\5
\\{printf}(\.{"..."});\C{ indicate that more is coming }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\Us180\ET182.\fi

\M{187}The \PB{\\{translate}} function assumes that scraps have been stored in
positions \PB{\\{scrap\_base}} through \PB{\\{scrap\_ptr}} of \PB{\\{cat}} and %
\PB{\\{trans}}. It
applies productions as much as
possible. The result is a token list containing the translation of
the given sequence of scraps.

After calling \PB{\\{translate}}, we will have \PB{$\\{text\_ptr}+\T{3}\Z\\{max%
\_texts}$} and
\PB{$\\{tok\_ptr}+\T{6}\Z\\{max\_toks}$}, so it will be possible to create up
to three token
lists with up to six tokens without checking for overflow. Before calling
\PB{\\{translate}}, we should have \PB{$\\{text\_ptr}<\\{max\_texts}$} and %
\PB{$\\{scrap\_ptr}<\\{max\_scraps}$},
since \PB{\\{translate}} might add a new text and a new scrap before it checks
for overflow.

\Y\B\&{text\_pointer} \\{translate}(\,)\C{ converts a sequence of scraps }\6
${}\{{}$\1\6
\&{scrap\_pointer} \|i${},{}$\C{ index into \PB{\\{cat}} }\6
\|j;\C{ runs through final scraps }\7
${}\\{pp}\K\\{scrap\_base};{}$\6
${}\\{lo\_ptr}\K\\{pp}-\T{1};{}$\6
${}\\{hi\_ptr}\K\\{pp};{}$\6
\X190:If tracing, print an indication of where we are\X;\6
\X183:Reduce the scraps using the productions until no more rules apply\X;\6
\X188:Combine the irreducible scraps that remain\X;\6
\4${}\}{}$\2\par
\fi

\M{188}If the initial sequence of scraps does not reduce to a single scrap,
we concatenate the translations of all remaining scraps, separated by
blank spaces, with dollar signs surrounding the translations of scraps
where appropriate.

\Y\B\4\X188:Combine the irreducible scraps that remain\X${}\E{}$\6
${}\{{}$\1\6
\X189:If semi-tracing, show the irreducible scraps\X;\6
\&{for} ${}(\|j\K\\{scrap\_base};{}$ ${}\|j\Z\\{lo\_ptr};{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
\&{if} ${}(\|j\I\\{scrap\_base}){}$\1\5
\\{app}(\.{'\ '});\2\6
\&{if} ${}(\|j\MG\\{mathness}\MOD\T{4}\E\\{yes\_math}){}$\1\5
\\{app}(\.{'\$'});\2\6
\\{app1}(\|j);\6
\&{if} ${}(\|j\MG\\{mathness}/\T{4}\E\\{yes\_math}){}$\1\5
\\{app}(\.{'\$'});\2\6
\&{if} ${}(\\{tok\_ptr}+\T{6}>\\{tok\_mem\_end}){}$\1\5
\\{overflow}(\.{"token"});\2\6
\4${}\}{}$\2\6
\\{freeze\_text};\6
\&{return} ${}(\\{text\_ptr}-\T{1});{}$\6
\4${}\}{}$\2\par
\U187.\fi

\M{189}\B\X189:If semi-tracing, show the irreducible scraps\X${}\E{}$\6
\&{if} ${}(\\{lo\_ptr}>\\{scrap\_base}\W\\{tracing}\E\T{1}){}$\5
${}\{{}$\1\6
${}\\{printf}(\.{"\\nIrreducible\ scrap}\)\.{\ sequence\ in\ section}\)\.{\ %
\%d:"},\39\\{section\_count});{}$\6
\\{mark\_harmless};\6
\&{for} ${}(\|j\K\\{scrap\_base};{}$ ${}\|j\Z\\{lo\_ptr};{}$ ${}\|j\PP){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\ "});\6
${}\\{print\_cat}(\|j\MG\\{cat});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U188.\fi

\M{190}\B\X190:If tracing, print an indication of where we are\X${}\E{}$\6
\&{if} ${}(\\{tracing}\E\T{2}){}$\5
${}\{{}$\1\6
${}\\{printf}(\.{"\\nTracing\ after\ l.\ }\)\.{\%d:\\n"},\39\\{cur\_line});{}$\6
\\{mark\_harmless};\6
\&{if} ${}(\\{loc}>\\{buffer}+\T{50}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"..."});\6
${}\\{term\_write}(\\{loc}-\T{51},\39\T{51});{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{term\_write}(\\{buffer},\39\\{loc}-\\{buffer});{}$\2\6
\4${}\}{}$\2\par
\U187.\fi

\N{1}{191}Initializing the scraps.
If we are going to use the powerful production mechanism just developed, we
must get the scraps set up in the first place, given a \CEE/ text. A table
of the initial scraps corresponding to \CEE/ tokens appeared above in the
section on parsing; our goal now is to implement that table. We shall do this
by implementing a subroutine called \PB{\\{C\_parse}} that is analogous to the
\PB{\\{C\_xref}} routine used during phase one.

Like \PB{\\{C\_xref}}, the \PB{\\{C\_parse}} procedure starts with the current
value of \PB{\\{next\_control}} and it uses the operation \PB{$\\{next%
\_control}\K\\{get\_next}(\,)$}
repeatedly to read \CEE/ text until encountering the next `\.{\v}' or
`\.{/*}', or until \PB{$\\{next\_control}\G\\{format\_code}$}. The scraps
corresponding to
what it reads are appended into the \PB{\\{cat}} and \PB{\\{trans}} arrays, and
\PB{\\{scrap\_ptr}}
is advanced.

\Y\B\&{void} \\{C\_parse}(\\{spec\_ctrl})\C{ creates scraps from \CEE/ tokens }%
\1\1\6
\&{eight\_bits} \\{spec\_ctrl};\2\2\6
${}\{{}$\1\6
\&{while} ${}(\\{next\_control}<\\{format\_code}\V\\{next\_control}\E\\{spec%
\_ctrl}){}$\5
${}\{{}$\1\6
\X193:Append the scrap appropriate to \PB{\\{next\_control}}\X;\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4\\{got\_next\_one}:\6
\&{if} ${}(\\{next\_control}\E\.{'|'}\V\\{next\_control}\E\\{begin\_comment}\V%
\\{next\_control}\E\\{begin\_short\_comment}){}$\1\5
\&{return};\2\6
\&{if} ${}(\\{next\_control}\E\\{example\_code}\W\\{is\_example}){}$\1\5
\&{return};\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{192}The following macro is used to append a scrap whose tokens have just
been appended:

\Y\B\4\D$\\{app\_scrap}(\|c,\|b)$ \6
${}\{{}$\1\6
${}(\PP\\{scrap\_ptr})\MG\\{cat}\K(\|c);{}$\6
${}\\{scrap\_ptr}\MG\\{trans}\K\\{text\_ptr};{}$\6
${}\\{scrap\_ptr}\MG\\{mathness}\K\T{5}*(\|b){}$;\C{ no no, yes yes, or maybe
maybe }\6
\\{freeze\_text};\6
\4${}\}{}$\2\par
\fi

\M{193}\B\X193:Append the scrap appropriate to \PB{\\{next\_control}}\X${}\E{}$%
\6
\X194:Make sure that there is room for the new scraps, tokens, and texts\X;\6
\&{switch} (\\{next\_control})\5
${}\{{}$\1\6
\4\&{case} \\{special\_command}:\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\X195:Special command seen in \CEE/ part (phase two)\X;\6
\&{goto} \\{got\_next\_one};\6
\4\&{case} \\{section\_name}:\5
${}\\{app}(\\{section\_flag}+{}$(\&{int}) ${}(\\{cur\_section}-\\{name%
\_dir}));{}$\6
${}\\{app\_scrap}(\\{section\_scrap},\39\\{maybe\_math});{}$\6
${}\\{app\_scrap}(\\{exp},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{string}:\5
\&{case} \\{constant}:\5
\&{case} \\{verbatim}:\5
\X199:Append a string or constant\X;\5
\&{break};\6
\4\&{case} \\{identifier}:\5
\\{app\_cur\_id}(\T{1});\5
\&{break};\6
\4\&{case} ${}\TeXxstring:{}$\5
\X202:Append a \TEX/ string, without forming a scrap\X;\5
\&{break};\6
\4\&{case} \.{'/'}:\5
\&{case} \.{'.'}:\5
\\{app}(\\{next\_control});\6
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'<'}:\5
\\{app\_str}(\.{"\\\\langle"});\5
${}\\{app\_scrap}(\\{prelangle},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'>'}:\5
\\{app\_str}(\.{"\\\\rangle"});\5
${}\\{app\_scrap}(\\{prerangle},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'='}:\5
\\{app\_str}(\.{"\\\\K"});\6
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'|'}:\5
\\{app\_str}(\.{"\\\\OR"});\6
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\^'}:\5
\\{app\_str}(\.{"\\\\XOR"});\6
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\%'}:\5
\\{app\_str}(\.{"\\\\MOD"});\6
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'!'}:\5
\\{app\_str}(\.{"\\\\R"});\6
${}\\{app\_scrap}(\\{unop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\~'}:\5
\\{app\_str}(\.{"\\\\CM"});\6
${}\\{app\_scrap}(\\{unop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'+'}:\5
\&{case} \.{'-'}:\5
\\{app}(\\{next\_control});\6
${}\\{app\_scrap}(\\{unorbinop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'*'}:\5
\\{app}(\\{next\_control});\6
${}\\{app\_scrap}(\\{raw\_unorbin},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\&'}:\5
\\{app\_str}(\.{"\\\\AND"});\6
${}\\{app\_scrap}(\\{raw\_unorbin},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'?'}:\5
\\{app\_str}(\.{"\\\\?"});\6
${}\\{app\_scrap}(\\{question},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\#'}:\5
\\{app\_str}(\.{"\\\\\#"});\6
${}\\{app\_scrap}(\\{unorbinop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{ignore}:\5
\&{case} \\{xref\_roman}:\5
\&{case} \\{xref\_wildcard}:\5
\&{case} \\{xref\_typewriter}:\5
\&{case} \\{noop}:\5
\&{break};\6
\4\&{case} \.{'('}:\5
\&{case} \.{'['}:\5
\\{app}(\\{next\_control});\6
${}\\{app\_scrap}(\\{lpar},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \.{')'}:\5
\&{case} \.{']'}:\5
\\{app}(\\{next\_control});\6
${}\\{app\_scrap}(\\{raw\_rpar},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\{'}:\5
\\{app\_str}(\.{"\\\\\{"});\6
${}\\{app\_scrap}(\\{lbrace},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{'\}'}:\5
\\{app\_str}(\.{"\\\\\}"});\6
${}\\{app\_scrap}(\\{rbrace},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{','}:\5
\\{app}(\.{','});\6
${}\\{app\_scrap}(\\{comma},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \.{';'}:\5
\\{app}(\.{';'});\6
${}\\{app\_scrap}(\\{semi},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \.{':'}:\5
\\{app}(\.{':'});\6
${}\\{app\_scrap}(\\{colon},\39\\{maybe\_math}){}$;\5
\&{break};\6
\hbox{\4}\X196:Cases involving nonstandard characters\X\6
\4\&{case} \\{thin\_space}:\5
\\{app\_str}(\.{"\\\\,"});\6
${}\\{app\_scrap}(\\{insert},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \\{math\_break}:\5
\\{app}(\\{opt});\6
\\{app\_str}(\.{"0"});\6
${}\\{app\_scrap}(\\{insert},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \\{line\_break}:\5
\\{app}(\\{force});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{case} \\{left\_preproc}:\5
\\{app}(\\{force});\6
\\{app}(\\{preproc\_line});\6
\\{app\_str}(\.{"\\\\\#"});\6
${}\\{app\_scrap}(\\{lproc},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{case} \\{right\_preproc}:\5
\\{app}(\\{force});\6
${}\\{app\_scrap}(\\{rproc},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{case} \\{big\_line\_break}:\5
\\{app}(\\{big\_force});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{case} \\{no\_line\_break}:\5
\\{app}(\\{big\_cancel});\6
\\{app}(\\{noop});\6
\\{app}(\\{break\_space});\6
\\{app}(\\{noop});\6
\\{app}(\\{big\_cancel});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{case} \\{pseudo\_semi}:\5
${}\\{app\_scrap}(\\{semi},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \\{macro\_arg\_open}:\5
${}\\{app\_scrap}(\\{begin\_arg},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \\{macro\_arg\_close}:\5
${}\\{app\_scrap}(\\{end\_arg},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \\{join}:\5
\\{app\_str}(\.{"\\\\J"});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{case} \\{output\_defs\_code}:\5
\\{app}(\\{force});\6
\\{app\_str}(\.{"\\\\ATH"});\6
\\{app}(\\{force});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math}){}$;\5
\&{break};\6
\4\&{default}:\5
\\{app}(\\{inserted});\6
\\{app}(\\{next\_control});\6
${}\\{app\_scrap}(\\{insert},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4${}\}{}$\2\par
\Us191\ET320.\fi

\M{194}\B\X194:Make sure that there is room for the new scraps, tokens, and
texts\X${}\E{}$\6
\&{if} ${}(\\{scrap\_ptr}+\\{safe\_scrap\_incr}>\\{scrap\_info\_end}\V\\{tok%
\_ptr}+\\{safe\_tok\_incr}>\\{tok\_mem\_end}\3{-1}\V\\{text\_ptr}+\\{safe\_text%
\_incr}>\\{tok\_start\_end}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{scrap\_ptr}>\\{max\_scr\_ptr}){}$\1\5
${}\\{max\_scr\_ptr}\K\\{scrap\_ptr};{}$\2\6
\&{if} ${}(\\{tok\_ptr}>\\{max\_tok\_ptr}){}$\1\5
${}\\{max\_tok\_ptr}\K\\{tok\_ptr};{}$\2\6
\&{if} ${}(\\{text\_ptr}>\\{max\_text\_ptr}){}$\1\5
${}\\{max\_text\_ptr}\K\\{text\_ptr};{}$\2\6
\\{overflow}(\.{"scrap/token/text"});\6
\4${}\}{}$\2\par
\Us193\ET206.\fi

\M{195}%mine
If we encounter a special command introduced by \.{@\_}
in the \CEE/ part of the current section during phase two,
we can either have an export command, an import command or
commands for mark/copy/paste.
\Y\B\4\X195:Special command seen in \CEE/ part (phase two)\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
\&{name\_pointer} \|p${}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39%
\\{normal});{}$\7
\&{if} ${}(\|p\E\\{id\_global}\V\|p\E\\{id\_shared}\V\|p\E\\{id\_export}){}$\5
${}\{{}$\C{ export command }\1\6
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
${}\\{app\_scrap}(\\{raw\_int},\39\\{maybe\_math});{}$\6
\&{break};\6
\4${}\}{}$\2\6
\&{if} ${}(\|p\E\\{id\_from}){}$\1\5
\X197:\&{from} command seen while parsing\X\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_import}){}$\1\5
\X198:\&{import} command seen while parsing\X\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_mark}){}$\5
${}\{{}$\C{ ignore \&{mark} and string following }\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\1\5
\&{break};\2\6
\\{err\_print}(\.{"!\ Name\ of\ copy\ buff}\)\.{er\ expected"});\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_copy}){}$\1\5
\&{break};\C{ ignore \&{copy} }\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_paste}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\K\T{0};{}$\6
\\{paste}(\\{id\_first});\6
\&{break};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{err\_print}(\.{"!\ Illegal\ special\ c}\)\.{ommand\ in\ C\ text"});\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U193.\fi

\M{196}Some nonstandard characters may have entered \.{CWEAVE} by means of
standard ones. They are converted to \TEX/ control sequences so that it is
possible to keep \.{CWEAVE} from outputting unusual \PB{\&{char}} codes.

\Y\B\4\X196:Cases involving nonstandard characters\X${}\E{}$\6
\4\&{case} \\{not\_eq}:\5
\\{app\_str}(\.{"\\\\I"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{lt\_eq}:\5
\\{app\_str}(\.{"\\\\Z"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{gt\_eq}:\5
\\{app\_str}(\.{"\\\\G"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{eq\_eq}:\5
\\{app\_str}(\.{"\\\\E"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{and\_and}:\5
\\{app\_str}(\.{"\\\\W"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{or\_or}:\5
\\{app\_str}(\.{"\\\\V"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{plus\_plus}:\5
\\{app\_str}(\.{"\\\\PP"});\5
${}\\{app\_scrap}(\\{unop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{minus\_minus}:\5
\\{app\_str}(\.{"\\\\MM"});\5
${}\\{app\_scrap}(\\{unop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{minus\_gt}:\5
\\{app\_str}(\.{"\\\\MG"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{gt\_gt}:\5
\\{app\_str}(\.{"\\\\GG"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{lt\_lt}:\5
\\{app\_str}(\.{"\\\\LL"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{dot\_dot\_dot}:\5
\\{app\_str}(\.{"\\\\,\\\\ldots\\\\,"});\5
${}\\{app\_scrap}(\\{exp},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{colon\_colon}:\5
\\{app\_str}(\.{"\\\\DC"});\5
${}\\{app\_scrap}(\\{colcol},\39\\{maybe\_math}){}$;\5
\&{break};\6
\4\&{case} \\{period\_ast}:\5
\\{app\_str}(\.{"\\\\PA"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\6
\4\&{case} \\{minus\_gt\_ast}:\5
\\{app\_str}(\.{"\\\\MGA"});\5
${}\\{app\_scrap}(\\{binop},\39\\{yes\_math}){}$;\5
\&{break};\par
\U193.\fi

\M{197}%mine
When we encounter a \&{from} command in phase two, we have to typeset it.
It gets a '\.{\#}' in front of it and is set like a preprocessor
statement.
\Y\B\4\X197:\&{from} command seen while parsing\X${}\E{}$\6
${}\{{}$\1\6
\\{app}(\\{force});\5
\\{app}(\\{preproc\_line});\5
\\{app\_str}(\.{"\\\\\#"});\6
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir})){}$;\C{ display %
\&{from} }\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_program}\V\|p\E\\{id\_library}){}$\5
${}\{{}$\1\6
\\{app}(\.{'\ '});\5
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
\\{app}(\.{'\ '});\5
\\{append\_string}(\,);\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_import}){}$\5
${}\{{}$\1\6
\\{app}(\.{'\ '});\5
\\{app}(\\{opt});\5
\\{app}(\.{'5'});\6
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\C{ optional \&{transitively} }\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_transitively}){}$\5
${}\{{}$\1\6
\\{app}(\.{'\ '});\5
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
\&{goto} \\{got\_next\_one};\2\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\C{ statement is valid now }\1\6
\&{while} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
\\{app}(\\{break\_space});\5
\\{append\_string}(\,);\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\.{','}){}$\5
${}\{{}$\1\6
\\{app}(\.{','});\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{app}(\\{force});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U195.\fi

\M{198}%mine
The same applies to an \&{import} command.
\Y\B\4\X198:\&{import} command seen while parsing\X${}\E{}$\6
${}\{{}$\1\6
\\{app}(\\{force});\5
\\{app}(\\{preproc\_line});\5
\\{app\_str}(\.{"\\\\\#"});\6
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir})){}$;\C{ display %
\&{import} }\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_transitively}){}$\5
${}\{{}$\C{ optional \&{transitively} }\1\6
\\{app}(\.{'\ '});\5
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\1\5
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\2\6
\&{else}\1\5
\&{goto} \\{got\_next\_one};\2\6
\4${}\}{}$\2\6
\&{if} ${}(\|p\E\\{id\_program}\V\|p\E\\{id\_library}\V\|p\E\\{id\_chapter}){}$%
\5
${}\{{}$\1\6
\\{app}(\.{'\ '});\5
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
\&{while} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
\\{app}(\\{break\_space});\5
\\{append\_string}(\,);\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\.{','}){}$\5
${}\{{}$\1\6
\\{app}(\.{','});\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{app}(\\{force});\C{ import statement complete }\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U195.\fi

\M{199}The following code must use \PB{\\{app\_tok}} instead of \PB{\\{app}} in
order to
protect against overflow. Note that \PB{$\\{tok\_ptr}+\T{1}\Z\\{max\_toks}$}
after \PB{\\{app\_tok}}
has been used, so another \PB{\\{app}} is legitimate before testing again.

Many of the special characters in a string must be prefixed by `\.\\' so that
\TEX/ will print them properly.

\Y\B\4\X199:Append a string or constant\X${}\E{}$\6
\\{append\_string}(\,);\par
\U193.\fi

\M{200}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{append\_string}(\,);\par
\fi

\M{201}
\Y\B\&{void} \\{append\_string}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{int} \\{count}${}\K{-}\T{1};{}$\7
\&{if} ${}(\\{next\_control}\E\\{constant}){}$\1\5
\\{app\_str}(\.{"\\\\T\{"});\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}\\{count}\K\T{20};{}$\6
\\{app\_str}(\.{"\\\\.\{"});\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{app\_str}(\.{"\\\\vb\{"});\2\6
\&{while} ${}(\\{id\_first}<\\{id\_loc}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{count}\E\T{0}){}$\5
${}\{{}$\C{ insert a discretionary break in a long string }\1\6
\\{app\_str}(\.{"\}\\\\)\\\\.\{"});\6
${}\\{count}\K\T{20};{}$\6
\4${}\}{}$\2\6
\&{if} ((\&{eight\_bits}) ${}({*}\\{id\_first})>\T{\~177}){}$\5
${}\{{}$\1\6
\\{app\_tok}(\\{quoted\_char});\6
\\{app\_tok}((\&{eight\_bits}) ${}({*}\\{id\_first}\PP));{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{switch} ${}({*}\\{id\_first}){}$\5
${}\{{}$\1\6
\4\&{case} \.{'\ '}:\5
\&{case} \.{'\\\\'}:\5
\&{case} \.{'\#'}:\5
\&{case} \.{'\%'}:\5
\&{case} \.{'\$'}:\5
\&{case} \.{'\^'}:\5
\&{case} \.{'\{'}:\5
\&{case} \.{'\}'}:\5
\&{case} \.{'\~'}:\5
\&{case} \.{'\&'}:\5
\&{case} \.{'\_'}:\5
\\{app}(\.{'\\\\'});\6
\&{break};\6
\4\&{case} \.{'@'}:\6
\&{if} ${}({*}(\\{id\_first}+\T{1})\E\.{'@'}){}$\1\5
${}\\{id\_first}\PP;{}$\2\6
\&{else} \&{if} ${}(\R\\{parsing\_exp\_file}){}$\1\5
\\{err\_print}(\.{"!\ Double\ @\ should\ b}\)\.{e\ used\ in\ strings"});\2\6
\4${}\}{}$\2\6
${}\\{app\_tok}({*}\\{id\_first}\PP);{}$\6
\4${}\}{}$\2\6
${}\\{count}\MM;{}$\6
\4${}\}{}$\2\6
\\{app}(\.{'\}'});\6
${}\\{app\_scrap}(\\{exp},\39\\{maybe\_math});{}$\6
\4${}\}{}$\2\par
\fi

\M{202}We do not make the \TEX/ string into a scrap, because there is no
telling what the user will be putting into it; instead we leave it
open, to be picked up by the next scrap. If it comes at the end of a
section, it will be made into a scrap when \PB{\\{finish\_C}} is called.

There's a known bug here, in cases where an adjacent scrap is
\PB{\\{prelangle}} or \PB{\\{prerangle}}. Then the \TEX/ string can disappear
when the \.{\\langle} or \.{\\rangle} becomes \.{<} or \.{>}.
For example, if the user writes \.{\v x<@ty@>\v}, the \TEX/ string
\.{\\hbox\{y\}} eventually becomes part of an \PB{\\{insert}} scrap, which is
combined
with a \PB{\\{prelangle}} scrap and eventually lost. The best way to work
around
this bug is probably to enclose the \.{@t...@>} in \.{@[...@]} so that
the \TEX/ string is treated as an expression.

\Y\B\4\X202:Append a \TEX/ string, without forming a scrap\X${}\E{}$\6
\\{app\_str}(\.{"\\\\hbox\{"});\6
\&{while} ${}(\\{id\_first}<\\{id\_loc}){}$\1\6
\&{if} ((\&{eight\_bits}) ${}({*}\\{id\_first})>\T{\~177}){}$\5
${}\{{}$\1\6
\\{app\_tok}(\\{quoted\_char});\6
\\{app\_tok}((\&{eight\_bits}) ${}({*}\\{id\_first}\PP));{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{if} ${}({*}\\{id\_first}\E\.{'@'}){}$\1\5
${}\\{id\_first}\PP;{}$\2\6
${}\\{app\_tok}({*}\\{id\_first}\PP);{}$\6
\4${}\}{}$\2\2\6
\\{app}(\.{'\}'});\par
\U193.\fi

\M{203}The function \PB{\\{app\_cur\_id}} appends the current identifier to the
token list; it also builds a new scrap if \PB{$\\{scrapping}\E\T{1}$}.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{app\_cur\_id}(\,);\par
\fi

\M{204}\B\&{void} \\{app\_cur\_id}(\\{scrapping})\1\1\6
\&{boolean} \\{scrapping};\C{ are we making this into a scrap? }\2\2\6
${}\{{}$\1\6
\&{name\_pointer} \|p${}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39%
\\{normal});{}$\7
\&{if} ${}(\|p\MG\\{ilk}\Z\\{quoted}){}$\5
${}\{{}$\C{ not a reserved word }\1\6
${}\\{app}(\\{id\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
\&{if} (\\{scrapping})\1\5
${}\\{app\_scrap}(\\{exp},\39\|p\MG\\{ilk}\G\\{custom}\?\\{yes\_math}:\\{maybe%
\_math});{}$\2\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
\&{if} (\\{scrapping})\1\5
${}\\{app\_scrap}(\|p\MG\\{ilk},\39\\{maybe\_math});{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{205}When the `\.{\v}' that introduces \CEE/ text is sensed, a call on
\PB{\\{C\_translate}} will return a pointer to the \TEX/ translation of
that text. If scraps exist in \PB{\\{scrap\_info}}, they are
unaffected by this translation process.

\Y\B\&{text\_pointer} \\{C\_translate}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{text\_pointer} \|p;\C{ points to the translation }\6
\&{scrap\_pointer} \\{save\_base};\C{ holds original value of \PB{\\{scrap%
\_base}} }\7
${}\\{save\_base}\K\\{scrap\_base};{}$\6
${}\\{scrap\_base}\K\\{scrap\_ptr}+\T{1};{}$\6
\\{C\_parse}(\\{section\_name});\C{ get the scraps together }\6
\&{if} ${}(\\{next\_control}\I\.{'|'}){}$\1\5
\\{err\_print}(\.{"!\ Missing\ '|'\ after}\)\.{\ C\ text"});\2\6
\\{app\_tok}(\\{cancel});\6
${}\\{app\_scrap}(\\{insert},\39\\{maybe\_math}){}$;\C{ place a \PB{\\{cancel}}
token as a final ``comment'' }\6
${}\|p\K\\{translate}(\,){}$;\C{ make the translation }\6
\&{if} ${}(\\{scrap\_ptr}>\\{max\_scr\_ptr}){}$\1\5
${}\\{max\_scr\_ptr}\K\\{scrap\_ptr};{}$\2\6
${}\\{scrap\_ptr}\K\\{scrap\_base}-\T{1};{}$\6
${}\\{scrap\_base}\K\\{save\_base}{}$;\C{ scrap the scraps }\6
\&{return} (\|p);\6
\4${}\}{}$\2\par
\fi

\M{206}The \PB{\\{outer\_parse}} routine is to \PB{\\{C\_parse}} as \PB{%
\\{outer\_xref}}
is to \PB{\\{C\_xref}}: it constructs a sequence of scraps for \CEE/ text
until \PB{$\\{next\_control}\G\\{format\_code}$}. Thus, it takes care of
embedded comments.

\Y\B\&{void} \\{outer\_parse}(\,)\C{ makes scraps from \CEE/ tokens and
comments }\6
${}\{{}$\1\6
\&{int} \\{bal};\C{ brace level in comment }\6
\&{text\_pointer} \|p${},{}$ \|q;\C{ partial comments }\7
\&{while} ${}(\\{next\_control}<\\{format\_code}){}$\1\6
\&{if} ${}(\\{next\_control}\I\\{begin\_comment}\W\\{next\_control}\I\\{begin%
\_short\_comment}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{is\_example}\W\\{next\_control}\E\\{example\_code}){}$\1\5
\&{return};\2\6
\\{C\_parse}(\\{ignore});\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{boolean} \\{is\_long\_comment}${}\K(\\{next\_control}\E\\{begin%
\_comment});{}$\7
\X194:Make sure that there is room for the new scraps, tokens, and texts\X;\6
\\{app}(\\{cancel});\6
\\{app}(\\{inserted});\6
\&{if} (\\{is\_long\_comment})\1\5
\\{app\_str}(\.{"\\\\C\{"});\2\6
\&{else}\1\5
\\{app\_str}(\.{"\\\\SHC\{"});\2\6
${}\\{bal}\K\\{copy\_comment}(\\{is\_long\_comment},\39\T{1});{}$\6
${}\\{next\_control}\K\\{ignore};{}$\6
\&{while} ${}(\\{bal}>\T{0}){}$\5
${}\{{}$\1\6
${}\|p\K\\{text\_ptr};{}$\6
\\{freeze\_text};\6
${}\|q\K\\{C\_translate}(\,){}$;\C{ at this point we have \PB{$\\{tok\_ptr}+%
\T{6}\Z\\{max\_toks}$} }\6
${}\\{app}(\\{tok\_flag}+{}$(\&{int}) ${}(\|p-\\{tok\_start}));{}$\6
\\{app\_str}(\.{"\\\\PB\{"});\6
${}\\{app}(\\{inner\_tok\_flag}+{}$(\&{int}) ${}(\|q-\\{tok\_start}));{}$\6
\\{app\_tok}(\.{'\}'});\6
\&{if} ${}(\\{next\_control}\E\.{'|'}){}$\5
${}\{{}$\1\6
${}\\{bal}\K\\{copy\_comment}(\\{is\_long\_comment},\39\\{bal});{}$\6
${}\\{next\_control}\K\\{ignore};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{bal}\K\T{0}{}$;\C{ an error has been reported }\2\6
\4${}\}{}$\2\6
\\{app}(\\{force});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math}){}$;\C{ the full comment becomes a
scrap }\6
\4${}\}{}$\2\2\6
\4${}\}{}$\2\par
\fi

\M{207}%mine
If we encounter a '\.{@e}' in \TeX{} text, we have to parse \CEE/ code
that is inserted into the text as an example code and contains no real code.
This code is printed like ordinary \CEE/ code but never gets its way
through \.{mCTANGLE}.
The global variable \PB{\\{is\_example}} is set, if we are parsing example
\CEE/ code rather than real code.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{boolean} \\{is\_example};\par
\fi

\M{208}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{is\_example}\K\T{0}{}$;\par
\fi

\M{209}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{process\_example}(\,);\par
\fi

\M{210}Example \CEE/ code can occur in \TeX{} text (and autodocs, see below).
It gets the scraps, translates them into \TeX{} code and outputs the result.
Afterwards, it switches back to \TeX{} mode.
\Y\B\&{void} \\{process\_example}(\,)\1\1\2\2\6
${}\{{}$\1\6
${}\\{is\_example}\K\T{1};{}$\6
\\{out\_str}(\.{"\\\\par"});\6
\\{init\_stack};\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\I\\{definition}){}$\5
${}\{{}$\C{ is code following? }\1\6
\\{outer\_parse}(\,);\6
\\{finish\_C}(\T{1});\6
\4${}\}{}$\2\6
\&{while} ${}(\\{next\_control}\E\\{definition}){}$\5
${}\{{}$\C{ translate all definitions }\1\6
\X242:Start a macro definition\X;\6
\\{outer\_parse}(\,);\6
\\{finish\_C}(\T{1});\6
\4${}\}{}$\2\6
\&{if} ${}(\\{next\_control}\I\\{example\_code}){}$\1\5
\\{err\_print}(\.{"!\ Closing\ @e\ of\ exa}\)\.{mple\ section\ expecte}\)%
\.{d"});\2\6
\\{out\_str}(\.{"\\\\setsec\\n"});\C{ return to \TeX{} section settings }\6
\\{finish\_line}(\,);\6
${}\\{is\_example}\K\T{0};{}$\6
\4${}\}{}$\2\par
\fi

\N{1}{211}Output of tokens.
So far our programs have only built up multi-layered token lists in
\.{CWEAVE}'s internal memory; we have to figure out how to get them into
the desired final form. The job of converting token lists to characters in
the \TEX/ output file is not difficult, although it is an implicitly
recursive process. Four main considerations had to be kept in mind when
this part of \.{CWEAVE} was designed.  (a) There are two modes of output:
\PB{\\{outer}} mode, which translates tokens like \PB{\\{force}} into
line-breaking
control sequences, and \PB{\\{inner}} mode, which ignores them except that
blank
spaces take the place of line breaks. (b) The \PB{\\{cancel}} instruction
applies
to adjacent token or tokens that are output, and this cuts across levels
of recursion since `\PB{\\{cancel}}' occurs at the beginning or end of a token
list on one level. (c) The \TEX/ output file will be semi-readable if line
breaks are inserted after the result of tokens like \PB{\\{break\_space}} and
\PB{\\{force}}.  (d) The final line break should be suppressed, and there
should
be no \PB{\\{force}} token output immediately after `\.{\\Y\\B}'.

\fi

\M{212}The output process uses a stack to keep track of what is going on at
different ``levels'' as the token lists are being written out. Entries on
this stack have three parts:

\yskip\hang \PB{\\{end\_field}} is the \PB{\\{tok\_mem}} location where the
token list of a
particular level will end;

\yskip\hang \PB{\\{tok\_field}} is the \PB{\\{tok\_mem}} location from which
the next token
on a particular level will be read;

\yskip\hang \PB{\\{mode\_field}} is the current mode, either \PB{\\{inner}} or %
\PB{\\{outer}}.

\yskip\noindent The current values of these quantities are referred to
quite frequently, so they are stored in a separate place instead of in the
\PB{\\{stack}} array. We call the current values \PB{\\{cur\_end}}, \PB{\\{cur%
\_tok}}, and
\PB{\\{cur\_mode}}.

The global variable \PB{\\{stack\_ptr}} tells how many levels of output are
currently in progress. The end of output occurs when an \PB{\\{end%
\_translation}}
token is found, so the stack is never empty except when we first begin the
output process.

\Y\B\4\D$\\{inner}$ \5
\T{0}\C{ value of \PB{\&{mode}} for \CEE/ texts within \TEX/ texts }\par
\B\4\D$\\{outer}$ \5
\T{1}\C{ value of \PB{\&{mode}} for \CEE/ texts in sections }\par
\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{typedef} \&{int} \&{mode};\6
\&{typedef} \&{struct} ${}\{{}$\1\6
\&{token\_pointer} \\{end\_field};\C{ ending location of token list }\6
\&{token\_pointer} \\{tok\_field};\C{ present location within token list }\6
\&{boolean} \\{mode\_field};\C{ interpretation of control tokens }\2\6
${}\}{}$ \&{output\_state};\6
\&{typedef} \&{output\_state} ${}{*}\&{stack\_pointer}{}$;\par
\fi

\M{213}\B\D$\\{cur\_end}$ \5
$\\{cur\_state}.{}$\\{end\_field}\C{ current ending location in \PB{\\{tok%
\_mem}} }\par
\B\4\D$\\{cur\_tok}$ \5
$\\{cur\_state}.{}$\\{tok\_field}\C{ location of next output token in \PB{%
\\{tok\_mem}} }\par
\B\4\D$\\{cur\_mode}$ \5
$\\{cur\_state}.{}$\\{mode\_field}\C{ current mode of interpretation }\par
\B\4\D$\\{init\_stack}$ \5
$\\{stack\_ptr}\K\\{stack};$ $\\{cur\_mode}\K{}$\\{outer}\C{ initialize the
stack }\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{output\_state} \\{cur\_state};\C{ \PB{\\{cur\_end}}, \PB{\\{cur\_tok}}, \PB{%
\\{cur\_mode}} }\6
\&{output\_state} \\{stack}[\\{stack\_size}];\C{ info for non-current levels }\6
\&{stack\_pointer} \\{stack\_ptr};\C{ first unused location in the output state
stack }\6
\&{stack\_pointer} \\{stack\_end}${}\K\\{stack}+\\{stack\_size}-\T{1}{}$;\C{
end of \PB{\\{stack}} }\6
\&{stack\_pointer} \\{max\_stack\_ptr};\C{ largest value assumed by \PB{%
\\{stack\_ptr}} }\par
\fi

\M{214}\B\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{max\_stack\_ptr}\K\\{stack}{}$;\par
\fi

\M{215}To insert token-list \PB{\|p} into the output, the \PB{\\{push\_level}}
subroutine
is called; it saves the old level of output and gets a new one going.
The value of \PB{\\{cur\_mode}} is not changed.

\Y\B\&{void} \\{push\_level}(\|p)\C{ suspends the current level }\1\1\6
\&{text\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{stack\_ptr}\E\\{stack\_end}){}$\1\5
\\{overflow}(\.{"stack"});\2\6
\&{if} ${}(\\{stack\_ptr}>\\{stack}){}$\5
${}\{{}$\C{ save current state }\1\6
${}\\{stack\_ptr}\MG\\{end\_field}\K\\{cur\_end};{}$\6
${}\\{stack\_ptr}\MG\\{tok\_field}\K\\{cur\_tok};{}$\6
${}\\{stack\_ptr}\MG\\{mode\_field}\K\\{cur\_mode};{}$\6
\4${}\}{}$\2\6
${}\\{stack\_ptr}\PP;{}$\6
\&{if} ${}(\\{stack\_ptr}>\\{max\_stack\_ptr}){}$\1\5
${}\\{max\_stack\_ptr}\K\\{stack\_ptr};{}$\2\6
${}\\{cur\_tok}\K{*}\|p;{}$\6
${}\\{cur\_end}\K{*}(\|p+\T{1});{}$\6
\4${}\}{}$\2\par
\fi

\M{216}Conversely, the \PB{\\{pop\_level}} routine restores the conditions that
were in
force when the current level was begun. This subroutine will never be
called when \PB{$\\{stack\_ptr}\E\T{1}$}.

\Y\B\&{void} \\{pop\_level}(\,)\1\1\2\2\6
${}\{{}$\1\6
${}\\{cur\_end}\K(\MM\\{stack\_ptr})\MG\\{end\_field};{}$\6
${}\\{cur\_tok}\K\\{stack\_ptr}\MG\\{tok\_field};{}$\6
${}\\{cur\_mode}\K\\{stack\_ptr}\MG\\{mode\_field};{}$\6
\4${}\}{}$\2\par
\fi

\M{217}The \PB{\\{get\_output}} function returns the next byte of output that
is not a
reference to a token list. It returns the values \PB{\\{identifier}} or \PB{%
\\{res\_word}}
or \PB{\\{section\_code}} if the next token is to be an identifier (typeset in
italics), a reserved word (typeset in boldface) or a section name (typeset
by a complex routine that might generate additional levels of output).
In these cases \PB{\\{cur\_name}} points to the identifier or section name in
question.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{name\_pointer} \\{cur\_name};\par
\fi

\M{218}\B\D$\\{res\_word}$ \5
\T{\~201}\C{ returned by \PB{\\{get\_output}} for reserved words }\par
\B\4\D$\\{section\_code}$ \5
\T{\~200}\C{ returned by \PB{\\{get\_output}} for section names }\par
\Y\B\&{eight\_bits} \\{get\_output}(\,)\C{ returns the next token of output }\6
${}\{{}$\1\6
\&{sixteen\_bits} \|a;\C{ current item read from \PB{\\{tok\_mem}} }\7
\4\\{restart}:\6
\&{while} ${}(\\{cur\_tok}\E\\{cur\_end}){}$\1\5
\\{pop\_level}(\,);\2\6
${}\|a\K{*}(\\{cur\_tok}\PP);{}$\6
\&{if} ${}(\|a\G\T{\~400}){}$\5
${}\{{}$\1\6
${}\\{cur\_name}\K\|a\MOD\\{id\_flag}+\\{name\_dir};{}$\6
\&{switch} ${}(\|a/\\{id\_flag}){}$\5
${}\{{}$\1\6
\4\&{case} \T{2}:\5
\&{return} (\\{res\_word});\C{ \PB{$\|a\E\\{res\_flag}+\\{cur\_name}$} }\6
\4\&{case} \T{3}:\5
\&{return} (\\{section\_code});\C{ \PB{$\|a\E\\{section\_flag}+\\{cur\_name}$}
}\6
\4\&{case} \T{4}:\5
${}\\{push\_level}(\|a\MOD\\{id\_flag}+\\{tok\_start});{}$\6
\&{goto} \\{restart};\C{ \PB{$\|a\E\\{tok\_flag}+\\{cur\_name}$} }\6
\4\&{case} \T{5}:\5
${}\\{push\_level}(\|a\MOD\\{id\_flag}+\\{tok\_start});{}$\6
${}\\{cur\_mode}\K\\{inner};{}$\6
\&{goto} \\{restart};\C{ \PB{$\|a\E\\{inner\_tok\_flag}+\\{cur\_name}$} }\6
\4\&{default}:\5
\&{return} (\\{identifier});\C{ \PB{$\|a\E\\{id\_flag}+\\{cur\_name}$} }\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{return} (\|a);\6
\4${}\}{}$\2\par
\fi

\M{219}The real work associated with token output is done by \PB{\\{make%
\_output}}.
This procedure appends an \PB{\\{end\_translation}} token to the current token
list,
and then it repeatedly calls \PB{\\{get\_output}} and feeds characters to the
output
buffer until reaching the \PB{\\{end\_translation}} sentinel. It is possible
for
\PB{\\{make\_output}} to be called recursively, since a section name may
include
embedded \CEE/ text; however, the depth of recursion never exceeds one
level, since section names cannot be inside of section names.

A procedure called \PB{\\{output\_C}} does the scanning, translation, and
output of \CEE/ text within `\pb' brackets, and this procedure uses
\PB{\\{make\_output}} to output the current token list. Thus, the recursive
call
of \PB{\\{make\_output}} actually occurs when \PB{\\{make\_output}} calls \PB{%
\\{output\_C}}
while outputting the name of a section.

The token list created from within `\pb' brackets is output as an argument
to \.{\\PB}. Although \.{mcwebmac} ignores \.{\\PB}, other macro packages
might use it to localize the special meaning of the macros that mark up
program text.

\Y\B\&{void} \\{output\_C}(\,)\C{ outputs the current token list }\6
${}\{{}$\1\6
\&{token\_pointer} \\{save\_tok\_ptr};\6
\&{text\_pointer} \\{save\_text\_ptr};\6
\&{sixteen\_bits} \\{save\_next\_control};\C{ values to be restored }\6
\&{text\_pointer} \|p;\C{ translation of the \CEE/ text }\7
${}\\{save\_tok\_ptr}\K\\{tok\_ptr};{}$\6
${}\\{save\_text\_ptr}\K\\{text\_ptr};{}$\6
${}\\{save\_next\_control}\K\\{next\_control};{}$\6
${}\\{next\_control}\K\\{ignore};{}$\6
${}\|p\K\\{C\_translate}(\,);{}$\6
${}\\{app}(\\{inner\_tok\_flag}+{}$(\&{int}) ${}(\|p-\\{tok\_start}));{}$\6
\\{out\_str}(\.{"\\\\PB\{"});\6
\\{make\_output}(\,);\6
\\{out}(\.{'\}'});\C{ output the list }\6
\&{if} ${}(\\{text\_ptr}>\\{max\_text\_ptr}){}$\1\5
${}\\{max\_text\_ptr}\K\\{text\_ptr};{}$\2\6
\&{if} ${}(\\{tok\_ptr}>\\{max\_tok\_ptr}){}$\1\5
${}\\{max\_tok\_ptr}\K\\{tok\_ptr};{}$\2\6
${}\\{text\_ptr}\K\\{save\_text\_ptr};{}$\6
${}\\{tok\_ptr}\K\\{save\_tok\_ptr}{}$;\C{ forget the tokens }\6
${}\\{next\_control}\K\\{save\_next\_control}{}$;\C{ restore \PB{\\{next%
\_control}} to original state }\6
\4${}\}{}$\2\par
\fi

\M{220}Here is \.{CWEAVE}'s major output handler.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{make\_output}(\,);\par
\fi

\M{221}\B\&{void} \\{make\_output}(\,)\C{ outputs the equivalents of tokens }\6
${}\{{}$\1\6
\&{eight\_bits} \|a${},{}$\C{ current output byte }\6
\|b;\C{ next output byte }\6
\&{int} \|c;\C{ count of \PB{\\{indent}} and \PB{\\{outdent}} tokens }\6
\&{char} \\{scratch}[\\{longest\_name}];\C{ scratch area for section names }\6
\&{char} ${}{*}\|k,{}$ ${}{*}\\{k\_limit}{}$;\C{ indices into \PB{\\{scratch}}
}\6
\&{char} ${}{*}\|j{}$;\C{ index into \PB{\\{buffer}} }\6
\&{char} ${}{*}\|p{}$;\C{ index into \PB{\\{byte\_mem}} }\6
\&{char} \\{delim};\C{ first and last character of string being copied }\6
\&{char} ${}{*}\\{save\_loc},{}$ ${}{*}\\{save\_limit}{}$;\C{ \PB{\\{loc}} and %
\PB{\\{limit}} to be restored }\6
\&{name\_pointer} \\{cur\_section\_name};\C{ name of section being output }\6
\&{boolean} \\{save\_mode};\C{ value of \PB{\\{cur\_mode}} before a sequence of
breaks }\7
\\{app}(\\{end\_translation});\C{ append a sentinel }\6
\\{freeze\_text};\6
${}\\{push\_level}(\\{text\_ptr}-\T{1});{}$\6
\&{while} (\T{1})\5
${}\{{}$\1\6
${}\|a\K\\{get\_output}(\,);{}$\6
\4\\{reswitch}:\6
\&{switch} (\|a)\5
${}\{{}$\1\6
\4\&{case} \\{end\_translation}:\5
\&{return};\6
\4\&{case} \\{identifier}:\5
\&{case} \\{res\_word}:\5
\X222:Output an identifier\X;\6
\&{break};\6
\4\&{case} \\{section\_code}:\5
\X226:Output a section name\X;\6
\&{break};\6
\4\&{case} \\{math\_rel}:\5
\\{out\_str}(\.{"\\\\MRL\{"});\6
\4\&{case} \\{noop}:\5
\&{case} \\{inserted}:\5
\&{break};\6
\4\&{case} \\{cancel}:\5
\&{case} \\{big\_cancel}:\5
${}\|c\K\T{0};{}$\6
${}\|b\K\|a;{}$\6
\&{while} (\T{1})\5
${}\{{}$\1\6
${}\|a\K\\{get\_output}(\,);{}$\6
\&{if} ${}(\|a\E\\{inserted}){}$\1\5
\&{continue};\2\6
\&{if} ${}((\|a<\\{indent}\W\R(\|b\E\\{big\_cancel}\W\|a\E\.{'\ '}))\V\|a>%
\\{big\_force}){}$\1\5
\&{break};\2\6
\&{if} ${}(\|a\E\\{indent}){}$\1\5
${}\|c\PP;{}$\2\6
\&{else} \&{if} ${}(\|a\E\\{outdent}){}$\1\5
${}\|c\MM;{}$\2\6
\&{else} \&{if} ${}(\|a\E\\{opt}){}$\1\5
${}\|a\K\\{get\_output}(\,);{}$\2\6
\4${}\}{}$\2\6
\X225:Output saved \PB{\\{indent}} or \PB{\\{outdent}} tokens\X;\6
\&{goto} \\{reswitch};\6
\4\&{case} \\{indent}:\5
\&{case} \\{outdent}:\5
\&{case} \\{opt}:\5
\&{case} \\{backup}:\5
\&{case} \\{break\_space}:\5
\&{case} \\{force}:\5
\&{case} \\{big\_force}:\5
\&{case} \\{preproc\_line}:\5
\X223:Output a control, look ahead in case of line breaks, possibly \PB{%
\&{goto} \\{reswitch}}\X;\6
\&{break};\6
\4\&{case} \\{quoted\_char}:\5
${}\\{out}({*}(\\{cur\_tok}\PP));{}$\6
\&{break};\6
\4\&{default}:\5
\\{out}(\|a);\C{ otherwise \PB{\|a} is an ordinary character }\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{222}An identifier of length one does not have to be enclosed in braces, and
it
looks slightly better if set in a math-italic font instead of a (slightly
narrower) text-italic font. Thus we output `\.{\\\v}\.{a}' but
`\.{\\\\\{aa\}}'.

\Y\B\4\X222:Output an identifier\X${}\E{}$\6
\\{out}(\.{'\\\\'}); \&{if} ${}(\|a\E\\{identifier})$ $\{$ \6
\&{if} ${}(\\{cur\_name}\MG\\{ilk}\G\\{custom}\W\\{cur\_name}\MG\\{ilk}\Z%
\\{quoted}\W\R\\{doing\_format}){}$\5
${}\{{}$\1\6
\&{for} ${}(\|p\K\\{cur\_name}\MG\\{byte\_start};{}$ ${}\|p<(\\{cur\_name}+%
\T{1})\MG\\{byte\_start};{}$ ${}\|p\PP){}$\1\5
${}\\{out}(\\{isxalpha}({*}\|p)\?\.{'x'}:{*}\|p);{}$\2\6
\&{break};\6
\4${}\}{}$\2\6
\&{else} \&{if} (\\{is\_tiny}(\\{cur\_name})) \\{out}(\.{'|'}) \6
\&{else}\5
${}\{{}$\1\6
${}\\{delim}\K\.{'.'};{}$\6
\&{for} ${}(\|p\K\\{cur\_name}\MG\\{byte\_start};{}$ ${}\|p<(\\{cur\_name}+%
\T{1})\MG\\{byte\_start};{}$ ${}\|p\PP){}$\1\6
\&{if} ${}(\\{xislower}({*}\|p)){}$\5
${}\{{}$\C{ not entirely uppercase }\1\6
${}\\{delim}\K\.{'\\\\'};{}$\6
\&{break};\6
\4${}\}{}$\2\2\6
\\{out}(\\{delim});\6
\4${}\}{}$\2\6
$\}$ \&{else} \\{out}(\.{'\&'})\C{ \PB{$\|a\E\\{res\_word}$} }\6
\&{if} (\\{is\_tiny}(\\{cur\_name}))\5
${}\{{}$\1\6
\&{if} ${}(\\{isxalpha}((\\{cur\_name}\MG\\{byte\_start})[\T{0}])){}$\1\5
\\{out}(\.{'\\\\'});\2\6
${}\\{out}((\\{cur\_name}\MG\\{byte\_start})[\T{0}]);{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{out\_name}(\\{cur\_name});\2\par
\U221.\fi

\M{223}The current mode does not affect the behavior of \.{CWEAVE}'s output
routine
except when we are outputting control tokens.

\Y\B\4\X223:Output a control, look ahead in case of line breaks, possibly \PB{%
\&{goto} \\{reswitch}}\X${}\E{}$\6
\&{if} ${}(\|a<\\{break\_space}\V\|a\E\\{preproc\_line}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cur\_mode}\E\\{outer}){}$\5
${}\{{}$\1\6
\\{out}(\.{'\\\\'});\6
${}\\{out}(\|a-\\{cancel}+\.{'0'});{}$\6
\&{if} ${}(\|a\E\\{opt}){}$\5
${}\{{}$\1\6
${}\|b\K\\{get\_output}(\,){}$;\C{ \PB{\\{opt}} is followed by a digit }\6
\&{if} ${}(\|b\I\.{'0'}\V\\{force\_lines}\E\T{0}){}$\1\5
\\{out}(\|b)\2\6
\&{else}\1\5
\\{out\_str}(\.{"\{-1\}"});\C{ \PB{\\{force\_lines}} encourages more \.{@\v}
breaks }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|a\E\\{opt}){}$\1\5
${}\|b\K\\{get\_output}(\,){}$;\C{ ignore digit following \PB{\\{opt}} }\2\6
\4${}\}{}$\2\6
\&{else} \X224:Look ahead for strongest line break, \PB{\&{goto} \\{reswitch}}%
\X\par
\U221.\fi

\M{224}If several of the tokens \PB{\\{break\_space}}, \PB{\\{force}}, \PB{%
\\{big\_force}} occur in a
row, possibly mixed with blank spaces (which are ignored),
the largest one is used. A line break also occurs in the output file,
except at the very end of the translation. The very first line break
is suppressed (i.e., a line break that follows `\.{\\Y\\B}').

\Y\B\4\X224:Look ahead for strongest line break, \PB{\&{goto} \\{reswitch}}%
\X${}\E{}$\6
${}\{{}$\1\6
${}\|b\K\|a;{}$\6
${}\\{save\_mode}\K\\{cur\_mode};{}$\6
${}\|c\K\T{0};{}$\6
\&{while} (\T{1})\5
${}\{{}$\1\6
${}\|a\K\\{get\_output}(\,);{}$\6
\&{if} ${}(\|a\E\\{inserted}){}$\1\5
\&{continue};\2\6
\&{if} ${}(\|a\E\\{cancel}\V\|a\E\\{big\_cancel}){}$\5
${}\{{}$\1\6
\X225:Output saved \PB{\\{indent}} or \PB{\\{outdent}} tokens\X;\6
\&{goto} \\{reswitch};\C{ \PB{\\{cancel}} overrides everything }\6
\4${}\}{}$\2\6
\&{if} ${}((\|a\I\.{'\ '}\W\|a<\\{indent})\V\|a\E\\{backup}\V\|a>\\{big%
\_force}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{save\_mode}\E\\{outer}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{out\_ptr}>\\{out\_buf}+\T{3}\W(\\{strncmp}(\\{out\_ptr}-\T{3},\39%
\.{"\\\\Y\\\\B"},\39\T{4})\E\T{0}\V\\{strncmp}(\\{out\_ptr}-\T{5},\39\.{"%
\\\\par\\\\B"},\39\T{6})\E\T{0})){}$\1\5
\&{goto} \\{reswitch};\2\6
\X225:Output saved \PB{\\{indent}} or \PB{\\{outdent}} tokens\X;\6
\\{out}(\.{'\\\\'});\6
${}\\{out}(\|b-\\{cancel}+\.{'0'});{}$\6
\&{if} ${}(\|a\I\\{end\_translation}){}$\1\5
\\{finish\_line}(\,);\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|a\I\\{end\_translation}\W\\{cur\_mode}\E\\{inner}){}$\1\5
\\{out}(\.{'\ '});\2\6
\&{goto} \\{reswitch};\6
\4${}\}{}$\2\6
\&{if} ${}(\|a\E\\{indent}){}$\1\5
${}\|c\PP;{}$\2\6
\&{else} \&{if} ${}(\|a\E\\{outdent}){}$\1\5
${}\|c\MM;{}$\2\6
\&{else} \&{if} ${}(\|a\E\\{opt}){}$\1\5
${}\|a\K\\{get\_output}(\,);{}$\2\6
\&{else} \&{if} ${}(\|a>\|b){}$\1\5
${}\|b\K\|a{}$;\C{ if \PB{$\|a\E\.{'\ '}$} we have \PB{$\|a<\|b$} }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U223.\fi

\M{225}\B\X225:Output saved \PB{\\{indent}} or \PB{\\{outdent}} tokens\X${}%
\E{}$\6
\&{for} ( ; ${}\|c>\T{0};{}$ ${}\|c\MM){}$\1\5
\\{out\_str}(\.{"\\\\1"});\2\6
\&{for} ( ; ${}\|c<\T{0};{}$ ${}\|c\PP){}$\1\5
\\{out\_str}(\.{"\\\\2"});\2\par
\Us221\ET224.\fi

\M{226}The remaining part of \PB{\\{make\_output}} is somewhat more
complicated. When we
output a section name, we may need to enter the parsing and translation
routines, since the name may contain \CEE/ code embedded in
\pb\ constructions. This \CEE/ code is placed at the end of the active
input buffer and the translation process uses the end of the active
\PB{\\{tok\_mem}} area.

\Y\B\4\X226:Output a section name\X${}\E{}$\6
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\X"});\6
${}\\{cur\_xref}\K{}$(\&{xref\_pointer}) \\{cur\_name}${}\MG\\{xref};{}$\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\E\\{file\_flag}){}$\5
${}\{{}$\1\6
${}\\{an\_output}\K\T{1};{}$\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{an\_output}\K\T{0};{}$\2\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\G\\{def\_flag}){}$\5
${}\{{}$\1\6
${}\\{out\_section}(\\{cur\_xref}\MG\\{num}-\\{def\_flag});{}$\6
\&{if} ${}(\\{phase}\E\T{3}){}$\5
${}\{{}$\1\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\6
\&{while} ${}(\\{cur\_xref}\MG\\{num}\G\\{def\_flag}){}$\5
${}\{{}$\1\6
\\{out\_str}(\.{",\ "});\6
${}\\{out\_section}(\\{cur\_xref}\MG\\{num}-\\{def\_flag});{}$\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{out}(\.{'0'});\C{ output the section number, or zero if it was undefined }\2%
\6
\\{out}(\.{':'});\6
\&{if} (\\{an\_output})\1\5
\\{out\_str}(\.{"\\\\.\{"});\2\6
\X227:Output the text of the section name\X;\6
\&{if} (\\{an\_output})\1\5
\\{out\_str}(\.{"\ \}"});\2\6
\\{out\_str}(\.{"\\\\X"});\6
\4${}\}{}$\2\par
\U221.\fi

\M{227}\B\X227:Output the text of the section name\X${}\E{}$\6
$\\{sprint\_section\_name}(\\{scratch},\39\\{cur\_name});{}$\6
${}\|k\K\\{scratch};{}$\6
${}\\{k\_limit}\K\\{scratch}+\\{strlen}(\\{scratch});{}$\6
${}\\{cur\_section\_name}\K\\{cur\_name};$ \&{while} ${}(\|k<\\{k\_limit})$ $%
\{$ $\|b\K{*}(\|k\PP);{}$\6
\&{if} ${}(\|b\E\.{'@'}){}$\1\5
\X228:Skip next character, give error if not `\.{@}'\X;\2\6
\&{if} (\\{an\_output})\1\6
\&{switch} (\|b)\5
${}\{{}$\1\6
\4\&{case} \.{'\ '}:\5
\&{case} \.{'\\\\'}:\5
\&{case} \.{'\#'}:\5
\&{case} \.{'\%'}:\5
\&{case} \.{'\$'}:\5
\&{case} \.{'\^'}:\5
\&{case} \.{'\{'}:\5
\&{case} \.{'\}'}:\5
\&{case} \.{'\~'}:\5
\&{case} \.{'\&'}:\5
\&{case} \.{'\_'}:\5
\\{out}(\.{'\\\\'});\C{ falls through }\6
\4\&{default}:\5
\\{out}(\|b);\6
\4${}\}{}$\2\2\6
\&{else} \&{if} ${}(\|b\I\.{'|'})$ \\{out}(\|b) \6
\&{else}\5
${}\{{}$\1\6
\X229:Copy the \CEE/ text into the \PB{\\{buffer}} array\X;\6
${}\\{save\_loc}\K\\{loc};{}$\6
${}\\{save\_limit}\K\\{limit};{}$\6
${}\\{loc}\K\\{limit}+\T{2};{}$\6
${}\\{limit}\K\|j+\T{1};{}$\6
${}{*}\\{limit}\K\.{'|'};{}$\6
\\{output\_C}(\,);\6
${}\\{loc}\K\\{save\_loc};{}$\6
${}\\{limit}\K\\{save\_limit};{}$\6
\4${}\}{}$\2\6
$\}{}$\par
\U226.\fi

\M{228}\B\X228:Skip next character, give error if not `\.{@}'\X${}\E{}$\6
\&{if} ${}({*}\|k\PP\I\.{'@'}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\n!\ Illegal\ control}\)\.{\ code\ in\ section\ nam}\)\.{e:\
<"});\6
\\{print\_section\_name}(\\{cur\_section\_name});\6
\\{printf}(\.{">\ "});\6
\\{mark\_error};\6
\4${}\}{}$\2\par
\U227.\fi

\M{229}The \CEE/ text enclosed in \pb\ should not contain `\.{\v}' characters,
except within strings. We put a `\.{\v}' at the front of the buffer, so that an
error message that displays the whole buffer will look a little bit sensible.
The variable \PB{\\{delim}} is zero outside of strings, otherwise it
equals the delimiter that began the string being copied.

\Y\B\4\X229:Copy the \CEE/ text into the \PB{\\{buffer}} array\X${}\E{}$\6
$\|j\K\\{limit}+\T{1};{}$\6
${}{*}\|j\K\.{'|'};{}$\6
${}\\{delim}\K\T{0};$ \&{while} (\T{1}) $\{$ \6
\&{if} ${}(\|k\G\\{k\_limit}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\n!\ C\ text\ in\ secti}\)\.{on\ name\ didn't\ end:\ }\)%
\.{<"});\6
\\{print\_section\_name}(\\{cur\_section\_name});\6
\\{printf}(\.{">\ "});\6
\\{mark\_error};\6
\&{break};\6
\4${}\}{}$\2\6
${}\|b\K{*}(\|k\PP);$ \&{if} ${}(\|b\E\.{'@'}\V(\|b\E\.{'\\\\'}\W\\{delim}\I%
\T{0}))$ \X230:Copy a quoted character into the buffer\X \6
\&{else}\5
${}\{{}$\1\6
\&{if} ${}(\|b\E\.{'\\''}\V\|b\E\.{'"'}){}$\1\6
\&{if} ${}(\\{delim}\E\T{0}){}$\1\5
${}\\{delim}\K\|b;{}$\2\6
\&{else} \&{if} ${}(\\{delim}\E\|b){}$\1\5
${}\\{delim}\K\T{0};{}$\2\2\6
\&{if} ${}(\|b\I\.{'|'}\V\\{delim}\I\T{0}){}$\5
${}\{{}$\1\6
\&{if} ${}(\|j>\\{buffer}+\\{long\_buf\_size}-\T{3}){}$\1\5
\\{overflow}(\.{"buffer"});\2\6
${}{*}(\PP\|j)\K\|b;{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
\&{break};\2\6
\4${}\}{}$\2\6
$\}{}$\par
\U227.\fi

\M{230}\B\X230:Copy a quoted character into the buffer\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\|j>\\{buffer}+\\{long\_buf\_size}-\T{4}){}$\1\5
\\{overflow}(\.{"buffer"});\2\6
${}{*}(\PP\|j)\K\|b;{}$\6
${}{*}(\PP\|j)\K{*}(\|k\PP);{}$\6
\4${}\}{}$\2\par
\U229.\fi

\N{0}{231}Phase two processing.
We have assembled enough pieces of the puzzle in order to be ready to specify
the processing in \.{CWEAVE}'s main pass over the source file. Phase two
is analogous to phase one, except that more work is involved because we must
actually output the \TEX/ material instead of merely looking at the
\.{CWEB} specifications.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{phase\_two}(\,);\par
\fi

\M{232}\B\&{void} \\{phase\_two}(\,)\1\1\2\2\6
${}\{{}$\1\6
\\{reset\_input}(\,);\6
\&{if} (\\{show\_progress})\1\5
\\{printf}(\.{"\\nWriting\ the\ outpu}\)\.{t\ file..."});\2\6
${}\\{section\_count}\K\T{0};{}$\6
${}\\{format\_visible}\K\T{1};{}$\6
\\{copy\_limbo}(\,);\6
\\{finish\_line}(\,);\6
${}\\{flush\_buffer}(\\{out\_buf},\39\T{0},\39\T{0}){}$;\C{ insert a blank
line, it looks nice }\6
\&{while} ${}(\R\\{input\_has\_ended}){}$\1\5
\X235:Translate the current section\X;\2\6
\4${}\}{}$\2\par
\fi

\M{233}The output file will contain the control sequence \.{\\Y} between
non-null
sections of a section, e.g., between the \TEX/ and definition parts if both
are nonempty. This puts a little white space between the parts when they are
printed. However, we don't want \.{\\Y} to occur between two definitions
within a single section. The variables \PB{\\{out\_line}} or \PB{\\{out\_ptr}}
will
change if a section is non-null, so the following macros `\PB{\\{save%
\_position}}'
and `\PB{\\{emit\_space\_if\_needed}}' are able to handle the situation:

\Y\B\4\D$\\{save\_position}$ \5
$\\{save\_line}\K\\{out\_line};$ $\\{save\_place}\K{}$\\{out\_ptr}\par
\B\4\D$\\{emit\_space\_if\_needed}$ \6
\&{if} ${}(\\{save\_line}\I\\{out\_line}\V\\{save\_place}\I\\{out\_ptr}){}$\1\5
\\{out\_str}(\.{"\\\\Y"});\2\6
$\\{space\_checked}\K{}$\T{1}\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{int} \\{save\_line};\C{ former value of \PB{\\{out\_line}} }\6
\&{char} ${}{*}\\{save\_place}{}$;\C{ former value of \PB{\\{out\_ptr}} }\6
\&{int} \\{sec\_depth};\C{ the integer, if any, following \.{@*} }\6
\&{boolean} \\{space\_checked};\C{ have we done \PB{\\{emit\_space\_if%
\_needed}}? }\6
\&{boolean} \\{format\_visible};\C{ should the next format declaration be
output? }\6
\&{boolean} \\{doing\_format}${}\K\T{0}{}$;\C{ are we outputting a format
declaration? }\6
\&{boolean} \\{group\_found}${}\K\T{0}{}$;\C{ has a starred section occurred? }%
\par
\fi

\M{234}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{doing\_format}\K\\{group\_found}\K\T{0}{}$;\par
\fi

\M{235}\B\X235:Translate the current section\X${}\E{}$\6
${}\{{}$\1\6
${}\\{section\_count}\PP;{}$\6
\X236:Output the code for the beginning of a new section\X;\6
\\{save\_position};\6
\X237:Translate the \TEX/ part of the current section\X;\6
\X239:Translate the definition part of the current section\X;\6
\X245:Translate the \CEE/ part of the current section\X;\6
\X248:Show cross-references to this section\X;\6
\X252:Output the code for the end of a section\X;\6
\4${}\}{}$\2\par
\U232.\fi

\M{236}Sections beginning with the \.{CWEB} control sequence `\.{@\ }' start in
the
output with the \TEX/ control sequence `\.{\\M}', followed by the section
number. Similarly, `\.{@*}' sections lead to the control sequence `\.{\\N}'.
In this case there's an additional parameter, representing one plus the
specified depth, immediately after the \.{\\N}.
If the section has changed, we put \.{\\*} just after the section number.

\Y\B\4\X236:Output the code for the beginning of a new section\X${}\E{}$\6
\&{if} ${}({*}(\\{loc}-\T{1})\I\.{'*'}){}$\1\5
\\{out\_str}(\.{"\\\\M"});\2\6
\&{else}\5
${}\{{}$\1\6
\&{while} ${}({*}\\{loc}\E\.{'\ '}){}$\1\5
${}\\{loc}\PP;{}$\2\6
\&{if} ${}({*}\\{loc}\E\.{'*'}){}$\5
${}\{{}$\C{ ``top'' level }\1\6
${}\\{sec\_depth}\K{-}\T{1};{}$\6
${}\\{loc}\PP;{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{for} ${}(\\{sec\_depth}\K\T{0};{}$ ${}\\{xisdigit}({*}\\{loc});{}$ ${}%
\\{loc}\PP){}$\1\5
${}\\{sec\_depth}\K\\{sec\_depth}*\T{10}+({*}\\{loc})-\.{'0'};{}$\2\6
\4${}\}{}$\2\6
\&{while} ${}({*}\\{loc}\E\.{'\ '}){}$\1\5
${}\\{loc}\PP{}$;\C{ remove spaces before group title }\2\6
${}\\{group\_found}\K\T{1};{}$\6
\\{out\_str}(\.{"\\\\N"});\6
${}\{{}$\5
\1\&{char} \|s[\T{32}];\5
${}\\{sprintf}(\|s,\39\.{"\{\%d\}"},\39\\{sec\_depth}+\T{1}){}$;\5
\\{out\_str}(\|s);\5
${}\}{}$\2\6
\&{if} (\\{show\_progress})\1\5
${}\\{printf}(\.{"*\%d"},\39\\{section\_count});{}$\2\6
\\{update\_terminal};\C{ print a progress report }\6
\4${}\}{}$\2\6
\\{out\_str}(\.{"\{"});\6
\\{out\_section}(\\{section\_count});\6
\\{out\_str}(\.{"\}"});\par
\U235.\fi

\M{237}In the \TEX/ part of a section, we simply copy the source text, except
that
index entries are not copied and \CEE/ text within \pb\ is translated.

\Y\B\4\X237:Translate the \TEX/ part of the current section\X${}\E{}$\6
\&{do}\5
${}\{{}$\1\6
${}\\{next\_control}\K\copyxTeX(\,);{}$\6
\&{switch} (\\{next\_control})\5
${}\{{}$\1\6
\4\&{case} \.{'|'}:\5
\\{init\_stack};\6
\\{output\_C}(\,);\6
\&{break};\6
\4\&{case} \.{'@'}:\5
\\{out}(\.{'@'});\6
\&{break};\6
\4\&{case} ${}\TeXxstring:{}$\5
\&{case} \\{noop}:\5
\&{case} \\{xref\_roman}:\5
\&{case} \\{xref\_wildcard}:\5
\&{case} \\{xref\_typewriter}:\5
\&{case} \\{section\_name}:\5
${}\\{loc}\MRL{-{\K}}\T{2};{}$\6
${}\\{next\_control}\K\\{get\_next}(\,){}$;\C{ skip to \.{@>} }\6
\&{if} ${}(\\{next\_control}\E\TeXxstring){}$\1\5
\\{err\_print}(\.{"!\ TeX\ string\ should}\)\.{\ be\ in\ C\ text\ only"});\2\6
\&{break};\6
\4\&{case} \\{thin\_space}:\5
\&{case} \\{math\_break}:\5
\&{case} \\{ord}:\5
\&{case} \\{line\_break}:\5
\&{case} \\{big\_line\_break}:\5
\&{case} \\{no\_line\_break}:\5
\&{case} \\{join}:\5
\&{case} \\{pseudo\_semi}:\5
\&{case} \\{macro\_arg\_open}:\5
\&{case} \\{macro\_arg\_close}:\5
\&{case} \\{output\_defs\_code}:\5
\\{err\_print}(\.{"!\ You\ can't\ do\ that}\)\.{\ in\ TeX\ text"});\6
\&{break};\6
\4\&{case} \\{autodoc\_code}:\5
\\{process\_autodoc}(\,);\6
\&{break};\6
\4\&{case} \\{example\_code}:\5
\\{process\_example}(\,);\6
\&{break};\6
\4\&{case} \\{special\_command}:\5
\X238:Special command seen in \TeX{} part (phase two)\X;\6
\&{break};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\5
\&{while} ${}(\\{next\_control}<\\{format\_code}){}$;\par
\U235.\fi

\M{238}%mine
If we see one of the \.{mCWEAVE} specific commands introduced by
\.{@\_} while scanning \TeX\ text in phase two, we have to see if
it's a mark/copy/paste construct.
\Y\B\4\X238:Special command seen in \TeX{} part (phase two)\X${}\E{}$\6
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\C{ get name of command }\1\6
\&{name\_pointer} \|p${}\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39%
\\{normal});{}$\7
\&{if} ${}(\|p\E\\{id\_paste}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\K\T{0};{}$\6
\\{paste}(\\{id\_first});\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{err\_print}(\.{"!\ Name\ of\ copy\ buff}\)\.{er\ expected"});\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_mark}){}$\1\5
${}\\{next\_control}\K\\{get\_next}(\,){}$;\C{ skip it }\2\6
\&{else} \&{if} ${}(\|p\I\\{id\_copy}){}$\1\5
\\{err\_print}(\.{"!\ Illegal\ special\ c}\)\.{ommand\ in\ TeX\ text"});\2\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{err\_print}(\.{"!\ Name\ of\ special\ c}\)\.{ommand\ expected"});\2\6
\4${}\}{}$\2\par
\U237.\fi

\M{239}When we get to the following code we have \PB{$\\{next\_control}\G%
\\{format\_code}$}, and
the token memory is in its initial empty state.

\Y\B\4\X239:Translate the definition part of the current section\X${}\E{}$\6
$\\{space\_checked}\K\T{0};{}$\6
\&{while} ${}(\\{next\_control}\Z\\{definition}){}$\5
${}\{{}$\C{ \PB{\\{format\_code}} or \PB{\\{definition}} }\1\6
\\{init\_stack};\6
\&{if} ${}(\\{next\_control}\E\\{definition}){}$\1\5
\X242:Start a macro definition\X\2\6
\&{else}\1\5
\X243:Start a format definition\X;\2\6
\\{outer\_parse}(\,);\6
\\{finish\_C}(\\{format\_visible});\6
${}\\{format\_visible}\K\T{1};{}$\6
${}\\{doing\_format}\K\T{0};{}$\6
\4${}\}{}$\2\par
\U235.\fi

\M{240}The \PB{\\{finish\_C}} procedure outputs the translation of the current
scraps, preceded by the control sequence `\.{\\B}' and followed by the
control sequence `\.{\\par}'. It also restores the token and scrap
memories to their initial empty state.

A \PB{\\{force}} token is appended to the current scraps before translation
takes place, so that the translation will normally end with \.{\\6} or
\.{\\7} (the \TEX/ macros for \PB{\\{force}} and \PB{\\{big\_force}}). This \.{%
\\6} or
\.{\\7} is replaced by the concluding \.{\\par} or by \.{\\Y\\par}.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{finish\_C}(\,);\par
\fi

\M{241}\B\&{void} \\{finish\_C}(\\{visible})\C{ finishes a definition or a %
\CEE/ part }\1\1\6
\&{boolean} \\{visible};\C{ nonzero if we should produce \TEX/ output }\2\2\6
${}\{{}$\1\6
\&{text\_pointer} \|p;\C{ translation of the scraps }\7
\&{if} (\\{visible})\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\B"});\6
\\{app\_tok}(\\{force});\6
${}\\{app\_scrap}(\\{insert},\39\\{no\_math});{}$\6
${}\|p\K\\{translate}(\,);{}$\6
${}\\{app}(\\{tok\_flag}+{}$(\&{int}) ${}(\|p-\\{tok\_start}));{}$\6
\\{make\_output}(\,);\C{ output the list }\6
\&{if} ${}(\\{out\_ptr}>\\{out\_buf}+\T{1}){}$\1\6
\&{if} ${}({*}(\\{out\_ptr}-\T{1})\E\.{'\\\\'}){}$\1\6
\&{if} ${}({*}\\{out\_ptr}\E\.{'6'}){}$\1\5
${}\\{out\_ptr}\MRL{-{\K}}\T{2};{}$\2\6
\&{else} \&{if} ${}({*}\\{out\_ptr}\E\.{'7'}){}$\1\5
${}{*}\\{out\_ptr}\K\.{'Y'};{}$\2\2\2\6
\\{out\_str}(\.{"\\\\par"});\6
\\{finish\_line}(\,);\6
\4${}\}{}$\2\6
\&{if} ${}(\\{text\_ptr}>\\{max\_text\_ptr}){}$\1\5
${}\\{max\_text\_ptr}\K\\{text\_ptr};{}$\2\6
\&{if} ${}(\\{tok\_ptr}>\\{max\_tok\_ptr}){}$\1\5
${}\\{max\_tok\_ptr}\K\\{tok\_ptr};{}$\2\6
\&{if} ${}(\\{scrap\_ptr}>\\{max\_scr\_ptr}){}$\1\5
${}\\{max\_scr\_ptr}\K\\{scrap\_ptr};{}$\2\6
${}\\{tok\_ptr}\K\\{tok\_mem}+\T{1};{}$\6
${}\\{text\_ptr}\K\\{tok\_start}+\T{1};{}$\6
${}\\{scrap\_ptr}\K\\{scrap\_info}{}$;\C{ forget the tokens and the scraps }\6
\4${}\}{}$\2\par
\fi

\M{242}Keeping in line with the conventions of the \CEE/ preprocessor (and
otherwise contrary to the rules of \.{CWEB}) we distinguish here
between the case that `\.(' immediately follows an identifier and the
case that the two are separated by a space.  In the latter case, and
if the identifier is not followed by `\.(' at all, the replacement
text starts immediately after the identifier.  In the former case,
it starts after we scan the matching `\.)'.

\Y\B\4\X242:Start a macro definition\X${}\E{}$\6
${}\{{}$\1\6
\&{name\_pointer} \|p;\7
\&{if} ${}(\\{save\_line}\I\\{out\_line}\V\\{save\_place}\I\\{out\_ptr}\V%
\\{space\_checked}){}$\1\5
\\{app}(\\{backup});\2\6
\&{if} ${}(\R\\{space\_checked}){}$\5
${}\{{}$\1\6
\\{emit\_space\_if\_needed};\6
\\{save\_position};\6
\4${}\}{}$\2\6
\\{app\_str}(\.{"\\\\D"});\C{ this will produce `\&{define }' }\6
\&{while} ${}((\\{next\_control}\K\\{get\_next}(\,))\E\\{special\_command}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\I\\{identifier}){}$\1\5
\&{break};\2\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_global}\V\|p\E\\{id\_shared}\V\|p\E\\{id\_export}){}$\5
${}\{{}$\1\6
${}\\{app}(\\{res\_flag}+{}$(\&{int}) ${}(\|p-\\{name\_dir}));{}$\6
\\{app}(\.{'\ '});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\\{next\_control}\I\\{identifier}){}$\1\5
\\{err\_print}(\.{"!\ Improper\ macro\ de}\)\.{finition"});\2\6
\&{else}\5
${}\{{}$\1\6
\\{app}(\.{'\$'});\6
\\{app\_cur\_id}(\T{0});\6
\&{if} ${}({*}\\{loc}\E\.{'('}){}$\1\6
\4\\{reswitch}:\6
\&{switch} ${}(\\{next\_control}\K\\{get\_next}(\,)){}$\5
${}\{{}$\1\6
\4\&{case} \.{'('}:\5
\&{case} \.{','}:\5
\\{app}(\\{next\_control});\6
\&{goto} \\{reswitch};\6
\4\&{case} \\{identifier}:\5
\\{app\_cur\_id}(\T{0});\6
\&{goto} \\{reswitch};\6
\4\&{case} \.{')'}:\5
\\{app}(\\{next\_control});\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{break};\6
\4\&{default}:\5
\\{err\_print}(\.{"!\ Improper\ macro\ de}\)\.{finition"});\6
\&{break};\6
\4${}\}{}$\2\2\6
\&{else}\1\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\2\6
\\{app\_str}(\.{"\$\ "});\6
\\{app}(\\{break\_space});\6
${}\\{app\_scrap}(\\{dead},\39\\{no\_math}){}$;\C{ scrap won't take part in the
parsing }\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\Us210\ET239.\fi

\M{243}\B\X243:Start a format definition\X${}\E{}$\6
${}\{{}$\1\6
${}\\{doing\_format}\K\T{1};{}$\6
\&{if} ${}({*}(\\{loc}-\T{1})\E\.{'s'}\V{*}(\\{loc}-\T{1})\E\.{'S'}){}$\1\5
${}\\{format\_visible}\K\T{0};{}$\2\6
\&{if} ${}(\R\\{space\_checked}){}$\5
${}\{{}$\1\6
\\{emit\_space\_if\_needed};\6
\\{save\_position};\6
\4${}\}{}$\2\6
\\{app\_str}(\.{"\\\\F"});\C{ this will produce `\&{format }' }\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\\{app}(\\{id\_flag}+{}$(\&{int}) ${}(\\{id\_lookup}(\\{id\_first},\39\\{id%
\_loc},\39\\{normal})-\\{name\_dir}));{}$\6
\\{app}(\.{'\ '});\6
\\{app}(\\{break\_space});\C{ this is syntactically separate from what follows
}\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\\{app}(\\{id\_flag}+{}$(\&{int}) ${}(\\{id\_lookup}(\\{id\_first},\39\\{id%
\_loc},\39\\{normal})-\\{name\_dir}));{}$\6
${}\\{app\_scrap}(\\{exp},\39\\{maybe\_math});{}$\6
${}\\{app\_scrap}(\\{semi},\39\\{maybe\_math});{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\\{scrap\_ptr}\I\\{scrap\_info}+\T{2}){}$\1\5
\\{err\_print}(\.{"!\ Improper\ format\ d}\)\.{efinition"});\2\6
\4${}\}{}$\2\par
\U239.\fi

\M{244}Finally, when the \TEX/ and definition parts have been treated, we have
\PB{$\\{next\_control}\G\\{begin\_C}$}. We will make the global variable \PB{%
\\{this\_section}}
point to the current section name, if it has a name.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{name\_pointer} \\{this\_section};\C{ the current section name, or zero }\par
\fi

\M{245}\B\X245:Translate the \CEE/ part of the current section\X${}\E{}$\6
$\\{this\_section}\K\\{name\_dir};{}$\6
\&{if} ${}(\\{next\_control}\Z\\{section\_name}){}$\5
${}\{{}$\1\6
\\{emit\_space\_if\_needed};\6
\\{init\_stack};\6
\&{if} ${}(\\{next\_control}\E\\{begin\_C}){}$\1\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{this\_section}\K\\{cur\_section};{}$\6
\X246:Check that '=' or '==' follows this section name, and emit the scraps to
start the section definition\X;\6
\4${}\}{}$\2\6
\&{while} ${}(\\{next\_control}\Z\\{section\_name}){}$\5
${}\{{}$\1\6
\\{outer\_parse}(\,);\6
\X247:Emit the scrap for a section name if present\X;\6
\4${}\}{}$\2\6
\\{finish\_C}(\T{1});\6
\4${}\}{}$\2\par
\U235.\fi

\M{246}The title of the section and an $\E$ or $\mathrel+\E$ are made
into a scrap that should not take part in the parsing.

\Y\B\4\X246:Check that '=' or '==' follows this section name, and emit the
scraps to start the section definition\X${}\E{}$\6
\&{do}\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\5
\&{while} ${}(\\{next\_control}\E\.{'+'}){}$;\C{ allow optional `\.{+=}' }\6
\&{if} ${}(\\{next\_control}\I\.{'='}\W\\{next\_control}\I\\{eq\_eq}){}$\1\5
\\{err\_print}(\.{"!\ You\ need\ an\ =\ sig}\)\.{n\ after\ the\ section\ }\)%
\.{name"});\2\6
\&{else}\1\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\2\6
\&{if} ${}(\\{out\_ptr}>\\{out\_buf}+\T{1}\W{*}\\{out\_ptr}\E\.{'Y'}\W{*}(%
\\{out\_ptr}-\T{1})\E\.{'\\\\'}){}$\1\5
\\{app}(\\{backup});\C{ the section name will be flush left }\2\6
${}\\{app}(\\{section\_flag}+{}$(\&{int}) ${}(\\{this\_section}-\\{name%
\_dir}));{}$\6
${}\\{cur\_xref}\K{}$(\&{xref\_pointer}) \\{this\_section}${}\MG\\{xref};{}$\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\E\\{file\_flag}){}$\1\5
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\2\6
\\{app\_str}(\.{"\$\{\}"});\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\I\\{section\_count}+\\{def\_flag}){}$\5
${}\{{}$\1\6
\\{app\_str}(\.{"\\\\mathrel+"});\C{section name is multiply defined}\6
${}\\{this\_section}\K\\{name\_dir}{}$;\C{so we won't give cross-reference info
here}\6
\4${}\}{}$\2\6
\\{app\_str}(\.{"\\\\E"});\C{ output an equivalence sign }\6
\\{app\_str}(\.{"\{\}\$"});\6
\\{app}(\\{force});\6
${}\\{app\_scrap}(\\{dead},\39\\{no\_math}){}$;\C{ this forces a line break
unless `\.{@+}' follows }\par
\U245.\fi

\M{247}\B\X247:Emit the scrap for a section name if present\X${}\E{}$\6
\&{if} ${}(\\{next\_control}<\\{section\_name}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ You\ can't\ do\ that}\)\.{\ in\ C\ text"});\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\\{section\_name}){}$\5
${}\{{}$\1\6
${}\\{app}(\\{section\_flag}+{}$(\&{int}) ${}(\\{cur\_section}-\\{name%
\_dir}));{}$\6
${}\\{app\_scrap}(\\{section\_scrap},\39\\{maybe\_math});{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\par
\U245.\fi

\M{248}Cross references relating to a named section are given
after the section ends.

\Y\B\4\X248:Show cross-references to this section\X${}\E{}$\6
\&{if} ${}(\\{this\_section}>\\{name\_dir}){}$\5
${}\{{}$\1\6
${}\\{cur\_xref}\K{}$(\&{xref\_pointer}) \\{this\_section}${}\MG\\{xref};{}$\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\E\\{file\_flag}){}$\5
${}\{{}$\1\6
${}\\{an\_output}\K\T{1};{}$\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}\\{an\_output}\K\T{0};{}$\2\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}>\\{def\_flag}){}$\1\5
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink}{}$;\C{ bypass current section
number }\2\6
\\{footnote}(\\{def\_flag});\6
\\{footnote}(\\{cite\_flag});\6
\\{footnote}(\T{0});\6
\4${}\}{}$\2\par
\U235.\fi

\M{249}The \PB{\\{footnote}} procedure gives cross-reference information about
multiply defined section names (if the \PB{\\{flag}} parameter is
\PB{\\{def\_flag}}), or about references to a section name
(if \PB{$\\{flag}\E\\{cite\_flag}$}), or to its uses (if \PB{$\\{flag}\E%
\T{0}$}). It assumes that
\PB{\\{cur\_xref}} points to the first cross-reference entry of interest, and
it
leaves \PB{\\{cur\_xref}} pointing to the first element not printed.  Typical
outputs:
`\.{\\A101.}'; `\.{\\Us 370\\ET1009.}';
`\.{\\As 8, 27\\*\\ETs64.}'.

Note that the output of \.{CWEAVE} is not English-specific; users may
supply new definitions for the macros \.{\\A}, \.{\\As}, etc.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{footnote}(\,);\par
\fi

\M{250}\B\&{void} \\{footnote}(\\{flag})\C{ outputs section cross-references }%
\1\1\6
\&{sixteen\_bits} \\{flag};\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \|q;\C{ cross-reference pointer variable }\7
\&{if} ${}(\\{cur\_xref}\MG\\{num}\Z\\{flag}){}$\1\5
\&{return};\2\6
\\{finish\_line}(\,);\6
\\{out}(\.{'\\\\'});\6
${}\\{out}(\\{flag}\E\T{0}\?\.{'U'}:\\{flag}\E\\{cite\_flag}\?\.{'Q'}:%
\.{'A'});{}$\6
\X251:Output all the section numbers on the reference list \PB{\\{cur\_xref}}%
\X;\6
\\{out}(\.{'.'});\6
\4${}\}{}$\2\par
\fi

\M{251}The following code distinguishes three cases, according as the number
of cross-references is one, two, or more than two. Variable \PB{\|q} points
to the first cross-reference, and the last link is a zero.

\Y\B\4\X251:Output all the section numbers on the reference list \PB{\\{cur%
\_xref}}\X${}\E{}$\6
$\|q\K\\{cur\_xref};{}$\6
\&{if} ${}(\|q\MG\\{xlink}\MG\\{num}>\\{flag}){}$\1\5
\\{out}(\.{'s'});\C{ plural }\2\6
\&{while} (\T{1})\5
${}\{{}$\1\6
${}\\{out\_section}(\\{cur\_xref}\MG\\{num}-\\{flag});{}$\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink}{}$;\C{ point to the next
cross-reference to output }\6
\&{if} ${}(\\{cur\_xref}\MG\\{num}\Z\\{flag}){}$\1\5
\&{break};\2\6
\&{if} ${}(\\{cur\_xref}\MG\\{xlink}\MG\\{num}>\\{flag}){}$\1\5
\\{out\_str}(\.{",\ "});\C{ not the last }\2\6
\&{else}\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\ET"});\C{ the last }\6
\&{if} ${}(\\{cur\_xref}\I\|q\MG\\{xlink}){}$\1\5
\\{out}(\.{'s'});\C{ the last of more than two }\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U250.\fi

\M{252}\B\X252:Output the code for the end of a section\X${}\E{}$\6
\\{out\_str}(\.{"\\\\fi"});\6
\\{finish\_line}(\,);\6
${}\\{flush\_buffer}(\\{out\_buf},\39\T{0},\39\T{0}){}$;\C{ insert a blank
line, it looks nice }\par
\U235.\fi

\N{0}{253}Phase three processing.
We are nearly finished! \.{CWEAVE}'s only remaining task is to write out the
index, after sorting the identifiers and index entries.

If the user has set the \PB{\\{no\_xref}} flag (the \.{-x} option on the
command line),
just finish off the page, omitting the index, section name list, and table of
contents.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{phase\_three}(\,);\par
\fi

\M{254}\B\&{void} \\{phase\_three}(\,)\1\1\2\2\6
${}\{{}$\1\6
${}\\{make\_xid\_file}(\.{".xid"},\39\\{own\_export});{}$\6
${}\\{make\_xid\_file}(\.{".sid"},\39\\{own\_shared});{}$\6
\\{make\_iid\_file}(\,);\6
\&{if} (\\{no\_xref})\5
${}\{{}$\1\6
\\{finish\_line}(\,);\6
\&{if} ${}(\R\\{book\_type}){}$\1\5
\\{out\_str}(\.{"\\\\end"});\2\6
\\{finish\_line}(\,);\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{phase}\K\T{3};{}$\6
\&{if} (\\{show\_progress})\1\5
\\{printf}(\.{"\\nWriting\ the\ index}\)\.{..."});\2\6
\\{finish\_line}(\,);\6
\&{if} ${}((\\{idx\_file}\K\\{fopen}(\\{idx\_file\_name},\39\.{"w"}))\E%
\NULL){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ open\ index}\)\.{\ file\ "},\39\\{idx\_file%
\_name});{}$\2\6
\&{if} (\\{change\_exists})\5
${}\{{}$\1\6
\X256:Tell about changed sections\X;\6
\\{finish\_line}(\,);\6
\\{finish\_line}(\,);\6
\4${}\}{}$\2\6
\\{out\_str}(\.{"\\\\inx"});\6
\\{finish\_line}(\,);\6
${}\\{active\_file}\K\\{idx\_file}{}$;\C{ change active file to the index file
}\6
\X258:Do the first pass of sorting\X;\6
\X267:Sort and output the index\X;\6
\\{output\_referenced\_books}(\,);\6
\\{finish\_line}(\,);\6
\\{fclose}(\\{active\_file});\C{ finished with \PB{\\{idx\_file}} }\6
${}\\{active\_file}\K\\{tex\_file}{}$;\C{ switch back to \PB{\\{tex\_file}} for
a tic }\6
\\{out\_str}(\.{"\\\\fin"});\6
\\{finish\_line}(\,);\6
\&{if} ${}((\\{scn\_file}\K\\{fopen}(\\{scn\_file\_name},\39\.{"w"}))\E%
\NULL){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ open\ secti}\)\.{on\ file\ "},\39\\{scn\_file%
\_name});{}$\2\6
${}\\{active\_file}\K\\{scn\_file}{}$;\C{ change active file to section listing
file }\6
\X283:Output all the section names\X;\6
\\{finish\_line}(\,);\6
\\{fclose}(\\{active\_file});\C{ finished with \PB{\\{scn\_file}} }\6
${}\\{active\_file}\K\\{tex\_file};{}$\6
\&{if} ${}(\\{group\_found}\W\R\\{book\_type}){}$\1\5
\\{out\_str}(\.{"\\\\con"});\2\6
\&{if} ${}(\R\\{book\_type}){}$\1\5
\\{out\_str}(\.{"\\\\end"});\2\6
\&{else}\1\5
\\{out\_str}(\.{"\\\\eject"});\2\6
\\{finish\_line}(\,);\6
\\{fclose}(\\{active\_file});\6
\4${}\}{}$\2\6
\&{if} (\\{show\_happiness})\1\5
\\{printf}(\.{"\\nDone."});\2\6
\\{check\_complete}(\,);\C{ was all of the change file used? }\6
\4${}\}{}$\2\par
\fi

\M{255}Just before the index comes a list of all the changed sections,
including
the index section itself.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{sixteen\_bits} \\{k\_section};\C{ runs through the sections }\par
\fi

\M{256}\B\X256:Tell about changed sections\X${}\E{}$\6
${}\{{}$\C{ remember that the index is already marked as changed }\1\6
${}\\{k\_section}\K\T{0};{}$\6
\&{while} ${}(\R\\{changed\_section}[\PP\\{k\_section}]){}$\1\5
;\2\6
\\{out\_str}(\.{"\\\\ch\ "});\6
\\{out\_section}(\\{k\_section});\6
\&{while} ${}(\\{k\_section}<\\{section\_count}){}$\5
${}\{{}$\1\6
\&{while} ${}(\R\\{changed\_section}[\PP\\{k\_section}]){}$\1\5
;\2\6
\\{out\_str}(\.{",\ "});\6
\\{out\_section}(\\{k\_section});\6
\4${}\}{}$\2\6
\\{out}(\.{'.'});\6
\4${}\}{}$\2\par
\U254.\fi

\M{257}A left-to-right radix sorting method is used, since this makes it easy
to
adjust the collating sequence and since the running time will be at worst
proportional to the total length of all entries in the index. We put the
identifiers into 102 different lists based on their first characters.
(Uppercase letters are put into the same list as the corresponding lowercase
letters, since we want to have `$t<\\{TeX}<\&{to}$'.) The
list for character \PB{\|c} begins at location \PB{\\{bucket}[\|c]} and
continues through
the \PB{\\{blink}} array.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{name\_pointer} \\{bucket}[\T{256}];\6
\&{name\_pointer} \\{next\_name};\C{ successor of \PB{\\{cur\_name}} when
sorting }\6
\&{name\_pointer} \\{blink}[\\{max\_names}];\C{ links in the buckets }\par
\fi

\M{258}To begin the sorting, we go through all the hash lists and put each
entry
having a nonempty cross-reference list into the proper bucket.

\Y\B\4\X258:Do the first pass of sorting\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \|c;\7
\&{for} ${}(\|c\K\T{0};{}$ ${}\|c\Z\T{255};{}$ ${}\|c\PP){}$\1\5
${}\\{bucket}[\|c]\K\NULL;{}$\2\6
\&{for} ${}(\|h\K\\{hash};{}$ ${}\|h\Z\\{hash\_end};{}$ ${}\|h\PP){}$\5
${}\{{}$\1\6
${}\\{next\_name}\K{*}\|h;{}$\6
\&{while} (\\{next\_name})\5
${}\{{}$\1\6
${}\\{cur\_name}\K\\{next\_name};{}$\6
${}\\{next\_name}\K\\{cur\_name}\MG\\{link};{}$\6
\&{if} ${}(\\{cur\_name}\MG\\{xref}\I{}$(\&{char} ${}{*}){}$ \\{xmem})\5
${}\{{}$\1\6
${}\|c\K{}$(\&{eight\_bits}) ${}((\\{cur\_name}\MG\\{byte\_start})[\T{0}]);{}$\6
\&{if} (\\{xisupper}(\|c))\1\5
${}\|c\K\\{tolower}(\|c);{}$\2\6
${}\\{blink}[\\{cur\_name}-\\{name\_dir}]\K\\{bucket}[\|c];{}$\6
${}\\{bucket}[\|c]\K\\{cur\_name};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\Us254\ET364.\fi

\M{259}During the sorting phase we shall use the \PB{\\{cat}} and \PB{%
\\{trans}} arrays from
\.{CWEAVE}'s parsing algorithm and rename them \PB{\\{depth}} and \PB{%
\\{head}}. They now
represent a stack of identifier lists for all the index entries that have
not yet been output. The variable \PB{\\{sort\_ptr}} tells how many such lists
are
present; the lists are output in reverse order (first \PB{\\{sort\_ptr}}, then
\PB{$\\{sort\_ptr}-\T{1}$}, etc.). The \PB{\|j}th list starts at \PB{\\{head}[%
\|j]}, and if the first
\PB{\|k} characters of all entries on this list are known to be equal we have
\PB{$\\{depth}[\|j]\E\|k$}.

\fi

\M{260}\B\X260:Rest of \PB{\\{trans\_plus}} union\X${}\E{}$\6
\&{name\_pointer} \\{Head};\par
\U116.\fi

\M{261}\B\D$\\{depth}$ \5
\\{cat}\C{ reclaims memory that is no longer needed for parsing }\par
\B\4\D$\\{head}$ \5
$\\{trans\_plus}.{}$\\{Head}\C{ ditto }\par
\B\F\\{sort\_pointer} \5
\\{int}\par
\B\4\D$\&{sort\_pointer}$ \5
\&{scrap\_pointer}\C{ ditto }\par
\B\4\D$\\{sort\_ptr}$ \5
\\{scrap\_ptr}\C{ ditto }\par
\B\4\D$\\{max\_sorts}$ \5
\\{max\_scraps}\C{ ditto }\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{eight\_bits} \\{cur\_depth};\C{ depth of current buckets }\6
\&{char} ${}{*}\\{cur\_byte}{}$;\C{ index into \PB{\\{byte\_mem}} }\6
\&{sixteen\_bits} \\{cur\_val};\C{ current cross-reference number }\6
\&{sort\_pointer} \\{max\_sort\_ptr};\C{ largest value of \PB{\\{sort\_ptr}} }%
\par
\fi

\M{262}\B\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{max\_sort\_ptr}\K\\{scrap\_info}{}$;\par
\fi

\M{263}The desired alphabetic order is specified by the \PB{\\{collate}} array;
namely,
\PB{$\\{collate}[\T{0}]<\\{collate}[\T{1}]\MRL{{<}{<}}\\{collate}[\T{100}]$}.

\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{eight\_bits} ${}\\{collate}[\T{102}+\T{128}]{}$;\C{ collation order }\par
\fi

\M{264}We use the order $\hbox{null}<\.\ <\hbox{other characters}<{}$\.\_${}<
\.A=\.a<\cdots<\.Z=\.z<\.0<\cdots<\.9.$ Warning: The collation mapping
needs to be changed if ASCII code is not being used.

\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{collate}[\T{0}]\K\T{0};{}$\6
${}\\{strcpy}(\\{collate}+\T{1},\39\.{"\ \\1\\2\\3\\4\\5\\6\\7\\10\\}\)\.{11%
\\12\\13\\14\\15\\16\\17}\)\.{\\20\\21\\22\\23\\24\\25\\2}\)\.{6\\27\\30\\31%
\\32\\33\\34\\}\)\.{35\\36\\37!\\42\#\$\%\&'()*}\)\.{+,-./:;<=>?@[\\\\]\^`\{|}%
\)\.{\}\~\_abcdefghijklmnopq}\)\.{rstuvwxyz0123456789\\}\)\.{200\\201\\202\\203%
\\204\\}\)\.{205\\206\\207\\210\\211\\}\)\.{212\\213\\214\\215\\216\\}\)\.{217%
\\220\\221\\222\\223\\}\)\.{224\\225\\226\\227\\230\\}\)\.{231\\232\\233\\234%
\\235\\}\)\.{236\\237\\240\\241\\242\\}\)\.{243\\244\\245\\246\\247\\}\)\.{250%
\\251\\252\\253\\254\\}\)\.{255\\256\\257\\260\\261\\}\)\.{262\\263\\264\\265%
\\266\\}\)\.{267\\270\\271\\272\\273\\}\)\.{274\\275\\276\\277\\300\\}\)\.{301%
\\302\\303\\304\\305\\}\)\.{306\\307\\310\\311\\312\\}\)\.{313\\314\\315\\316%
\\317\\}\)\.{320\\321\\322\\323\\324\\}\)\.{325\\326\\327\\330\\331\\}\)\.{332%
\\333\\334\\335\\336\\}\)\.{337\\340\\341\\342\\343\\}\)\.{344\\345\\346\\347%
\\350\\}\)\.{351\\352\\353\\354\\355\\}\)\.{356\\357\\360\\361\\362\\}\)\.{363%
\\364\\365\\366\\367\\}\)\.{370\\371\\372\\373\\374\\}\)\.{375\\376\\377"}){}$;%
\par
\fi

\M{265}Procedure \PB{\\{unbucket}} goes through the buckets and adds nonempty
lists
to the stack, using the collating sequence specified in the \PB{\\{collate}}
array.
The parameter to \PB{\\{unbucket}} tells the current depth in the buckets.
Any two sequences that agree in their first 255 character positions are
regarded as identical.

\Y\B\4\D$\\{infinity}$ \5
\T{255}\C{ $\infty$ (approximately) }\par
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{unbucket}(\,);\par
\fi

\M{266}\B\&{void} \\{unbucket}(\|d)\C{ empties buckets having depth \PB{\|d} }%
\1\1\6
\&{eight\_bits} \|d;\2\2\6
${}\{{}$\1\6
\&{int} \|c;\C{ index into \PB{\\{bucket}}; cannot be a simple \PB{\&{char}}
because of sign     comparison below}\7
\&{for} ${}(\|c\K\T{100}+\T{128};{}$ ${}\|c\G\T{0};{}$ ${}\|c\MM){}$\1\6
\&{if} (\\{bucket}[\\{collate}[\|c]])\5
${}\{{}$\1\6
\&{if} ${}(\\{sort\_ptr}\G\\{scrap\_info\_end}){}$\1\5
\\{overflow}(\.{"sorting"});\2\6
${}\\{sort\_ptr}\PP;{}$\6
\&{if} ${}(\\{sort\_ptr}>\\{max\_sort\_ptr}){}$\1\5
${}\\{max\_sort\_ptr}\K\\{sort\_ptr};{}$\2\6
\&{if} ${}(\|c\E\T{0}){}$\1\5
${}\\{sort\_ptr}\MG\\{depth}\K\\{infinity};{}$\2\6
\&{else}\1\5
${}\\{sort\_ptr}\MG\\{depth}\K\|d;{}$\2\6
${}\\{sort\_ptr}\MG\\{head}\K\\{bucket}[\\{collate}[\|c]];{}$\6
${}\\{bucket}[\\{collate}[\|c]]\K\NULL;{}$\6
\4${}\}{}$\2\2\6
\4${}\}{}$\2\par
\fi

\M{267}\B\X267:Sort and output the index\X${}\E{}$\6
$\\{sort\_ptr}\K\\{scrap\_info};{}$\6
\\{unbucket}(\T{1});\6
\&{while} ${}(\\{sort\_ptr}>\\{scrap\_info}){}$\5
${}\{{}$\1\6
${}\\{cur\_depth}\K\\{sort\_ptr}\MG\\{depth};{}$\6
\&{if} ${}(\\{blink}[\\{sort\_ptr}\MG\\{head}-\\{name\_dir}]\E\T{0}\V\\{cur%
\_depth}\E\\{infinity}){}$\1\5
\X269:Output index entries for the list at \PB{\\{sort\_ptr}}\X\2\6
\&{else}\1\5
\X268:Split the list at \PB{\\{sort\_ptr}} into further lists\X;\2\6
\4${}\}{}$\2\par
\Us254\ET364.\fi

\M{268}\B\X268:Split the list at \PB{\\{sort\_ptr}} into further lists\X${}%
\E{}$\6
${}\{{}$\1\6
\&{eight\_bits} \|c;\7
${}\\{next\_name}\K\\{sort\_ptr}\MG\\{head};{}$\6
\&{do}\5
${}\{{}$\1\6
${}\\{cur\_name}\K\\{next\_name};{}$\6
${}\\{next\_name}\K\\{blink}[\\{cur\_name}-\\{name\_dir}];{}$\6
${}\\{cur\_byte}\K\\{cur\_name}\MG\\{byte\_start}+\\{cur\_depth};{}$\6
\&{if} ${}(\\{cur\_byte}\E(\\{cur\_name}+\T{1})\MG\\{byte\_start}){}$\1\5
${}\|c\K\T{0}{}$;\C{ hit end of the name }\2\6
\&{else}\5
${}\{{}$\1\6
${}\|c\K{}$(\&{eight\_bits}) ${}{*}\\{cur\_byte};{}$\6
\&{if} (\\{xisupper}(\|c))\1\5
${}\|c\K\\{tolower}(\|c);{}$\2\6
\4${}\}{}$\2\6
${}\\{blink}[\\{cur\_name}-\\{name\_dir}]\K\\{bucket}[\|c];{}$\6
${}\\{bucket}[\|c]\K\\{cur\_name};{}$\6
\4${}\}{}$\2\5
\&{while} (\\{next\_name});\6
${}\MM\\{sort\_ptr};{}$\6
${}\\{unbucket}(\\{cur\_depth}+\T{1});{}$\6
\4${}\}{}$\2\par
\U267.\fi

\M{269}\B\X269:Output index entries for the list at \PB{\\{sort\_ptr}}\X${}%
\E{}$\6
${}\{{}$\1\6
${}\\{cur\_name}\K\\{sort\_ptr}\MG\\{head};{}$\6
\&{do}\5
${}\{{}$\1\6
\&{if} ${}(\\{keep\_only\_ext\_def}\V\R\\{only\_ext\_def}(\\{cur\_name})){}$\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\I"});\6
\X272:Output the name at \PB{\\{cur\_name}}\X;\6
\X273:Output the cross-references at \PB{\\{cur\_name}}\X;\6
\4${}\}{}$\2\6
${}\\{cur\_name}\K\\{blink}[\\{cur\_name}-\\{name\_dir}];{}$\6
\4${}\}{}$\2\5
\&{while} (\\{cur\_name});\6
${}\MM\\{sort\_ptr};{}$\6
\4${}\}{}$\2\par
\U267.\fi

\M{270}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{boolean} \\{only\_ext\_def}(\,);\par
\fi

\M{271}%mine
We don't want to have identifiers that are imported from another book
but never used to be part of the index.
The following function returns 1, if the name \PB{\|p} is defined externally
and never referenced from within our book.
\Y\B\&{boolean} \\{only\_ext\_def}(\|p)\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{xref\_pointer} \\{xref};\7
${}\\{xref}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$\6
\&{if} ${}(\\{xref}\E\\{xmem}){}$\1\5
\&{return} \T{0};\C{ no reference at all? }\2\6
\&{if} ${}(\R\\{xref}\MG\\{ext\_ref}\V\\{xref}\MG\\{ext\_ref}\E\\{own\_shared}%
\V\\{xref}\MG\\{ext\_ref}\E\\{own\_export}){}$\1\5
\&{return} \T{0};\C{ not an external reference }\2\6
\&{if} ${}(\\{xref}\MG\\{num}\AND\\{def\_flag}{}$)\C{ yes, it's a definition }%
\1\6
\&{if} ${}(\\{xref}\MG\\{xlink}\E\\{xmem}{}$)\C{ and nothing follows }\1\6
\&{return} \T{1};\2\2\6
\&{return} \T{0};\6
\4${}\}{}$\2\par
\fi

\M{272}\B\X272:Output the name at \PB{\\{cur\_name}}\X${}\E{}$\6
\&{switch} ${}(\\{cur\_name}\MG\\{ilk}){}$\5
${}\{{}$\1\6
\4\&{case} \\{normal}:\6
\&{if} (\\{is\_tiny}(\\{cur\_name}))\1\5
\\{out\_str}(\.{"\\\\|"});\2\6
\&{else}\5
${}\{{}$\1\6
\&{char} ${}{*}\|j;{}$\7
\&{for} ${}(\|j\K\\{cur\_name}\MG\\{byte\_start};{}$ ${}\|j<(\\{cur\_name}+%
\T{1})\MG\\{byte\_start};{}$ ${}\|j\PP){}$\1\6
\&{if} ${}(\\{xislower}({*}\|j)){}$\1\5
\&{goto} \\{lowcase};\2\2\6
\\{out\_str}(\.{"\\\\."});\6
\&{break};\6
\4\\{lowcase}:\5
\\{out\_str}(\.{"\\\\\\\\"});\6
\4${}\}{}$\2\6
\&{break};\6
\4\&{case} \\{roman}:\5
\&{break};\6
\4\&{case} \\{wildcard}:\5
\\{out\_str}(\.{"\\\\9"});\6
\&{break};\6
\4\&{case} \\{typewriter}:\5
\\{out\_str}(\.{"\\\\."});\6
\&{break};\6
\4\&{case} \\{custom}:\5
\&{case} \\{quoted}:\6
${}\{{}$\1\6
\&{char} ${}{*}\|j;{}$\7
\\{out\_str}(\.{"\$\\\\"});\6
\&{for} ${}(\|j\K\\{cur\_name}\MG\\{byte\_start};{}$ ${}\|j<(\\{cur\_name}+%
\T{1})\MG\\{byte\_start};{}$ ${}\|j\PP){}$\1\5
${}\\{out}(\\{isxalpha}({*}\|j)\?\.{'x'}:{*}\|j);{}$\2\6
\\{out}(\.{'\$'});\6
\&{goto} \\{name\_done};\6
\4${}\}{}$\2\6
\4\&{default}:\5
\\{out\_str}(\.{"\\\\\&"});\6
\4${}\}{}$\2\6
\\{out\_name}(\\{cur\_name}); \\{name\_done}:\par
\U269.\fi

\M{273}Section numbers that are to be underlined are enclosed in
`\.{\\[}$\,\ldots\,$\.]'.

\Y\B\4\X273:Output the cross-references at \PB{\\{cur\_name}}\X${}\E{}$\6
\X275:Invert the cross-reference list at \PB{\\{cur\_name}}, making \PB{\\{cur%
\_xref}} the head\X;\6
\&{do}\5
${}\{{}$\1\6
\\{out\_str}(\.{",\ "});\6
${}\\{cur\_val}\K\\{cur\_xref}\MG\\{num};{}$\6
\&{if} ${}(\\{cur\_val}<\\{def\_flag}){}$\1\5
\\{out\_section}(\\{cur\_val});\2\6
\&{else}\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\["});\6
${}\\{out\_section}(\\{cur\_val}-\\{def\_flag});{}$\6
\\{out}(\.{']'});\6
\4${}\}{}$\2\6
\&{if} ${}(\\{cur\_xref}\MG\\{ext\_ref}){}$\1\5
\X278:Output footnote index to book referenced from \PB{\\{cur\_xref}}\X;\2\6
${}\\{cur\_xref}\K\\{cur\_xref}\MG\\{xlink};{}$\6
\4${}\}{}$\2\5
\&{while} ${}(\\{cur\_xref}\I\\{xmem});{}$\6
\\{out}(\.{'.'});\6
\\{finish\_line}(\,);\par
\U269.\fi

\M{274}List inversion is best thought of as popping elements off one stack and
pushing them onto another. In this case \PB{\\{cur\_xref}} will be the head of
the stack that we push things onto.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{xref\_pointer} \\{next\_xref}${},{}$ \\{this\_xref};\C{ pointer variables
for rearranging a list }\par
\fi

\M{275}\B\X275:Invert the cross-reference list at \PB{\\{cur\_name}}, making %
\PB{\\{cur\_xref}} the head\X${}\E{}$\6
$\\{this\_xref}\K{}$(\&{xref\_pointer}) \\{cur\_name}${}\MG\\{xref};{}$\6
${}\\{cur\_xref}\K\\{xmem};{}$\6
\&{do}\5
${}\{{}$\1\6
${}\\{next\_xref}\K\\{this\_xref}\MG\\{xlink};{}$\6
${}\\{this\_xref}\MG\\{xlink}\K\\{cur\_xref};{}$\6
${}\\{cur\_xref}\K\\{this\_xref};{}$\6
${}\\{this\_xref}\K\\{next\_xref};{}$\6
\4${}\}{}$\2\5
\&{while} ${}(\\{this\_xref}\I\\{xmem}){}$;\par
\U273.\fi

\M{276}%mine
Do we have shared and exported identifiers which are marked with $\dag$
and $\ddag$, respectively?
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{boolean} \\{dag\_seen}${},{}$ \\{ddag\_seen};\par
\fi

\M{277}%mine
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{dag\_seen}\K\\{ddag\_seen}\K\T{0}{}$;\par
\fi

\M{278}%mine
\Y\B\4\X278:Output footnote index to book referenced from \PB{\\{cur\_xref}}%
\X${}\E{}$\6
${}\{{}$\1\6
\&{struct} \\{external\_reference} ${}{*}\\{ref};{}$\6
\&{int} \|i;\6
\&{char} \\{ref\_nr}[\T{20}];\7
\&{if} ${}(\\{cur\_xref}\MG\\{ext\_ref}\E\\{own\_shared}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cur\_val}\G\\{def\_flag}){}$\5
${}\{{}$\C{ only if defined }\1\6
${}\\{dag\_seen}\K\T{1};{}$\6
${}\\{sprintf}(\\{ref\_nr},\39\.{"\$\{\}\^\{\\\\dag\}\$"});{}$\6
\\{out\_str}(\\{ref\_nr});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{cur\_xref}\MG\\{ext\_ref}\E\\{own\_export}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{cur\_val}\G\\{def\_flag}){}$\5
${}\{{}$\C{ only if defined }\1\6
${}\\{ddag\_seen}\K\T{1};{}$\6
${}\\{sprintf}(\\{ref\_nr},\39\.{"\$\{\}\^\{\\\\ddag\}\$"});{}$\6
\\{out\_str}(\\{ref\_nr});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\6
\&{for} ${}(\|i\K\T{1},\39\\{ref}\K\\{first\_ext\_ref};{}$ \\{ref}; ${}\|i\PP,%
\39\\{ref}\K\\{ref}\MG\\{next\_ext\_ref}){}$\1\6
\&{if} ${}(\\{ref}\E\\{cur\_xref}\MG\\{ext\_ref}){}$\5
${}\{{}$\1\6
${}\\{sprintf}(\\{ref\_nr},\39\.{"\$\{\}\^\{\%d\}\$"},\39\|i);{}$\6
\\{out\_str}(\\{ref\_nr});\6
\&{break};\6
\4${}\}{}$\2\2\2\6
\4${}\}{}$\2\par
\U273.\fi

\M{279}%mine
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{output\_referenced\_books}(\,);\par
\fi

\M{280}%mine
Output all books we find references to in the list \PB{\\{first\_ext\_ref}}.
\Y\B\&{void} \\{output\_referenced\_books}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{struct} \\{external\_reference} ${}{*}\\{ref},{}$ ${}{*}\\{ref2};{}$\6
\&{char} \\{ref\_str}[\T{128}];\6
\&{int} \|i;\7
\&{if} ${}(\\{dag\_seen}\V\\{ddag\_seen}){}$\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\bigskip"});\6
\&{if} (\\{dag\_seen})\1\5
\\{out\_str}(\.{"\\\\shared\\n"});\2\6
\&{if} (\\{ddag\_seen})\1\5
\\{out\_str}(\.{"\\\\exported\\n"});\2\6
\4${}\}{}$\2\6
\&{if} (\\{first\_ext\_ref})\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\refchaps\\n"});\6
\&{for} ${}(\|i\K\T{1},\39\\{ref}\K\\{first\_ext\_ref};{}$ \\{ref}; ${}\|i%
\PP){}$\5
${}\{{}$\1\6
${}\\{sprintf}(\\{ref\_str},\39\.{"\\\\chapref\{\%d\}\{"},\39\|i);{}$\6
\\{out\_str}(\\{ref\_str});\6
\&{if} ${}({*}\\{ref}\MG\\{book\_name}\W\\{strcmp}(\\{ref}\MG\\{book\_name},\39%
\\{book\_name})){}$\5
${}\{{}$\1\6
${}\\{sprintf}(\\{ref\_str},\39\.{"\{\\\\tt\ \%s\},\ "},\39\\{ref}\MG\\{book%
\_name});{}$\6
\\{out\_str}(\\{ref\_str});\6
\4${}\}{}$\2\6
${}\\{sprintf}(\\{ref\_str},\39\.{"\\\\chaptxt\\\\\ \%d\}\\n"},\39\\{ref}\MG%
\\{chapter});{}$\6
\\{out\_str}(\\{ref\_str});\6
${}\\{ref2}\K\\{ref};{}$\6
${}\\{ref}\K\\{ref}\MG\\{next\_ext\_ref};{}$\6
${}\\{free}(\\{ref2}\MG\\{book\_name});{}$\6
\\{free}(\\{ref2});\6
\4${}\}{}$\2\6
${}\\{first\_ext\_ref}\K\NULL;{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{281}The following recursive procedure walks through the tree of section
names and
prints them.

\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{section\_print}(\,);\par
\fi

\M{282}\B\&{void} \\{section\_print}(\|p)\C{ print all section names in subtree
\PB{\|p} }\1\1\6
\&{name\_pointer} \|p;\2\2\6
${}\{{}$\1\6
\&{if} (\|p)\5
${}\{{}$\1\6
${}\\{section\_print}(\|p\MG\\{llink});{}$\6
\\{out\_str}(\.{"\\\\I"});\6
${}\\{tok\_ptr}\K\\{tok\_mem}+\T{1};{}$\6
${}\\{text\_ptr}\K\\{tok\_start}+\T{1};{}$\6
${}\\{scrap\_ptr}\K\\{scrap\_info};{}$\6
\\{init\_stack};\6
${}\\{app}(\|p-\\{name\_dir}+\\{section\_flag});{}$\6
\\{make\_output}(\,);\6
\\{footnote}(\\{cite\_flag});\6
\\{footnote}(\T{0});\C{ \PB{\\{cur\_xref}} was set by \PB{\\{make\_output}} }\6
\\{finish\_line}(\,);\6
${}\\{section\_print}(\|p\MG\\{rlink});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{283}\B\X283:Output all the section names\X${}\E{}$\6
\\{section\_print}(\\{root})\par
\U254.\fi

\M{284}Because on some systems the difference between two pointers is a \PB{%
\&{long}}
rather than an \PB{\&{int}}, we use \.{\%ld} to print these quantities.

\Y\B\&{void} \\{print\_stats}(\,)\1\1\2\2\6
${}\{{}$\1\6
\\{printf}(\.{"\\nMemory\ usage\ stat}\)\.{istics:\\n"});\6
${}\\{printf}(\.{"\%ld\ names\ (out\ of\ \%}\)\.{ld)\\n"},\39{}$(\&{long}) ${}(%
\\{name\_ptr}-\\{name\_dir}),\39{}$(\&{long}) \\{max\_names});\6
${}\\{printf}(\.{"\%ld\ cross-reference}\)\.{s\ (out\ of\ \%ld)\\n"},\39{}$(%
\&{long}) ${}(\\{xref\_ptr}-\\{xmem}),\39{}$(\&{long}) \\{max\_refs});\6
${}\\{printf}(\.{"\%ld\ bytes\ (out\ of\ \%}\)\.{ld)\\n"},\39{}$(\&{long}) ${}(%
\\{byte\_ptr}-\\{byte\_mem}),\39{}$(\&{long}) \\{max\_bytes});\6
\\{printf}(\.{"Parsing:\\n"});\6
${}\\{printf}(\.{"\%ld\ scraps\ (out\ of\ }\)\.{\%ld)\\n"},\39{}$(\&{long})
${}(\\{max\_scr\_ptr}-\\{scrap\_info}),\39{}$(\&{long}) \\{max\_scraps});\6
${}\\{printf}(\.{"\%ld\ texts\ (out\ of\ \%}\)\.{ld)\\n"},\39{}$(\&{long}) ${}(%
\\{max\_text\_ptr}-\\{tok\_start}),\39{}$(\&{long}) \\{max\_texts});\6
${}\\{printf}(\.{"\%ld\ tokens\ (out\ of\ }\)\.{\%ld)\\n"},\39{}$(\&{long})
${}(\\{max\_tok\_ptr}-\\{tok\_mem}),\39{}$(\&{long}) \\{max\_toks});\6
${}\\{printf}(\.{"\%ld\ levels\ (out\ of\ }\)\.{\%ld)\\n"},\39{}$(\&{long})
${}(\\{max\_stack\_ptr}-\\{stack}),\39{}$(\&{long}) \\{stack\_size});\6
\\{printf}(\.{"Sorting:\\n"});\6
${}\\{printf}(\.{"\%ld\ levels\ (out\ of\ }\)\.{\%ld)\\n"},\39{}$(\&{long})
${}(\\{max\_sort\_ptr}-\\{scrap\_info}),\39{}$(\&{long}) \\{max\_scraps});\6
\4${}\}{}$\2\par
\fi

\N{0}{285}Multiple files.
I've tried to concentrate most of the extensions of \.{mCWEAVE}
concerning multiple file support in this section. Nevertheless,
numerous changes to the preceding sections were inevitable.
However, everything from here on is completely \.{mCWEB}-specific.

\fi

\N{1}{286}External references.
One of the major tasks \.{mCWEAVE} does in addition to \.{CWEAVE}'s work
is to to make an index including identifiers that are not defined
in the current chapter but imported from other parts.

In order to know which identifiers are defined by other books and in
the include files included by the chapter, we have to scan the corresponding
\.{exp}, \.{shr} and \.{h} files. During phase one,
each file gets stored in a list of imported files.
All files in this list are then parsed after phase one.

\fi

\M{287}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{file\_name\_ext}(\,);{}$\6
\&{char} ${}{*}\\{file\_name\_part}(\,);{}$\6
\&{void} \\{to\_parent}(\,);\par
\fi

\M{288}Returns the file name part of path \PB{\|s}. Never returns \PB{$\NULL$}.
Please change the \PB{\\{file\_name\_separator}} for non-\UNIX/ systems.
\Y\B\4\D$\\{file\_name\_separator}$ \5
\.{'/'}\par
\B\4\D$\\{file\_name\_sep\_str}$ \5
\.{"/"}\par
\Y\B\&{char} ${}{*}\\{file\_name\_part}(\|s){}$\1\1\6
\&{char} ${}{*}\|s;\2\2{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{slash\_pos};{}$\7
${}\\{slash\_pos}\K\\{strrchr}(\|s,\39\\{file\_name\_separator});{}$\6
\&{if} (\\{slash\_pos})\1\5
${}\\{slash\_pos}\PP;{}$\2\6
\&{else}\1\5
${}\\{slash\_pos}\K\|s;{}$\2\6
\&{return} \\{slash\_pos};\6
\4${}\}{}$\2\par
\fi

\M{289}Strips the filename from a full path.
\Y\B\&{void} \\{to\_parent}(\|s)\1\1\6
\&{char} ${}{*}\|s;\2\2{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp}\K\\{file\_name\_part}(\|s);{}$\7
\&{if} ${}(\\{cp}\E\|s){}$\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
\&{else}\1\5
${}\\{cp}[{-}\T{1}]\K\T{0};{}$\2\6
\4${}\}{}$\2\par
\fi

\M{290}Returns a pointer to the file name extension (e.g.~to \PB{\.{".exp"}})
or \PB{$\NULL$}.
\Y\B\&{char} ${}{*}\\{file\_name\_ext}(\|s){}$\1\1\6
\&{char} ${}{*}\|s;\2\2{}$\6
${}\{{}$\1\6
\&{return} ${}\\{strrchr}(\\{file\_name\_part}(\|s),\39\.{'.'});{}$\6
\4${}\}{}$\2\par
\fi

\M{291}The environment variable \PB{\.{DEPDIR}} gives us a reference point from
which we can find all export files of all books known to \.{mCWEB}.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{dep\_dir}{}$;\par
\fi

\M{292}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{dep\_dir}\K\\{getenv}(\.{"DEPDIR"});{}$\6
\&{if} ${}(\R\\{dep\_dir}){}$\1\5
${}\\{fatal}(\.{"!\ Environment\ varia}\)\.{ble\ not\ set:"},\39%
\.{"DEPDIR"}){}$;\2\par
\fi

\N{2}{293}Parse special commands in phase one.
If we encounter a special command in phase one while scanning the
\CEE/ part of a section, we must not include the keyword
in the reference index, but examine the following tokens more closely
in order to find out what to do with it.
\Y\B\4\X293:Special command seen in phase one\X${}\E{}$\6
${}\{{}$\1\6
\&{name\_pointer} \|p;\6
\&{int} \\{len};\6
\&{char} \\{name}[\\{max\_file\_name\_length}];\7
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_from}){}$\5
${}\{{}$\1\6
\X294:\&{from} seen in phase one\X;\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_import}){}$\5
${}\{{}$\1\6
\X296:\&{import} seen in phase one\X;\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_mark}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\K\T{0};{}$\6
\\{mark}(\\{id\_first});\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Name\ of\ copy\ buff}\)\.{er\ expected"});\6
\&{goto} \\{got\_next\_one};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_copy}){}$\1\5
\\{copy}(\,);\2\6
\4${}\}{}$\2\par
\U66.\fi

\M{294}If we see a \PB{ \#\&{from}} import command, we parse it and call
\PB{\\{remember\_import\_file}} for every import file name we get from it.
\Y\B\4\X294:\&{from} seen in phase one\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{ch\_name};{}$\7
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_program}\V\|p\E\\{id\_library}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}\\{len}\K\\{id\_loc}-\\{id\_first}-\T{2}{}$;\C{ length excl.~quotes }\6
${}\\{strncpy}(\\{name},\39\\{id\_first}+\T{1},\39\\{len});{}$\6
${}\\{name}[\\{len}]\K\T{0};{}$\6
\X295:\PB{\\{name}}$\leftarrow$\PB{\\{name}}\.{/}\PB{\\{name}}\X;\6
${}\\{ch\_name}\K\\{file\_name\_part}(\\{name});{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_import}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\I\\{id\_transitively}){}$\1\5
\&{goto} \\{got\_next\_one};\2\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4${}\}{}$\2\6
\&{while} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}\\{len}\K\\{id\_loc}-\\{id\_first}-\T{2};{}$\6
${}\\{strncpy}(\\{ch\_name},\39\\{id\_first}+\T{1},\39\\{len});{}$\6
${}\\{strcpy}(\\{ch\_name}+\\{len},\39\.{".exp"});{}$\6
${}\\{remember\_import\_file}(\\{name},\39\T{1},\39\T{1});{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\.{','}){}$\1\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{goto} \\{got\_next\_one};\C{ already having next token }\6
\4${}\}{}$\2\par
\U293.\fi

\M{295}In \PB{\\{name}} (which is of length \PB{\\{len}}),
we can find the name of the book we import from.
Since the name of the export file is
\.{\$(DEPDIR)/{\it bookname}/{\it bookname}.exp}, we double \PB{\\{name}},
which means that for a string \PB{\.{"mybook"}} we create a string
\PB{\.{"mybook/mybook"}}.
\Y\B\4\X295:\PB{\\{name}}$\leftarrow$\PB{\\{name}}\.{/}\PB{\\{name}}\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\R\\{strchr}(\\{name},\39\\{file\_name\_separator})){}$\5
${}\{{}$\1\6
${}\\{strcpy}(\\{name}+\\{len}+\T{1},\39\\{name});{}$\6
${}\\{name}[\\{len}]\K\\{file\_name\_separator};{}$\6
${}\\{len}\K\\{len}*\T{2}+\T{1};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\Us294\ET296.\fi

\M{296}If we encounter an import command in phase one, we have to take a look
at the following token in order to know where to import from.
There are three possibilities: {\it chapter}, {\it program} and {\it library}.
After these keywords, there may follow strings separated by commas which
indicate the file names.
\Y\B\4\X296:\&{import} seen in phase one\X${}\E{}$\6
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_transitively}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\I\\{identifier}){}$\1\5
\&{goto} \\{got\_next\_one};\2\6
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\4${}\}{}$\2\6
\&{if} ${}(\|p\E\\{id\_chapter}\V\|p\E\\{id\_program}\V\|p\E\\{id\_library}){}$%
\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{while} ${}(\\{next\_control}\E\\{string}){}$\5
${}\{{}$\1\6
${}\\{len}\K\\{id\_loc}-\\{id\_first}-\T{2};{}$\6
${}\\{strncpy}(\\{name},\39\\{id\_first}+\T{1},\39\\{len});{}$\6
${}\\{name}[\\{len}]\K\T{0};{}$\6
\&{if} ${}(\|p\I\\{id\_chapter}){}$\1\5
\X295:\PB{\\{name}}$\leftarrow$\PB{\\{name}}\.{/}\PB{\\{name}}\X;\2\6
${}\\{strcpy}(\\{name}+\\{len},\39\|p\E\\{id\_chapter}\?\.{".shr"}:%
\.{".exp"});{}$\6
${}\\{remember\_import\_file}(\\{name},\39\|p\I\\{id\_chapter},\39\T{1});{}$\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\E\.{','}){}$\1\5
${}\\{next\_control}\K\\{get\_next}(\,);{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{goto} \\{got\_next\_one};\C{ already having next token }\6
\4${}\}{}$\2\par
\U293.\fi

\N{2}{297}Imported files.
As we have seen above, we store all imported files in a list.
These files are processed right after pass one.
Imported files can either be files exported by other books (like
shared or export files) or standard include files.
\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{struct} \\{imported\_file} ${}\{{}$\1\6
\&{struct} \\{imported\_file} ${}{*}\\{next\_imported\_file};{}$\6
\&{int} \\{tangled\_file};\C{ 1 if from other book, 2 if from our book }\6
\&{char} ${}{*}\\{given\_name}{}$;\C{ as given after \&{\#include}, without
path }\6
\&{char} \\{file\_name}[\T{2}];\C{ full name of file to be read (incl. path) }%
\2\6
${}\}{}$;\par
\fi

\M{298}We need a variable that always points to the first imported file in
order to find the head of the list of imported files.
In addition, we need a \PB{\\{current\_imported\_file}} pointer that keeps
track
of the position where new files will be inserted.

Note, that when we are scanning an include file or an export file,
we might find additional includes which have to be added to the list.
These should be either added at the very end of the list (in case we
are not processing imported files yet but the web file itself) or right
after the import file we are currently parsing.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{struct} \\{imported\_file} ${}{*}\\{first\_imported\_file};{}$\6
\&{struct} \\{imported\_file} ${}{*}\\{current\_imported\_file}{}$;\par
\fi

\M{299}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{first\_imported\_file}\K\NULL{}$;\C{ \PB{$\NULL$} means: no files in list
yet }\6
${}\\{current\_imported\_file}\K\NULL{}$;\C{ \PB{$\NULL$} means: append at the
end of the list }\par
\fi

\M{300}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{struct} \\{imported\_file} ${}{*}\\{remember\_import\_file}(\,);{}$\6
\&{void} \\{remember\_include\_file}(\,);\par
\fi

\M{301}This function is called for every file that has to be read because
our book should know about all definitions which occur in it.
Each file is only stored once so that no file will be parsed twice.
If \PB{$\\{exp\_file}\E\T{1}$} then we are handling an export file which might
be relative
to \.{DEPDIR}. If \PB{$\\{tangled\_file}\I\T{0}$} the file was created by %
\.{mCTANGLE},
otherwise it's an include file.
\PB{$\\{tangled\_file}\E\T{1}$} means that we are dealing with an export file
of another
chapter, maybe even of another book,
\PB{$\\{tangled\_file}\E\T{2}$} indicates that it's our own shared file and
\PB{$\\{tangled\_file}\E\T{3}$} means our own export file.
\Y\B\4\D$\\{is\_absolute\_path}(\\{file\_name})$ \5
$({*}(\\{file\_name})\E\\{file\_name\_separator}{}$)\par
\Y\B\&{struct} \\{imported\_file} ${}{*}\\{remember\_import\_file}(\\{name},\39%
\\{exp\_file},\39\\{tangled\_file}){}$\1\1\6
\&{char} ${}{*}\\{name};{}$\6
\&{boolean} \\{exp\_file};\6
\&{int} \\{tangled\_file};\2\2\6
${}\{{}$\1\6
\&{struct} \\{imported\_file} ${}{*}\\{imf},{}$ ${}{*}\\{limf};{}$\6
\&{char} \\{full\_name}[\\{max\_file\_name\_length}];\6
\&{int} \\{len};\7
\&{if} ${}(\\{exp\_file}\W\R\\{is\_absolute\_path}(\\{name})\W\\{dep\_dir}){}$\5
${}\{{}$\1\6
${}\\{sprintf}(\\{full\_name},\39\.{"\%s\%c\%s"},\39\\{dep\_dir},\39\\{file%
\_name\_separator},\39\\{name});{}$\6
${}\\{name}\K\\{full\_name};{}$\6
\4${}\}{}$\2\6
${}\\{limf}\K\NULL;{}$\6
\&{for} ${}(\\{imf}\K\\{first\_imported\_file};{}$ \\{imf}; ${}\\{imf}\K\\{imf}%
\MG\\{next\_imported\_file}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\\{strcmp}(\\{imf}\MG\\{file\_name},\39\\{name})){}$\1\5
\&{return} ${}\NULL{}$;\C{ already in list }\2\6
${}\\{limf}\K\\{imf};{}$\6
\4${}\}{}$\2\6
${}\\{len}\K\\{strlen}(\\{name});{}$\6
${}\\{imf}\K{}$(\&{struct} \\{imported\_file} ${}{*}){}$ \\{malloc}(\&{sizeof}
${}({*}\\{imf})+\\{len}-\T{1});{}$\6
\&{if} ${}(\R\\{imf}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory"},\39\.{"\ for\ import\ file\ na}\)\.{me"});{}$%
\2\6
${}\\{strcpy}(\\{imf}\MG\\{file\_name},\39\\{name});{}$\6
${}\\{imf}\MG\\{given\_name}\K\NULL{}$;\C{ only used by include files }\6
${}\\{imf}\MG\\{tangled\_file}\K\\{tangled\_file};{}$\6
\&{if} (\\{current\_imported\_file})\5
${}\{{}$\C{ append right after \PB{\\{current\_imported\_file}} }\1\6
${}\\{imf}\MG\\{next\_imported\_file}\K\\{current\_imported\_file}\MG\\{next%
\_imported\_file};{}$\6
${}\\{current\_imported\_file}\MG\\{next\_imported\_file}\K\\{imf};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\C{ append at end of list (i.e.~after \PB{\\{limf}}) }\1\6
${}\\{imf}\MG\\{next\_imported\_file}\K\NULL;{}$\6
\&{if} ${}(\R\\{limf}){}$\1\5
${}\\{first\_imported\_file}\K\\{imf}{}$;\C{ first and only node in list }\2\6
\&{else}\1\5
${}\\{limf}\MG\\{next\_imported\_file}\K\\{imf}{}$;\C{ append at end of list }%
\2\6
\4${}\}{}$\2\6
\&{return} \\{imf};\6
\4${}\}{}$\2\par
\fi

\M{302}Include files are special import files because they have names relative
to the include directories. Therefore, the following piece of code tries
to find out the full path name of the include file stored in
\PB{\\{id\_first}}--\PB{\\{id\_loc}} by searching it in each of the
colon
separated directories of the environment variable
\.{INCLUDE}.
If it can find the file, it is added to the list of imported files.
\Y\B\4\D$\\{include\_dir\_separator}$ \5
\.{':'}\par
\Y\B\&{void} \\{remember\_include\_file}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{char} ${}{*}\\{incl\_dirs}\K\\{getenv}(\.{"INCLUDE"});{}$\6
\&{char} ${}{*}\\{cp},{}$ ${}{*}\\{col};{}$\6
\&{char} \\{full\_name}[\\{max\_file\_name\_length}];\6
\&{int} \\{len}${},{}$ \\{id\_len}${},{}$ \\{path\_len};\6
\&{struct} \\{stat} \|s;\6
\&{struct} \\{imported\_file} ${}{*}\\{imf};{}$\7
${}\\{id\_len}\K\\{id\_loc}-\\{id\_first}-\T{2};{}$\6
${}\\{strncpy}(\\{full\_name},\39\\{id\_first}+\T{1},\39\\{id\_len}){}$;\C{
this is the given include file name }\6
${}\\{full\_name}[\\{id\_len}]\K\T{0};{}$\6
\X303:If \PB{\\{full\_name}} equal a \PB{\\{given\_name}} in the import file
list, \PB{\&{return}}\X\6
\X304:Handle case that include file is in current directory, \PB{\&{return}} if
yes\X;\6
\X305:Try if include file is in \PB{\.{DEPDIR}}, \PB{\&{return}} if yes\X;\6
\&{if} ${}(\\{incl\_dirs}\W{*}\\{incl\_dirs}){}$\1\5
\&{do}\5
${}\{{}$\1\6
${}\\{cp}\K\\{col}\K\\{strchr}(\\{incl\_dirs},\39\\{include\_dir%
\_separator});{}$\6
\&{if} ${}(\R\\{cp}){}$\1\5
${}\\{cp}\K\\{incl\_dirs}+\\{strlen}(\\{incl\_dirs});{}$\2\6
${}\\{len}\K\\{cp}-\\{incl\_dirs};{}$\6
${}\\{strncpy}(\\{full\_name},\39\\{incl\_dirs},\39\\{len});{}$\6
${}\\{full\_name}[\\{len}\PP]\K\\{file\_name\_separator};{}$\6
${}\\{path\_len}\K\\{len};{}$\6
${}\\{strncpy}(\\{full\_name}+\\{len},\39\\{id\_first}+\T{1},\39\\{id%
\_len});{}$\6
${}\\{len}\MRL{+{\K}}\\{id\_len};{}$\6
${}\\{full\_name}[\\{len}]\K\T{0};{}$\6
\&{if} ${}(\R\\{stat}(\\{full\_name},\39{\AND}\|s)){}$\5
${}\{{}$\1\6
${}\\{imf}\K\\{remember\_import\_file}(\\{full\_name},\39\T{0},\39\R%
\\{strncmp}(\\{full\_name},\39\\{dep\_dir},\39\\{strlen}(\\{dep\_dir})));{}$\6
\&{if} (\\{imf})\1\5
${}\\{imf}\MG\\{given\_name}\K\\{imf}\MG\\{file\_name}+\\{path\_len};{}$\2\6
\&{return};\6
\4${}\}{}$\2\6
${}\\{incl\_dirs}\K\\{cp}+\T{1};{}$\6
\4${}\}{}$\2\5
\&{while} (\\{col});\2\6
\&{if} (\\{report\_include})\5
${}\{{}$\1\6
\\{printf}(\.{"\\ncannot\ find\ inclu}\)\.{de\ file:\ "});\6
${}\\{term\_write}(\\{id\_first}+\T{1},\39\\{id\_len});{}$\6
\\{printf}(\.{"\\n(environment\ vari}\)\.{able\ INCLUDE\ not\ pro}\)\.{perly\
set?)\\n"});\6
\\{mark\_harmless};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{303}If we find the name given after the \&{\#include} statement in the
\PB{\\{given\_name}} field of the list of imported files, we already have that
include file in the list and bail out.
\Y\B\4\X303:If \PB{\\{full\_name}} equal a \PB{\\{given\_name}} in the import
file list, \PB{\&{return}}\X${}\E{}$\6
${}\{{}$\1\6
\&{for} ${}(\\{imf}\K\\{first\_imported\_file};{}$ \\{imf}; ${}\\{imf}\K\\{imf}%
\MG\\{next\_imported\_file}){}$\1\6
\&{if} ${}(\\{imf}\MG\\{given\_name}\W\R\\{strcmp}(\\{full\_name},\39\\{imf}\MG%
\\{given\_name})){}$\1\5
\&{return};\2\2\6
\4${}\}{}$\2\par
\U302.\fi

\M{304}If the file can be found in the current directory, there is no need
to search it in the directories given by the \.{INCLUDE} environment
variables.
\Y\B\4\X304:Handle case that include file is in current directory, \PB{%
\&{return}} if yes\X${}\E{}$\6
${}\{{}$\1\6
\&{if} ${}(\R\\{stat}(\\{full\_name},\39{\AND}\|s)){}$\5
${}\{{}$\1\6
${}\\{imf}\K\\{remember\_import\_file}(\\{full\_name},\39\T{0},\39\T{0});{}$\6
\&{if} (\\{imf})\1\5
${}\\{imf}\MG\\{given\_name}\K\\{imf}\MG\\{file\_name};{}$\2\6
\&{return};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U302.\fi

\M{305}We also always try to locate the include file relative to the
\.{DEPDIR} environment variable.
\Y\B\4\X305:Try if include file is in \PB{\.{DEPDIR}}, \PB{\&{return}} if yes%
\X${}\E{}$\6
${}\{{}$\1\6
${}\\{strcpy}(\\{full\_name},\39\\{dep\_dir});{}$\6
${}\\{len}\K\\{strlen}(\\{full\_name});{}$\6
${}\\{full\_name}[\\{len}\PP]\K\\{file\_name\_separator};{}$\6
${}\\{path\_len}\K\\{len};{}$\6
${}\\{strncpy}(\\{full\_name}+\\{len},\39\\{id\_first}+\T{1},\39\\{id%
\_len});{}$\6
${}\\{len}\MRL{+{\K}}\\{id\_len};{}$\6
${}\\{full\_name}[\\{len}]\K\T{0};{}$\6
\&{if} ${}(\R\\{stat}(\\{full\_name},\39{\AND}\|s)){}$\5
${}\{{}$\1\6
${}\\{imf}\K\\{remember\_import\_file}(\\{full\_name},\39\T{0},\39\T{1});{}$\6
\&{if} (\\{imf})\1\5
${}\\{imf}\MG\\{given\_name}\K\\{imf}\MG\\{file\_name}+\\{path\_len};{}$\2\6
\&{return};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U302.\fi

\N{2}{306}External references.
Since a book can reference other books, we keep a list chapters of all
books our book references.
\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{struct} \\{external\_reference} ${}\{{}$\1\6
\&{struct} \\{external\_reference} ${}{*}\\{next\_ext\_ref};{}$\6
\&{char} ${}{*}\\{book\_name};{}$\6
\&{int} \\{chapter};\2\6
${}\}{}$;\par
\fi

\M{307}We keep a pointer to the first referenced book.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{struct} \\{external\_reference} ${}{*}\\{first\_ext\_ref}{}$;\par
\fi

\M{308}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{first\_ext\_ref}\K\NULL{}$;\par
\fi

\M{309}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{strmem}(\,){}$;\par
\fi

\M{310}The following function copies the given string \PB{\|s} to allocated
memory.
\Y\B\&{char} ${}{*}\\{strmem}(\|s){}$\1\1\6
\&{char} ${}{*}\|s;\2\2{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp}\K\\{malloc}(\\{strlen}(\|s)+\T{1});{}$\7
\&{if} ${}(\R\\{cp}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory\ for\ str}\)\.{ing\ "},\39\|s);{}$\2\6
\&{return} ${}\\{strcpy}(\\{cp},\39\|s);{}$\6
\4${}\}{}$\2\par
\fi

\M{311}For each new reference to a chapter of another book, we allocate
a new \PB{\\{external\_reference}} structure and append it to the list of
referenced books.

The list is always kept sorted, where the book name is the first
sorting criterion and the chapter number the second. If the external
reference is already part of the list, this instance will be returned
and no new external reference will be created.
\Y\B\&{struct} \\{external\_reference} ${}{*}\\{new\_ext\_ref}(\\{bookname},\39%
\\{chapter\_no}){}$\1\1\6
\&{char} ${}{*}\\{bookname};\2\2{}$\6
${}\{{}$\1\6
\&{struct} \\{external\_reference} ${}{*}\\{ref},{}$ ${}{*}\\{last\_ref}\K%
\NULL;{}$\6
\&{boolean} \\{must\_alloc\_book\_name}${}\K\T{1}{}$;\C{ \PB{\\{bookname}} must
be copied to allocated memory }\6
\&{boolean} \\{own\_book}${}\K\R\\{strcmp}(\\{bookname},\39\\{book\_name});{}$\6
\&{int} \|c;\7
\&{if} (\\{own\_book})\1\5
${}\\{bookname}\K\.{""};{}$\2\6
\&{for} ${}(\\{ref}\K\\{first\_ext\_ref};{}$ \\{ref}; ${}\\{ref}\K\\{ref}\MG%
\\{next\_ext\_ref}){}$\5
${}\{{}$\1\6
${}\|c\K\\{strcmp}(\\{ref}\MG\\{book\_name},\39\\{bookname});{}$\6
\&{if} ${}(\R\|c){}$\5
${}\{{}$\1\6
${}\\{bookname}\K\\{ref}\MG\\{book\_name};{}$\6
${}\\{must\_alloc\_book\_name}\K\T{0};{}$\6
\&{if} ${}(\\{ref}\MG\\{chapter}\E\\{chapter\_no}){}$\1\5
\&{return} \\{ref};\C{ already exists }\2\6
\&{if} ${}(\\{ref}\MG\\{chapter}>\\{chapter\_no}){}$\1\5
\&{break};\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|c>\T{0}){}$\1\5
\&{break};\2\6
${}\\{last\_ref}\K\\{ref};{}$\6
\4${}\}{}$\2\6
\&{if} (\\{must\_alloc\_book\_name})\1\5
${}\\{bookname}\K\\{strmem}(\\{bookname});{}$\2\6
${}\\{ref}\K{}$(\&{struct} \\{external\_reference} ${}{*}){}$ \\{malloc}(%
\&{sizeof}(\&{struct} \\{external\_reference}));\6
\&{if} ${}(\R\\{ref}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory\ for\ ref}\)\.{erence\ to\ book\ "},\39%
\\{bookname});{}$\2\6
\&{if} ${}(\R\\{last\_ref}){}$\5
${}\{{}$\C{ \PB{\\{ref}} should be first node in list }\1\6
${}\\{ref}\MG\\{next\_ext\_ref}\K\\{first\_ext\_ref};{}$\6
${}\\{first\_ext\_ref}\K\\{ref};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\C{ \PB{\\{ref}} will be appended after \PB{\\{last\_ref}} }\1\6
${}\\{ref}\MG\\{next\_ext\_ref}\K\\{last\_ref}\MG\\{next\_ext\_ref};{}$\6
${}\\{last\_ref}\MG\\{next\_ext\_ref}\K\\{ref};{}$\6
\4${}\}{}$\2\6
${}\\{ref}\MG\\{chapter}\K\\{chapter\_no};{}$\6
${}\\{ref}\MG\\{book\_name}\K\\{strmem}(\\{bookname});{}$\6
\&{return} \\{ref};\6
\4${}\}{}$\2\par
\fi

\N{1}{312}Process imported files.
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{process\_imported\_files}(\,);\par
\fi

\M{313}In phase one we have collected a lot of imported files.
They are processed right at the end of phase one. During processing,
new imported files may be found and added to the list.
This happens, when there are new \PB{$\#$ \&{include}} statements in the
imported
files.
\Y\B\4\D$\\{report\_include}$ \5
\\{flags}[\.{'i'}]\par
\Y\B\&{void} \\{process\_imported\_files}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{struct} \\{imported\_file} ${}{*}\\{imf};{}$\6
\&{boolean} \\{file\_name\_printed}${}\K\T{0};{}$\7
\\{printf}(\.{"\\nParsing\ include\ f}\)\.{iles..."});\6
\\{update\_terminal};\6
\&{for} ${}(\\{imf}\K\\{first\_imported\_file};{}$ \\{imf}; ${}\\{imf}\K\\{imf}%
\MG\\{next\_imported\_file}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{report\_include}\V\\{imf}\MG\\{tangled\_file}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\\{file\_name\_printed}){}$\5
${}\{{}$\1\6
\\{printf}(\.{"\\nReading\ imported\ }\)\.{files:\ "});\6
${}\\{file\_name\_printed}\K\T{1};{}$\6
\4${}\}{}$\2\6
${}\\{printf}(\.{"\%s\ "},\39\\{imf}\MG\\{file\_name});{}$\6
\\{update\_terminal};\6
\4${}\}{}$\2\6
\\{parse\_imported\_file}(\\{imf});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{314}Note that we are now parsing \CEE/ files and no web files, since
both, export/shared files and standard \CEE/ header files are ordinary
\CEE/ files. Files created by \.{mCTANGLE} (export and shared files)
have special comments which tell us, which section the following code
comes from and which book and chapter is the source of this file.

In addition, \.{mCTANGLE} inserts section numbers like \.{1:} as comments
into the output file in order to indicate, that the following part
is from section~1. A \.{:1} says, that section~1 ends here.

In order to make proper references, it is important to know which token
comes from which section. The following array provides this information.
It is sorted by \PB{\\{token\_ptr}} which means that all tokens whose address
\PB{\\{token\_ptr}} is
\PB{$\\{token\_sec\_info}[\|i]\MG\\{token\_ptr}\Z\\{token\_ptr}<\\{token\_sec%
\_info}[\|i+\T{1}]\MG\\{token\_ptr}$}
come from section \PB{$\\{token\_sec\_info}[\|i]\MG\\{section\_count}$}.
\Y\B\4\D$\\{max\_token\_sec\_info}$ \5
\T{300}\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{struct} \\{token\_section} ${}\{{}$\1\6
\&{token\_pointer} \\{token\_ptr};\C{ this token and all following tokens }\6
\&{int} \\{section\_count};\C{ are from this section }\2\6
${}\}{}$ \\{token\_sec\_info}[\\{max\_token\_sec\_info}];\6
\&{struct} \\{token\_section} ${}{*}\\{token\_sec\_ptr}{}$;\C{ next unused \PB{%
\\{token\_section}} }\6
\&{extern} \&{boolean} \\{parsing\_exp\_file};\C{ 1 if we are parsing an
imported file }\par
\fi

\M{315}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{new\_token\_section}(\,);\par
\fi

\M{316}The following function stores the current token pointer \PB{\\{tok%
\_ptr}}
and the current section number \PB{\\{section\_count}} in the array described
above.
\Y\B\&{void} \\{new\_token\_section}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{token\_sec\_ptr}\E\\{token\_sec\_info}+\\{max\_token\_sec%
\_info}){}$\1\5
\\{overflow}(\.{"token\ section\ info"});\2\6
${}\\{token\_sec\_ptr}\MG\\{token\_ptr}\K\\{tok\_ptr};{}$\6
${}\\{token\_sec\_ptr}\MG\\{section\_count}\K\\{section\_count};{}$\6
${}\\{token\_sec\_ptr}\PP;{}$\6
\4${}\}{}$\2\par
\fi

\M{317}In order to find out which section a given token pointer \PB{\\{tk}}
belongs to,
we only have to scan the array for the appropriate entry.
\Y\B\&{int} \\{section\_of\_token}(\\{tk})\1\1\6
\&{token\_pointer} \\{tk};\2\2\6
${}\{{}$\1\6
\&{struct} \\{token\_section} ${}{*}\\{ts};{}$\6
\&{int} \\{sec}${}\K\T{0};{}$\7
\&{for} ${}(\\{ts}\K\\{token\_sec\_info};{}$ ${}\\{ts}<\\{token\_sec\_ptr};{}$
${}\\{ts}\PP){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{tk}<\\{ts}\MG\\{token\_ptr}){}$\1\5
\&{break};\2\6
${}\\{sec}\K\\{ts}\MG\\{section\_count};{}$\6
\4${}\}{}$\2\6
\&{return} \\{sec};\6
\4${}\}{}$\2\par
\fi

\M{318}
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{static} \&{char} \\{foreign\_book\_name}[\\{max\_file\_name\_length}];\C{
book we are importing from }\6
\&{int} \\{foreign\_chapter};\C{ which chapter of that book }\6
\&{struct} \\{external\_reference} ${}{*}\\{ext\_ref}{}$;\C{ current \PB{%
\\{external\_reference}} }\par
\fi

\M{319}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{parse\_imported\_file}(\,);\par
\fi

\M{320}Here is the routine that actually does the parsing of the imported
file. It opens the file, makes a list of scraps and then translates it.
Note, that a translation is also done each time a \PB{\&{typedef}} or \PB{%
\&{extern}} is
encountered. This keeps us from running out of token, scrap or text memory
when parsing \CEE/ Header files which can be quite long compared to \CEE/
sections.
\Y\B\&{void} \\{parse\_imported\_file}(\\{imf})\1\1\6
\&{struct} \\{imported\_file} ${}{*}\\{imf};\2\2{}$\6
${}\{{}$\1\6
\&{char} \\{save\_web\_file\_name}[\\{max\_file\_name\_length}];\6
\&{char} \\{save\_alt\_web\_file\_name}[\\{max\_file\_name\_length}];\6
\&{char} \\{save\_change\_file\_name}[\\{max\_file\_name\_length}];\6
\&{int} \\{len};\7
${}\\{current\_imported\_file}\K\\{imf}{}$;\C{ remember where we last were }\6
${}\\{strcpy}(\\{save\_web\_file\_name},\39\\{web\_file\_name});{}$\6
${}\\{strcpy}(\\{save\_alt\_web\_file\_name},\39\\{alt\_web\_file\_name});{}$\6
${}\\{strcpy}(\\{save\_change\_file\_name},\39\\{change\_file\_name});{}$\6
${}\\{strcpy}(\\{web\_file\_name},\39\\{imf}\MG\\{file\_name});{}$\6
${}\\{strcpy}(\\{alt\_web\_file\_name},\39\\{web\_file\_name});{}$\6
${}\\{strcpy}(\\{change\_file\_name},\39\.{"/dev/null"}){}$;\7
${}\\{parsing\_exp\_file}\K\T{1};{}$\6
${}\\{ext\_ref}\K\NULL{}$;\C{ no current external reference to a book }\6
${}\\{token\_sec\_ptr}\K\\{token\_sec\_info}{}$;\C{ reset token section list }\6
${}\\{sec\_cnt\_sp}\K\T{0}{}$;\C{ reset section counter stack }\6
\\{reset\_input}(\,);\6
${}\\{section\_count}\K\T{0};{}$\6
\&{while} ${}(\R\\{input\_has\_ended}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\4\\{got\_next\_one}:\6
\&{if} ${}(\\{next\_control}\E\\{identifier}){}$\5
${}\{{}$\1\6
${}\\{len}\K\\{id\_loc}-\\{id\_first};{}$\6
\&{if} ${}(\R\\{strncmp}(\\{id\_first},\39\.{"typedef"},\39\\{len})\W\\{len}\E%
\T{7}\V\R\\{strncmp}(\\{id\_first},\39\.{"extern"},\39\\{len})\W\\{len}\E%
\T{6}){}$\1\5
\\{translate\_and\_reset}(\,);\2\6
\4${}\}{}$\2\6
\&{if} ${}(\\{next\_control}\E\\{begin\_comment}){}$\1\5
${}\\{parse\_comment}(\\{imf}\MG\\{tangled\_file});{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\\{begin\_short\_comment}){}$\1\5
${}\\{loc}\K\\{limit};{}$\2\6
\&{else} \&{if} ${}(\R\\{preprocessing}\W\\{next\_control}\I\\{right\_preproc}%
\V\\{section\_count}){}$\5
${}\{{}$\1\6
\X193:Append the scrap appropriate to \PB{\\{next\_control}}\X;\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{translate\_and\_reset}(\,);\6
${}\\{ext\_ref}\K\NULL;{}$\6
${}\\{parsing\_exp\_file}\K\T{0}{}$;\7
\\{fclose}(\\{file}[\T{0}]);\6
\\{fclose}(\\{change\_file});\6
${}\\{strcpy}(\\{web\_file\_name},\39\\{save\_web\_file\_name});{}$\6
${}\\{strcpy}(\\{alt\_web\_file\_name},\39\\{save\_alt\_web\_file\_name});{}$\6
${}\\{strcpy}(\\{change\_file\_name},\39\\{save\_change\_file\_name});{}$\6
\4${}\}{}$\2\par
\fi

\M{321}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{translate\_and\_reset}(\,);\par
\fi

\M{322}Translate the current scraps into \TeX\ code and reset the
texts/tokens/scraps.
\Y\B\&{void} \\{translate\_and\_reset}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{int} \\{sec}${}\K\\{section\_count};{}$\6
\&{text\_pointer} \|p;\7
\&{if} ${}(\\{scrap\_ptr}>\\{scrap\_info}){}$\1\5
${}\|p\K\\{translate}(\,);{}$\2\6
\&{if} ${}(\\{text\_ptr}>\\{max\_text\_ptr}){}$\1\5
${}\\{max\_text\_ptr}\K\\{text\_ptr};{}$\2\6
\&{if} ${}(\\{tok\_ptr}>\\{max\_tok\_ptr}){}$\1\5
${}\\{max\_tok\_ptr}\K\\{tok\_ptr};{}$\2\6
\&{if} ${}(\\{scrap\_ptr}>\\{max\_scr\_ptr}){}$\1\5
${}\\{max\_scr\_ptr}\K\\{scrap\_ptr};{}$\2\6
${}\\{tok\_ptr}\K\\{tok\_mem}+\T{1};{}$\6
${}\\{text\_ptr}\K\\{tok\_start}+\T{1};{}$\6
${}\\{scrap\_ptr}\K\\{scrap\_info}{}$;\C{ forget the tokens and the scraps }\6
${}\\{token\_sec\_ptr}\K\\{token\_sec\_info}{}$;\C{ reset token section list }\6
${}\\{section\_count}\K\\{sec};{}$\6
\\{new\_token\_section}(\,);\C{ remember from where first token comes }\6
\4${}\}{}$\2\par
\fi

\M{323}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{parse\_comment}(\,);\par
\fi

\M{324}Since we might read files created by \.{mCTANGLE}, we have to parse
the contents of a traditional \CEE/ commands for the section counter.

\.{mCTANGLE} has inserted the following comments into its export files:

\item{$\bullet$} \.{ Book:"$\langle\hbox{\it book name}\rangle$", Chapter
$n$} informs us about which book and chapter the export file belongs to.
\item{$\bullet$} \.{Section:$n$} means that the following code piece
comes from section $n$.
\item{$\bullet$} \.{$n$:} means the same but pushes the old section number
on a stack.
\item{$\bullet$} \.{:$n$} restores the previously restored section counter
by popping it from the stack.
\Y\B\&{void} \\{parse\_comment}(\\{tangled\_file})\1\1\6
\&{int} \\{tangled\_file};\2\2\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp};{}$\6
\&{int} \\{len};\6
\&{int} \\{sec};\7
\&{if} (\\{tangled\_file})\5
${}\{{}$\C{ if an export file rather than an include file }\1\6
\&{if} ${}(\R\\{strncmp}(\\{loc},\39\.{"Section:"},\39\T{8})){}$\5
${}\{{}$\1\6
${}\\{sscanf}(\\{loc}+\T{8},\39\.{"\%d"},\39{\AND}\\{sec});{}$\6
${}\\{section\_count}\K{}$(\&{sixteen\_bits}) \\{sec};\6
\\{new\_token\_section}(\,);\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\R\\{strncmp}(\\{loc},\39\.{"\ Book:\\""},\39\T{7})){}$\5
${}\{{}$\1\6
${}\\{cp}\K\\{strchr}(\\{loc}+\T{7},\39\.{'\\"'});{}$\6
${}\\{len}\K\\{cp}-\\{loc}-\T{7};{}$\6
${}\\{strncpy}(\\{foreign\_book\_name},\39\\{loc}+\T{7},\39\\{len});{}$\6
${}\\{foreign\_book\_name}[\\{len}]\K\T{0};{}$\6
${}\\{sscanf}(\\{loc}+\T{7}+\\{len}+\T{11},\39\.{"\%d"},\39{\AND}\\{foreign%
\_chapter});{}$\6
\&{if} ${}(\\{tangled\_file}\E\T{2}){}$\1\5
${}\\{ext\_ref}\K\\{own\_shared}{}$;\C{ parsing own shared file }\2\6
\&{else} \&{if} ${}(\\{tangled\_file}\E\T{3}){}$\1\5
${}\\{ext\_ref}\K\\{own\_export}{}$;\C{ parsing own export file }\2\6
\&{else}\1\5
${}\\{ext\_ref}\K\\{new\_ext\_ref}(\\{foreign\_book\_name},\39\\{foreign%
\_chapter});{}$\2\6
;\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{isdigit}({*}\\{loc})){}$\5
${}\{{}$\1\6
${}\\{sscanf}(\\{loc},\39\.{"\%d"},\39{\AND}\\{sec});{}$\6
\&{do}\5
${}\\{loc}\PP;{}$\5
\&{while} ${}(\\{isdigit}({*}\\{loc}));{}$\6
\&{if} ${}({*}\\{loc}\E\.{':'}){}$\5
${}\{{}$\1\6
\\{push\_sec\_cnt}(\,);\6
${}\\{section\_count}\K\\{sec};{}$\6
\\{new\_token\_section}(\,);\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}({*}\\{loc}\E\.{':'}\W\\{isdigit}(\\{loc}[\T{1}])){}$\5
${}\{{}$\1\6
\\{pop\_sec\_cnt}(\,);\6
\\{new\_token\_section}(\,);\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\X325:Simply skip the comment\X;\6
\4${}\}{}$\2\par
\fi

\M{325}After parsing the comment we simply skip it.
%"
\Y\B\4\X325:Simply skip the comment\X${}\E{}$\6
\&{for} ( ;  ; \,)\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}){}$\1\6
\&{if} ${}(\\{get\_line}(\,)\E\T{0}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Input\ ended\ in\ mi}\)\.{d-comment"});\6
${}\\{loc}\K\\{buffer}+\T{1};{}$\6
\&{break};\6
\4${}\}{}$\2\2\6
${}\\{next\_control}\K{*}\\{loc}\PP;{}$\6
\&{if} ${}(\\{next\_control}\E\.{'*'}\W{*}\\{loc}\E\.{'/'}){}$\5
${}\{{}$\1\6
${}\\{loc}\PP;{}$\6
\&{break};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U324.\fi

\M{326}Here comes the section counter stack.
\Y\B\4\D$\\{max\_section\_nest}$ \5
\T{16}\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{int} \\{sec\_cnt\_stack}[\\{max\_section\_nest}];\6
\&{int} \\{sec\_cnt\_sp};\par
\fi

\M{327}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{push\_sec\_cnt}(\,);\6
\&{int} \\{pop\_sec\_cnt}(\,);\par
\fi

\M{328}Each time we find a new section in the comments, we push the
current section on the stack for later reuse.
\Y\B\&{void} \\{push\_sec\_cnt}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{if} ${}(\\{sec\_cnt\_sp}\G\\{max\_section\_nest}){}$\1\5
\\{overflow}(\.{"section\ nest\ in\ imp}\)\.{orted\ file"});\2\6
${}\\{sec\_cnt\_stack}[\\{sec\_cnt\_sp}\PP]\K\\{section\_count};{}$\6
\4${}\}{}$\2\par
\fi

\M{329}When the comments in the export file tell us that the current section
ends,
we pop the topmost section from the section counter stack.
\Y\B\&{int} \\{pop\_sec\_cnt}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{if} (\\{sec\_cnt\_sp})\1\5
\&{return} ${}\\{section\_count}\K\\{sec\_cnt\_stack}[\MM\\{sec\_cnt\_sp}];{}$%
\2\6
\&{return} \T{0};\6
\4${}\}{}$\2\par
\fi

\N{2}{330}Exported stuff.
Now we have seen how \.{mCWEAVE} reads files which contain data our current
chapter has references to. Now we want to deal with those things our chapter
exports to other books. Since these declarations come from our book,
\.{mCWEAVE} already encounters them during phase one and puts it into the
cross reference list. All we want to do now, is to mark it as exported
stuff in order to print it properly when we will output the index.

\fi

\M{331}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{remember\_export\_file}(\,);\par
\fi

\M{332}Again, this is done by parsing \.{mCTANGLE}'s output. We simply read
our own shared and export files just like the imported files.
\Y\B\&{void} \\{remember\_export\_file}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{char} \\{name}[\\{max\_file\_name\_length}];\6
\&{char} ${}{*}\\{dot};{}$\6
\&{FILE} ${}{*}\\{fd};{}$\6
\&{int} \\{len};\7
${}\\{strcpy}(\\{name},\39\\{file\_name}[\T{0}]);{}$\6
${}\\{dot}\K\\{file\_name\_ext}(\\{name});{}$\6
\&{if} (\\{dot})\1\5
${}{*}\\{dot}\K\T{0};{}$\2\6
${}\\{strcat}(\\{name},\39\.{".shr"});{}$\6
\&{if} ${}(\\{fd}\K\\{fopen}(\\{name},\39\.{"r"})){}$\5
${}\{{}$\1\6
\\{fclose}(\\{fd});\6
${}\\{remember\_import\_file}(\\{name},\39\T{0},\39\T{2}){}$;\C{ 2 means: our
own shared file }\6
\4${}\}{}$\2\6
\&{if} (\\{book\_type})\5
${}\{{}$\C{ if we are weaving a whole book rather than a simple \.{CWEB} file }%
\1\6
${}\\{strcpy}(\\{name},\39\\{dep\_dir}){}$;\C{ export file name is relative to %
\PB{\.{DEPDIR}} }\6
${}\\{len}\K\\{strlen}(\\{name});{}$\6
\&{if} (\\{len})\1\5
${}\\{name}[\\{len}\PP]\K\\{file\_name\_separator};{}$\2\6
${}\\{strcpy}(\\{name}+\\{len},\39\\{book\_name}){}$;\C{ file name is preceded
by book name }\6
${}\\{len}\K\\{strlen}(\\{name});{}$\6
${}\\{name}[\\{len}\PP]\K\\{file\_name\_separator};{}$\6
${}\\{strcpy}(\\{name}+\\{len},\39\\{file\_name}[\T{0}]){}$;\C{ file name is
same as chapter name }\6
${}\\{dot}\K\\{file\_name\_ext}(\\{name}+\\{len});{}$\6
\&{if} (\\{dot})\1\5
${}{*}\\{dot}\K\T{0};{}$\2\6
${}\\{strcat}(\\{name}+\\{len},\39\.{".exp"}){}$;\C{ but with extension \PB{%
\.{".exp"}} }\6
\&{if} ${}(\\{fd}\K\\{fopen}(\\{name},\39\.{"r"})){}$\5
${}\{{}$\1\6
\\{fclose}(\\{fd});\6
${}\\{remember\_import\_file}(\\{name},\39\T{1},\39\T{3}){}$;\C{ 3 means: our
own export file }\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\N{0}{333}Book file.
Like \.{mCTANGLE}, \.{mCWEAVE} has to find out if we are dealing with a book
or a simple old style \.{CWEB} file.

\fi

\M{334}References to \.{mcommon.w}.
\Y\B\4\D$\\{longest\_name}$ \5
\T{1000}\par
\B\4\D$\\{long\_buf\_size}$ \5
$(\\{buf\_size}+\\{longest\_name}{}$)\par
\B\4\D$\\{max\_include\_depth}$ \5
\T{10}\par
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{extern} \&{char} \\{buffer}[\\{long\_buf\_size}];\6
\&{extern} \&{char} \\{file\_name}[\\{max\_include\_depth}][\\{max\_file\_name%
\_length}];\6
\&{extern} \&{char} \\{alt\_web\_file\_name}[\\{max\_file\_name\_length}];\6
\&{extern} \&{char} ${}{*}{*}\\{argv\_web},{}$ ${}{*}{*}\\{argv\_change},{}$
${}{*}{*}\\{argv\_out};{}$\6
\&{extern} \&{char} \\{tex\_file\_name}[\\{max\_file\_name\_length}];\6
\&{extern} \&{char} \\{alt\_web\_file\_name}[\\{max\_file\_name\_length}];\6
\&{extern} \&{char} \\{change\_file\_name}[\\{max\_file\_name\_length}];\par
\fi

\M{335}Each line in the book file starts with a keyword. They have one
of the following tokens.
\Y\B\4\D$\\{no\_book}$ \5
\T{0}\par
\B\4\D$\\{book\_program}$ \5
\T{1}\C{ book keywords }\par
\B\4\D$\\{book\_library}$ \5
\T{2}\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{int} \\{book\_type};\C{ what kind of book do we have (\PB{\\{no\_book}} if
old style) }\6
\&{char} \\{book\_file\_name}[\\{max\_file\_name\_length}];\C{ name of book
file }\6
\&{char} \\{book\_name}[\\{max\_file\_name\_length}];\C{ name of book }\6
\&{char} \\{chapter\_name}[\\{max\_file\_name\_length}];\C{ name of current
chapter }\6
\&{char} \\{out\_file\_name}[\\{max\_file\_name\_length}];\C{ name of \TeX\
file }\6
\&{char} \\{book\_dir}[\\{max\_file\_name\_length}];\C{ directory of current
book }\par
\fi

\M{336}Each book can have up to \PB{\\{max\_chapters}} chapters.
\Y\B\4\D$\\{max\_chapters}$ \5
\T{64}\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{int} \\{chapter\_no};\C{ current chapter number }\par
\fi

\M{337}Here, we do the check for a book file. Books have the file extension
of \.{.prg}.
\Y\B\4\X337:Check for book file\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \\{ret\_val}${}\K\T{0};{}$\6
\&{int} \\{len}${},{}$ \|c;\6
\&{char} ${}{*}\\{cp};{}$\7
\X338:Check if we should append \.{.prg} to \PB{\\{file\_name}[\T{0}]}\X;\6
${}\\{len}\K\\{strlen}(\\{file\_name}[\T{0}]);{}$\6
\&{if} ${}(\R\\{strcmp}(\\{file\_name}[\T{0}]+\\{len}-\T{4},\39\.{".prg"})\V%
\\{flags}[\.{'m'}]){}$\5
${}\{{}$\1\6
${}\\{book\_type}\K\T{1};{}$\6
${}\\{change\_file}\K\NULL;{}$\6
\\{reset\_input}(\,);\6
${}\\{strcpy}(\\{book\_file\_name},\39\\{file\_name}[\T{0}]);{}$\6
\X345:Get book directory\X;\6
\X346:Construct \PB{\\{book\_name}} out of \PB{\\{book\_file\_name}}\X;\6
\&{if} (\\{show\_progress})\1\5
${}\\{printf}(\.{"Book\ '\%s'\\n"},\39\\{book\_name});{}$\2\6
${}\\{tex\_file}\K\\{fopen}(\\{tex\_file\_name},\39\.{"w"});{}$\6
\&{if} ${}(\R\\{tex\_file}){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ open\ TeX\ f}\)\.{ile\ for\ book:\ "},\39\\{tex%
\_file\_name});{}$\2\6
\X21:Set initial values\X;\6
\X339:Read book file\X;\6
\\{fclose}(\\{file}[\T{0}]);\6
\&{if} (\\{change\_file})\5
${}\{{}$\1\6
\\{fclose}(\\{change\_file});\6
${}\\{change\_file}\K\NULL;{}$\6
\4${}\}{}$\2\6
\\{finish\_line}(\,);\6
\\{fclose}(\\{tex\_file});\6
\X343:Translate all chapters\X;\6
\&{return} \\{ret\_val};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U3.\fi

\M{338}If the web file argument is a file without a file extension, we try
give it \.{.prg}. If this files exists,
\PB{\\{file\_name}[\T{0}]} gets the \.{.prg} extension appended.
\Y\B\4\X338:Check if we should append \.{.prg} to \PB{\\{file\_name}[\T{0}]}%
\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp};{}$\6
\&{FILE} ${}{*}\|f;{}$\7
${}\\{strcpy}(\\{a\_file\_name},\39{*}\\{argv\_web});{}$\6
\&{if} ${}(\R\\{file\_name\_ext}(\\{a\_file\_name})){}$\5
${}\{{}$\C{ if no file extension }\1\6
${}\\{cp}\K\\{a\_file\_name}+\\{strlen}(\\{a\_file\_name});{}$\6
${}\\{strcpy}(\\{cp},\39\.{".prg"});{}$\6
\&{if} ${}((\|f\K\\{fopen}(\\{a\_file\_name},\39\.{"r"}))\I\NULL){}$\5
${}\{{}$\C{ \.{.prg} file exists }\1\6
\\{fclose}(\|f);\6
${}\\{strcpy}(\\{file\_name}[\T{0}],\39\\{a\_file\_name});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U337.\fi

\M{339}Now we read the book file line by line. All characters are copied to
the \TeX\ output file, except for commmands introduced by '\.{@}'.
Chapters are remembered for later processing. If we encounter \.{@m},
the makefile starts.

At the end of the book, we append commands to output the book index and
table of contents.
\Y\B\4\X339:Read book file\X${}\E{}$\6
\&{while} (\\{get\_line}(\,))\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}\E\\{limit}){}$\1\5
\\{out}(\.{'\\n'});\C{ empty line }\2\6
\\{finish\_line}(\,);\6
\&{while} ${}(\\{loc}<\\{limit}){}$\5
${}\{{}$\1\6
${}\|c\K{*}\\{loc}\PP;{}$\6
\&{if} ${}(\|c\E\.{'@'}){}$\5
${}\{{}$\1\6
\&{switch} ${}({*}\\{loc}\PP){}$\5
${}\{{}$\1\6
\4\&{case} \.{'@'}:\5
\\{out}(\.{'@'});\6
\&{break};\6
\4\&{case} \.{'c'}:\5
\X341:Remember chapter\X;\6
\X342:Output {\tt\BS input} for chapter\X;\5
\&{break};\6
\4\&{case} \.{'m'}:\5
\X344:Skip Makefile\X;\5
\&{break};\6
\4\&{default}:\5
\\{err\_print}(\.{"!\ Illegal\ @\ command}\)\.{\ in\ book"});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{out}(\|c);\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{out\_str}(\.{"\\\\let\\\\curjob\\\\jobn}\)\.{ame\\n"});\6
\\{out\_str}(\.{"\\\\binx\\n\\\\bfin\\n\\\\c}\)\.{on\\n"});\par
\U337.\fi

\M{340}Here, we store all chapter names and their change and output file names,
if they exist. We will postpone the processing of all chapters until we have
read the whole book.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{ch\_web\_name}[\\{max\_chapters}];{}$\6
\&{char} ${}{*}\\{ch\_change\_name}[\\{max\_chapters}];{}$\6
\&{char} ${}{*}\\{ch\_out\_name}[\\{max\_chapters}];{}$\6
\&{int} \\{n\_chapters\_remembered};\par
\fi

\M{341}So, at each occurrence of a \.{@c}, we store the following names in the
above array.
\Y\B\4\X341:Remember chapter\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp};{}$\7
\&{if} ${}(\\{n\_chapters\_remembered}\G\\{max\_chapters}){}$\1\5
\\{overflow}(\.{"chapters"});\2\6
${}{*}\\{limit}\K\T{0};{}$\6
${}\\{cp}\K\\{get\_name}(\\{loc},\39\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\5
${}\{{}$\1\6
${}\\{loc}\K\\{cp};{}$\6
${}\\{ch\_web\_name}[\\{n\_chapters\_remembered}]\K\\{strmem}(\\{a\_file%
\_name});{}$\6
${}\\{ch\_change\_name}[\\{n\_chapters\_remembered}]\K\NULL;{}$\6
${}\\{ch\_out\_name}[\\{n\_chapters\_remembered}]\K\NULL;{}$\6
${}\\{cp}\K\\{get\_name}(\\{loc},\39\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\5
${}\{{}$\1\6
${}\\{loc}\K\\{cp};{}$\6
${}\\{ch\_change\_name}[\\{n\_chapters\_remembered}]\K\\{strmem}(\\{a\_file%
\_name});{}$\6
${}\\{cp}\K\\{get\_name}(\\{loc},\39\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\5
${}\{{}$\1\6
${}\\{loc}\K\\{cp};{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name},\39\.{'.'});{}$\6
\&{if} (\\{cp})\1\5
${}\\{strcpy}(\\{cp},\39\.{".tex"});{}$\2\6
${}\\{ch\_out\_name}[\\{n\_chapters\_remembered}]\K\\{strmem}(\\{a\_file%
\_name});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
${}\\{n\_chapters\_remembered}\PP;{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{err\_print}(\.{"!\ Chapter\ name\ expe}\)\.{cted"});\2\6
\4${}\}{}$\2\par
\U339.\fi

\M{342}For each chapter, we construct an \.{\BS input} command in order
to input the corresponding \TeX\ file.
\Y\B\4\X342:Output {\tt\BS input} for chapter\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp};{}$\7
\\{out\_str}(\.{"\\\\input\ "});\6
\&{if} ${}(\\{ch\_out\_name}[\\{n\_chapters\_remembered}-\T{1}]){}$\1\5
${}\\{out\_str}(\\{ch\_out\_name}[\\{n\_chapters\_remembered}-\T{1}]);{}$\2\6
\&{else}\5
${}\{{}$\C{ derive name from web name }\1\6
${}\\{strcpy}(\\{a\_file\_name},\39\\{ch\_web\_name}[\\{n\_chapters%
\_remembered}-\T{1}]);{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
\\{out\_str}(\\{a\_file\_name});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U339.\fi

\M{343}When we have scanned the whole book file, we can finally start weaving
the individual chapters we have found in the book.
\Y\B\4\X343:Translate all chapters\X${}\E{}$\6
${}\{{}$\1\6
\&{char} ${}{*}\\{change\_exists},{}$ ${}{*}\\{out\_exists};{}$\7
\&{for} ${}(\\{chapter\_no}\K\T{0};{}$ ${}\\{chapter\_no}<\\{n\_chapters%
\_remembered};{}$ ${}\\{chapter\_no}\PP){}$\5
${}\{{}$\1\6
\&{if} (\\{show\_progress})\1\5
${}\\{printf}(\.{"\\nChapter\ \%d:"},\39\\{chapter\_no}+\T{1});{}$\2\6
${}\\{strcpy}(\\{chapter\_name},\39\\{book\_dir}){}$;\C{ relative to book
directory }\6
${}\\{strcat}(\\{chapter\_name},\39\\{ch\_web\_name}[\\{chapter\_no}]);{}$\6
${}\\{change\_exists}\K\\{ch\_change\_name}[\\{chapter\_no}];{}$\6
\&{if} (\\{change\_exists})\1\5
${}\\{strcpy}(\\{change\_file\_name},\39\\{change\_exists});{}$\2\6
${}\\{out\_exists}\K\\{ch\_out\_name}[\\{chapter\_no}];{}$\6
\&{if} (\\{out\_exists})\1\5
${}\\{strcpy}(\\{out\_file\_name},\39\\{out\_exists});{}$\2\6
\&{if} (\\{show\_progress})\1\5
${}\\{printf}(\.{"\%s\\n"},\39\\{chapter\_name});{}$\2\6
\X349:Weave chapter\X;\6
\4${}\}{}$\2\6
\\{make\_book\_xref}(\,);\6
\\{output\_adocs}(\,);\6
\&{if} (\\{ret\_val})\1\5
\\{printf}(\.{"\\n(Book\ not\ success}\)\.{fully\ translated.)\\n}\)\.{"});\2\6
\&{else} \&{if} (\\{show\_happiness})\1\5
\\{printf}(\.{"\\n(Book\ successfull}\)\.{y\ translated.)\\n"});\2\6
\4${}\}{}$\2\par
\U337.\fi

\M{344}For now, the makefile part is only skipped.
\Y\B\4\X344:Skip Makefile\X${}\E{}$\6
${}\{{}$\1\6
\&{while} ${}(\R\\{input\_has\_ended}){}$\1\5
\\{get\_line}(\,);\2\6
${}\\{loc}\K\\{limit};{}$\6
\4${}\}{}$\2\par
\U339.\fi

\M{345}
\Y\B\4\X345:Get book directory\X${}\E{}$\6
$\\{strcpy}(\\{book\_dir},\39\\{book\_file\_name});{}$\6
${}\\{cp}\K\\{file\_name\_part}(\\{book\_dir});{}$\6
${}{*}\\{cp}\K\T{0}{}$;\par
\U337.\fi

\M{346}
\Y\B\4\X346:Construct \PB{\\{book\_name}} out of \PB{\\{book\_file\_name}}\X${}%
\E{}$\6
$\\{cp}\K\\{file\_name\_part}(\\{file\_name}[\T{0}]);{}$\6
${}\\{strcpy}(\\{book\_name},\39\\{cp});{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{book\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0}{}$;\2\par
\U337.\fi

\M{347}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{get\_name}(\,);{}$\6
\&{extern} \&{int} \\{input\_ln}(\,);\par
\fi

\M{348}Copies a name from \PB{\\{cp}} to \PB{\\{buffer}}. The name maybe be
optionally quoted
and preceded by white space.
\Y\B\&{char} ${}{*}\\{get\_name}(\\{cp},\39\\{buffer}){}$\1\1\6
\&{char} ${}{*}\\{cp},{}$ ${}{*}\\{buffer};\2\2{}$\6
${}\{{}$\1\6
\&{int} \|i;\7
\&{while} ${}(\\{isspace}({*}\\{cp})){}$\1\5
${}\\{cp}\PP;{}$\2\6
\&{if} ${}({*}\\{cp}\E\.{'\\"'}){}$\5
${}\{{}$\1\6
${}\\{cp}\PP;{}$\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{max\_file\_name\_length};{}$ ${}\|i\PP){}$%
\1\6
\&{if} ${}({*}\\{cp}\E\.{'\\"'}){}$\5
${}\{{}$\1\6
${}{*}\\{buffer}\K\T{0};{}$\6
\&{return} ${}\PP\\{cp};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
${}{*}\\{buffer}\PP\K{*}\\{cp}\PP;{}$\2\2\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{max\_file\_name\_length};{}$ ${}\|i\PP){}$%
\1\6
\&{if} ${}(\R{*}\\{cp}\V\\{isspace}({*}\\{cp})){}$\5
${}\{{}$\1\6
${}{*}\\{buffer}\K\T{0};{}$\6
\&{if} ${}(\R\|i){}$\1\5
\&{return} \T{0};\2\6
\&{return} \\{cp};\6
\4${}\}{}$\2\6
\&{else}\1\5
${}{*}\\{buffer}\PP\K{*}\\{cp}\PP;{}$\2\2\6
\4${}\}{}$\2\6
${}{*}\\{buffer}\K\T{0};{}$\6
\&{return} \T{0};\6
\4${}\}{}$\2\par
\fi

\M{349}Weave the current chapter. We allocate space for a new argument vector
and let \.{mcommon.w} parse it as if it came from the user's imput line.
%"
\Y\B\4\X349:Weave chapter\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \|i;\6
\&{char} ${}{*}{*}\\{new\_argv},{}$ ${}{*}{*}\\{argv\_ptr};{}$\7
${}\\{argc}\K\\{ac};{}$\6
${}\\{new\_argv}\K\\{argv}\K{}$(\&{char} ${}{*}{*}){}$ \\{malloc}${}((\\{argc}+%
\T{3})*{}$\&{sizeof}(\&{char} ${}{*}));{}$\6
\&{if} ${}(\R\\{argv}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory,\ cannot}\)\.{\ weave\ "},\39\\{chapter%
\_name});{}$\2\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{argc};{}$ ${}\|i\PP){}$\1\5
${}\\{argv}[\|i]\K\\{av}[\|i];{}$\2\6
${}\\{argv\_ptr}\K\\{argv}+(\\{argv\_web}-\\{av});{}$\6
${}{*}\\{argv\_ptr}\K\\{chapter\_name}{}$;\C{ our chapter is the first argument
}\6
\&{if} (\\{argv\_change})\1\5
${}{*}\\{argv\_change}\K\.{"-"};{}$\2\6
\&{if} (\\{argv\_out})\1\5
${}{*}\\{argv\_out}\K\\{chapter\_name};{}$\2\6
\&{if} (\\{change\_exists})\5
${}\{{}$\1\6
\&{if} (\\{argv\_change})\1\5
${}\\{argv\_ptr}\K\\{argv}+(\\{argv\_change}-\\{av});{}$\2\6
\&{else}\1\5
${}\\{argv\_ptr}\K{\AND}\\{argv}[\\{argc}\PP];{}$\2\6
${}{*}\\{argv\_ptr}\K\\{change\_file\_name}{}$;\C{ optional change file as next
argument }\6
\&{if} (\\{out\_exists})\5
${}\{{}$\1\6
\&{if} (\\{argv\_out})\1\5
${}\\{argv\_ptr}\K\\{argv}+(\\{argv\_out}-\\{av});{}$\2\6
\&{else}\1\5
${}\\{argv\_ptr}\K{\AND}\\{argv}[\\{argc}\PP];{}$\2\6
${}{*}\\{argv\_ptr}\K\\{out\_file\_name}{}$;\C{ \TeX\ output file is last
argument }\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
${}\\{history}\K\T{0};{}$\6
${}\\{ret\_val}\MRL{{\OR}{\K}}\\{weave\_file}(\,){}$;\C{ weave it with these
arguments }\6
\X351:Remember \TeX\ file name of current chapter\X;\6
\\{free}(\\{new\_argv});\6
\4${}\}{}$\2\par
\U343.\fi

\M{350}The \TeX\ file names of all chapters
are stored for the final table of contents.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} ${}{*}\\{ch\_TeX\_name}[\\{max\_chapters}]{}$;\par
\fi

\M{351}
\Y\B\4\X351:Remember \TeX\ file name of current chapter\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \|i${}\K\\{chapter\_no};{}$\7
\&{if} ${}(\|i\G\\{max\_chapters}){}$\1\5
\\{overflow}(\.{"chapters"});\2\6
${}\\{ch\_TeX\_name}[\|i]\K\\{strmem}(\\{tex\_file\_name});{}$\6
\4${}\}{}$\2\par
\U349.\fi

\N{1}{352}Global index.
There we will be a final index at the end of the book which will only contain
those identifiers that are exported to other books or chapters.
Therefore, we have to go through the cross references of our current
chapter and write out all references that are not resolved within that
chapter for further use. All this happens in phase three.

They will go into three files, the \.{xid} file for exported identifiers,
the \.{sid} for shared identifiers and
the \.{iid} file for imported identifiers.

\fi

\M{353}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{make\_xid\_file}(\,);\par
\fi

\M{354}The \.{xid} and \.{sid} files
are written at the beginning of phase three of each chapter.
They will contain the names and all section numbers where they
are defined separated by \PB{\.{'\\t'}} from each other.
\Y\B\&{void} ${}\\{make\_xid\_file}(\\{file\_extension},\39\\{ref}){}$\1\1\6
\&{char} ${}{*}\\{file\_extension}{}$;\C{ \PB{\.{".xid"}} or \PB{\.{".sid"}} }\6
\&{struct} \\{external\_reference} ${}{*}\\{ref}{}$;\C{ \PB{\\{own\_export}} or
\PB{\\{own\_shared}} }\2\2\6
${}\{{}$\1\6
\&{name\_pointer} \|p;\6
\&{int} \\{len}${},{}$ \|i;\6
\&{xref\_pointer} \\{xp};\6
\&{boolean} \\{name\_written};\6
\&{FILE} ${}{*}\\{xid\_file}\K\NULL{}$;\C{ not opened yet }\6
\&{char} ${}{*}\\{cp};{}$\7
${}\\{strcpy}(\\{a\_file\_name},\39\\{tex\_file\_name});{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
${}\\{strcat}(\\{a\_file\_name},\39\\{file\_extension});{}$\6
\&{for} ${}(\|p\K\\{name\_dir}+\T{1};{}$ ${}\|p<\\{name\_ptr};{}$ ${}\|p\PP){}$%
\5
${}\{{}$\1\6
\&{if} ${}(\|p\MG\\{ilk}\E\\{normal}){}$\5
${}\{{}$\1\6
${}\\{len}\K\|p[\T{1}].\\{byte\_start}-\|p\MG\\{byte\_start};{}$\6
${}\\{name\_written}\K\T{0};{}$\6
\&{for} ${}(\\{xp}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$ ${}\\{xp}\I{%
\AND}\\{xmem}[\T{0}];{}$ ${}\\{xp}\K\\{xp}\MG\\{xlink}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{xp}\MG\\{ext\_ref}\E\\{ref}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\\{xid\_file}){}$\5
${}\{{}$\1\6
${}\\{xid\_file}\K\\{fopen}(\\{a\_file\_name},\39\.{"w"});{}$\6
\&{if} ${}(\R\\{xid\_file}){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ create\ xid}\)\.{/sid\ file:\ "},\39\\{a\_file%
\_name});{}$\2\6
\4${}\}{}$\2\6
\&{if} ${}(\R\\{name\_written}){}$\5
${}\{{}$\1\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{len};{}$ ${}\|i\PP){}$\1\5
${}\\{putc}(\|p\MG\\{byte\_start}[\|i],\39\\{xid\_file});{}$\2\6
${}\\{name\_written}\K\T{1};{}$\6
\4${}\}{}$\2\6
${}\\{fprintf}(\\{xid\_file},\39\.{"\\t\%d"},\39\\{xp}\MG\\{num}\MOD\\{def%
\_flag});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} (\\{name\_written})\1\5
${}\\{putc}(\.{'\\n'},\39\\{xid\_file});{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} (\\{xid\_file})\1\5
\\{fclose}(\\{xid\_file});\2\6
\&{else}\1\5
\\{remove}(\\{a\_file\_name});\2\6
\4${}\}{}$\2\par
\fi

\M{355}At the end of the book, when all chapters will have been processed,
we will read all the \.{xid} files previously created and store the
identifiers in the name memory.
\Y\B\&{void} \\{read\_xid\_files}(\\{file\_extension})\1\1\6
\&{char} ${}{*}\\{file\_extension};\2\2{}$\6
${}\{{}$\1\6
\&{int} \\{ch}${},{}$ \\{sec};\6
\&{char} ${}{*}\\{cp};{}$\6
\&{FILE} ${}{*}\\{xid\_file};{}$\6
\&{name\_pointer} \|p;\7
\\{init\_common\_ptrs}(\,);\C{ clear symbol table }\6
${}\\{xref\_ptr}\K\\{xmem};{}$\6
${}\\{name\_dir}\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xmem};\7
\&{for} ${}(\\{ch}\K\\{chapter\_no}-\T{1};{}$ ${}\\{ch}\G\T{0};{}$ ${}\\{ch}%
\MM){}$\5
${}\{{}$\1\6
${}\\{strcpy}(\\{a\_file\_name},\39\\{ch\_TeX\_name}[\\{ch}]);{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
${}\\{strcat}(\\{a\_file\_name},\39\\{file\_extension});{}$\6
${}\\{xid\_file}\K\\{fopen}(\\{a\_file\_name},\39\.{"r"});{}$\6
\&{if} (\\{xid\_file})\5
${}\{{}$\1\6
${}\\{ext\_ref}\K\\{new\_ext\_ref}(\.{""},\39\\{ch}+\T{1});{}$\6
\&{while} ${}(\\{fscanf}(\\{xid\_file},\39\.{"\%s"},\39\\{buffer})\E\T{1}){}$\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{buffer},\39\NULL,\39\\{normal});{}$\6
${}\\{fgets}(\\{buffer},\39{}$\&{sizeof} (\\{buffer})${},\39\\{xid\_file});{}$\6
${}\\{cp}\K\\{buffer};{}$\6
\&{do}\5
${}\{{}$\1\6
\&{while} ${}(\\{isspace}({*}\\{cp})){}$\1\5
${}\\{cp}\PP;{}$\2\6
${}\\{sscanf}(\\{cp},\39\.{"\%d"},\39{\AND}\\{sec});{}$\6
${}\\{section\_count}\K{}$(\&{sixteen\_bits}) \\{sec};\6
${}\\{xref\_switch}\K\\{def\_flag};{}$\6
\\{underline\_xref}(\|p);\6
${}\\{cp}\K\\{strchr}(\\{cp},\39\.{'\\t'});{}$\6
\4${}\}{}$\2\5
\&{while} (\\{cp});\6
\4${}\}{}$\2\6
\\{fclose}(\\{xid\_file});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{356}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{make\_iid\_file}(\,);\par
\fi

\M{357}Making the \.{iid} file is a little bit like making the \.{xid} file,
except that we must include the referenced books.
Lines, that contain book names and chapter numbers begin with an
asterisk \.{*}, followed by the book name and the chapter number,
separated by a tabulator. A typical line would be:\smallskip

\line{\.{*testbook\BS t2}\hfill}

\smallskip\noindent
Lines like this one are at the beginning of the file and each line
gets a number, so that these books can be referenced.

The remaining lines contain identifier names and section numbers together
with the number of the referenced book in parentheses.\smallskip

\line{\.{ testvar\BS t5(1)}\hfill}

\smallskip\noindent
This means that the identifier {\it testvar} is imported from section~5
of the first book stated in the \.{iid} file (i.e.~\.{testbook}, chapter~2).
\Y\B\&{void} \\{make\_iid\_file}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{int} \\{len}${},{}$ \|i;\6
\&{name\_pointer} \|p;\6
\&{xref\_pointer} \\{xp};\6
\&{boolean} \\{name\_written};\6
\&{FILE} ${}{*}\\{iid\_file}\K\NULL;{}$\6
\&{char} ${}{*}\\{cp};{}$\6
\&{struct} \\{external\_reference} ${}{*}\\{ref};{}$\7
${}\\{strcpy}(\\{a\_file\_name},\39\\{tex\_file\_name});{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
${}\\{strcat}(\\{a\_file\_name},\39\.{".iid"});{}$\6
\&{for} ${}(\|p\K\\{name\_dir}+\T{1};{}$ ${}\|p<\\{name\_ptr};{}$ ${}\|p\PP){}$%
\5
${}\{{}$\1\6
\&{if} ${}(\|p\MG\\{ilk}\E\\{normal}){}$\5
${}\{{}$\1\6
${}\\{len}\K\|p[\T{1}].\\{byte\_start}-\|p\MG\\{byte\_start};{}$\6
${}\\{name\_written}\K\T{0};{}$\6
\&{for} ${}(\\{xp}\K{}$(\&{xref\_pointer}) \|p${}\MG\\{xref};{}$ ${}\\{xp}\I{%
\AND}\\{xmem}[\T{0}];{}$ ${}\\{xp}\K\\{xp}\MG\\{xlink}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{xp}\MG\\{ext\_ref}\I\\{own\_export}\W\\{xp}\MG\\{ext\_ref}\I%
\\{own\_shared}\W\\{xp}\MG\\{ext\_ref}\W{*}\\{xp}\MG\\{ext\_ref}\MG\\{book%
\_name}){}$\5
${}\{{}$\1\6
\&{if} ${}(\R\\{iid\_file}){}$\1\5
\X358:Create the {\tt iid} file\X;\2\6
\&{if} ${}(\R\\{name\_written}){}$\5
${}\{{}$\1\6
${}\\{putc}(\.{'\ '},\39\\{iid\_file});{}$\6
\&{for} ${}(\|i\K\T{0};{}$ ${}\|i<\\{len};{}$ ${}\|i\PP){}$\1\5
${}\\{putc}(\|p\MG\\{byte\_start}[\|i],\39\\{iid\_file});{}$\2\6
${}\\{name\_written}\K\T{1};{}$\6
\4${}\}{}$\2\6
\&{for} ${}(\|i\K\T{0},\39\\{ref}\K\\{first\_ext\_ref};{}$ \\{ref}; ${}\|i\PP,%
\39\\{ref}\K\\{ref}\MG\\{next\_ext\_ref}){}$\1\6
\&{if} ${}(\\{ref}\E\\{xp}\MG\\{ext\_ref}){}$\1\5
\&{break};\2\2\6
${}\\{fprintf}(\\{iid\_file},\39\.{"\\t\%d(\%d)"},\39\\{xp}\MG\\{num}\MOD\\{def%
\_flag},\39\|i);{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} (\\{name\_written})\1\5
${}\\{putc}(\.{'\\n'},\39\\{iid\_file});{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{if} (\\{iid\_file})\1\5
\\{fclose}(\\{iid\_file});\2\6
\&{else}\1\5
\\{remove}(\\{a\_file\_name});\2\6
\4${}\}{}$\2\par
\fi

\M{358}As mentioned above, the beginning of the \.{iid} file consists of a list
of books referenced. When we create the \.{iid} file, we also write this
list.
\Y\B\4\X358:Create the {\tt iid} file\X${}\E{}$\6
${}\{{}$\1\6
${}\\{iid\_file}\K\\{fopen}(\\{a\_file\_name},\39\.{"w"});{}$\6
\&{if} ${}(\R\\{iid\_file}){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ create\ iid}\)\.{\ file:\ "},\39\\{a\_file%
\_name});{}$\2\6
\&{for} ${}(\\{ref}\K\\{first\_ext\_ref};{}$ \\{ref}; ${}\\{ref}\K\\{ref}\MG%
\\{next\_ext\_ref}){}$\1\5
${}\\{fprintf}(\\{iid\_file},\39\.{"*\%s\\t\%d\\n"},\39\\{ref}\MG\\{book%
\_name},\39\\{ref}\MG\\{chapter});{}$\2\6
\4${}\}{}$\2\par
\U357.\fi

\M{359}The following function reads the \.{iid} file created above and
inserts all referenced books that are different from our current
book into the list of external references \PB{\\{first\_ext\_ref}}.
The identifiers are inserted into the symbol table with the right
section numbers.
\Y\B\4\D$\\{max\_ref\_per\_chapter}$ \5
\T{128}\par
\Y\B\&{void} \\{read\_iid\_files}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{int} \\{ch}${},{}$ \|c${},{}$ \\{sec};\6
\&{char} ${}{*}\\{cp};{}$\6
\&{FILE} ${}{*}\\{iid\_file};{}$\6
\&{name\_pointer} \|p;\6
\&{struct} \\{external\_reference} ${}{*}\\{ch\_ext\_refs}[\\{max\_ref\_per%
\_chapter}];{}$\6
\&{int} \\{n\_ch\_ext\_refs};\7
\\{init\_common\_ptrs}(\,);\C{ clear symbol table }\6
${}\\{xref\_ptr}\K\\{xmem};{}$\6
${}\\{name\_dir}\MG\\{xref}\K{}$(\&{char} ${}{*}){}$ \\{xmem};\6
\&{for} ${}(\\{ch}\K\\{chapter\_no}-\T{1};{}$ ${}\\{ch}\G\T{0};{}$ ${}\\{ch}%
\MM){}$\5
${}\{{}$\1\6
${}\\{strcpy}(\\{a\_file\_name},\39\\{ch\_TeX\_name}[\\{ch}]);{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{a\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
${}\\{strcat}(\\{a\_file\_name},\39\.{".iid"});{}$\6
${}\\{iid\_file}\K\\{fopen}(\\{a\_file\_name},\39\.{"r"});{}$\6
\&{if} (\\{iid\_file})\5
${}\{{}$\1\6
${}\\{n\_ch\_ext\_refs}\K\T{0};{}$\6
\&{while} ${}((\|c\K\\{getc}(\\{iid\_file}))\I\.{EOF}){}$\5
${}\{{}$\1\6
${}\\{fgets}(\\{buffer},\39{}$\&{sizeof} (\\{buffer})${},\39\\{iid\_file});{}$\6
\&{if} ${}((\\{cp}\K\\{strchr}(\\{buffer},\39\.{'\\t'}))\I\NULL){}$\5
${}\{{}$\1\6
${}{*}\\{cp}\PP\K\T{0};{}$\6
\&{if} ${}(\|c\E\.{'*'}){}$\5
${}\{{}$\C{ indicates a new chapter of a book }\1\6
${}\\{sscanf}(\\{cp},\39\.{"\%d"},\39{\AND}\|c);{}$\6
\&{if} ${}(\\{strcmp}(\\{buffer},\39\\{book\_name})){}$\1\5
${}\\{ext\_ref}\K\\{new\_ext\_ref}(\\{buffer},\39\|c);{}$\2\6
\&{else}\1\5
${}\\{ext\_ref}\K\NULL;{}$\2\6
\&{if} ${}(\\{n\_ch\_ext\_refs}\G\\{max\_ref\_per\_chapter}){}$\1\5
\\{overflow}(\.{"maximum\ external\ re}\)\.{ferences\ per\ chapter}\)\.{"});\2\6
${}\\{ch\_ext\_refs}[\\{n\_ch\_ext\_refs}\PP]\K\\{ext\_ref};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\C{ indicates an identifier we have references to }\1\6
${}\\{sscanf}(\\{cp},\39\.{"\%d(\%d)"},\39{\AND}\\{sec},\39{\AND}\|c);{}$\6
${}\\{section\_count}\K{}$(\&{sixteen\_bits}) \\{sec};\6
${}\\{ext\_ref}\K\\{ch\_ext\_refs}[\|c];{}$\6
\&{if} (\\{ext\_ref})\5
${}\{{}$\1\6
${}\|p\K\\{id\_lookup}(\\{buffer},\39\NULL,\39\\{normal});{}$\6
${}\\{xref\_switch}\K\\{def\_flag};{}$\6
\\{underline\_xref}(\|p);\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\\{fclose}(\\{iid\_file});\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{360}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{make\_book\_xref}(\,);\par
\fi

\M{361}With all the information gained from the \.{xid}, \.{sid} and
\.{iid} files, we can finally
output the book index for exported and imported names.
\Y\B\&{void} \\{make\_book\_xref}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{char} ${}{*}\\{cp};{}$\7
\&{if} (\\{no\_xref})\1\5
\&{return};\2\6
${}\\{dag\_seen}\K\\{ddag\_seen}\K\T{0};{}$\6
${}\\{strcpy}(\\{idx\_file\_name},\39\\{book\_name});{}$\6
${}\\{cp}\K\\{file\_name\_ext}(\\{idx\_file\_name});{}$\6
\&{if} (\\{cp})\1\5
${}{*}\\{cp}\K\T{0};{}$\2\6
${}\\{strcat}(\\{idx\_file\_name},\39\.{".idx"});{}$\6
${}\\{idx\_file}\K\\{fopen}(\\{idx\_file\_name},\39\.{"w"});{}$\6
\&{if} ${}(\R\\{idx\_file}){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ create\ ind}\)\.{ex\ file\ for\ book:\ "},\39\\{idx%
\_file\_name});{}$\2\6
${}\\{active\_file}\K\\{idx\_file};{}$\6
\\{read\_xid\_files}(\.{".sid"});\6
\&{if} ${}(\\{xref\_ptr}\I\\{xmem}){}$\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\shrnames\\n"});\6
\\{sort\_and\_output\_index}(\,);\6
\\{output\_referenced\_books}(\,);\6
\\{out\_str}(\.{"\\\\vfill\\\\eject\\n"});\6
\4${}\}{}$\2\6
\\{read\_xid\_files}(\.{".xid"});\6
\&{if} ${}(\\{xref\_ptr}\I\\{xmem}){}$\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\expnames\\n"});\6
\\{sort\_and\_output\_index}(\,);\6
\\{output\_referenced\_books}(\,);\6
\\{out\_str}(\.{"\\\\vfill\\\\eject\\n"});\6
\4${}\}{}$\2\6
\\{read\_iid\_files}(\,);\6
\&{if} ${}(\\{xref\_ptr}\I\\{xmem}){}$\5
${}\{{}$\1\6
\\{out\_str}(\.{"\\\\impnames\\n"});\6
\\{sort\_and\_output\_index}(\,);\6
\\{output\_referenced\_books}(\,);\6
\\{out\_str}(\.{"\\\\vfill\\\\eject\\n"});\6
\4${}\}{}$\2\6
\\{finish\_line}(\,);\6
\\{fclose}(\\{idx\_file});\6
\4${}\}{}$\2\par
\fi

\M{362}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{sort\_and\_output\_index}(\,);\par
\fi

\M{363}The following variable determines, if index entries of identifiers,
that are only externally defined, but never referenced from within the book
are output in the index.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{boolean} \\{keep\_only\_ext\_def}${}\K\T{0}{}$;\par
\fi

\M{364}Sort the index and output it, including those entries that are only
externally defined and never referenced (as they are defined in our book).
\Y\B\&{void} \\{sort\_and\_output\_index}(\,)\1\1\2\2\6
${}\{{}$\1\6
${}\\{keep\_only\_ext\_def}\K\T{1};{}$\6
\X258:Do the first pass of sorting\X;\6
\X267:Sort and output the index\X;\6
${}\\{keep\_only\_ext\_def}\K\T{0};{}$\6
\4${}\}{}$\2\par
\fi

\N{1}{365}Autodocs.
Autodocs contain interface documentation and can occur in the \TeX
part of a program. They have a class, a name and a description, each
enclosed in braces. All descriptions are grouped by their class, sorted
by their name and written into separate \TeX\ files.

\fi

\M{366}Since we want to group autodocs by their class, we need a
\PB{\\{adoc\_class}}-structure that contains a linked list of
all autodocs of the same class.
\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{struct} \\{adoc\_class} ${}\{{}$\1\6
\&{struct} \\{adoc\_class} ${}{*}\\{next}{}$;\C{ next autodoc class }\6
\&{struct} \\{adoc} ${}{*}\\{first\_adoc}{}$;\C{ first autodoc entry of this
class }\6
\&{char} \\{class\_name}[\T{2}];\C{ name of the class }\2\6
${}\}{}$;\par
\fi

\M{367}Autodoc entries are sorted by name and have the following form:
\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{struct} \\{adoc} ${}\{{}$\1\6
\&{struct} \\{adoc} ${}{*}\\{next}{}$;\C{ next autodoc entry of same class }\6
\&{char} ${}{*}\\{description}{}$;\C{ explaining text }\6
\&{char} \\{name}[\T{2}];\C{ name of autodoc entry }\2\6
${}\}{}$;\par
\fi

\M{368}\PB{\\{first\_adoc\_class}} points to the head of the autodoc class
list.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{struct} \\{adoc\_class} ${}{*}\\{first\_adoc\_class}{}$;\par
\fi

\M{369}
\Y\B\4\X369:Initialize at the very beginning\X${}\E{}$\6
$\\{first\_adoc\_class}\K\NULL{}$;\par
\U3.\fi

\M{370}The following functions looks up an autodoc class. The class name starts
at \PB{\\{name\_start}} and ends at \PB{\\{name\_end}}.
If the class is not already part of the \PB{\\{first\_adoc\_class}} list, a new
entry
is created and inserted into the list.
\Y\B\&{struct} \\{adoc\_class} ${}{*}\\{lookup\_adoc\_class}(\\{name\_start},%
\39\\{name\_end}){}$\1\1\6
\&{char} ${}{*}\\{name\_start},{}$ ${}{*}\\{name\_end};\2\2{}$\6
${}\{{}$\1\6
\&{struct} \\{adoc\_class} ${}{*}\\{ac},{}$ ${}{*}\\{last\_ac}\K\NULL;{}$\6
\&{int} \\{len}${}\K\\{name\_end}-\\{name\_start};{}$\7
\&{if} ${}(\\{name\_start}<\\{name\_end}){}$\1\6
\&{for} ${}(\\{ac}\K\\{first\_adoc\_class};{}$ \\{ac}; ${}\\{ac}\K\\{ac}\MG%
\\{next}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{len}\E\\{strlen}(\\{ac}\MG\\{class\_name})\W\R\\{strncmp}(\\{name%
\_start},\39\\{ac}\MG\\{class\_name},\39\\{len})){}$\1\5
\&{return} \\{ac};\2\6
${}\\{last\_ac}\K\\{ac};{}$\6
\4${}\}{}$\2\2\6
${}\\{ac}\K{}$(\&{struct} \\{adoc\_class} ${}{*}){}$ \\{malloc}(\&{sizeof}
${}({*}\\{ac})+\\{len}-\T{1});{}$\6
\&{if} ${}(\R\\{ac}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory"},\39\.{"\ for\ autodoc\ class"});{}$\2\6
${}\\{strncpy}(\\{ac}\MG\\{class\_name},\39\\{name\_start},\39\\{len});{}$\6
${}\\{ac}\MG\\{class\_name}[\\{len}]\K\T{0};{}$\6
\&{if} ${}(\R\\{last\_ac}){}$\5
${}\{{}$\1\6
${}\\{ac}\MG\\{next}\K\\{first\_adoc\_class};{}$\6
${}\\{first\_adoc\_class}\K\\{ac};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{ac}\MG\\{next}\K\\{last\_ac}\MG\\{next};{}$\6
${}\\{last\_ac}\MG\\{next}\K\\{ac};{}$\6
\4${}\}{}$\2\6
${}\\{ac}\MG\\{first\_adoc}\K\NULL;{}$\6
\&{return} \\{ac};\6
\4${}\}{}$\2\par
\fi

\M{371}The linked list of autodocs in an autodoc class is always kept sorted.
The following function inserts a new entry in the given autodoc class list.
\Y\B\&{struct} \\{adoc} ${}{*}\\{insert\_adoc}(\\{ac},\39\\{name\_start},\39%
\\{name\_end}){}$\1\1\6
\&{struct} \\{adoc\_class} ${}{*}\\{ac};{}$\6
\&{char} ${}{*}\\{name\_start},{}$ ${}{*}\\{name\_end};\2\2{}$\6
${}\{{}$\1\6
\&{int} \\{len}${}\K\\{name\_end}-\\{name\_start};{}$\6
\&{struct} \\{adoc} ${}{*}\|a\K{}$(\&{struct} \\{adoc} ${}{*}){}$ \\{malloc}(%
\&{sizeof} ${}({*}\|a)+\\{len}-\T{1}),{}$ ${}{*}\\{a2},{}$ ${}{*}\\{a3};{}$\7
\&{if} ${}(\R\|a){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory"},\39\.{"\ for\ autodoc\ entry"});{}$\2\6
${}\\{strncpy}(\|a\MG\\{name},\39\\{name\_start},\39\\{len});{}$\6
${}\|a\MG\\{name}[\\{len}]\K\T{0};{}$\6
${}\|a\MG\\{description}\K\NULL;{}$\6
${}\\{a3}\K\NULL;{}$\6
\&{for} ${}(\\{a2}\K\\{ac}\MG\\{first\_adoc};{}$ \\{a2}; ${}\\{a2}\K\\{a2}\MG%
\\{next}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{strcmp}(\\{a2}\MG\\{name},\39\|a\MG\\{name})>\T{0}){}$\1\5
\&{break};\2\6
${}\\{a3}\K\\{a2};{}$\6
\4${}\}{}$\2\6
\&{if} (\\{a3})\5
${}\{{}$\1\6
${}\|a\MG\\{next}\K\\{a3}\MG\\{next};{}$\6
${}\\{a3}\MG\\{next}\K\|a;{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\|a\MG\\{next}\K\\{ac}\MG\\{first\_adoc};{}$\6
${}\\{ac}\MG\\{first\_adoc}\K\|a;{}$\6
\4${}\}{}$\2\6
\&{return} \|a;\6
\4${}\}{}$\2\par
\fi

\M{372}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{process\_autodoc}(\,);\par
\fi

\M{373}If we encounter a '\.{@a}' command in the \TeX\ part of a section during
phase two, we insert it into the autodoc dictionary.
\Y\B\&{void} \\{process\_autodoc}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{int} \|c;\6
\&{char} ${}{*}\\{cp};{}$\6
\&{struct} \\{adoc\_class} ${}{*}\\{ac};{}$\6
\&{char} ${}{*}\\{name\_start},{}$ ${}{*}\\{name\_end},{}$ ${}{*}\\{desc};{}$\6
\&{struct} \\{adoc} ${}{*}\|a;{}$\7
\&{do}\5
${}\|c\K\\{get\_next}(\,);{}$\5
\&{while} ${}(\|c\E\.{'\\n'});{}$\6
\&{if} ${}(\|c\I\.{'\{'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Autodoc\ class\ nam}\)\.{e\ enclosed\ in\ braces}\)\.{\
expected"});\6
\&{return};\6
\4${}\}{}$\2\6
\&{for} ${}(\\{cp}\K\\{loc};{}$  ; \,)\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ '\}'\ for\ autodoc\ c}\)\.{lass\ missing"});\6
\&{return};\6
\4${}\}{}$\2\6
${}\|c\K{*}\\{loc}\PP;{}$\6
\&{if} ${}(\|c\E\.{'\}'}){}$\1\5
\&{break};\2\6
\4${}\}{}$\2\6
${}\\{ac}\K\\{lookup\_adoc\_class}(\\{cp},\39\\{loc}-\T{1});{}$\6
\X374:Read autodoc name \PB{\\{name\_start}}, \PB{\\{name\_end}}\X;\6
${}\|a\K\\{insert\_adoc}(\\{ac},\39\\{name\_start},\39\\{name\_end});{}$\6
\X376:Read autodoc description \PB{\\{desc}}\X;\6
${}\|a\MG\\{description}\K\\{desc};{}$\6
\4${}\}{}$\2\par
\fi

\M{374}The class is followed by a name, which is also enclosed in braces.
We now read this name and store its start and end position in
\PB{\\{name\_start}} and \PB{\\{name\_end}}, respectively.
\Y\B\4\X374:Read autodoc name \PB{\\{name\_start}}, \PB{\\{name\_end}}\X${}%
\E{}$\6
${}\{{}$\1\6
\&{do}\5
${}\|c\K\\{get\_next}(\,);{}$\5
\&{while} ${}(\|c\E\.{'\\n'});{}$\6
\&{if} ${}(\|c\I\.{'\{'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ '\{'\ for\ autodoc\ n}\)\.{ame\ expected"});\6
\&{return};\6
\4${}\}{}$\2\6
\&{for} ${}(\\{name\_start}\K\\{loc};{}$  ; \,)\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ '\}'\ for\ autodoc\ n}\)\.{ame\ missing"});\6
\&{return};\6
\4${}\}{}$\2\6
${}\|c\K{*}\\{loc}\PP;{}$\6
\&{if} ${}(\|c\E\.{'\}'}){}$\1\5
\&{break};\2\6
\4${}\}{}$\2\6
${}\\{name\_end}\K\\{loc}-\T{1};{}$\6
\4${}\}{}$\2\par
\U373.\fi

\M{375}Each description is first stored in the static memory pool \PB{\\{desc%
\_mem}}
until it has been read in and its real length is known. Then we can
allocate memory for it and copy it there.

In phase one, \PB{\\{desc\_mem}} is also used for copy buffers.
\Y\B\4\D$\\{max\_desc\_size}$ \5
\T{10240}\par
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{char} \\{desc\_mem}[\\{max\_desc\_size}];\6
\&{char} ${}{*}\\{desc\_mem\_end}\K\\{desc\_mem}+\\{max\_desc\_size};{}$\6
\&{char} ${}{*}\\{desc\_ptr};{}$\6
\&{boolean} \\{is\_adoc};\C{ causes output to be written to \PB{\\{desc\_mem}}
}\par
\fi

\M{376}Read autodoc description which starts with an opening brace and ends
with
the corresponding closing brace. The variable \PB{\\{desc}} will point to
allocated memory which contains the whole description.
\Y\B\4\D$\\{app\_adoc}(\|c)$ \6
${}\{{}$\1\6
\&{if} ${}(\\{desc\_ptr}\G\\{desc\_mem\_end}){}$\1\5
\\{overflow}(\.{"autodoc\ description}\)\.{"});\2\6
\&{if} (\|c)\1\5
${}{*}\\{desc\_ptr}\PP\K(\|c);{}$\2\6
\4${}\}{}$\2\par
\Y\B\4\X376:Read autodoc description \PB{\\{desc}}\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \\{braces};\7
\&{do}\5
${}\|c\K\\{get\_next}(\,);{}$\5
\&{while} ${}(\|c\E\.{'\\n'});{}$\6
\&{if} ${}(\|c\I\.{'\{'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ '\{'\ for\ autodoc\ d}\)\.{escription\ expected"});\6
\&{return};\6
\4${}\}{}$\2\6
${}\\{is\_adoc}\K\T{1};{}$\6
${}\\{braces}\K\T{1};{}$\6
${}\\{desc\_ptr}\K\\{desc\_mem};{}$\6
\&{for} ( ;  ; \,)\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}\G\\{limit}){}$\5
${}\{{}$\1\6
\&{if} ${}(\\{get\_line}(\,)\E\T{0}){}$\5
${}\{{}$\1\6
${}\\{is\_adoc}\K\T{0};{}$\6
\&{return};\6
\4${}\}{}$\2\6
\\{finish\_line}(\,);\6
\4${}\}{}$\2\6
${}\\{next\_control}\K{*}\\{loc}\PP;{}$\6
\&{if} ${}(\\{next\_control}\E\.{'@'}){}$\5
${}\{{}$\1\6
${}\\{next\_control}\K{*}\\{loc}\PP;{}$\6
\&{if} ${}(\\{next\_control}\E\.{'e'}\V\\{next\_control}\E\.{'E'}){}$\5
${}\{{}$\1\6
\\{process\_example}(\,);\6
${}\\{next\_control}\K\\{ignore};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'\_'}){}$\5
${}\{{}$\1\6
\X377:Special command seen in autodoc section (phase two)\X;\6
${}\\{next\_control}\K\\{ignore};{}$\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\I\.{'@'}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Only\ @@,\ @\_\ or\ @e}\)\.{\ allowed\ in\ autodoc\ }\)%
\.{section"});\6
\&{return};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'\{'}){}$\1\5
${}\\{braces}\PP;{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'\}'}\W\MM\\{braces}\E\T{0}){}$\1\5
\&{break};\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\.{'|'}){}$\5
${}\{{}$\1\6
${}{*}\\{limit}\K\.{'|'};{}$\6
\\{init\_stack};\6
\\{output\_C}(\,);\6
${}\\{next\_control}\K\\{ignore};{}$\6
\4${}\}{}$\2\6
\&{if} (\\{next\_control})\1\5
\\{out}(\\{next\_control});\2\6
\4${}\}{}$\2\6
\\{finish\_line}(\,);\6
${}\\{desc}\K\\{malloc}(\\{desc\_ptr}-\\{desc\_mem}+\T{1});{}$\6
\&{if} ${}(\R\\{desc}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory"},\39\.{"\ for\ autodoc\ descri}\)%
\.{ption"});{}$\2\6
${}\\{strncpy}(\\{desc},\39\\{desc\_mem},\39\\{desc\_ptr}-\\{desc\_mem});{}$\6
${}\\{desc}[\\{desc\_ptr}-\\{desc\_mem}]\K\T{0};{}$\6
${}\\{is\_adoc}\K\T{0};{}$\6
\4${}\}{}$\2\par
\U373.\fi

\M{377}The only special commands that are admitted in autodoc sections are
mark/copy/paste.
\Y\B\4\X377:Special command seen in autodoc section (phase two)\X${}\E{}$\6
${}\{{}$\1\6
${}\|c\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\|c\E\\{identifier}){}$\5
${}\{{}$\1\6
\&{name\_pointer} \|p;\7
${}\|p\K\\{id\_lookup}(\\{id\_first},\39\\{id\_loc},\39\\{normal});{}$\6
\&{if} ${}(\|p\E\\{id\_paste}){}$\5
${}\{{}$\1\6
${}\|c\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\|c\E\\{string}){}$\5
${}\{{}$\1\6
${}{*}\\{id\_loc}\K\T{0};{}$\6
\\{paste}(\\{id\_first});\6
${}\|c\K\\{ignore};{}$\6
\4${}\}{}$\2\6
\&{else}\1\5
\\{err\_print}(\.{"!\ Name\ of\ copy\ buff}\)\.{er\ expected"});\2\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\|p\E\\{id\_mark}){}$\1\5
${}\|c\K\\{get\_next}(\,){}$;\C{ skip string }\2\6
\&{else} \&{if} ${}(\|p\I\\{id\_copy}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Not\ allowed\ in\ au}\)\.{todoc"});\6
\&{return};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\U376.\fi

\M{378}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{output\_adocs}(\,);\par
\fi

\M{379}We now have a complete set of autodoc entries and want to output
them to \TeX\ files, one for each class. The \TeX\ files have the
same name as the autodoc class and the file name extension \PB{\.{".adc"}}.

In addition, we create a file called
\.{autodoc.tex} that is the book file that includes all \.{adc} files.
\Y\B\&{void} \\{output\_adocs}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{struct} \\{adoc\_class} ${}{*}\\{ac};{}$\6
\&{struct} \\{adoc} ${}{*}\|a;{}$\6
\&{FILE} ${}{*}\\{adoc\_file},{}$ ${}{*}\\{adc\_book\_file};{}$\7
\&{if} ${}(\R\\{first\_adoc\_class}){}$\1\5
\&{return};\2\6
${}\\{strcpy}(\\{a\_file\_name},\39\.{"autodoc.tex"});{}$\6
${}\\{adc\_book\_file}\K\\{fopen}(\\{a\_file\_name},\39\.{"w"});{}$\6
\&{if} ${}(\R\\{adc\_book\_file}){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ create\ aut}\)\.{odoc\ file:"},\39\\{a\_file%
\_name});{}$\2\6
${}\\{fprintf}(\\{adc\_book\_file},\39\.{"\\\\def\\\\adocjob\{\%s\}\\}\)\.{n"},%
\39\\{book\_name});{}$\6
${}\\{fprintf}(\\{adc\_book\_file},\39\.{"\\\\input\ \%smcwebmac\\}\)\.{n"},\39%
\\{mcwebmac\_prefix});{}$\6
${}\\{fprintf}(\\{adc\_book\_file},\39\.{"\\\\adocfile\\n"});{}$\6
\&{if} ${}(\R{*}\\{first\_adoc\_class}\MG\\{class\_name}){}$\1\6
\&{for} ${}(\|a\K\\{first\_adoc\_class}\MG\\{first\_adoc};{}$ \|a; ${}\|a\K\|a%
\MG\\{next}){}$\1\6
\&{if} ${}(\|a\MG\\{description}){}$\1\5
${}\\{fprintf}(\\{adc\_book\_file},\39\.{"\%s"},\39\|a\MG\\{description});{}$\2%
\2\2\6
\&{if} (\\{show\_progress})\1\5
${}\\{printf}(\.{"\\nCreating\ autodoc\ }\)\.{files:\ \%s"},\39\\{a\_file%
\_name});{}$\2\6
\&{for} ${}(\\{ac}\K\\{first\_adoc\_class};{}$ \\{ac}; ${}\\{ac}\K\\{ac}\MG%
\\{next}){}$\1\6
\&{if} ${}({*}\\{ac}\MG\\{class\_name}){}$\5
${}\{{}$\1\6
${}\\{strcpy}(\\{a\_file\_name},\39\\{ac}\MG\\{class\_name});{}$\6
\&{if} ${}(\R\\{file\_name\_ext}(\\{a\_file\_name})){}$\1\5
${}\\{strcat}(\\{a\_file\_name},\39\.{".adc"});{}$\2\6
${}\\{adoc\_file}\K\\{fopen}(\\{a\_file\_name},\39\.{"w"});{}$\6
\&{if} ${}(\R\\{adoc\_file}){}$\1\5
${}\\{fatal}(\.{"!\ Cannot\ create\ aut}\)\.{odoc\ file:"},\39\\{a\_file%
\_name});{}$\2\6
${}\\{fprintf}(\\{adc\_book\_file},\39\.{"\\\\input\ \%s\\n"},\39\\{a\_file%
\_name});{}$\6
${}\\{fprintf}(\\{adoc\_file},\39\.{"\\\\def\\\\curjob\{\%s\}"},\39\\{ac}\MG%
\\{class\_name});{}$\6
${}\\{fprintf}(\\{adoc\_file},\39\.{"\\\\def\\\\chapname\{\%s\}}\)\.{"},\39%
\\{ac}\MG\\{class\_name});{}$\6
\X381:Output the \.{*} name, if it exists\X;\6
${}\\{fprintf}(\\{adoc\_file},\39\.{"\\\\adocclass\\n"});{}$\6
\&{if} (\\{show\_progress})\5
${}\{{}$\1\6
${}\\{printf}(\.{"\ \%s"},\39\\{a\_file\_name});{}$\6
\\{update\_terminal};\6
\4${}\}{}$\2\6
\X380:Output all autodocs of autodoc class \PB{\\{ac}}\X;\6
\\{fclose}(\\{adoc\_file});\6
\4${}\}{}$\2\2\6
${}\\{fprintf}(\\{adc\_book\_file},\39\.{"\\\\con\\n"});{}$\6
\\{fclose}(\\{adc\_book\_file});\6
\4${}\}{}$\2\par
\fi

\M{380}The lists is already sorted, so we only have to write the
entries to \PB{\\{adoc\_file}} in the order they appear. Entries with the same
name are concatenated and put into one single autodoc entry.
\Y\B\4\X380:Output all autodocs of autodoc class \PB{\\{ac}}\X${}\E{}$\6
${}\{{}$\1\6
\&{for} ${}(\|a\K\\{ac}\MG\\{first\_adoc};{}$ \|a; ${}\|a\K\|a\MG\\{next}){}$\1%
\6
\&{if} ${}(\|a\MG\\{description}){}$\5
${}\{{}$\1\6
\&{if} ${}({*}\|a\MG\\{name}\E\.{'*'}\W\|a\MG\\{name}[\T{1}]\E\T{0}){}$\1\5
\&{continue};\C{ see below }\2\6
\&{if} ${}(\R{*}\|a\MG\\{name}){}$\1\5
${}\\{fprintf}(\\{adoc\_file},\39\.{"\%s"},\39\|a\MG\\{description});{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{fprintf}(\\{adoc\_file},\39\.{"\\\\adoc\{\%s\}\\n"},\39\|a\MG%
\\{name});{}$\6
\&{for} ( ;  ; \,)\5
${}\{{}$\1\6
${}\\{fprintf}(\\{adoc\_file},\39\.{"\%s"},\39\|a\MG\\{description});{}$\6
\&{if} ${}(\R\|a\MG\\{next}\V\\{strcmp}(\|a\MG\\{name},\39\|a\MG\\{next}\MG%
\\{name}){}$)\C{ next one same name? }\1\6
\&{break};\2\6
${}\|a\K\|a\MG\\{next}{}$;\C{ yes, just append it }\6
\4${}\}{}$\2\6
${}\\{fprintf}(\\{adoc\_file},\39\.{"\\\\endadoc\\n"});{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\2\6
\4${}\}{}$\2\par
\U379.\fi

\M{381}The autodoc entry with name \.{*} is special in that it is output before
the
\.{\\adocclass} \TeX\ macro. It is intended for defining macros
that have to be defined before the autodoc chapter title is output.
\Y\B\4\X381:Output the \.{*} name, if it exists\X${}\E{}$\6
${}\{{}$\1\6
\&{for} ${}(\|a\K\\{ac}\MG\\{first\_adoc};{}$ \|a; ${}\|a\K\|a\MG\\{next}){}$\1%
\6
\&{if} ${}(\|a\MG\\{description}\W{*}\|a\MG\\{name}\E\.{'*'}\W\|a\MG\\{name}[%
\T{1}]\E\T{0}){}$\1\5
${}\\{fprintf}(\\{adoc\_file},\39\.{"\%s"},\39\|a\MG\\{description});{}$\2\2\6
\4${}\}{}$\2\par
\U379.\fi

\M{382}If we are in phase one rather than phase two, we skip autodocs so that
no references go to the symbol table. We simply skip three blocks
enclosed in curly braces.
\Y\B\4\X382:Skip autodoc in phase one\X${}\E{}$\6
${}\{{}$\1\6
\&{int} \\{braces\_opened}${}\K\T{0}{}$;\C{ how many braces still open? }\6
\&{int} \\{braces\_closed}${}\K\T{0}{}$;\C{ how many braces closed up to now? }%
\7
\&{do}\5
${}\{{}$\1\6
\&{if} ${}(\\{loc}>\\{limit}\W\\{get\_line}(\,)\E\T{0}){}$\1\5
\&{break};\2\6
\&{switch} ${}({*}\\{loc}\PP){}$\5
${}\{{}$\1\6
\4\&{case} \.{'\{'}:\5
${}\\{braces\_opened}\PP{}$;\5
\&{break};\6
\4\&{case} \.{'\}'}:\6
\&{if} ${}(\MM\\{braces\_opened}\Z\T{0}){}$\5
${}\{{}$\1\6
${}\\{braces\_closed}\PP;{}$\6
${}\\{braces\_opened}\K\T{0};{}$\6
\4${}\}{}$\2\6
\&{break};\6
\4\&{case} \.{'@'}:\5
${}\\{loc}\MM{}$;\C{ back to '\.{@}' }\6
${}\\{next\_control}\K\\{get\_next}(\,);{}$\6
\&{if} ${}(\\{next\_control}\G\\{format\_code}\W\R\\{is\_example}){}$\1\5
${}\\{braces\_closed}\K\T{3};{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\\{special\_command}){}$\5
${}\{{}$\1\6
\X75:Special command seen in \TeX{} part (phase one)\X;\6
\4${}\}{}$\2\6
\&{else} \&{if} ${}(\\{next\_control}\E\\{example\_code}){}$\1\5
${}\\{is\_example}\K\R\\{is\_example};{}$\2\6
\&{break};\6
\4${}\}{}$\2\6
\4${}\}{}$\2\5
\&{while} ${}(\\{braces\_closed}<\T{3});{}$\6
\4${}\}{}$\2\par
\U73.\fi

\N{1}{383}Copy buffer.
\.{mCWEAVE} now offers the possibility of copying parts of its \CEE/ code
to the \TeX\ part of a section by means of \&{mark}, \&{copy} and \&{paste}.
This avoids repeating code.

The actual copying is done in the input function \PB{\\{get\_line}} in %
\.{mcommon.w}.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{extern} \&{char} ${}{*}\\{copy\_ptr},{}$ ${}{*}\\{copy\_end}{}$;\C{ from %
\.{mcommon} }\6
\&{extern} \&{boolean} \\{copy\_from\_buffer}${},{}$ \\{copy\_to\_buffer};\6
\&{extern} \&{char} ${}{*}\\{rest\_after\_paste}{}$;\par
\fi

\M{384}For each named copy, we have a structure of the following form:
\Y\B\4\X19:Typedef declarations\X${}\mathrel+\E{}$\6
\&{struct} \\{copy\_buffer} ${}\{{}$\1\6
\&{struct} \\{copy\_buffer} ${}{*}\\{next};{}$\6
\&{char} ${}{*}\\{start};{}$\6
\&{char} ${}{*}\\{end};{}$\6
\&{char} \\{name}[\T{2}];\2\6
${}\}{}$;\par
\fi

\M{385}These structures are linked together and \PB{\\{first\_copy\_buffer}}
points to
the head of the list.
\Y\B\4\X18:Global variables\X${}\mathrel+\E{}$\6
\&{struct} \\{copy\_buffer} ${}{*}\\{first\_copy\_buffer};{}$\6
\&{struct} \\{copy\_buffer} ${}{*}\\{current\_copy\_buffer}{}$;\par
\fi

\M{386}
\Y\B\4\X21:Set initial values\X${}\mathrel+\E{}$\6
$\\{first\_copy\_buffer}\K\NULL;{}$\6
${}\\{rest\_after\_paste}\K\NULL{}$;\par
\fi

\M{387}
\Y\B\4\X2:Predeclaration of procedures\X${}\mathrel+\E{}$\6
\&{void} \\{mark}(\,)${},{}$ \\{copy}(\,)${},{}$ \\{paste}(\,);\par
\fi

\M{388}\PB{\\{mark}} is called when we encounter the \&{mark} command followed
by a name
enclosed in quotes in phase one.
It creates a new \PB{\\{copy\_buffer}} and makes it the
\PB{\\{current\_copy\_buffer}}. All characters of the input buffer \PB{%
\\{buffer}} starting
from the \&{mark} command are copied.

We collect all characters up to the corresponding \&{copy} in \PB{\\{desc%
\_mem}}.
\PB{\\{desc\_mem}} is also used for autodoc descriptions, but since these are
processed
in phase two, there will never be a collision.
\Y\B\&{void} \\{mark}(\\{name})\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\1\6
\&{int} \\{len};\7
\&{if} (\\{copy\_to\_buffer})\5
${}\{{}$\C{ \&{mark} and \&{copy} pairs may not be nested }\1\6
\\{err\_print}(\.{"!\ Still\ in\ copy\ mod}\)\.{e,\ nesting\ not\ allow}\)%
\.{ed"});\6
\&{return};\6
\4${}\}{}$\2\6
${}\\{copy\_ptr}\K\\{desc\_mem}{}$;\C{ use same buffer as for autodocs }\6
${}\\{copy\_end}\K\\{desc\_mem\_end};{}$\6
${}\\{copy\_to\_buffer}\K\T{1};{}$\6
${}\\{current\_copy\_buffer}\K{}$(\&{struct} \\{copy\_buffer} ${}{*}){}$ %
\\{malloc}(\&{sizeof}(\&{struct} \\{copy\_buffer})${}+\\{strlen}(\\{name})-%
\T{1});{}$\6
\&{if} ${}(\R\\{current\_copy\_buffer}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory"},\39\.{"\ for\ copy\ buffer"});{}$\2\6
${}\\{strcpy}(\\{current\_copy\_buffer}\MG\\{name},\39\\{name});{}$\6
${}\\{len}\K\\{limit}-\\{loc}{}$;\C{ copy rest of buffer }\6
${}\\{memcpy}(\\{copy\_ptr},\39\\{loc},\39\\{len});{}$\6
${}\\{copy\_ptr}\MRL{+{\K}}\\{len};{}$\6
${}{*}\\{copy\_ptr}\PP\K\T{0};{}$\6
\4${}\}{}$\2\par
\fi

\M{389}When we see \&{copy} (again in phase one), we stop copying the input
buffer
to \PB{\\{desc\_mem}}. We now finally know the size of the copied text and
allocate
an appropriate chunk from the memory pool.

Note that the current line has already been copied to the copy buffer,
so we must truncate it before the \&{copy} command.
\Y\B\&{void} \\{copy}(\,)\1\1\2\2\6
${}\{{}$\1\6
\&{struct} \\{copy\_buffer} ${}{*}\\{cb};{}$\6
\&{int} \\{size};\7
\&{if} ${}(\\{copy\_to\_buffer}\W\\{current\_copy\_buffer}){}$\5
${}\{{}$\C{ are we copying? }\1\6
${}\\{copy\_to\_buffer}\K\T{0};{}$\6
${}\\{cb}\K\\{current\_copy\_buffer};{}$\6
${}\\{copy\_ptr}\MRL{-{\K}}\\{limit}-\\{loc}+\T{1}{}$;\C{ truncate after %
\&{copy} command }\6
${}\\{copy\_ptr}\MRL{-{\K}}\T{6}{}$;\C{ 6 characters for \.{@$\_$copy} }\6
${}{*}\\{copy\_ptr}\PP\K\T{0};{}$\6
${}\\{size}\K\\{copy\_ptr}-\\{desc\_mem};{}$\6
${}\\{cb}\MG\\{start}\K\\{malloc}(\\{size});{}$\6
\&{if} ${}(\R\\{cb}\MG\\{start}){}$\1\5
${}\\{fatal}(\.{"!\ No\ memory"},\39\.{"\ for\ copy\ buffer"});{}$\2\6
${}\\{memcpy}(\\{cb}\MG\\{start},\39\\{desc\_mem},\39\\{size});{}$\6
${}\\{cb}\MG\\{end}\K\\{cb}\MG\\{start}+\\{size};{}$\6
\&{if} ${}(\R\\{first\_copy\_buffer}){}$\5
${}\{{}$\1\6
${}\\{cb}\MG\\{next}\K\NULL;{}$\6
${}\\{first\_copy\_buffer}\K\\{cb};{}$\6
\4${}\}{}$\2\6
\&{else}\5
${}\{{}$\1\6
${}\\{cb}\MG\\{next}\K\\{first\_copy\_buffer};{}$\6
${}\\{first\_copy\_buffer}\K\\{cb};{}$\6
\4${}\}{}$\2\6
\4${}\}{}$\2\6
\4${}\}{}$\2\par
\fi

\M{390}All copy buffers have a name which has been given with the \&{mark}
command.
We can find each copy buffer in the list \PB{\\{first\_copy\_buffer}} with the
following function.
\Y\B\&{struct} \\{copy\_buffer} ${}{*}\\{find\_copy\_buffer}(\\{name}){}$\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\1\6
\&{struct} \\{copy\_buffer} ${}{*}\\{cb};{}$\7
\&{for} ${}(\\{cb}\K\\{first\_copy\_buffer};{}$ \\{cb}; ${}\\{cb}\K\\{cb}\MG%
\\{next}){}$\1\6
\&{if} ${}(\R\\{strcmp}(\\{cb}\MG\\{name},\39\\{name})){}$\1\5
\&{return} \\{cb};\2\2\6
\&{return} ${}\NULL;{}$\6
\4${}\}{}$\2\par
\fi

\M{391}Unlike \PB{\\{mark}} and \PB{\\{copy}}, \PB{\\{paste}} is called in
phase two, when we
actually want to insert stuff from a copy buffer. It switches on
\PB{\\{copy\_from\_buffer}}, thus causing \PB{\\{get\_line}} in \.{mcommon.w}
to read from
the copy buffer.

Since we want to keep the rest of the line after \&{paste}, we copy it to
\PB{\\{rest\_after\_paste}} in order to append it to the input buffer, when the
copy buffer ends.
\Y\B\&{void} \\{paste}(\\{name})\1\1\6
\&{char} ${}{*}\\{name};\2\2{}$\6
${}\{{}$\1\6
\&{struct} \\{copy\_buffer} ${}{*}\\{cb}\K\\{find\_copy\_buffer}(\\{name});{}$\6
\&{int} \\{len};\7
\&{if} ${}(\R\\{cb}){}$\5
${}\{{}$\1\6
\\{err\_print}(\.{"!\ Copy\ buffer\ not\ f}\)\.{ound"});\6
\&{return};\6
\4${}\}{}$\2\6
${}\\{copy\_ptr}\K\\{cb}\MG\\{start};{}$\6
${}\\{copy\_end}\K\\{cb}\MG\\{end};{}$\6
${}\\{copy\_from\_buffer}\K\T{1};{}$\6
${}\\{len}\K\\{limit}-\\{loc}{}$;\C{ copy rest of input buffer to \PB{\\{rest%
\_after\_paste}} }\6
${}\\{rest\_after\_paste}\K\\{malloc}(\\{len}+\T{1});{}$\6
${}\\{strncpy}(\\{rest\_after\_paste},\39\\{loc},\39\\{len});{}$\6
${}\\{rest\_after\_paste}[\\{len}]\K\T{0};{}$\6
${}\\{loc}\K\\{limit}{}$;\C{ skip rest of input buffer }\6
\4${}\}{}$\2\par
\fi

\N{0}{392}Index.
If you have read and understood the code for Phase III above, you know what
is in this index and how it got here. All sections in which an identifier is
used are listed with that identifier, except that reserved words are
indexed only when they appear in format definitions, and the appearances
of identifiers in section names are not indexed. Underlined entries
correspond to where the identifier was declared. Error messages, control
sequences put into the output, and a few
other things like ``recursion'' are indexed here too.
\fi


\inx
\fin
\con\end
