summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/cwebdir
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
committerKarl Berry <karl@freefriends.org>2021-02-25 19:22:25 +0000
commitad547a6b5986815fda458221149728d9d9ab1d87 (patch)
tree16296910eb3eca724371474ea9aea3994dc69614 /Build/source/texk/web2c/cwebdir
parent947b43de3dd21d58ccc2ffadefc4441ea1c2a813 (diff)
restore Build,TODO from r57911
git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/cwebdir')
-rw-r--r--Build/source/texk/web2c/cwebdir/ChangeLog635
-rw-r--r--Build/source/texk/web2c/cwebdir/Makefile200
-rw-r--r--Build/source/texk/web2c/cwebdir/README109
-rw-r--r--Build/source/texk/web2c/cwebdir/c++lib.w85
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-amiga.ch17
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-bs.ch223
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-mac.ch155
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-man.ch22
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-os2.ch24
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-pc.ch33
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-ql.ch277
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-vms.ch88
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-w2c.ch866
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-w2c.h265
-rw-r--r--Build/source/texk/web2c/cwebdir/comm-w32.ch66
-rw-r--r--Build/source/texk/web2c/cwebdir/common.c1327
-rw-r--r--Build/source/texk/web2c/cwebdir/common.h243
-rw-r--r--Build/source/texk/web2c/cwebdir/common.w1301
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-bs.ch192
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-man.ch22
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-pc.ch24
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-ql.ch25
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-vms.ch35
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-w2c.ch481
-rw-r--r--Build/source/texk/web2c/cwebdir/ctang-w32.ch44
-rw-r--r--Build/source/texk/web2c/cwebdir/ctangle.c1626
-rw-r--r--Build/source/texk/web2c/cwebdir/ctangle.w1543
-rw-r--r--Build/source/texk/web2c/cwebdir/ctproofmac.tex353
-rw-r--r--Build/source/texk/web2c/cwebdir/cttwinxmac.tex319
-rw-r--r--Build/source/texk/web2c/cwebdir/ctwill-mini.ch1151
-rw-r--r--Build/source/texk/web2c/cwebdir/ctwill-w2c.ch1996
-rw-r--r--Build/source/texk/web2c/cwebdir/ctwill.bux88
-rw-r--r--Build/source/texk/web2c/cwebdir/ctwimac.tex476
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-bs.ch236
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-man.ch22
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-pc.ch28
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-ql.ch32
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-vms.ch38
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-w2c.ch713
-rw-r--r--Build/source/texk/web2c/cwebdir/cweav-w32.ch34
-rwxr-xr-xBuild/source/texk/web2c/cwebdir/cweave.test9
-rw-r--r--Build/source/texk/web2c/cwebdir/cweave.w4696
-rw-r--r--Build/source/texk/web2c/cwebdir/cweb.1132
-rw-r--r--Build/source/texk/web2c/cwebdir/cweb.el218
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/amiga_types.w109
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/c++1xlib.w37
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/cweb_ecma94.w44
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/cweb_hp8.w47
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/cweb_mac8.w53
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/cweb_pc850.w50
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebinputs/iso_types.w119
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebmac.tex552
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebman-w2c.ch333
-rw-r--r--Build/source/texk/web2c/cwebdir/cwebman.tex1774
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/Makefile57
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/README55
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/extex.ch23
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/extex.w366
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/kspell.el228
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/oemacs.el176
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/oemacs.w896
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/treeprint.w248
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/wc-dos.ch8
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/wc.w254
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/wmer-os2.ch21
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/wmerg-pc.ch22
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/wmerge.w717
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/wordtest.w540
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/xlib_types.w92
-rw-r--r--Build/source/texk/web2c/cwebdir/examples/xview_types.w274
-rw-r--r--Build/source/texk/web2c/cwebdir/makefile.bs60
-rw-r--r--Build/source/texk/web2c/cwebdir/po/cweb-tl.pot47
-rw-r--r--Build/source/texk/web2c/cwebdir/po/cweb.pot604
-rw-r--r--Build/source/texk/web2c/cwebdir/po/de/cweb-tl.po49
-rw-r--r--Build/source/texk/web2c/cwebdir/po/de/cweb.po684
-rw-r--r--Build/source/texk/web2c/cwebdir/po/de/web2c-help.po140
-rw-r--r--Build/source/texk/web2c/cwebdir/po/it/cweb.po679
-rw-r--r--Build/source/texk/web2c/cwebdir/po/web2c-help.pot137
-rw-r--r--Build/source/texk/web2c/cwebdir/prod-twill.w303
-rw-r--r--Build/source/texk/web2c/cwebdir/prod.w307
-rw-r--r--Build/source/texk/web2c/cwebdir/readme.ql84
-rw-r--r--Build/source/texk/web2c/cwebdir/refsort.w165
-rw-r--r--Build/source/texk/web2c/cwebdir/system.bux49
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/Xcwebmac.tex41
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/cweb_ecma94.sty206
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/cweb_hp8.sty184
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/cweb_mac8.sty232
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/cweb_pc850.sty194
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/dctproofmac.tex28
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/dctwimac.tex12
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/dcwebmac.tex105
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/dcwebstrings.tex40
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/fcwebmac.tex135
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/icwebmac.tex156
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/pdfctwimac.tex693
-rw-r--r--Build/source/texk/web2c/cwebdir/texinputs/pdfwebtocfront.tex85
-rw-r--r--Build/source/texk/web2c/cwebdir/twinx.w460
97 files changed, 33443 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/cwebdir/ChangeLog b/Build/source/texk/web2c/cwebdir/ChangeLog
new file mode 100644
index 00000000000..be924eeb0c1
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ChangeLog
@@ -0,0 +1,635 @@
+2021-02-25 Andreas Scherer <https://ascherer.github.io>
+
+ * Makefile,
+ * comm-{mac,ql,vms,w32}.ch,
+ * comm-w2c.ch,
+ * comm-w2c.h,
+ * common.c,
+ * common.h,
+ * common.w,
+ * ctang-{bs,pc,ql,vms,w32}.ch,
+ * ctang-w2c.ch,
+ * ctangle.c,
+ * ctangle.w,
+ * ctwill-mini.ch,
+ * ctwill-w2c.ch,
+ * cweav-{bs,pc,ql,vms,w32}.ch,
+ * cweav-man.ch,
+ * cweav-w2c.ch,
+ * cweave.w,
+ * cwebmac.tex,
+ * cwebman-w2c.ch,
+ * cwebman.tex,
+ * po/{cweb,cweb-tl}.pot,
+ * po/de/{cweb,cweb-tl}.po,
+ * po/it/cweb.po: CWEB 4.2 and CWEBbin 2021.
+
+2021-02-24 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.h,
+ * common.c,
+ * common.h
+ * common.w,
+ * ctangle.c,
+ * ctangle.w,
+ * ctwill-mini.ch,
+ * ctwill-w2c.ch,
+ * cweav-w2c.ch,
+ * cweave.w: Fix spacing for |#include| in TeX comment.
+
+2021-02-24 Andreas Scherer <https://ascherer.github.io>
+
+ * cweave.w: Fix spacing for |#include| in TeX comment.
+
+2021-02-24 Andreas Scherer <https://ascherer.github.io>
+
+ * common.w,
+ * ctangle.w,
+ * cweave.w: Fine print for single '@' characters in TeX text.
+
+2021-02-24 Andreas Scherer <https://ascherer.github.io>
+
+ * cweave.w: Fix output format when 'tracing @2'.
+
+2021-02-23 Andreas Scherer <https://ascherer.github.io>
+
+ * cwebman.tex,
+ * cwebman-w2c.ch: Minor redactions.
+
+2021-02-23 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Simplify documentation.
+
+2021-02-22 Andreas Scherer <https://ascherer.github.io>
+
+ * Makefile,
+ * comm-w2c.ch
+ * comm-w2c.h
+ * common.c
+ * common.h
+ * common.w
+ * ctang-bs.ch,
+ * ctangle.c,
+ * ctangle.w,
+ * ctwill-mini.ch,
+ * ctwill-w2c.ch,
+ * cweav-bs.ch,
+ * cweav-man.ch,
+ * cweave.w: Decouple CTANGLE and CWEAVE from COMMON.
+
+2021-02-20 Andreas Scherer <https://ascherer.github.io>
+
+ * Makefile,
+ * comm-{mac,ql,vms,w32}.ch,
+ * comm-w2c.ch,
+ * comm-w2c.h,
+ * common.c,
+ * common.h,
+ * common.w,
+ * ctang-{bs,pc,ql,vms,w32}.ch,
+ * ctang-w2c.ch,
+ * ctangle.c,
+ * ctangle.w,
+ * ctwill-mini.ch,
+ * ctwill-w2c.ch,
+ * cweav-{bs,pc,ql,vms,w32}.ch,
+ * cweav-man.ch,
+ * cweav-w2c.ch,
+ * cweave.w,
+ * cwebmac.tex,
+ * cwebman-w2c.ch,
+ * cwebman.tex,
+ * po/{cweb,cweb-tl}.pot,
+ * po/de/{cweb,cweb-tl}.po,
+ * po/it/cweb.po: CWEB 4.1 and CWEBbin 2021.
+
+2021-02-19 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-bs.ch,
+ * comm-mac.ch,
+ * com-ql.ch,
+ * comm-w2c.ch,
+ * comm-w2c.h,
+ * common.c,
+ * common.h,
+ * common.w,
+ * ctang-bs.ch,
+ * ctangle.c,
+ * ctangle.w,
+ * ctwill-w2c.ch,
+ * cweav-bs.ch,
+ * cweave.w,
+ * cwebman.tex: Replace 'boolean' values upstream.
+
+2021-02-18 Andreas Scherer <https://ascherer.github.io>
+
+ * cweave.w: Purge unused macro definition.
+
+2021-02-18 Andreas Scherer <https://ascherer.github.io>
+
+ * ctangle.c,
+ * ctangle.w,
+ * cweave.w: Reshuffle a few variables (upstream).
+
+2021-02-18 Andreas Scherer <https://ascherer.github.io>
+
+ * cweave.w: Fix an 'aspell'ing error and one old macro call.
+
+2021-02-17 Andreas Scherer <https://ascherer.github.io>
+
+ * cweave.w: Fix 'Illegal hardware instruction' on MacOS.
+
+2021-02-17 Andreas Scherer <https://ascherer.github.io>
+
+ * Makefile: Main CWEB modules depend on COMMON interface.
+
+2021-02-16 Andreas Scherer <https://ascherer.github.io>
+
+ * common.c,
+ * common.h,
+ * ctangle.c,
+ * comm-w2c.h: Reshuffle byte_mem pointer.
+
+2021-02-16 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * common.h: Restore comment from 'cweave.w' (3.64c).
+
+2021-02-11 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfctwimac.tex: Fix bug in color setter.
+
+2021-02-08 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * common.c,
+ * common.h,
+ * common.w,
+ * ctangle.c,
+ * ctangle.w,
+ * cweave.w: Don't repeat yourself.
+
+2021-02-07 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Fix 'reading error';
+ CWEB development has moved to another level.
+
+2021-02-07 Andreas Scherer <https://ascherer.github.io>
+
+ * Makefile,
+ * README,
+ * comm-{amiga,bs,mac,os2,pc,ql,vms,w32}.ch,
+ * comm-w2c.ch,
+ * comm-w2c.h,
+ * common.c,
+ * common.h,
+ * common.w,
+ * ctang-{bs,pc,ql,vms,w32}.ch,
+ * ctang-man.ch,
+ * ctang-w2c.ch,
+ * ctangle.c,
+ * ctangle.w,
+ * ctwill-mini.ch,
+ * ctwill-w2c.ch,
+ * ctwill.bux,
+ * cweav-{bs,pc,ql,vms,w32}.ch,
+ * cweav-man.ch,
+ * cweav-w2c.ch,
+ * cweave.w,
+ * cweb.1,
+ * cwebmac.tex,
+ * cwebman-w2c.ch,
+ * cwebman.tex,
+ * examples/wmerge.w,
+ * po/{cweb,cweb-tl,web2c-help}.pot,
+ * po/de/{cweb,cweb-tl,web2c-help}.po,
+ * po/it/cweb.po,
+ * system.bux: New CWEB 4.0 and CWEBbin 2021.
+
+2020-07-30 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * ctang-w2c.ch,
+ * ctwill-w2c.ch,
+ * cweav-w2c.ch: Fix typographic inconsistency.
+
+2020-07-15 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * comm-w2c.hch,
+ * ctwill-mini.ch: Clearer exposition re external type definitions.
+
+2020-07-08 Andreas Scherer <https://ascherer.github.io>
+
+ * cwebman-w2c.ch,
+ * po/web2c-help.pot,
+ * po/de/web2c-help.po: Add '-dN' to 'help' message.
+
+2020-07-08 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Add special index entries for Kpathsea values.
+
+2020-07-08 Andreas Scherer <https://ascherer.github.io>
+
+ * cwebman-w2c.ch: Add links to appendices D, E, F, and G.
+
+2020-07-05 Andreas Scherer <https://ascherer.github.io>
+
+ * ctwill-mini.ch,
+ * texinputs/pdfctwimac.tex: Fix two issues with 'ctwill.dvi/pdf'.
+
+2020-07-02 Andreas Scherer <https://ascherer.github.io>
+
+ * cwebman-w2c.ch: Add links and bookmarks in PDF.
+
+2020-06-29 Andreas Scherer <https://ascherer.github.io>
+
+ * ctwill-mini.ch,
+ * prod-mini.ch: Merge editorial changes with CTIE;
+ no need for a separate changefile for 'prod.w'.
+
+2020-06-24 Andreas Scherer <https://ascherer.github.io>
+
+ * ctwill-w2c.ch,
+ * ctwill-mini.ch,
+ * ctwill.bux,
+ * system.bux,
+ * prod-mini.ch: Add editorial material to produce 'ctwill.pdf'
+ with CTWILL itself.
+
+2020-06-23 Andreas Scherer <https://ascherer.github.io>
+
+ * prod-twill.w: Roll back editorial changes.
+
+2020-06-21 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfwebtocfront.tex: Fix start pageno after dynamic to.
+ MF and [{pdf|Xe}]TeX start their main body on pageno 3.
+
+2020-06-20 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfwebtocfront.tex: Generic solution for the headers in
+ WEB and CWEB programs (with four special cases with their own '\N').
+
+2020-06-20 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Clarify triple responsibility.
+
+2020-06-19 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfwebtocfront.tex: Generic 'group title' on the first
+ page after the table-of-contents.
+
+2020-06-16 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfctimac.tex: Bookmarks for "Names of the sections".
+
+2020-06-16 Andreas Scherer <https://ascherer.github.io>
+
+ * ctang-w2c.ch: Translate another message string.
+ * ctwill-w2c.ch,
+ * prod-twill.w: Page breaks for CWILL format. Fix final header.
+ * texinputs/pdfctimac.tex: Alternative comment font (9pt).
+ Don't force small borders in standard macros for PDF output.
+
+2020-06-15 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfctimac.tex: Unified color management;
+ code compaction; simplified if-else inside \acro;
+ structured outlines/bookmarks with all supported TeX engines.
+
+2020-06-14 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfctimac.tex: New macros for PDF output with hyperlinks
+ created with 'ctwill +lpdf' followed by 'tex'+'dvipdfm', 'pdftex',
+ or 'xetex' on your CWEB source.
+
+2020-06-13 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * ctang-w2c.ch,
+ * ctwill-w2c.ch,
+ * cweav-w2c.ch: Purge space from 'covernote'.
+
+2020-06-11 Andreas Scherer <https://ascherer.github.io>
+
+ * cwebman-w2c.ch: Add footnotes for TeX Live extensions.
+
+2020-06-10 Andreas Scherer <https://ascherer.github.io>
+
+ * ctang-w2c.ch: Add short comments to new material.
+
+2020-06-10 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/p+cwebmac.tex: Switch on PDF creation with 'cweave -lp+'
+ followed by 'tex'+'dvipdfm' or 'xetex' on your CWEB source.
+
+2020-06-07 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * ctang-w2c.ch,
+ * cweav-w2c.ch,
+ * ctwill-w2c.ch: Add date to table-of-contents page.
+
+2020-06-07 Andreas Scherer <https://ascherer.github.io>
+
+ * ctang-w2c.ch: Handle special 'files' as secondary output.
+
+2020-06-07 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * ctang-w2c.ch,
+ * cweav-w2c.ch,
+ * ctwill-w2c.ch: Check accessibility to designated output files.
+
+2020-06-07 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * comm-w2c.h,
+ * ctang-w2c.ch,
+ * cweav-w2c.ch,
+ * ctwill-w2c.ch: Underscore 'enum'erated values in index.
+
+2020-06-06 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Add index entries for the CWEBINPUTS envvar.
+
+2020-06-05 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Fix newline blunder in case of error.
+
+2020-06-01 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfwebtocfront.tex: Adapt to 'pwebmac.tex 4.5.2'.
+
+2020-05-31 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Sanitize command for PDF outlines.
+
+2020-05-26 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfwebtocfront.tex: Fake headline on page after TOC.
+
+2020-05-23 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/pdfwebtocfront.tex: Add treatment for {pdf,xe}tex.web.
+
+2020-05-22 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/Xcwebmac.tex: Activate alternative assignment operator.
+ * texinputs/pdfwebtocfront.tex: Add comments to the macro code.
+
+2020-05-07 Andreas Scherer <https://ascherer.github.io>
+
+ * texinputs/Xcwebmac.tex: Amend macros from knuth.drv (in
+ github.com/oberdiek/latex-tds) to move table-of-contents
+ up front in PDF output (on second TeX run).
+
+2020-04-30 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Clarify §95 and fix missing type format.
+
+2020-04-29 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Purge irrelevant mention of .web extension.
+
+2020-04-28 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Purge standard headers already in KPathSea.
+
+2020-04-27 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch,
+ * comm-w2c.h: Use enum'erated program identifiers.
+ Reshuffle typedef's to fix formatting in §7 of COMMON.
+
+2020-04-16 Andreas Scherer <https://ascherer.github.io>
+
+ * cweav-w2c.ch,
+ * ctwill-w2c.ch: Fix missing hyphen.
+
+2020-04-14 Andreas Scherer <https://ascherer.github.io>
+
+ * cweav-w2c.ch,
+ * ctwill-w2c.ch: Fix uppercase spelling for COMMON module.
+
+2020-04-13 Andreas Scherer <https://ascherer.github.io>
+
+ * ctwill-w2c.ch: Print CTWILL user manual on two pages.
+
+2020-04-13 Andreas Scherer <https://ascherer.github.io>
+
+ * cweav-w2c.ch,
+ * ctwill-w2c.ch: Move reference to global variable 'use_language'
+ from 'main' to section 'Extensions'.
+
+2020-04-13 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.h: Add comment for section 6 in CWEB programs.
+
+2020-04-11 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch, comm-w2c.h: Rearrange 'common variables'.
+
+2020-03-30 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch, comm-w2c.h, ctang-w2c.ch, ctwill-w2c.ch, cweav-w2c.ch,
+ * po/de/cweb.po, po/de/web2c-help.po,
+ * po/it/cweb.po,
+ * po/web2c-help.pot: Add new option '-t'.
+
+2020-02-01 Andreas Scherer <https://ascherer.github.io>
+
+ * ctang-w2c.ch: Fix verbosity bug in ctangle.
+
+2019-05-29 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch, comm-w2c.h: Minor changes.
+
+2019-02-16 Andreas Scherer <https://ascherer.github.io>
+
+ * cwebinputs/c++1xlib.w: Add some C++1x class names.
+
+2019-01-20 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Use braced evaluation and save a macro variable.
+
+2019-01-19 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Extended notes about NLS activation.
+ * po/web2c-help.pot, po/de/web2c-help.po: Fix typos.
+
+2019-01-18 Andreas Scherer <https://ascherer.github.io>
+
+ * po/cweb.pot, po/de/cweb.po, po/it/cweb.po:
+ Update NLS references for TP notification.
+
+2019-01-17 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch, comm-w2c.h,
+ * ctang-w2c.ch, ctwill-w2c.ch, cweav-w2c.ch:
+ Translate 'banner' if HAVE_GETTEXT set and cweb-tl.mo available.
+
+2019-01-16 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Correct usage of 'kpse_var_expand';
+ skip numeric argument of '-d' flag.
+
+2019-01-15 Andreas Scherer <https://ascherer.github.io>
+
+ * comm-w2c.ch: Provisional 'bindtextdomain' lookup in TDS.
+ * cwebinputs/texinputs: Add prefix 'cweb_' to TeX macros
+ and transliteration files.
+ * po/cweb-tl.pot: Realign NLS modules with texlive changes.
+
+2019-01-05 Andreas Scherer <https://ascherer.github.io>
+
+ Integration of CWEBbin as the new CWEB in TeX Live,
+ https://github.com/ascherer/cwebbin.
+
+ Purge cwebboot.h[in] from CWEB build process;
+ see ../ChangeLog for more changes in ../am/, etc.
+
+ * comm-w2c.h: new file.
+ * ctang-w2c.ch,
+ * cweav-w2c.ch: cwebbin changes for translations and everything else.
+
+ * ctproofmac.tex,
+ * cttwinxmac.tex,
+ * ctwimac.tex: new macro files.
+
+ * po/: new subdirectory for translations.
+ * cwebinputs,
+ * texinputs: new subdirs to include entire original cweb distribution.
+
+ Add CTWILL material on top of CWEAVE.
+ * prod-twill.w,
+ * refsort.w,
+ * twinx.w,
+ * ctwill-w2c.ch: new files.
+
+2018-12-30 Andreas Scherer <https://ascherer.github.io>
+
+ * cweave.w,
+ * common.w,
+ * common.c,
+ * ../cwebboot.cin: do not change the CWEB sources, use
+ changefile entries instead.
+ * examples: add directory (unchanged) from cweb-3.64c.tar.gz.
+
+2018-11-02 Andreas Scherer <https://ascherer.github.io>
+
+ * ctang-w2c.ch,
+ * cweav-w2c.ch,
+ * ../ctangleboot.cin: clean build with non-implicit 'int change_depth'.
+ tex-k mail, 2 Nov 2018 18:03:39.
+
+2018-01-18 Karl Berry <karl@tug.org>
+
+ * cweave.w,
+ * common.w,
+ * common.c,
+ * ../cwebboot.cin: printf %s instead of direct string (from Debian).
+ (Also sent to DEK.)
+
+2017-01-29 Karl Berry <karl@tug.org>
+
+ * ../cwebboot.cin,
+ * Makefile,
+ * README,
+ * common.c,
+ * common.h,
+ * common.w,
+ * ctang-bs.ch,
+ * ctangle.w,
+ * cweav-bs.ch,
+ * cweav-w2c.ch,
+ * cweave.w,
+ * cweb.el,
+ * cwebmac.tex,
+ * cwebman.tex,
+ * Master/texmf-dist/tex/plain/cweb/cwebmac.tex: sync all with
+ cweb 3.64ai from DEK, http://ctan.org/pkg/cweb.
+ * cweav-w2c.ch: sync @x blocks with 3.64ai.
+
+2014-06-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * comm-w2c.ch, ctang-w2c.ch, cweav-w2c.ch: Avoid useless
+ char subscript warnings.
+
+2014-02-12 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * comm-w2c.ch: Handle input lines with CRLF.
+
+2013-07-02 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * comm-w2c.ch: Include system headers after "cpascal.h".
+
+2013-06-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * comm-w2c.ch, ctang-w2c.ch, cweav-w2c.ch: Include system
+ headers after <kpathsea/kpathsea.h>.
+
+2012-09-05 Akira Kakuto <kakuto@fuk.kindai.ac.jp>
+
+ * common.w, ctangle.w, cweave.w: copy the original ones in
+ ftp://ftp.cs.stanford.edu/pub/cweb/cweb.tar.gz.
+ * comm-w2c.ch, ctang-w2c.ch, cweav-w2c.ch: move our changes to change
+ files.
+
+2012-09-05 Karl Berry <karl@tug.org>
+
+ * cweave.w (longest_name): restore to 10000,
+ the value in the Knuth/Levy distribution on CTAN
+ (which matches Knuth, ftp://ftp.cs.stanford.edu/pub/cweb/cweb.tar.gz)
+ Report from Arthur O'Dwyer, 3 Sep 2012 18:06:05.
+
+ Our cweave.w has many other changes relative to the original.
+ These should be moved to cweav-w2c.ch so our originals are
+ unmodified, but can't do everything right now.
+
+2012-05-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * {comm,ctang,cweav}-w2c.ch: Use binary mode for output files.
+ From Akira Kakuto <kakuto@fuk.kindai.ac.jp> (W32TeX).
+
+2011-04-19 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Avoid 'differ in signedness' warnings.
+ * cweav-w2c.ch: cast strcpy() arg collate to 'char *'.
+
+2010-01-18 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * {comm,ctang,cweav}-w2c.ch: Move extern declaration of
+ versionstring from {ctangle,cweave}.c to cweb.h.
+
+2009-08-29 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * {comm,ctang,cweav}-w2c.ch: Create a header file cweb.h with
+ prototypes for all functions declared in common.w and used in
+ ctangle.w and cweave.w or vice versa, and #include "cweb.h" in
+ cweb.c, ctangle.c, and cweave.c.
+
+ Avoid maximal compiler warnings.
+ * {comm,ctang,cweav}-w2c.ch (names_match, id_lookup, err_print,
+ fatal, overflow): Constify string params and local vars.
+ * ctang-w2c.ch (Insert the line): Rename inner local var a=>a_l,
+ not to shadow previous local.
+ * cweav-w2c.ch (out_str, app_str): Constify string params.
+ (Print a snapsh...): Rename local var k=>k_l, not to shadow
+ a param.
+ In main(), 'use' print_text() not used somewhere else.
+
+2009-08-28 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * ../am/cweb.am (ctie_CFLAGS, cweave_CFLAGS, tie_CFLAGS),
+ ../am/bootstrap.am (ctangle_CFLAGS): Enable compiler warnings.
+ * {comm,ctang,cweav}-w2c.ch: Declare most functions as static.
+ * ctang-w2c.ch, cweav-w2c.ch: Put explicit braces around
+ ambiguous else.
+
+2009-06-23 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * comm-w2c.ch, ctang-w2c.ch, cweav-w2c.ch: drop P?C, P?H macros,
+ use ANSI C function declarations.
+
diff --git a/Build/source/texk/web2c/cwebdir/Makefile b/Build/source/texk/web2c/cwebdir/Makefile
new file mode 100644
index 00000000000..0c20d83c10c
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/Makefile
@@ -0,0 +1,200 @@
+# This file is part of CWEB.
+# It is distributed WITHOUT ANY WARRANTY, express or implied.
+# Version 4.2 --- February 2021
+
+# Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
+
+# 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.
+
+#
+# Read the README file, then edit this file to reflect local conditions
+#
+
+# directory for TeX inputs (cwebmac.tex goes here)
+MACROSDIR= /usr/share/texmf/tex/generic
+
+# directory for CWEB inputs in @i files
+CWEBINPUTS= /usr/local/lib/cweb
+
+# extension for manual pages ("l" distinguishes local from system stuff)
+MANEXT= l
+#MANEXT= 1
+
+# directory for manual pages (cweb.1 goes here)
+MANDIR= /usr/share/man/man$(MANEXT)
+
+# destination directory for executables; must end in /
+DESTDIR= /usr/local/bin/
+
+# directory for GNU EMACS Lisp code (cweb.el goes here)
+EMACSDIR= /usr/share/emacs/site-lisp
+
+# Set DESTPREF to null if you want to call the executables "tangle" and "weave"
+# (probably NOT a good idea; we recommend leaving DESTPREF=c)
+DESTPREF=c
+
+# Set CCHANGES to comm-foo.ch if you need changes to common.w
+CCHANGES=
+
+# Set TCHANGES to ctang-foo.ch if you need changes to ctangle.w
+TCHANGES=
+
+# Set WCHANGES to cweav-foo.ch if you need changes to cweave.w
+WCHANGES=
+
+# We keep debugging info around, for fun, but most users don't need it
+CFLAGS = -g
+#CFLAGS = -O
+LINKFLAGS = -g
+#LINKFLAGS = -s # for smaller (stripped) executables on many UNIX systems
+
+# What C compiler are you using?
+CC = cc
+
+# RM and CP are used below in case rm and cp are aliased
+RM= /bin/rm
+CP= /bin/cp
+
+# uncomment the second line if you use pdftex to bypass .dvi files
+# uncomment the third line if you use xetex to bypass .dvi files
+PDFTEX = dvipdfm
+#PDFTEX = pdftex
+#PDFTEX = xetex
+
+########## You shouldn't have to change anything after this point #######
+
+CWEAVE = ./cweave
+CTANGLE = ./ctangle
+SOURCES = cweave.w common.w ctangle.w
+ALL = common.w ctangle.w cweave.w prod.w \
+ Makefile common.c common.h ctangle.c \
+ cwebman.tex cwebmac.tex comm-vms.ch ctang-vms.ch \
+ cweav-vms.ch comm-man.ch ctang-man.ch cweav-man.ch \
+ comm-pc.ch ctang-pc.ch cweav-pc.ch comm-amiga.ch \
+ comm-bs.ch ctang-bs.ch cweav-bs.ch makefile.bs \
+ comm-ql.ch ctang-ql.ch cweav-ql.ch readme.ql \
+ comm-w32.ch ctang-w32.ch cweav-w32.ch \
+ comm-os2.ch comm-mac.ch cweb.1 cweb.el c++lib.w README
+
+.SUFFIXES: .dvi .tex .w .pdf
+
+.w.tex:
+ $(CWEAVE) $*
+
+.tex.dvi:
+ tex $<
+
+.w.dvi:
+ make $*.tex
+ make $*.dvi
+
+.w.c:
+ $(CTANGLE) $*
+
+.w.o:
+ make $*.c
+ make $*.o
+
+.w.pdf:
+ make $*.tex
+ case "$(PDFTEX)" in \
+ dvipdfm ) tex "\let\pdf+ \input $*"; dvipdfm $* ;; \
+ pdftex ) pdftex $* ;; \
+ xetex ) xetex $* ;; \
+ esac
+
+all: ctangle cweave
+
+cautiously: ctangle
+ $(CP) common.c SAVEcommon.c
+ ./ctangle common $(CCHANGES)
+ diff common.c SAVEcommon.c
+ $(RM) SAVEcommon.c
+ $(CP) ctangle.c SAVEctangle.c
+ ./ctangle ctangle $(TCHANGES)
+ diff ctangle.c SAVEctangle.c
+ $(RM) SAVEctangle.c
+
+SAVEctangle.c:
+ $(CP) ctangle.c SAVEctangle.c
+
+SAVEcommon.c:
+ $(CP) common.c SAVEcommon.c
+
+common.c: common.w $(CCHANGES) common.h
+ $(CTANGLE) common $(CCHANGES)
+
+common.o: common.c
+ $(CC) $(CFLAGS) -DCWEBINPUTS=\"$(CWEBINPUTS)\" -c common.c
+
+ctangle: ctangle.o common.o
+ $(CC) $(LINKFLAGS) -o ctangle ctangle.o common.o
+
+ctangle.c: ctangle.w $(TCHANGES) common.h
+ $(CTANGLE) ctangle $(TCHANGES)
+
+cweave: cweave.o common.o
+ $(CC) $(LINKFLAGS) -o cweave cweave.o common.o
+
+cweave.c: cweave.w $(WCHANGES) common.h prod.w
+ $(CTANGLE) cweave $(WCHANGES)
+
+doc: $(SOURCES:.w=.dvi)
+
+usermanual: cwebman.tex cwebmac.tex
+ tex cwebman
+
+fullmanual: usermanual $(SOURCES) comm-man.ch ctang-man.ch cweav-man.ch
+ make cweave
+ ./cweave common.w comm-man.ch
+ tex common.tex
+ ./cweave ctangle.w ctang-man.ch
+ tex ctangle.tex
+ ./cweave cweave.w cweav-man.ch
+ tex cweave.tex
+
+# be sure to leave ctangle.c and common.c for bootstrapping
+clean:
+ $(RM) -f -r *~ *.o common.tex cweave.tex cweave.c ctangle.tex \
+ *.log *.dvi *.toc *.idx *.scn *.pdf core cweave ctangle
+
+install: all
+ - mkdir $(DESTDIR)
+ $(CP) cweave $(DESTDIR)$(DESTPREF)weave
+ chmod 755 $(DESTDIR)$(DESTPREF)weave
+ $(CP) ctangle $(DESTDIR)$(DESTPREF)tangle
+ chmod 755 $(DESTDIR)$(DESTPREF)tangle
+ - mkdir $(MANDIR)
+ $(CP) cweb.1 $(MANDIR)/cweb.$(MANEXT)
+ chmod 644 $(MANDIR)/cweb.$(MANEXT)
+ - mkdir $(MACROSDIR)
+ $(CP) cwebmac.tex $(MACROSDIR)
+ chmod 644 $(MACROSDIR)/cwebmac.tex
+ - mkdir $(EMACSDIR)
+ $(CP) cweb.el $(EMACSDIR)
+ chmod 644 $(EMACSDIR)/cweb.el
+ - mkdir $(CWEBINPUTS)
+ $(CP) c++lib.w $(CWEBINPUTS)
+ chmod 644 $(CWEBINPUTS)/c++lib.w
+
+floppy: $(ALL) examples
+ bar cvhf /dev/rfd0 $(ALL) examples
+ bar tvf /dev/rfd0
+ eject
+
+tags: $(ALL)
+ etags -lnone $(ALL)
+
+tarfile: $(ALL) examples
+ tar cvhf /tmp/cweb.tar $(ALL) examples
+ gzip -9 /tmp/cweb.tar
+
+tarball:
+ tar zcvhf /tmp/cweb.tgz $(ALL) examples
diff --git a/Build/source/texk/web2c/cwebdir/README b/Build/source/texk/web2c/cwebdir/README
new file mode 100644
index 00000000000..081dc5aa0b6
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/README
@@ -0,0 +1,109 @@
+% This file is part of CWEB.
+% The CWEB programs by Silvio Levy are based on programs by D. E. Knuth.
+% They are distributed WITHOUT ANY WARRANTY, express or implied.
+% This README file last updated February 2021 by Andreas Scherer
+
+% Copyright (C) 1987,1990,1993,2000,2016 Silvio Levy and Donald E. Knuth
+
+% 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.
+
+% Please send comments, suggestions, etc. to tex-k@tug.org, and people
+% there will verify and forward bug reports.
+%
+% DEK takes no responsibility for the changefiles; they should be
+% maintained independently. He even transferred the job to correct errors
+% in ctangle.w, cweave.w, prod.w, common.w, cwebmac.tex, cwebman.tex,
+% and in the files of examples/*.w to Andreas Scherer in 2021.
+% Further significant developments, including versions that neither
+% Don Knuth nor Silvio Levy themselves do maintain, are ongoing.
+% All of the really current news about CWEB is, in fact, now to be found
+% on the CWEB development page https://github.com/ascherer/cweb.
+
+This directory contains the following files:
+
+Makefile
+README
+comm-amiga.ch
+comm-bs.ch
+comm-mac.ch
+comm-man.ch
+comm-os2.ch
+comm-pc.ch
+comm-ql.ch
+comm-vms.ch
+comm-w32.ch
+common.c
+common.h
+common.w
+ctang-bs.ch
+ctang-man.ch
+ctang-pc.ch
+ctang-ql.ch
+ctang-vms.ch
+ctang-w32.ch
+ctangle.c
+ctangle.w
+cweav-bs.ch
+cweav-man.ch
+cweav-pc.ch
+cweav-ql.ch
+cweav-vms.ch
+cweave-w32.ch
+cweave.w
+cweb.1
+cweb.el
+cwebmac.tex
+cwebman.tex
+examples/
+makefile.bs
+prod.w
+readme.ql
+c++lib.w
+
+The file cwebman.tex is the user manual.
+The examples directory contains additional examples of the use of CWEB.
+The files common.c and ctangle.c are used for bootstrapping.
+The file cweb.1 is a manual page.
+The file cweb.el is suggested for GNU-Emacs users.
+The file c++lib.w is for C++ users (say `@i c++lib.w' at beginning of program).
+The files *-man.ch are used if you want to make the full 240-page CWEB manual.
+The files *-bs.ch are used instead of *-pc.ch if you are doing BIG programs.
+You can use makefile.bs to make CWEB with *-bs.ch.
+The files *-ql.ch are for QDOS/SMSQ systems; see readme.ql for further info.
+The files *-w32.ch use __fastcall conventions on win32 systems.
+The file comm-mac.ch is for Macintosh conventions.
+The other files named *.ch are sample change files for local customization.
+
+IMPORTANT: Please touch *.c before proceeding.
+Then edit the opening lines of Makefile so that it has the proper
+directory information for your local system.
+
+To make ctangle and cweave say `make all'; this should produce roughly
+the following actions (possibly with harmless warning messages from cc):
+
+cc -g -w -c ctangle.c
+cc -g -w -DCWEBINPUTS=\"/usr/local/lib/cweb\" -c common.c
+cc -g -o ctangle ctangle.o common.o
+./ctangle cweave
+cc -g -w -c cweave.c
+cc -g -w -o cweave cweave.o common.o
+
+To get some reassurance that things are OK, you can say `make cautiously',
+which ensures that CTANGLE will reproduce itself. (Otherwise the source
+files common.w and ctangle.w won't actually have been used.)
+
+To install cweave and ctangle say `make install'. You probably need to
+be superuser to do this; but it's wise to `make all' first, BEFORE
+becoming superuser and saying `make install'.
+
+Note that change files for VMS, AMIGA, MAC, and PCs are provided. When you
+are first bootstrapping to a new system, you may need to edit common.c and
+ctangle.c by hand, but the vast majority of the change-file changes are
+minor refinements that are not necessary for a rudimentary ctangle.
diff --git a/Build/source/texk/web2c/cwebdir/c++lib.w b/Build/source/texk/web2c/cwebdir/c++lib.w
new file mode 100644
index 00000000000..15e59cc8851
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/c++lib.w
@@ -0,0 +1,85 @@
+@q This file defines standard C++ namespaces and classes @>
+@q Please send corrections to saroj-tamasa@@worldnet.att.net @>
+@s std int
+@s rel_ops int
+@s bitset int
+@s char_traits int
+@s deque int
+@s list int
+@s map int
+@s multimap int
+@s multiset int
+@s pair int
+@s set int
+@s stack int
+@s exception int
+@s logic_error int
+@s runtime_error int
+@s domain_error int
+@s invalid_argument int
+@s length_error int
+@s out_of_range int
+@s range_error int
+@s overflow_error int
+@s underflow_error int
+@s back_insert_iterator int
+@s front_insert_iterator int
+@s insert_iterator int
+@s reverse_iterator int
+@s istream_iterator int
+@s ostream_iterator int
+@s istreambuf_iterator int
+@s ostreambuf_iterator int
+@s iterator_traits int
+@s queue int
+@s vector int
+@s basic_string int
+@s string int
+@s auto_ptr int
+@s valarray int
+@s ios_base int
+@s basic_ios int
+@s basic_streambuf int
+@s basic_istream int
+@s basic_ostream int
+@s basic_iostream int
+@s basic_stringbuf int
+@s basic_istringstream int
+@s basic_ostringstream int
+@s basic_stringstream int
+@s basic_filebuf int
+@s basic_ifstream int
+@s basic_ofstream int
+@s basic_fstream int
+@s ctype int
+@s collate int
+@s collate_byname int
+@s streambuf int
+@s istream int
+@s ostream int
+@s iostream int
+@s stringbuf int
+@s istringstream int
+@s ostringstream int
+@s stringstream int
+@s filebuf int
+@s ifstream int
+@s ofstream int
+@s fstream int
+@s wstreambuf int
+@s wistream int
+@s wostream int
+@s wiostram int
+@s wstringbuf int
+@s wistringstream int
+@s wostringstream int
+@s wstringstream int
+@s wfilebuf int
+@s wifstream int
+@s wofstream int
+@s wfstream int
+@s streamoff int
+@s streamsize int
+@s fpos int
+@s streampos int
+@s wstreampos int
diff --git a/Build/source/texk/web2c/cwebdir/comm-amiga.ch b/Build/source/texk/web2c/cwebdir/comm-amiga.ch
new file mode 100644
index 00000000000..f17c2d333b4
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-amiga.ch
@@ -0,0 +1,17 @@
+This is the change file for CWEB's COMMON on the Amiga
+(Contributed by Tomas Rokicki, June 1993)
+
+With Lattice C 5.1, use compilation switches -b0 -r0, and ignore the
+compiler warnings. With SAS 6.0, use compilation switches Code=far Data=far.
+
+@x section 75
+An omitted change file argument means that |"/dev/null"| should be used,
+@y
+An omitted change file argument means that |"nil:"| should be used,
+@z
+
+@x section 76
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"nil:");
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-bs.ch b/Build/source/texk/web2c/cwebdir/comm-bs.ch
new file mode 100644
index 00000000000..b01b86799d7
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-bs.ch
@@ -0,0 +1,223 @@
+Changes for code common to CTANGLE and CWEAVE, for MSDOS
+and Borland C++ 3.1 using the following options (and perhaps others):
+
+ -mc -w-pro -Ff=5000 -Z- -O-p
+
+The options -Z- and -O-p explicitly turn off optimizations that seem to be
+dangerous for the style of code in the CWEB sources. (See makefile.bs.)
+
+The main purpose of these changes is to support MSDOS with full-size arrays
+by using "huge" pointers.
+
+(This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94;
+ revised 24 Jul 94.)
+
+(Update attempt by Andreas Scherer, 31 Jan 2021. Good luck!)
+
+
+@x Section 6.
+ for section names */
+
+@<Common code...@>=
+typedef struct name_info {
+ char *byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ void *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char byte_mem[]; /* characters of names */
+extern char *byte_mem_end; /* end of |byte_mem| */
+@y
+ for section names */
+
+@f huge extern
+
+@<Common code...@>=
+typedef struct name_info {
+ char huge* byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ union {
+ void huge* equiv_member;
+ void huge* xref_member;
+ } ptr_union; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char huge byte_mem[]; /* characters of names */
+extern char huge* byte_mem_end; /* end of |byte_mem| */
+@z
+
+
+@x Section 39.
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+@y
+ cur_file_name[l]='/'; /* A valid {\mc MSDOS} pathname separator */
+@z
+
+
+@x Section 44.
+char *byte_ptr; /* first unused position in |byte_mem| */
+@y
+char huge* byte_ptr; /* first unused position in |byte_mem| */
+@z
+
+
+@x Section 45.
+@ @<Init...@>=
+name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */
+name_ptr=name_dir+1; /* |name_dir[0]| will be used only for error recovery */
+name_ptr->byte_start=byte_mem; /* this makes name 0 of length zero */
+@y
+@ @<Init...@>=
+name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */
+name_ptr=name_dir+1; /* |name_dir[0]| will be used only for error recovery */
+name_ptr->byte_start=byte_mem; /* this makes name 0 of length zero */
+byte_mem_end = byte_mem+max_bytes-1;
+@z
+
+
+@x Section 52.
+void
+print_section_name(
+name_pointer p)
+{
+ char *ss, *s = first_chunk(p);
+@y
+void
+print_section_name(
+name_pointer p)
+{
+ char huge* ss, huge* s = first_chunk(p);
+@z
+
+
+@x Section 53.
+void
+sprint_section_name(
+ char *dest,
+ name_pointer p)
+{
+ char *ss, *s = first_chunk(p);
+@y
+void
+sprint_section_name(
+ char huge* dest,
+ name_pointer p)
+{
+ char huge* ss, huge* s = first_chunk(p);
+@z
+
+
+@x Section 54.
+void
+print_prefix_name(
+name_pointer p)
+{
+ char *s = first_chunk(p);
+@y
+void
+print_prefix_name(
+name_pointer p)
+{
+ char huge* s = first_chunk(p);
+@z
+
+
+@x Section 57.
+static name_pointer
+add_section_name(@t\1\1@> /* install a new node in the tree */
+name_pointer par, /* parent of new node */
+int c, /* right or left? */
+char *first, /* first character of section name */
+char *last, /* last character of section name, plus one */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+{
+ name_pointer p=name_ptr; /* new node */
+ char *s=first_chunk(p);
+@y
+static name_pointer
+add_section_name(@t\1\1@> /* install a new node in the tree */
+name_pointer par, /* parent of new node */
+int c, /* right or left? */
+char huge* first, /* first character of section name */
+char huge* last, /* last character of section name, plus one */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+{
+ name_pointer p=name_ptr; /* new node */
+ char huge* s=first_chunk(p);
+@z
+
+
+@x Section 58.
+static void
+extend_section_name(@t\1\1@>
+name_pointer p, /* name to be extended */
+char *first, /* beginning of extension text */
+char *last, /* one beyond end of extension text */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+{
+ char *s;
+@y
+static void
+extend_section_name(@t\1\1@>
+name_pointer p, /* name to be extended */
+char huge* first, /* beginning of extension text */
+char huge* last, /* one beyond end of extension text */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+{
+ char huge* s;
+@z
+
+
+@x Section 64.
+static int section_name_cmp(@t\1\1@>
+char **pfirst, /* pointer to beginning of comparison string */
+int len, /* length of string */
+name_pointer r@t\2\2@>) /* section name being compared */
+{
+ char *first=*pfirst; /* beginning of comparison string */
+ name_pointer q=r+1; /* access to subsequent chunks */
+ char *ss, *s=first_chunk(r);
+@y
+static int section_name_cmp(@t\1\1@>
+char huge** pfirst, /* pointer to beginning of comparison string */
+int len, /* length of string */
+name_pointer r@t\2\2@>) /* section name being compared */
+{
+ char huge* first=*pfirst; /* beginning of comparison string */
+ name_pointer q=r+1; /* access to subsequent chunks */
+ char huge* ss, huge* s=first_chunk(r);
+@z
+
+
+@x Section 75.
+An omitted change file argument means that |"/dev/null"| should be used,
+@y
+An omitted change file argument means that |"NUL"| should be used,
+@z
+
+
+@x Section 76.
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"NUL");
+@z
+
+
+@x Section 76.
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+@y
+ else if (*s == ':' || *s == '\\' || *s == '/')
+ dot_pos=NULL,name_pos=++s;
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-mac.ch b/Build/source/texk/web2c/cwebdir/comm-mac.ch
new file mode 100644
index 00000000000..aa3a77fed4e
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-mac.ch
@@ -0,0 +1,155 @@
+This is the change file to CWEB's COMMON for porting to Macintoshes.
+No changes to CTANGLE or CWEAVE are needed.
+
+(Contributed 13 Oct 2000 by AndPio@aol.com; slightly edited by Don Knuth)
+
+@x in limbo, change the title page document to specify Mac version
+ \centerline{(Version 4.2)}
+@y
+ \centerline{(Version 4.2 for MacOS)}
+@z
+
+@x sections 23/24: Make input_ln accept \n, \r, \n\r, or \r\n as line endings
+@ In the unlikely event that your standard I/O library does not
+support |feof|, |getc|, and |ungetc| you may have to change things here.
+@^system dependencies@>
+
+@<Predecl...@>=
+static boolean input_ln(FILE *);@/
+
+@ @c
+static boolean input_ln(@t\1\1@> /* copies a line into |buffer| or returns |false| */
+FILE *fp@t\2\2@>) /* what file to read from */
+{
+ register int c=EOF; /* character read; initialized so some compilers won't complain */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return false; /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
+ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')
+ if ((*(k++) = c) != ' ') limit = k;
+ if (k>buffer_end)
+ if ((c=getc(fp))!=EOF && c!='\n') {
+ ungetc(c,fp); loc=buffer; err_print("! Input line too long");
+@.Input line too long@>
+ }
+ if (c==EOF && limit==buffer) return false; /* there was nothing after
+ the last newline */
+ return true;
+}
+@y
+@ In the unlikely event that your standard I/O library does not
+support |feof|, |getc|, and |ungetc| you may have to change things here.
+
+This |input_ln| function accepts |"\n"|, |"\r"|, |"\n\r"| and |"\r\n"| as
+line endings, so that \.{CWEB} will works with ASCII files stored in
+\UNIX/, {\mc DOS} or {\mc MAC} format.
+@^system dependencies@>
+
+@<Predecl...@>=
+static boolean input_ln(FILE *);@/
+
+@ @c
+static boolean input_ln(@t\1\1@> /* copies a line into |buffer| or returns |false| */
+FILE *fp@t\2\2@>) /* what file to read from */
+{
+ register int c=EOF; /* character read; initialized so some compilers won't complain */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return false; /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
+ while (true) {
+ c = getc(fp);
+ if (c==EOF) return limit!=buffer; /* |false|, if there was nothing after
+ the last newline */
+ else if (c=='\n' || c=='\r') { /* we have hit end-of-line */
+ int d = getc(fp);
+ if (c+d!='\n'+'\r') /* no combination |"\n\r"| or |"\r\n"| */
+ ungetc(d,fp);
+ return true;
+ }
+ else if (k>buffer_end) {
+ ungetc(c,fp); loc=buffer; err_print("! Input line too long");
+ return true;
+@.Input line too long@>
+ }
+ else
+ if ((*(k++)=c) != ' ') limit = k;
+ }
+}
+@z
+
+@x section 28, simply return if no change file was specified
+ change_limit=change_buffer; /* this value is used if the change file ends */
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
+@y
+ change_limit=change_buffer; /* this value is used if the change file ends */
+ if (change_file_name[0] == '\0') /* no change file specified */
+ return; /* so we have reached the end of that file */
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
+@z
+
+@x section 36, don't try to open a change file if none was specified
+if ((change_file=fopen(change_file_name,"r"))==NULL)
+ fatal("! Cannot open change file ", change_file_name);
+@y
+if (change_file_name[0] == '\0') /* no change file specified */
+ change_file = NULL; /* reset at least the |change_file| */
+else if ((change_file=fopen(change_file_name,"r"))==NULL)
+ fatal("! Cannot open change file ", change_file_name);
+@z
+
+@x section 39, declare colon as Mac's path separator
+(Colon-separated paths are not supported.)
+The remainder of the \.{@@i} line after the file name is ignored.
+
+@y
+(Colon-separated path alternatives in the style of \UNIX/ or Kpathsea
+are not supported. On a Macintosh, colons are used to separate the names on
+different levels of a path.)
+The remainder of the \.{@@i} line after the file name is ignored.
+
+@d PATH_SEP ':' /* MacOS pathname separator */
+@^system dependencies@>
+@z
+@x section 39, use the path separator constant
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+@y
+ cur_file_name[l]=PATH_SEP; /* pathname separator */
+@z
+
+@x section 75, explain the convention for omitted change files
+An omitted change file argument means that |"/dev/null"| should be used,
+@y
+An omitted change file argument means that no change file should be used,
+@z
+
+@x section 76, make change file name empty when it is unspecified
+ strcpy(change_file_name,"/dev/null");
+@y
+ change_file_name[0]='\0'; /* empty string */
+@z
+@x section 76, use the Metrowerks |ccommand| to access command lines
+ while (--argc > 0) {
+@y
+ argc = ccommand (&argv); /* use Mac interface to command line */
+@^system dependencies@>
+ while (--argc > 0) {
+@z
+@x section 76, use the path separator constant
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+@y
+ else if (*s==PATH_SEP) dot_pos=NULL,name_pos=++s;
+@z
+
+@x section 85, insert an extra module before the index
+@** Index.
+@y by putting the new module here, we preserve all the previous section numbers
+@ We assume an interface to \CEE/ command-line emulation as supplied by
+the |ccommand| function of Metrowerks CodeWarrior, as defined in
+the header file \.{console.h}.
+
+@<Include files@>=
+#include <console.h>
+@^system dependencies@>
+
+@** Index.
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-man.ch b/Build/source/texk/web2c/cwebdir/comm-man.ch
new file mode 100644
index 00000000000..c922c036312
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-man.ch
@@ -0,0 +1,22 @@
+Change file to help make Appendix D of the full CWEB manual
+@x
+\def\botofcontents{\vfill
+\noindent
+Copyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth
+\bigskip\noindent
+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.
+
+\smallskip\noindent
+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.
+}
+@y
+\def\botofcontents{\vfill\titlefalse}
+\def\contentspagenumber{28}
+\def\title{APPENDIX D: COMMON}
+\let\K=\leftarrow
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-os2.ch b/Build/source/texk/web2c/cwebdir/comm-os2.ch
new file mode 100644
index 00000000000..2b85f8b1f6d
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-os2.ch
@@ -0,0 +1,24 @@
+This is the change file for CWEB's COMMON under OS/2
+(Contributed by Jim Nutt, jnutt@PrimeNet.Com, May 1995)
+
+These changes tested with WATCOM C v10.0a.
+No changes to CTANGLE or CWEAVE are needed with OS/2.
+
+@x section 75
+An omitted change file argument means that |"/dev/null"| should be used,
+@y
+An omitted change file argument means that |"NUL"| should be used,
+@z
+
+@x section 76
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"NUL");
+@z
+
+@x section 76 (this change copied from comm-pc.ch)
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+@y
+ else if (*s == ':' || *s == '\\' || *s == '/')
+ dot_pos=NULL,name_pos=++s;
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-pc.ch b/Build/source/texk/web2c/cwebdir/comm-pc.ch
new file mode 100644
index 00000000000..5f7d9c42ffe
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-pc.ch
@@ -0,0 +1,33 @@
+This is the change file for CWEB's COMMON under DOS
+(Contributed by Lee Wittenberg, March 1993)
+
+Changes necessary for compiling with Borland C/C++
+Use compilation switches -mc -w-pro -Ff=5000
+
+Note: The change to section 16 is not necessary if using a compiler
+that allows >64K arrays.
+
+@x section 16
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+@y
+@d max_bytes (unsigned)60000 /* the number of bytes in identifiers,
+@z
+
+@x section 75
+An omitted change file argument means that |"/dev/null"| should be used,
+@y
+An omitted change file argument means that |"NUL"| should be used,
+@z
+
+@x section 76
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"NUL");
+@z
+
+@x section 76 (this change copied from comm-bs.ch, July 94)
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+@y
+ else if (*s == ':' || *s == '\\' || *s == '/')
+ dot_pos=NULL,name_pos=++s;
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-ql.ch b/Build/source/texk/web2c/cwebdir/comm-ql.ch
new file mode 100644
index 00000000000..c03b9185cb9
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-ql.ch
@@ -0,0 +1,277 @@
+This is the change file for CWEB's COMMON under QSOD/SMSQ
+(Contributed by Robert H. Klein, September 1994)
+
+This change file is intended for use with C68 v4.13 (or later).
+compile with
+ex <dev_>cc;'-v -h -c -=500000 -DCWEBINPUTS=flp2_ common_c'
+
+
+
+@x
+\def\v{\char'174} % vertical (|) in typewriter font
+
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
+ {\ttitlefont CWEAVE}}
+ \vskip 15pt
+ \centerline{(Version 4.2)}
+ \vfill}
+\def\botofcontents{\vfill
+\noindent
+@y
+\def\v{\char'174} % vertical (|) in typewriter font
+
+\def\title{Common code for CTANGLE and CWEAVE (QL Version 4.2)}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
+ {\ttitlefont CWEAVE}}
+ \vskip 15pt
+ \centerline{(Version 4.2)}
+ \vfill}
+\def\botofcontents{\vfill
+\noindent
+@z
+
+
+For use on QDOS/SMSQ systems the variable |max_file_name_length| is shortened
+to 42 characters, i.e. 5 characters for the device name, 36 characters
+for the file name plus one character as string terminator. (Note that
+(current) QDOS/SMSQ file systems have a limitation of 36 characters as
+maximum length for a file name.
+@x
+@d max_file_name_length 1024
+@y
+@d max_file_name_length 42
+@z
+
+
+@x
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+@y
+ cur_file_name[l]='_'; /* QDOS/SMSQ pathname separator */
+@z
+
+
+@x
+@ We now must look at the command line arguments and set the file names
+accordingly. At least one file name must be present: the \.{CWEB}
+file. It may have an extension, or it may omit the extension to get |".w"| or
+|".web"| added. The \TEX/ output file name is formed by replacing the \.{CWEB}
+file name extension by |".tex"|, and the \CEE/ file name by replacing
+the extension by |".c"|, after removing the directory name (if any).
+
+If there is a second file name present among the arguments, it is the
+change file, again either with an extension or without one to get |".ch"|.
+An omitted change file argument means that |"/dev/null"| should be used,
+when no changes are desired.
+@^system dependencies@>
+
+If there's a third file name, it will be the output file.
+@y
+@ We now must look at the command line arguments and set the file names
+accordingly. At least one file name must be present: the \.{CWEB}
+file. It may have an extension, or it may omit the extension to get |"_w"| or
+|"_web"| added. The \TEX/ output file name is formed by replacing the \.{CWEB}
+file name extension by |"_tex"|, and the \CEE/ file name by replacing
+the extension by |"_c"|, after removing the directory name (if any).
+
+If there is a second file name present among the arguments, it is the
+change file, again either with an extension or without one to get |"_ch"|.
+An omitted change file argument means that |"NUL"| should be used,
+when no changes are desired.
+@^system dependencies@>
+
+If there's a third file name, it will be the output file.
+
+Because |"_"| is a directory {\em and} extension separator, \.{CWEB} will
+always use the {\em full} name (i.e. with full path). Fortunately the
+routine has been written to search for the last ``dot'', so the altered
+version will search for the last |"_"| (including directory separators),
+so we have what we want.
+@z
+
+
+@x
+ char *dot_pos; /* position of |'.'| in the argument */
+@y
+ char *dot_pos; /* position of |'_'| in the argument */
+@z
+
+
+@x
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"NUL");
+@z
+
+
+@x
+ if (*s=='.') dot_pos=s++;
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+ else s++;
+@y
+ if (*s=='_') dot_pos=s++;
+ else if (*s=='_') dot_pos=NULL,name_pos=++s;
+ else s++;
+@z
+
+
+@x
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|. If this file can't be opened, we prepare an
+|alt_web_file_name| by adding |"web"| after the dot.
+The other file names come from adding other things
+after the dot. We must check that there is enough room in
+|web_file_name| and the other arrays for the argument.
+@y
+@ We use all of |*argv| for the |web_file_name| if there is a |'_'| in it,
+otherwise we add |"_w"|. If this file can't be opened, we prepare an
+|alt_web_file_name| by adding |"web"| after the dot.
+The other file names come from adding other things
+after the dot. We must check that there is enough room in
+|web_file_name| and the other arrays for the argument.
+
+If you've read the section before carefully you'll have noticed, that
+QDOS/SMSQ file names contain almost a |"_"|, so this routine will not work,
+i.e. you'll {\em have} to add the |"_w"| always. Nevertheless I adapted
+the routine as if it would work.
+@z
+
+
+@x
+@<Make |web_file_name|...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL)
+ sprintf(web_file_name,"%s.w",*argv);
+ else {
+ strcpy(web_file_name,*argv);
+ *dot_pos=0; /* string now ends where the dot was */
+ }
+ sprintf(alt_web_file_name,"%s.web",*argv);
+ sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */
+ sprintf(idx_file_name,"%s.idx",name_pos);
+ sprintf(scn_file_name,"%s.scn",name_pos);
+ sprintf(C_file_name,"%s.c",name_pos);
+ found_web=true;
+}
+@y
+@<Make |web_file_name|...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>;
+ if (dot_pos==NULL)
+ sprintf(web_file_name,"%s_w",*argv);
+ else {
+ strcpy(web_file_name,*argv);
+ *dot_pos=0; /* string now ends where the dot was */
+ }
+ sprintf(alt_web_file_name,"%s_web",*argv);
+ sprintf(tex_file_name,"%s_tex",name_pos); /* strip off directory name */
+ sprintf(idx_file_name,"%s_idx",name_pos);
+ sprintf(scn_file_name,"%s_scn",name_pos);
+ sprintf(C_file_name,"%s_c",name_pos);
+ found_web=true;
+}
+@z
+
+
+@x
+@ @<Make |change_file_name|...@>=
+{
+ if (strcmp(*argv,"-")!=0) {
+ if (s-*argv > max_file_name_length-4)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL)
+ sprintf(change_file_name,"%s.ch",*argv);
+ else strcpy(change_file_name,*argv);
+ }
+ found_change=true;
+}
+@y
+@ @<Make |change_file_name|...@>=
+{
+ if (strcmp(*argv,"-")!=0) {
+ if (s-*argv > max_file_name_length-4)
+ @<Complain about argument length@>;
+ if (dot_pos==NULL)
+ sprintf(change_file_name,"%s_ch",*argv);
+ else strcpy(change_file_name,*argv);
+ found_change=true;
+ }
+}
+@z
+
+
+@x
+@ @<Override...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL) {
+ sprintf(tex_file_name,"%s.tex",*argv);
+ sprintf(idx_file_name,"%s.idx",*argv);
+ sprintf(scn_file_name,"%s.scn",*argv);
+ sprintf(C_file_name,"%s.c",*argv);
+ } else {
+ strcpy(tex_file_name,*argv);
+ strcpy(C_file_name,*argv);
+ if (make_xrefs) { /* indexes will be generated */
+ *dot_pos=0;
+ sprintf(idx_file_name,"%s.idx",*argv);
+ sprintf(scn_file_name,"%s.scn",*argv);
+ }
+ }
+ found_out=true;
+}
+@y
+@ @<Override...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>;
+ if (dot_pos==NULL) {
+ sprintf(tex_file_name,"%s_tex",*argv);
+ sprintf(idx_file_name,"%s_idx",*argv);
+ sprintf(scn_file_name,"%s_scn",*argv);
+ sprintf(C_file_name,"%s_c",*argv);
+ } else {
+ strcpy(tex_file_name,*argv);
+ strcpy(C_file_name,*argv);
+ if (make_xrefs) { /* indexes will be generated */
+ *dot_pos=0;
+ sprintf(idx_file_name,"%s_idx",*argv);
+ sprintf(scn_file_name,"%s_scn",*argv);
+ }
+ }
+ found_out=true;
+}
+@z
+
+
+@x
+@ @<Print usage error message and quit@>=
+{
+if (program==ctangle)
+ fatal(
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+ ,"");
+@.Usage:@>
+else fatal(
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+ ,"");
+}
+@y
+@ @<Print usage error message and quit@>=
+{
+if (program==ctangle)
+ fatal(
+"! Usage: ctangle [options] webfile[_w] [{changefile[_ch]|-} [outfile[_c]]]\n"
+ ,"");
+@.Usage:@>
+else fatal(
+"! Usage: cweave [options] webfile[_w] [{changefile[_ch]|-} [outfile[_tex]]]\n"
+ ,"");
+}
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-vms.ch b/Build/source/texk/web2c/cwebdir/comm-vms.ch
new file mode 100644
index 00000000000..caf8ecef795
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-vms.ch
@@ -0,0 +1,88 @@
+This is the change file for CWEB's COMMON under VAX/VMS.
+
+created:
+ 1987 BL (Bjorn Larsen, University of Oslo)
+
+modified:
+ 01-FEB-1992 ST (Stephan Trebels <trebels@ams02.dnet.gwdg.de>)
+ > include ctype,stdio,ssdef from textlibrary SYS$SHARE:VAXCDEF.TLB
+ > change error return code to SS$_ABORT
+ (perhaps better than %NONAME-E-NOMSG, Message number 2 )
+
+(also modified by Don Knuth to match changes in the master file)
+(only the two changes by BL are necessary for initial bootstrapping
+ via hand-editing of common.c)
+
+@x section 3 (01-FEB-1992 ST)
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
+@y
+#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */
+ /* VMS searches text libraries faster */
+#include stdbool /* definition of |@!bool|, |@!true| and |@!false| */
+#include stddef /* definition of |@!ptrdiff_t| */
+#include stdint /* definition of |@!uint8_t| and |@!uint16_t| */
+#include stdlib /* definition of |@!getenv| and |@!exit| */
+#include stdio /* definition of |@!printf| and friends */
+#include string /* definition of |@!strlen|, |@!strcmp| and so on */
+@z
+
+@x section 68 (01-FEB-1992 ST)
+programs are started. Here, for instance, we pass the operating system
+a status of 0 if and only if only harmless messages were printed.
+@y
+programs are started. Here, for instance, we pass VAX/VMS
+a status of |SS$_NORMAL| if and only if only harmless
+messages have been printed.
+A suitable status to signal an error condition to VAX/VMS could be
+|SS$_ABORT|, telling the operating system to
+print |"%SYSTEM-F-ABORT, abort"|, if |history > harmless_message|.
+@z
+
+@x section 68 (1987 BL) (01-FEB-1992 ST) (11-JAN-1993 DEK)
+ if (history > harmless_message) return EXIT_FAILURE;
+ else return EXIT_SUCCESS;
+@y
+/*
+ VAX/VMS and UNIX have different error status conventions.
+ VAX/VMS uses odd values (for example |SS$_NORMAL|) to indicate success,
+ even values indicate errors, resulting in messages displayed
+ on the screen. |SS$_ABORT| has been chosen, to indicate an
+ error and display something that's not complete nonsense.
+*/
+ if (history > harmless_message) exit(SS$_ABORT);
+ else exit(SS$_NORMAL);
+@z
+
+@x section 75 (01-FEB-1992 ST)
+An omitted change file argument means that |"/dev/null"| should be used,
+when no changes are desired.
+@y
+An omitted change file argument means that the
+null device |"NL:"| should be used, when no changes are desired.
+@z
+
+@x section 76 (1987 BL) (01-FEB-1992 ST) (05-APR-1992 DEK)
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"NL:");
+ /* {\tt NL:} is the VAX/VMS notation for {\tt /dev/null} */
+@z
+
+@x section 85 (01-FEB-1992 ST)
+@** Index.
+@y
+@* VAX/VMS specific code.
+We have used |SS$_NORMAL| and |SS$_ABORT| as return codes,
+so we have to include the system message codes.
+
+@<Include files@>=
+#include ssdef /* we need VAX/VMS system messages */
+
+@** Index.
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-w2c.ch b/Build/source/texk/web2c/cwebdir/comm-w2c.ch
new file mode 100644
index 00000000000..286a39723e1
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-w2c.ch
@@ -0,0 +1,866 @@
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
+
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
+
+@q This stripped change file {comm,ctang,cweav,ctwill,cwebman}-w2c.ch @>
+@q has been created from the elaborate set of change files @>
+@q {comm,ctang,cweav,cwebman}-patch.ch, @>
+@q {comm,cweav,cwebman}-extensions.ch, {comm,ctang,cweav}-output.ch, @>
+@q {comm,ctang,cweav}-i18n.ch, and cweav-twill.ch for CTWILL, and @>
+@q {comm,ctang,cweav,ctwill,cwebman}-texlive.ch with the 'tie' processor @>
+@q and is used as a monolithic changefile for {common,ctangle,cweave}.w @>
+@q and cwebman.tex in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)}
+@y
+\def\Kpathsea/{{\mc KPATHSEA\spacefactor1000}} \ifacro\sanitizecommand\Kpathsea{KPATHSEA}\fi
+\def\title{Common code for CTANGLE and CWEAVE (4.2 [\TeX~Live])}
+@z
+
+@x
+ \centerline{(Version 4.2)}
+@y
+ \centerline{(Version 4.2 [\TeX~Live])}
+@z
+
+@x
+\def\botofcontents{\vfill
+@y
+\def\covernote{\vbox{%
+@z
+
+@x
+}
+@y
+}}\datecontentspage
+@z
+
+@x
+to both \.{CTANGLE} and \.{CWEAVE}, which roughly concerns the following
+@y
+to \.{CTANGLE}, \.{CWEAVE}, and \.{CTWILL},
+which roughly concerns the following
+@z
+
+@x
+sometimes use \.{CWEB} to refer to either of the two component
+@y
+sometimes use \.{CWEB} to refer to any of the three component
+@z
+
+@x
+@i common.h
+@y
+@i comm-w2c.h
+@z
+
+@x
+|program|.
+@y
+|program|. And \.{CTWILL} adds some extra twists.
+@z
+
+@x
+boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */
+@y
+cweb program; /* \.{CTANGLE} or \.{CWEAVE} or \.{CTWILL}? */
+@z
+
+@x
+ @<Initialize pointers@>@;
+@y
+ @<Initialize pointers@>@;
+ @<Set up |PROGNAME| feature and initialize the search path mechanism@>@;
+@z
+
+@x
+ @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>@;
+@y
+ @<Set locale and bind language catalogs@>@;
+ @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>@;
+@z
+
+@x
+ if ((*(k++) = c) != ' ') limit = k;
+@y
+ if ((*(k++) = c) != ' ' && c != '\r') limit = k;
+@z
+
+@x
+ ungetc(c,fp); loc=buffer; err_print("! Input line too long");
+@y
+ ungetc(c,fp); loc=buffer; err_print(_("! Input line too long"));
+@z
+
+@x
+static char alt_web_file_name[max_file_name_length]; /* alternate name to try */
+@y
+@z
+
+@x
+ err_print("! Missing @@x in change file");
+@y
+ err_print(_("! Missing @@x in change file"));
+@z
+
+@x
+ err_print("! Change file ended after @@x");
+@y
+ err_print(_("! Change file ended after @@x"));
+@z
+
+@x
+ err_print("! Change file ended before @@y");
+@y
+ err_print(_("! Change file ended before @@y"));
+@z
+
+@x
+ err_print("! CWEB file ended during a change");
+@y
+ err_print(_("! CWEB file ended during a change"));
+@z
+
+@x
+ loc=buffer+2; err_print("! Where is the matching @@y?");
+@y
+ loc=buffer+2; err_print(_("! Where is the matching @@y?"));
+@z
+
+@x
+ err_print("of the preceding lines failed to match");
+@y
+ err_print(_("of the preceding lines failed to match"));
+@z
+
+@x
+if ((web_file=fopen(web_file_name,"r"))==NULL) {
+ strcpy(web_file_name,alt_web_file_name);
+ if ((web_file=fopen(web_file_name,"r"))==NULL)
+ fatal("! Cannot open input file ", web_file_name);
+}
+@y
+if ((found_filename=kpse_find_cweb(web_file_name))==NULL || @|
+ (web_file=fopen(found_filename,"r"))==NULL) {
+ fatal(_("! Cannot open input file "), web_file_name);
+} else if (strlen(found_filename) < max_file_name_length) {
+ /* Copy name for |#line| directives. */
+ if (strcmp(web_file_name, found_filename))
+ strcpy(web_file_name, found_filename +
+ ((strncmp(found_filename,"./",2)==0) ? 2 : 0));
+ free(found_filename);
+} else fatal(_("! Filename too long\n"), found_filename);
+@z
+
+@x
+if ((change_file=fopen(change_file_name,"r"))==NULL)
+ fatal("! Cannot open change file ", change_file_name);
+@y
+if ((found_filename=kpse_find_cweb(change_file_name))==NULL || @|
+ (change_file=fopen(found_filename,"r"))==NULL) {
+ fatal(_("! Cannot open change file "), change_file_name);
+} else if (strlen(found_filename) < max_file_name_length) {
+ /* Copy name for |#line| directives. */
+ if (strcmp(change_file_name, found_filename))
+ strcpy(change_file_name, found_filename +
+ ((strncmp(found_filename,"./",2)==0) ? 2 : 0));
+ free(found_filename);
+} else fatal(_("! Filename too long\n"), found_filename);
+@z
+
+@x
+ err_print("! Include file name not given");
+@y
+ err_print(_("! Include file name not given"));
+@z
+
+@x
+ err_print("! Too many nested includes");
+@y
+ err_print(_("! Too many nested includes"));
+@z
+
+@x
+@ When an \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without
+double quotes.
+If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
+of the same name was defined at compile time,
+\.{CWEB} will look for include files in the directory thus named, if
+it cannot find them in the current directory.
+(Colon-separated paths are not supported.)
+The remainder of the \.{@@i} line after the file name is ignored.
+@y
+@ When an \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without
+double quotes.
+The actual file lookup is done with the help of the \Kpathsea/ library;
+see section~\X91:File lookup with \Kpathsea/\X~for details. % FIXME
+The remainder of the \.{@@i} line after the file name is ignored.
+@^system dependencies@> @.CWEBINPUTS@>
+@z
+
+@x
+ err_print("! Include file name too long"); goto restart;}
+@y
+ err_print(_("! Include file name too long")); goto restart;}
+@z
+
+@x
+ char temp_file_name[max_file_name_length];
+ char *cur_file_name_end=cur_file_name+max_file_name_length-1;
+ char *k=cur_file_name, *kk;
+ int l; /* length of file name */
+@y
+ char *cur_file_name_end=cur_file_name+max_file_name_length-1;
+ char *k=cur_file_name;
+@z
+
+@x
+ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
+@y
+ if ((found_filename=kpse_find_cweb(cur_file_name))!=NULL && @|
+ (cur_file=fopen(found_filename,"r"))!=NULL) {
+ /* Copy name for |#line| directives. */
+ if (strlen(found_filename) < max_file_name_length) {
+ if (strcmp(cur_file_name, found_filename))
+ strcpy(cur_file_name, found_filename +
+ ((strncmp(found_filename,"./",2)==0) ? 2 : 0));
+ free(found_filename);
+ } else fatal(_("! Filename too long\n"), found_filename);
+@z
+
+@x
+ kk=getenv("CWEBINPUTS");
+ if (kk!=NULL) {
+ if ((l=strlen(kk))>max_file_name_length-2) too_long();
+ strcpy(temp_file_name,kk);
+ }
+ else {
+#ifdef CWEBINPUTS
+ if ((l=strlen(CWEBINPUTS))>max_file_name_length-2) too_long();
+ strcpy(temp_file_name,CWEBINPUTS);
+#else
+ l=0;
+#endif /* |CWEBINPUTS| */
+ }
+ if (l>0) {
+ if (k+l+2>=cur_file_name_end) too_long();
+@.Include file name ...@>
+ for (; k>= cur_file_name; k--) *(k+l+1)=*k;
+ strcpy(cur_file_name,temp_file_name);
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
+ cur_line=0; print_where=true;
+ goto restart; /* success */
+ }
+ }
+ include_depth--; err_print("! Cannot open include file"); goto restart;
+@y
+ include_depth--; err_print(_("! Cannot open include file")); goto restart;
+@z
+
+@x
+ err_print("! Change file ended without @@z");
+@y
+ err_print(_("! Change file ended without @@z"));
+@z
+
+@x
+ err_print("! Where is the matching @@z?");
+@y
+ err_print(_("! Where is the matching @@z?"));
+@z
+
+@x
+ err_print("! Change file entry did not match");
+@y
+ err_print(_("! Change file entry did not match"));
+@z
+
+@x
+ if (byte_ptr+l>byte_mem_end) overflow("byte memory");
+ if (name_ptr>=name_dir_end) overflow("name");
+@y
+ if (byte_ptr+l>byte_mem_end) overflow(_("byte memory"));
+ if (name_ptr>=name_dir_end) overflow(_("name"));
+@z
+
+@x
+ if (s+name_len>byte_mem_end) overflow("byte memory");
+ if (name_ptr+1>=name_dir_end) overflow("name");
+@y
+ if (s+name_len>byte_mem_end) overflow(_("byte memory"));
+ if (name_ptr+1>=name_dir_end) overflow(_("name"));
+@z
+
+@x
+ if (name_ptr>=name_dir_end) overflow("name");
+@y
+ if (name_ptr>=name_dir_end) overflow(_("name"));
+@z
+
+@x
+ if (s+name_len>byte_mem_end) overflow("byte memory");
+@y
+ if (s+name_len>byte_mem_end) overflow(_("byte memory"));
+@z
+
+@x
+ fputs("\n! Ambiguous prefix: matches <",stdout);
+@y
+ fputs(_("\n! Ambiguous prefix: matches <"),stdout);
+@z
+
+@x
+ fputs(">\n and <",stdout);
+@y
+ fputs(_(">\n and <"),stdout);
+@z
+
+@x
+ fputs("\n! New name is a prefix of <",stdout);
+@y
+ fputs(_("\n! New name is a prefix of <"),stdout);
+@z
+
+@x
+ fputs("\n! New name extends <",stdout);
+@y
+ fputs(_("\n! New name extends <"),stdout);
+@z
+
+@x
+ fputs("\n! Section name incompatible with <",stdout);
+@y
+ fputs(_("\n! Section name incompatible with <"),stdout);
+@z
+
+@x
+ fputs(">,\n which abbreviates <",stdout);
+@y
+ fputs(_(">,\n which abbreviates <"),stdout);
+@z
+
+@x
+ printf(". (l. %d of change file)\n", change_line);
+else if (include_depth==0) printf(". (l. %d)\n", cur_line);
+ else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
+@y
+ printf(_(". (l. %d of change file)\n"), change_line);
+else if (include_depth==0) printf(_(". (l. %d)\n"), cur_line);
+ else printf(_(". (l. %d of include file %s)\n"), cur_line, cur_file_name);
+@z
+
+@x
+Some implementations may wish to pass the |history| value to the
+operating system so that it can be used to govern whether or not other
+programs are started. Here, for instance, we pass the operating system
+a status of 0 if and only if only harmless messages were printed.
+@^system dependencies@>
+@y
+On multi-tasking systems like the {\mc AMIGA} it is very convenient to
+know a little bit more about the reasons why a program failed. The four
+levels of return indicated by the |history| value are very suitable for
+this purpose. Here, for instance, we pass the operating system a status
+of~0 if and only if the run was a complete success. Any warning or error
+message will result in a higher return value, so that {\mc AREXX} scripts
+can be made sensitive to these conditions.
+@^system dependencies@>
+
+@d RETURN_OK 0 /* No problems, success */
+@d RETURN_WARN 5 /* A warning only */
+@d RETURN_ERROR 10 /* Something wrong */
+@d RETURN_FAIL 20 /* Complete or severe failure */
+@z
+
+@x
+ @<Print the job |history|@>@;
+@y
+ @<Print the job |history|@>@;
+ @<Remove the temporary file if not already done@>@;
+@z
+
+@x
+ if (history > harmless_message) return EXIT_FAILURE;
+ else return EXIT_SUCCESS;
+@y
+ switch(history) {
+ case harmless_message: return RETURN_WARN;
+ case error_message: return RETURN_ERROR;
+ case fatal_message: return RETURN_FAIL;
+ default: return RETURN_OK;
+ }
+@z
+
+@x
+case spotless: if (show_happiness) puts("(No errors were found.)"); break;
+case harmless_message:
+ puts("(Did you see the warning message above?)"); break;
+case error_message:
+ puts("(Pardon me, but I think I spotted something wrong.)"); break;
+case fatal_message: puts("(That was a fatal error, my friend.)");
+@y
+case spotless:
+ if (show_happiness) puts(_("(No errors were found.)")); break;
+case harmless_message:
+ puts(_("(Did you see the warning message above?)")); break;
+case error_message:
+ puts(_("(Pardon me, but I think I spotted something wrong.)")); break;
+case fatal_message:
+ puts(_("(That was a fatal error, my friend.)"));
+@z
+
+@x
+ printf("\n! Sorry, %s capacity exceeded",t); fatal("","");
+@y
+ printf(_("\n! Sorry, %s capacity exceeded"),t); fatal("","");
+@z
+
+@x
+char scn_file_name[max_file_name_length]; /* name of |scn_file| */
+@y
+char scn_file_name[max_file_name_length]; /* name of |scn_file| */
+char check_file_name[max_file_name_length]; /* name of |check_file| */
+@z
+
+@x
+show_banner=show_happiness=show_progress=make_xrefs=true;@/
+@y
+make_xrefs=true;@/
+temporary_output=true; /* Check temporary output for changes */
+@z
+
+@x
+file. It may have an extension, or it may omit the extension to get |".w"| or
+|".web"| added. The \TEX/ output file name is formed by replacing the \.{CWEB}
+@y
+file. It may have an extension, or it may omit the extension to get |".w"|
+added. The \TEX/ output file name is formed by replacing the \.{CWEB}
+@z
+
+@x
+An omitted change file argument means that |"/dev/null"| should be used,
+when no changes are desired.
+@y
+An omitted change file argument means that |"/dev/null"| or---on non-\UNIX/
+systems the contents of the compile-time variable |DEV_NULL| (\TeX~Live) or
+|_DEV_NULL| (Amiga)---should be used, when no changes are desired.
+@z
+
+@x
+ strcpy(change_file_name,"/dev/null");
+@y
+@#
+#if defined DEV_NULL
+ strncpy(change_file_name,DEV_NULL,max_file_name_length-2);
+ change_file_name[max_file_name_length-2]='\0';
+#elif defined _DEV_NULL
+ strncpy(change_file_name,_DEV_NULL,max_file_name_length-2);
+ change_file_name[max_file_name_length-2]='\0';
+#else
+ strcpy(change_file_name,"/dev/null");
+#endif
+@^system dependencies@>
+@z
+
+@x
+ while (*s) {
+ if (*s=='.') dot_pos=s++;
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+ else s++;
+ }
+@y
+ while (*s) {
+ if (*s=='.') dot_pos=s++;
+ else if (*s==DIR_SEPARATOR || *s==DEVICE_SEPARATOR || *s=='/')
+ dot_pos=NULL,name_pos=++s;
+ else s++;
+ }
+@^system dependencies@>
+@z
+
+@x
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|. If this file can't be opened, we prepare an
+|alt_web_file_name| by adding |"web"| after the dot.
+@y
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|.
+@z
+
+@x
+ sprintf(alt_web_file_name,"%s.web",*argv);
+@y
+@z
+
+@x
+@<Handle flag...@>=
+{
+ for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
+@y
+@<Handle flag...@>=
+{
+ if (strcmp("-help",*argv)==0 || strcmp("--help",*argv)==0)
+@.--help@>
+ @<Display help message and |exit|@>@;
+ if (strcmp("-version",*argv)==0 || strcmp("--version",*argv)==0)
+@.--version@>
+ @<Display version information and |exit|@>@;
+ if (strcmp("-verbose",*argv)==0 || strcmp("--verbose",*argv)==0)
+@.--verbose@>
+ { show_banner=show_progress=show_happiness=1; continue; }
+ if (strcmp("-quiet",*argv)==0 || strcmp("--quiet",*argv)==0)
+@.--quiet@>
+ { show_banner=show_progress=show_happiness=0; continue; }
+ for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
+ if (*dot_pos=='v') {
+ show_banner=show_progress=show_happiness=true;
+ } else
+ if (*dot_pos=='q') {
+ show_banner=show_progress=show_happiness=false;
+ } else
+ if (*dot_pos=='d') {
+ if (sscanf(++dot_pos,"%u",&kpathsea_debug)!=1) @<Print usage error...@>@;
+ while (isdigit(*dot_pos)) dot_pos++; /* skip numeric part */
+ dot_pos--; /* reset to final digit */
+ } else
+ if(*dot_pos=='l') {
+ use_language=++dot_pos;
+ break;
+ } else
+@z
+
+@x
+@ @<Print usage error message and quit@>=
+{
+if (program==ctangle)
+ fatal(
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+ ,"");
+@.Usage:@>
+else fatal(
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+ ,"");
+}
+@y
+@ @<Print usage error message and quit@>=
+cb_usage(program==ctangle ? "ctangle" : program==cweave ? "cweave" : "ctwill");
+@.Usage:@>
+@z
+
+@x
+@ @<Complain about arg...@>= fatal("! Filename too long\n", *argv);
+@y
+@ @<Complain about arg...@>= fatal(_("! Filename too long\n"), *argv);
+@z
+
+@x
+FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+@y
+FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+FILE *check_file; /* temporary output file */
+@z
+
+@x
+FILE *active_file; /* currently active file for \.{CWEAVE} output */
+@y
+FILE *active_file; /* currently active file for \.{CWEAVE} output */
+char *found_filename; /* filename found by |kpse_find_file| */
+@z
+
+@x
+@ @<Scan arguments and open output files@>=
+scan_args();
+if (program==ctangle) {
+ if ((C_file=fopen(C_file_name,"wb"))==NULL)
+ fatal("! Cannot open output file ", C_file_name);
+@.Cannot open output file@>
+}
+else {
+ if ((tex_file=fopen(tex_file_name,"wb"))==NULL)
+ fatal("! Cannot open output file ", tex_file_name);
+}
+@y
+@ @<Scan arguments and open output files@>=
+scan_args();
+if (program==ctangle) {
+ if ((C_file=fopen(C_file_name,"a"))==NULL)
+ fatal(_("! Cannot open output file "), C_file_name);
+@.Cannot open output file@>
+ else fclose(C_file); /* Test accessability */
+ strcpy(check_file_name,C_file_name);
+ if(check_file_name[0]!='\0') {
+ char *dot_pos=strrchr(check_file_name,'.');
+ if(dot_pos==NULL) strcat(check_file_name,".ttp");
+ else strcpy(dot_pos,".ttp");
+ }
+ if ((C_file=fopen(check_file_name,"wb"))==NULL)
+ fatal(_("! Cannot open output file "), check_file_name);
+@.Cannot open output file@>
+}
+else {
+ if ((tex_file=fopen(tex_file_name,"a"))==NULL)
+ fatal(_("! Cannot open output file "), tex_file_name);
+ else fclose(tex_file); /* Test accessability */
+ strcpy(check_file_name,tex_file_name);
+ if(check_file_name[0]!='\0') {
+ char *dot_pos=strrchr(check_file_name,'.');
+ if(dot_pos==NULL) strcat(check_file_name,".wtp");
+ else strcpy(dot_pos,".wtp");
+ }
+ if ((tex_file=fopen(check_file_name,"wb"))==NULL)
+ fatal(_("! Cannot open output file "), check_file_name);
+}
+@z
+
+@x
+@** Index.
+@y
+@** Extensions to \.{CWEB}. The following sections introduce new or improved
+features that have been created by numerous contributors over the course of a
+quarter century.
+
+Care has been taken to keep the original section numbering intact, so this new
+material should nicely integrate with the original ``\&{85.~Index}.''
+
+@* Language setting. This global variable is set by the argument of the
+`\.{+l}' (or `\.{-l}') command-line option.
+
+@<Global var...@>=
+const char *use_language=""; /* prefix of \.{cwebmac.tex} in \TEX/ output */
+
+
+@* User communication. The |scan_args| and |cb_show_banner| routines and the
+|bindtextdomain| argument string need a few extra variables.
+
+@d max_banner 50
+
+@d PATH_SEPARATOR separators[0]
+@d DIR_SEPARATOR separators[1]
+@d DEVICE_SEPARATOR separators[2]
+
+@<Global var...@>=
+char cb_banner[max_banner];@/
+string texmf_locale;@/
+#ifndef SEPARATORS
+#define SEPARATORS "://"
+#endif
+char separators[]=SEPARATORS;
+
+@* Temporary file output. Before we leave the program we have to make
+sure that the output files are correctly written.
+
+@<Remove the temporary file...@>=
+if(C_file) fclose(C_file);
+if(tex_file) fclose(tex_file);
+if(check_file) fclose(check_file);
+if(strlen(check_file_name)) /* Delete the temporary file in case of a break */
+ remove(check_file_name);
+
+@* Internationalization. If translation catalogs for your personal
+\.{LANGUAGE} are installed at the appropriate place, \.{CTANGLE} and \.{CWEAVE}
+will talk to you in your favorite language. Catalog \.{cweb} contains all
+strings from ``plain \.{CWEB},'' catalog \.{cweb-tl} contains a few extra
+strings specific to the \TeX~Live interface, and catalog \.{web2c-help}
+contains the ``\.{--help}'' texts for \.{CTANGLE} and \.{CWEAVE}.
+@.cweb.mo@>
+@.cweb-tl.mo@>
+@.web2c-help.mo@>
+@.--help@>
+
+If such translation files are not available, you may want to improve this
+system by checking out the sources and translating the strings in files
+\.{cweb.pot}, \.{cweb-tl.pot}, and \.{web2c-help.pot}, and submitting the
+resulting \.{*.po} files to the maintainers at \.{tex-k@@tug.org}.
+
+\medskip \noindent \&{Note to maintainers:} \.{CWEB} in \TeX~Live generally
+does \\{not} set |HAVE_GETTEXT| at build-time, so \.{i18n} is ``off'' by
+default. If you want to create \.{CWEB} executables with NLS support, you
+have to recompile the \TeX~Live sources with a positive value for
+|HAVE_GETTEXT| in \.{comm-w2c.h}. Also you have to ``compile'' the NLS
+catalogs provided for \.{CWEB} in the source tree with \.{msgfmt} and store the
+resulting \.{.mo} files at an appropriate place in the file system.
+
+Plans for \TeX~Live are to store NLS catalogs inside the ``\TeX\ Directory
+Structure'' (TDS) and look them up with the help of the configuration variable
+``|TEXMFLOCALEDIR|,'' which should contain a single absolute path definition.
+Below we use the \Kpathsea/ function |kpse_var_expand| to evaluate this
+variable from various origins and redirect the ``GNU~gettext utilities''
+to a possibly different location than the canonical \.{/usr/share/locale}.
+
+There are several ways to set |TEXMFLOCALEDIR|:
+\smallskip
+{\parindent5em
+\item{(a)} a user-set environment variable \.{TEXMFLOCALEDIR}\hfil\break
+ (overridden by \.{TEXMFLOCALEDIR\_cweb});
+\item{(b)} a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
+ e.g., \.{TEXMFLOCALEDIR=\$TEXMFMAIN/locale}\hfil\break
+ or \.{TEXMFLOCALEDIR.cweb=\$TEXMFMAIN/locale}.\par}
+
+@<Include files@>=
+#if HAVE_GETTEXT
+#include <locale.h> /* |@!LC_MESSAGES|, |@!LC_CTYPE| */
+#else
+#define setlocale(A,B) ""
+#define bindtextdomain(A,B) ""
+#define textdomain(A) ""
+#endif
+
+@ @<Set locale...@>=
+setlocale(LC_MESSAGES, setlocale(LC_CTYPE, ""));
+texmf_locale = kpse_var_expand ("${TEXMFLOCALEDIR}");
+
+bindtextdomain("cweb",
+ bindtextdomain("cweb-tl",
+ bindtextdomain("web2c-help", @|
+ strcmp(texmf_locale, "") ?
+ texmf_locale : "/usr/share/locale")));
+
+free(texmf_locale);
+textdomain("cweb"); /* the majority of |"strings"| come from ``plain \.{CWEB}'' */
+@.cweb.mo@>
+
+@* File lookup with \Kpathsea/. The \.{CTANGLE} and \.{CWEAVE} programs from
+the original \.{CWEB} package use the compile-time default directory or the
+value of the environment variable \.{CWEBINPUTS} as an alternative place to be
+searched for files, if they could not be found in the current directory.
+
+This version uses the \Kpathsea/ mechanism for searching files.
+The directories to be searched for come from three sources:
+\smallskip
+{\parindent5em
+\item{(a)} a user-set environment variable \.{CWEBINPUTS}
+ (overridden by \.{CWEBINPUTS\_cweb});
+\item{(b)} a line in \Kpathsea/ configuration file \.{texmf.cnf},\hfil\break
+ e.g., \.{CWEBINPUTS=\$TEXMFDOTDIR:\$TEXMF/texmf/cweb//}\hfil\break
+ or \.{CWEBINPUTS.cweb=\$TEXMFDOTDIR:\$TEXMF/texmf/cweb//};
+\item{(c)} compile-time default directories (specified in
+ \.{texmf.in}),\hfil\break
+ i.e., \.{\$TEXMFDOTDIR:\$TEXMF/texmf/cweb//}.\par}
+@.CWEBINPUTS@>
+
+@s const_string int
+@s string int
+
+@d kpse_find_cweb(name) kpse_find_file(name,kpse_cweb_format,true)
+
+@<Include files@>=
+typedef bool boolean;
+#define HAVE_BOOLEAN
+#include <kpathsea/kpathsea.h> /* include every \Kpathsea/ header;
+ |@!kpathsea_debug|, |@!const_string|, |@!string| */
+#include <w2c/config.h> /* \&{integer} */
+#include <lib/lib.h> /* |@!versionstring| */
+
+@ We set |kpse_program_name| to `\.{cweb}'. This means if the variable
+\.{CWEBINPUTS.cweb} is present in \.{texmf.cnf} (or \.{CWEBINPUTS\_cweb}
+in the environment) its value will be used as the search path for filenames.
+This allows different flavors of \.{CWEB} to have different search paths.
+@.CWEBINPUTS@>
+
+@<Set up |PROGNAME| feature and initialize the search path mechanism@>=
+kpse_set_program_name(argv[0], "cweb");
+
+@ When the files you expect are not found, the thing to do is to enable
+\Kpathsea/ runtime debugging by assigning to the |kpathsea_debug| variable a
+small number via the `\.{-d}' option. The meaning of this number is shown
+below. To set more than one debugging option, simply sum the corresponding
+numbers.
+\medskip
+\halign{\hskip5em\tt\hfil#&&\qquad\rm#\hfil\cr
+ 1&report `\.{stat}' calls\cr
+ 2&report lookups in all hash tables\cr
+ 4&report file openings and closings\cr
+ 8&report path information\cr
+16&report directory list\cr
+32&report on each file search\cr
+64&report values of variables being looked up\cr}
+\medskip
+Debugging output is always written to |stderr|, and begins with the string
+`\.{kdebug:}'.
+
+@* System dependent changes. The most volatile stuff comes at the very end.
+
+Modules for dealing with help messages and version info.
+
+@<Include files@>=
+#define CWEB
+#include "help.h" /* |@!CTANGLEHELP|, |@!CWEAVEHELP|, |@!CTWILLHELP| */
+
+@ @<Display help message and |exit|@>=
+cb_usagehelp(program==ctangle ? CTANGLEHELP :
+ program==cweave ? CWEAVEHELP : CTWILLHELP, NULL);
+@.--help@>
+
+@ Special variants from Web2c's `\.{lib/usage.c}', adapted for
+\.{i18n}/\.{t10n}. We simply filter the strings through the catalogs
+(if available).
+
+@<Predecl...@>=
+static void cb_usage (const_string str);@/
+static void cb_usagehelp (const_string *message, const_string bug_email);@/
+
+@ @c
+static void cb_usage (const_string str)
+{
+ textdomain("cweb-tl");
+@.cweb-tl.mo@>
+ fprintf(stderr, _("%s: Need one to three file arguments.\n"), str);
+ fprintf(stderr, _("Try `%s --help' for more information.\n"), str);
+@.--help@>
+ textdomain("cweb");
+@.cweb.mo@>
+ history=fatal_message; exit(wrap_up());
+}
+
+static void cb_usagehelp (const_string *message, const_string bug_email)
+{
+ if (!bug_email)
+ bug_email = "tex-k@@tug.org";
+ textdomain("web2c-help");
+@.web2c-help.mo@>
+ while (*message) {
+ printf("%s\n", strcmp("", *message) ? _(*message) : *message);
+ ++message;
+ }
+ textdomain("cweb-tl");
+@.cweb-tl.mo@>
+ printf(_("\nEmail bug reports to %s.\n"), bug_email);
+ textdomain("cweb");
+@.cweb.mo@>
+ history=spotless; exit(wrap_up());
+}
+
+@ The version information will not be translated, it uses a generic text
+template in English.
+
+@<Display version information and |exit|@>=
+printversionandexit(cb_banner,
+ program == ctwill ? "Donald E. Knuth" : "Silvio Levy and Donald E. Knuth",
+ NULL, "Contemporary development on https://github.com/ascherer/cweb.\n");
+@.--version@>
+
+@ But the ``banner'' is, at least the first part.
+
+@c
+void cb_show_banner (void)
+{
+ assert(cb_banner[0]!='\0');
+ textdomain("cweb-tl");
+@.cweb-tl.mo@>
+ printf("%s%s\n", _(cb_banner), versionstring);
+ textdomain("cweb");
+@.cweb.mo@>
+}
+
+@** Index.
+@z
diff --git a/Build/source/texk/web2c/cwebdir/comm-w2c.h b/Build/source/texk/web2c/cwebdir/comm-w2c.h
new file mode 100644
index 00000000000..6c9e605b1d0
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-w2c.h
@@ -0,0 +1,265 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 4.2 --- February 2021 (works also with later versions)
+
+% Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
+
+% 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.
+
+% Amendments to 'common.h' resulting in this updated version were created
+% by numerous collaborators over the course of many years.
+
+% Please send comments, suggestions, etc. to tex-k@@tug.org.
+
+% The next few sections contain stuff from the file |"common.w"| that has
+% to be included in both |"ctangle.w"| and |"cweave.w"|. It appears in this
+% file |"common.h"|, which is also included in |"common.w"| to propagate
+% possible changes from this single source consistently.
+
+First comes general stuff:
+
+@s boolean int
+@s uint8_t int
+@s uint16_t int
+
+
+@<Common code...@>=
+typedef bool boolean;
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+typedef enum {
+ @!ctangle, @!cweave, @!ctwill
+} cweb;
+extern cweb program; /* \.{CTANGLE} or \.{CWEAVE} or \.{CTWILL}? */
+extern int phase; /* which phase are we in? */
+
+@ You may have noticed that almost all \.{"strings"} in the \.{CWEB} sources
+are placed in the context of the `|_|'~macro. This is just a shortcut for the
+`|@!gettext|' function from the ``GNU~gettext utilities.'' For systems that do
+not have this library installed, we wrap things for neutral behavior without
+internationalization.
+
+@d _(S) gettext(S)
+
+@<Include files@>=
+#ifndef HAVE_GETTEXT
+#define HAVE_GETTEXT 0
+#endif
+@#
+#if HAVE_GETTEXT
+#include <libintl.h>
+#else
+#define gettext(A) A
+#endif
+@#
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
+
+@ Code related to the character set:
+@^ASCII code dependencies@>
+
+@d and_and 04 /* `\.{\&\&}'\,; corresponds to MIT's {\tentex\char'4} */
+@d lt_lt 020 /* `\.{<<}'\,; corresponds to MIT's {\tentex\char'20} */
+@d gt_gt 021 /* `\.{>>}'\,; corresponds to MIT's {\tentex\char'21} */
+@d plus_plus 013 /* `\.{++}'\,; corresponds to MIT's {\tentex\char'13} */
+@d minus_minus 01 /* `\.{--}'\,; corresponds to MIT's {\tentex\char'1} */
+@d minus_gt 031 /* `\.{->}'\,; corresponds to MIT's {\tentex\char'31} */
+@d non_eq 032 /* `\.{!=}'\,; corresponds to MIT's {\tentex\char'32} */
+@d lt_eq 034 /* `\.{<=}'\,; corresponds to MIT's {\tentex\char'34} */
+@d gt_eq 035 /* `\.{>=}'\,; corresponds to MIT's {\tentex\char'35} */
+@d eq_eq 036 /* `\.{==}'\,; corresponds to MIT's {\tentex\char'36} */
+@d or_or 037 /* `\.{\v\v}'\,; corresponds to MIT's {\tentex\char'37} */
+@d dot_dot_dot 016 /* `\.{...}'\,; corresponds to MIT's {\tentex\char'16} */
+@d colon_colon 06 /* `\.{::}'\,; corresponds to MIT's {\tentex\char'6} */
+@d period_ast 026 /* `\.{.*}'\,; corresponds to MIT's {\tentex\char'26} */
+@d minus_gt_ast 027 /* `\.{->*}'\,; corresponds to MIT's {\tentex\char'27} */
+
+@<Common code...@>=
+extern char section_text[]; /* text being sought for */
+extern char *section_text_end; /* end of |section_text| */
+extern char *id_first; /* where the current identifier begins in the buffer */
+extern char *id_loc; /* just after the current identifier in the buffer */
+
+@ Code related to input routines:
+@d xisalpha(c) (isalpha((eight_bits)c)&&((eight_bits)c<0200))
+@d xisdigit(c) (isdigit((eight_bits)c)&&((eight_bits)c<0200))
+@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200))
+@d xislower(c) (islower((eight_bits)c)&&((eight_bits)c<0200))
+@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200))
+@d xisxdigit(c) (isxdigit((eight_bits)c)&&((eight_bits)c<0200))
+
+@<Common code...@>=
+extern char buffer[]; /* where each line of input goes */
+extern char *buffer_end; /* end of |buffer| */
+extern char *loc; /* points to the next character to be read from the buffer */
+extern char *limit; /* points to the last character in the buffer */
+
+@ Code related to file handling:
+@f line x /* make |line| an unreserved word */
+@d max_include_depth 10 /* maximum number of source files open
+ simultaneously, not counting the change file */
+@d max_file_name_length 1024
+@d cur_file file[include_depth] /* current file */
+@d cur_file_name file_name[include_depth] /* current file name */
+@d cur_line line[include_depth] /* number of current line in current file */
+@d web_file file[0] /* main source file */
+@d web_file_name file_name[0] /* main source file name */
+
+@<Common code...@>=
+extern int include_depth; /* current level of nesting */
+extern FILE *file[]; /* stack of non-change files */
+extern FILE *change_file; /* change file */
+extern char file_name[][max_file_name_length];
+ /* stack of non-change file names */
+extern char change_file_name[]; /* name of change file */
+extern char check_file_name[]; /* name of |check_file| */
+extern int line[]; /* number of current line in the stacked files */
+extern int change_line; /* number of current line in change file */
+extern int change_depth; /* where \.{@@y} originated during a change */
+extern boolean input_has_ended; /* if there is no more input */
+extern boolean changing; /* if the current line is from |change_file| */
+extern boolean web_file_open; /* if the web file is being read */
+
+@ @<Predecl...@>=
+extern boolean get_line(void); /* inputs the next line */
+extern void check_complete(void); /* checks that all changes were picked up */
+extern void reset_input(void); /* initialize to read the web file and change file */
+
+@ Code related to section numbers:
+@<Common code...@>=
+extern sixteen_bits section_count; /* the current section number */
+extern boolean changed_section[]; /* is the section changed? */
+extern boolean change_pending; /* is a decision about change still unclear? */
+extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */
+
+@ Code related to identifier and section name storage:
+@d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */
+@d print_id(c) term_write((c)->byte_start,length((c))) /* print identifier */
+@d llink link /* left link in binary search tree for section names */
+@d rlink dummy.Rlink /* right link in binary search tree for section names */
+@d root name_dir->rlink /* the root of the binary search tree
+ for section names */
+
+@<Common code...@>=
+typedef struct name_info {
+ char *byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ void *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char byte_mem[]; /* characters of names */
+extern char *byte_mem_end; /* end of |byte_mem| */
+extern char *byte_ptr; /* first unused position in |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+
+@ @<Predecl...@>=
+extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
+extern name_pointer id_lookup(const char *,const char *,char);
+ /* looks up a string in the identifier table */
+extern name_pointer section_lookup(char *,char *,int); /* finds section name */
+extern void init_node(name_pointer);@/
+extern void init_p(name_pointer,eight_bits);@/
+extern void print_prefix_name(name_pointer);@/
+extern void print_section_name(name_pointer);@/
+extern void sprint_section_name(char *,name_pointer);
+
+@ Code related to error handling:
+@d spotless 0 /* |history| value for normal jobs */
+@d harmless_message 1 /* |history| value when non-serious info was printed */
+@d error_message 2 /* |history| value when an error was noted */
+@d fatal_message 3 /* |history| value when we had to stop prematurely */
+@d mark_harmless {if (history==spotless) history=harmless_message;}
+@d mark_error history=error_message
+@d confusion(s) fatal(_("! This can't happen: "),s)
+@.This can't happen@>
+
+@<Common code...@>=
+extern int history; /* indicates how bad this run was */
+
+@ @<Predecl...@>=
+extern int wrap_up(void); /* indicate |history| and exit */
+extern void err_print(const char *); /* print error message and context */
+extern void fatal(const char *,const char *); /* issue error message and die */
+extern void overflow(const char *); /* succumb because a table has overflowed */
+
+@ Code related to command line arguments:
+@d show_banner flags['b'] /* should the banner line be printed? */
+@d show_progress flags['p'] /* should progress reports be printed? */
+@d show_stats flags['s'] /* should statistics be printed at end of run? */
+@d show_happiness flags['h'] /* should lack of errors be announced? */
+@d temporary_output flags['t'] /* should temporary output take precedence? */
+@d make_xrefs flags['x'] /* should cross references be output? */
+
+@<Common code...@>=
+extern int argc; /* copy of |ac| parameter to |main| */
+extern char **argv; /* copy of |av| parameter to |main| */
+extern char C_file_name[]; /* name of |C_file| */
+extern char tex_file_name[]; /* name of |tex_file| */
+extern char idx_file_name[]; /* name of |idx_file| */
+extern char scn_file_name[]; /* name of |scn_file| */
+extern boolean flags[]; /* an option for each 7-bit code */
+extern const char *use_language; /* prefix to \.{cwebmac.tex} in \TEX/ output */
+
+@ Code related to output:
+@d update_terminal fflush(stdout) /* empty the terminal output buffer */
+@d new_line putchar('\n') @d putxchar putchar
+@d term_write(a,b) fflush(stdout),fwrite(a,sizeof(char),b,stdout)
+@d C_printf(c,a) fprintf(C_file,c,a)
+@d C_putc(c) putc(c,C_file) /* isn't \CEE/ wonderfully consistent? */
+
+@<Common code...@>=
+extern FILE *C_file; /* where output of \.{CTANGLE} goes */
+extern FILE *tex_file; /* where output of \.{CWEAVE} goes */
+extern FILE *idx_file; /* where index from \.{CWEAVE} goes */
+extern FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+extern FILE *active_file; /* currently active file for \.{CWEAVE} output */
+extern FILE *check_file; /* temporary output file */
+
+@ The procedure that gets everything rolling:
+@<Predecl...@>=
+extern void common_init(void);@/
+extern void print_stats(void);@/
+extern void cb_show_banner(void);
+
+@ The following parameters were sufficient in the original \.{WEB} to
+handle \TEX/, so they should be sufficient for most applications of
+\.{CWEB}.
+
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+ index entries, and section names */
+@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */
+@d max_names 10239 /* number of identifiers, strings, section names;
+ must be less than 10240 */
+@d max_sections 4000 /* greater than the total number of sections */
+@d max_texts 10239 /* number of replacement texts, must be less than 10240 */
+@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */
+@d stack_size 500 /* number of simultaneous levels of macro expansion */
+@d buf_size 1000 /* maximum length of input line, plus one */
+@d long_buf_size (buf_size+longest_name) /* for \.{CWEAVE} */
+
+@ End of \.{COMMON} interface.
diff --git a/Build/source/texk/web2c/cwebdir/comm-w32.ch b/Build/source/texk/web2c/cwebdir/comm-w32.ch
new file mode 100644
index 00000000000..d256cedf121
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/comm-w32.ch
@@ -0,0 +1,66 @@
+This is the change file for CWEB's COMMON under Win32
+(Contributed by Fabrice Popineau, February 2002 <Fabrice.Popineau@supelec.fr>)
+
+The Microsoft C compiler included in Visual Studio allows for different
+parameter passing conventions than the standard one. This is actually
+specified with the Intel IA32 architecture. There exist three
+calling conventions under the IA32 architecture as defined by Intel.
+
+One of them is the standard C calling convention: Parameters are passed on
+the stack, calling function is responsible to unstack arguments. Names are
+decorated with a prefixed underscore. It is called the __cdecl convention.
+
+Another calling convention is the __fastcall convention. The first two 32bits
+arguments are passed on the stack. The called function is responsible for
+stack maintenance. Names are decorated with an @ sign as prefix, and another
+@ sign followed by the size of the arguments as suffix.
+
+The third one is the __stdcall convention and is basically the Pascal calling
+convention.
+
+Using the __fastcall convention is usually faster on Intel architecture. Names
+are decorated because obviously a __cdecl function can't behave the same way
+as a __fastcall one of the same prototype. So the new full prototype includes
+the keyword __cdecl or __fastcall. A compiler option allows to compile all
+functions using one or the other calling convention. If you compile using
+__fastcall, then you are bound to explicitly declare a few functions as
+__cdecl : the ones that are passed to the C library (like function pointers
+for qsort() or signal()) or functions that replace functions from the C
+library, because the standard headers have a __cdecl prototype for these
+functions. Also, you cannot declare a library function without giving it the
+exact prototype used in the library headers files. So you'd better use the
+header files to be safe.
+
+Admittedly, this is not vital for cweb, except that I build the whole texlive
+set of programs using the __fastcall convention.
+
+@x
+extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
+@y
+extern boolean __cdecl names_match(name_pointer,const char *,size_t,eight_bits);@/
+@z
+
+@x
+extern void init_p(name_pointer,eight_bits);@/
+@y
+extern void __cdecl init_p(name_pointer,eight_bits);@/
+@z
+
+@x section 75
+An omitted change file argument means that |"/dev/null"| should be used,
+@y
+An omitted change file argument means that |"NUL"| should be used,
+@z
+
+@x section 76
+ strcpy(change_file_name,"/dev/null");
+@y
+ strcpy(change_file_name,"NUL");
+@z
+
+@x section 76 (this change copied from comm-bs.ch, July 94)
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+@y
+ else if (*s == ':' || *s == '\\' || *s == '/')
+ dot_pos=NULL,name_pos=++s;
+@z
diff --git a/Build/source/texk/web2c/cwebdir/common.c b/Build/source/texk/web2c/cwebdir/common.c
new file mode 100644
index 00000000000..7dd0f0c0838
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/common.c
@@ -0,0 +1,1327 @@
+/*1:*/
+#line 66 "common.w"
+
+/*3:*/
+#line 46 "common.h"
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*:3*/
+#line 67 "common.w"
+
+#define ctangle false
+#define cweave true \
+
+#define and_and 04
+#define lt_lt 020
+#define gt_gt 021
+#define plus_plus 013
+#define minus_minus 01
+#define minus_gt 031
+#define non_eq 032
+#define lt_eq 034
+#define gt_eq 035
+#define eq_eq 036
+#define or_or 037
+#define dot_dot_dot 016
+#define colon_colon 06
+#define period_ast 026
+#define minus_gt_ast 027 \
+
+#define xisalpha(c) (isalpha((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisdigit(c) (isdigit((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisspace(c) (isspace((eight_bits) c) &&((eight_bits) c<0200) )
+#define xislower(c) (islower((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisxdigit(c) (isxdigit((eight_bits) c) &&((eight_bits) c<0200) ) \
+
+#define max_include_depth 10 \
+
+#define max_file_name_length 1024
+#define cur_file file[include_depth]
+#define cur_file_name file_name[include_depth]
+#define cur_line line[include_depth]
+#define web_file file[0]
+#define web_file_name file_name[0] \
+
+#define length(c) (size_t) ((c+1) ->byte_start-(c) ->byte_start)
+#define print_id(c) term_write((c) ->byte_start,length((c) ) )
+#define llink link
+#define rlink dummy.Rlink
+#define root name_dir->rlink \
+ \
+
+#define spotless 0
+#define harmless_message 1
+#define error_message 2
+#define fatal_message 3
+#define mark_harmless {if(history==spotless) history= harmless_message;}
+#define mark_error history= error_message
+#define confusion(s) fatal("! This can't happen: ",s) \
+ \
+
+#define show_banner flags['b']
+#define show_progress flags['p']
+#define show_stats flags['s']
+#define show_happiness flags['h']
+#define make_xrefs flags['x'] \
+
+#define update_terminal fflush(stdout)
+#define new_line putchar('\n')
+#define putxchar putchar
+#define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout)
+#define C_printf(c,a) fprintf(C_file,c,a)
+#define C_putc(c) putc(c,C_file) \
+
+#define max_bytes 1000000 \
+
+#define max_toks 1000000
+#define max_names 10239 \
+
+#define max_sections 4000
+#define max_texts 10239
+#define longest_name 10000
+#define stack_size 500
+#define buf_size 1000
+#define long_buf_size (buf_size+longest_name) \
+
+#define lines_dont_match (change_limit-change_buffer!=limit-buffer|| \
+strncmp(buffer,change_buffer,(size_t) (limit-buffer) ) ) \
+
+#define if_section_start_make_pending(b) {*limit= '!'; \
+for(loc= buffer;xisspace(*loc) ;loc++) ; \
+*limit= ' '; \
+if(*loc=='@'&&(xisspace(*(loc+1) ) ||*(loc+1) =='*') ) change_pending= b; \
+} \
+
+#define too_long() {include_depth--; \
+err_print("! Include file name too long") ;goto restart;} \
+
+#define hash_size 8501 \
+
+#define first_chunk(p) ((p) ->byte_start+2)
+#define prefix_length(p) (int) ((eight_bits) *((p) ->byte_start) *256+ \
+(eight_bits) *((p) ->byte_start+1) )
+#define set_prefix_length(p,m) (*((p) ->byte_start) = (m) /256, \
+*((p) ->byte_start+1) = (m) %256) \
+
+#define less 0
+#define equal 1
+#define greater 2
+#define prefix 3
+#define extension 4 \
+
+#define bad_extension 5 \
+
+#define flag_change (**argv!='-')
+
+#line 68 "common.w"
+
+/*2:*/
+#line 37 "common.h"
+
+typedef bool boolean;
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+extern boolean program;
+extern int phase;
+
+/*:2*//*4:*/
+#line 74 "common.h"
+
+extern char section_text[];
+extern char*section_text_end;
+extern char*id_first;
+extern char*id_loc;
+
+/*:4*//*5:*/
+#line 88 "common.h"
+
+extern char buffer[];
+extern char*buffer_end;
+extern char*loc;
+extern char*limit;
+
+/*:5*//*6:*/
+#line 105 "common.h"
+
+extern int include_depth;
+extern FILE*file[];
+extern FILE*change_file;
+extern char file_name[][max_file_name_length];
+
+extern char change_file_name[];
+extern int line[];
+extern int change_line;
+extern int change_depth;
+extern boolean input_has_ended;
+extern boolean changing;
+extern boolean web_file_open;
+
+/*:6*//*8:*/
+#line 125 "common.h"
+
+extern sixteen_bits section_count;
+extern boolean changed_section[];
+extern boolean change_pending;
+extern boolean print_where;
+
+/*:8*//*9:*/
+#line 139 "common.h"
+
+typedef struct name_info{
+char*byte_start;
+struct name_info*link;
+union{
+struct name_info*Rlink;
+
+char Ilk;
+}dummy;
+void*equiv_or_xref;
+}name_info;
+typedef name_info*name_pointer;
+typedef name_pointer*hash_pointer;
+extern char byte_mem[];
+extern char*byte_mem_end;
+extern char*byte_ptr;
+extern name_info name_dir[];
+extern name_pointer name_dir_end;
+extern name_pointer name_ptr;
+extern name_pointer hash[];
+extern hash_pointer hash_end;
+extern hash_pointer h;
+
+/*:9*//*11:*/
+#line 183 "common.h"
+
+extern int history;
+
+/*:11*//*13:*/
+#line 199 "common.h"
+
+extern int argc;
+extern char**argv;
+extern char C_file_name[];
+extern char tex_file_name[];
+extern char idx_file_name[];
+extern char scn_file_name[];
+extern boolean flags[];
+
+/*:13*//*14:*/
+#line 215 "common.h"
+
+extern FILE*C_file;
+extern FILE*tex_file;
+extern FILE*idx_file;
+extern FILE*scn_file;
+extern FILE*active_file;
+
+/*:14*/
+#line 69 "common.w"
+
+/*18:*/
+#line 83 "common.w"
+
+boolean program;
+
+/*:18*//*19:*/
+#line 92 "common.w"
+
+int phase;
+
+/*:19*//*21:*/
+#line 130 "common.w"
+
+char section_text[longest_name+1];
+char*section_text_end= section_text+longest_name;
+char*id_first;
+char*id_loc;
+
+/*:21*//*22:*/
+#line 150 "common.w"
+
+char buffer[long_buf_size];
+char*buffer_end= buffer+buf_size-2;
+char*loc= buffer;
+char*limit= buffer;
+
+/*:22*//*25:*/
+#line 194 "common.w"
+
+int include_depth;
+FILE*file[max_include_depth];
+FILE*change_file;
+char file_name[max_include_depth][max_file_name_length];
+
+char change_file_name[max_file_name_length];
+static char alt_web_file_name[max_file_name_length];
+int line[max_include_depth];
+int change_line;
+int change_depth;
+boolean input_has_ended;
+boolean changing;
+boolean web_file_open= false;
+
+/*:25*//*26:*/
+#line 220 "common.w"
+
+static char change_buffer[buf_size];
+static char*change_limit;
+
+/*:26*//*37:*/
+#line 399 "common.w"
+
+sixteen_bits section_count;
+boolean changed_section[max_sections];
+boolean change_pending;
+
+boolean print_where= false;
+
+/*:37*//*43:*/
+#line 596 "common.w"
+
+char byte_mem[max_bytes];
+char*byte_mem_end= byte_mem+max_bytes-1;
+name_info name_dir[max_names];
+name_pointer name_dir_end= name_dir+max_names-1;
+
+/*:43*//*44:*/
+#line 607 "common.w"
+
+char*byte_ptr;
+name_pointer name_ptr;
+
+/*:44*//*46:*/
+#line 627 "common.w"
+
+name_pointer hash[hash_size];
+hash_pointer hash_end= hash+hash_size-1;
+hash_pointer h;
+
+/*:46*//*65:*/
+#line 1014 "common.w"
+
+int history= spotless;
+
+/*:65*//*73:*/
+#line 1135 "common.w"
+
+int argc;
+char**argv;
+char C_file_name[max_file_name_length];
+char tex_file_name[max_file_name_length];
+char idx_file_name[max_file_name_length];
+char scn_file_name[max_file_name_length];
+boolean flags[128];
+
+/*:73*//*83:*/
+#line 1282 "common.w"
+
+FILE*C_file;
+FILE*tex_file;
+FILE*idx_file;
+FILE*scn_file;
+FILE*active_file;
+
+/*:83*/
+#line 70 "common.w"
+
+/*7:*/
+#line 119 "common.h"
+
+extern boolean get_line(void);
+extern void check_complete(void);
+extern void reset_input(void);
+
+/*:7*//*10:*/
+#line 162 "common.h"
+
+extern boolean names_match(name_pointer,const char*,size_t,eight_bits);
+extern name_pointer id_lookup(const char*,const char*,char);
+
+extern name_pointer section_lookup(char*,char*,int);
+extern void init_node(name_pointer);
+extern void init_p(name_pointer,eight_bits);
+extern void print_prefix_name(name_pointer);
+extern void print_section_name(name_pointer);
+extern void sprint_section_name(char*,name_pointer);
+
+/*:10*//*12:*/
+#line 186 "common.h"
+
+extern int wrap_up(void);
+extern void err_print(const char*);
+extern void fatal(const char*,const char*);
+extern void overflow(const char*);
+
+/*:12*//*15:*/
+#line 223 "common.h"
+
+extern void common_init(void);
+extern void print_stats(void);
+
+/*:15*//*24:*/
+#line 180 "common.w"
+static boolean input_ln(FILE*);
+
+/*:24*//*28:*/
+#line 241 "common.w"
+static void prime_the_change_buffer(void);
+
+/*:28*//*33:*/
+#line 340 "common.w"
+static void check_change(void);
+
+/*:33*//*55:*/
+#line 774 "common.w"
+
+static int web_strcmp(char*,int,char*,int);
+static name_pointer add_section_name(name_pointer,int,char*,char*,int);
+static void extend_section_name(name_pointer,char*,char*,int);
+
+/*:55*//*64:*/
+#line 1002 "common.w"
+static int section_name_cmp(char**,int,name_pointer);
+
+/*:64*//*76:*/
+#line 1197 "common.w"
+static void scan_args(void);
+
+/*:76*/
+#line 71 "common.w"
+
+
+/*:1*//*20:*/
+#line 99 "common.w"
+
+void
+common_init(void)
+{
+/*45:*/
+#line 611 "common.w"
+
+name_dir->byte_start= byte_ptr= byte_mem;
+name_ptr= name_dir+1;
+name_ptr->byte_start= byte_mem;
+root= NULL;
+
+/*:45*//*47:*/
+#line 634 "common.w"
+
+for(h= hash;h<=hash_end;*h++= NULL);
+
+/*:47*/
+#line 103 "common.w"
+
+/*74:*/
+#line 1148 "common.w"
+
+show_banner= show_happiness= show_progress= make_xrefs= true;
+show_stats= false;
+
+/*:74*/
+#line 104 "common.w"
+
+/*84:*/
+#line 1289 "common.w"
+
+scan_args();
+if(program==ctangle){
+if((C_file= fopen(C_file_name,"wb"))==NULL)
+fatal("! Cannot open output file ",C_file_name);
+
+}
+else{
+if((tex_file= fopen(tex_file_name,"wb"))==NULL)
+fatal("! Cannot open output file ",tex_file_name);
+}
+
+/*:84*/
+#line 105 "common.w"
+
+}
+
+/*:20*//*23:*/
+#line 160 "common.w"
+
+static boolean input_ln(
+FILE*fp)
+{
+register int c= EOF;
+register char*k;
+if(feof(fp))return false;
+limit= k= buffer;
+while(k<=buffer_end&&(c= getc(fp))!=EOF&&c!='\n')
+if((*(k++)= c)!=' ')limit= k;
+if(k> buffer_end)
+if((c= getc(fp))!=EOF&&c!='\n'){
+ungetc(c,fp);loc= buffer;err_print("! Input line too long");
+
+}
+if(c==EOF&&limit==buffer)return false;
+
+return true;
+}
+
+/*:23*//*27:*/
+#line 231 "common.w"
+
+static void
+prime_the_change_buffer(void)
+{
+change_limit= change_buffer;
+/*29:*/
+#line 247 "common.w"
+
+while(true){
+change_line++;
+if(!input_ln(change_file))return;
+if(limit<buffer+2)continue;
+if(buffer[0]!='@')continue;
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
+if(buffer[1]=='x')break;
+if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
+loc= buffer+2;
+err_print("! Missing @x in change file");
+
+}
+}
+
+/*:29*/
+#line 236 "common.w"
+
+/*30:*/
+#line 264 "common.w"
+
+do{
+change_line++;
+if(!input_ln(change_file)){
+err_print("! Change file ended after @x");
+
+return;
+}
+}while(limit==buffer);
+
+/*:30*/
+#line 237 "common.w"
+
+/*31:*/
+#line 274 "common.w"
+
+{
+change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
+strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+}
+
+/*:31*/
+#line 238 "common.w"
+
+}
+
+/*:27*//*32:*/
+#line 302 "common.w"
+
+static void
+check_change(void)
+{
+int n= 0;
+if(lines_dont_match)return;
+change_pending= false;
+if(!changed_section[section_count]){
+if_section_start_make_pending(true);
+if(!change_pending)changed_section[section_count]= true;
+}
+while(true){
+changing= true;print_where= true;change_line++;
+if(!input_ln(change_file)){
+err_print("! Change file ended before @y");
+
+change_limit= change_buffer;changing= false;
+return;
+}
+if(limit> buffer+1&&buffer[0]=='@'){
+char xyz_code= xisupper(buffer[1])?tolower((eight_bits)buffer[1]):buffer[1];
+/*34:*/
+#line 342 "common.w"
+
+if(xyz_code=='x'||xyz_code=='z'){
+loc= buffer+2;err_print("! Where is the matching @y?");
+
+}
+else if(xyz_code=='y'){
+if(n> 0){
+loc= buffer+2;
+printf("\n! Hmm... %d ",n);
+err_print("of the preceding lines failed to match");
+
+}
+change_depth= include_depth;
+return;
+}
+
+/*:34*/
+#line 324 "common.w"
+
+}
+/*31:*/
+#line 274 "common.w"
+
+{
+change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
+strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+}
+
+/*:31*/
+#line 326 "common.w"
+
+changing= false;cur_line++;
+while(!input_ln(cur_file)){
+if(include_depth==0){
+err_print("! CWEB file ended during a change");
+
+input_has_ended= true;return;
+}
+include_depth--;cur_line++;
+}
+if(lines_dont_match)n++;
+}
+}
+
+/*:32*//*35:*/
+#line 362 "common.w"
+
+void
+reset_input(void)
+{
+limit= buffer;loc= buffer+1;buffer[0]= ' ';
+/*36:*/
+#line 377 "common.w"
+
+if((web_file= fopen(web_file_name,"r"))==NULL){
+strcpy(web_file_name,alt_web_file_name);
+if((web_file= fopen(web_file_name,"r"))==NULL)
+fatal("! Cannot open input file ",web_file_name);
+}
+
+
+web_file_open= true;
+if((change_file= fopen(change_file_name,"r"))==NULL)
+fatal("! Cannot open change file ",change_file_name);
+
+/*:36*/
+#line 367 "common.w"
+
+include_depth= 0;cur_line= 0;change_line= 0;
+change_depth= include_depth;
+changing= 1;prime_the_change_buffer();changing= !changing;
+limit= buffer;loc= buffer+1;buffer[0]= ' ';input_has_ended= false;
+}
+
+/*:35*//*38:*/
+#line 406 "common.w"
+
+boolean get_line(void)
+{
+restart:
+if(changing&&include_depth==change_depth)
+/*41:*/
+#line 514 "common.w"
+{
+change_line++;
+if(!input_ln(change_file)){
+err_print("! Change file ended without @z");
+
+buffer[0]= '@';buffer[1]= 'z';limit= buffer+2;
+}
+if(limit> buffer){
+if(change_pending){
+if_section_start_make_pending(false);
+if(change_pending){
+changed_section[section_count]= true;change_pending= false;
+}
+}
+*limit= ' ';
+if(buffer[0]=='@'){
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
+if(buffer[1]=='x'||buffer[1]=='y'){
+loc= buffer+2;
+err_print("! Where is the matching @z?");
+
+}
+else if(buffer[1]=='z'){
+prime_the_change_buffer();changing= !changing;print_where= true;
+}
+}
+}
+}
+
+/*:41*/
+#line 411 "common.w"
+
+if(!changing||include_depth> change_depth){
+/*40:*/
+#line 497 "common.w"
+{
+cur_line++;
+while(!input_ln(cur_file)){
+print_where= true;
+if(include_depth==0){input_has_ended= true;break;}
+else{
+fclose(cur_file);include_depth--;
+if(changing&&include_depth==change_depth)break;
+cur_line++;
+}
+}
+if(!changing&&!input_has_ended)
+if(limit-buffer==change_limit-change_buffer)
+if(buffer[0]==change_buffer[0])
+if(change_limit> change_buffer)check_change();
+}
+
+/*:40*/
+#line 413 "common.w"
+
+if(changing&&include_depth==change_depth)goto restart;
+}
+if(input_has_ended)return false;
+loc= buffer;*limit= ' ';
+if(buffer[0]=='@'&&(buffer[1]=='i'||buffer[1]=='I')){
+loc= buffer+2;*limit= '"';
+while(*loc==' '||*loc=='\t')loc++;
+if(loc>=limit){
+err_print("! Include file name not given");
+
+goto restart;
+}
+if(include_depth>=max_include_depth-1){
+err_print("! Too many nested includes");
+
+goto restart;
+}
+include_depth++;
+/*39:*/
+#line 451 "common.w"
+{
+char temp_file_name[max_file_name_length];
+char*cur_file_name_end= cur_file_name+max_file_name_length-1;
+char*k= cur_file_name,*kk;
+int l;
+
+if(*loc=='"'){
+loc++;
+while(*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
+if(loc==limit)k= cur_file_name_end+1;
+}else
+while(*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end)*k++= *loc++;
+if(k> cur_file_name_end)too_long();
+
+*k= '\0';
+if((cur_file= fopen(cur_file_name,"r"))!=NULL){
+cur_line= 0;print_where= true;
+goto restart;
+}
+kk= getenv("CWEBINPUTS");
+if(kk!=NULL){
+if((l= strlen(kk))> max_file_name_length-2)too_long();
+strcpy(temp_file_name,kk);
+}
+else{
+#ifdef CWEBINPUTS
+if((l= strlen(CWEBINPUTS))> max_file_name_length-2)too_long();
+strcpy(temp_file_name,CWEBINPUTS);
+#else
+l= 0;
+#endif
+}
+if(l> 0){
+if(k+l+2>=cur_file_name_end)too_long();
+
+for(;k>=cur_file_name;k--)*(k+l+1)= *k;
+strcpy(cur_file_name,temp_file_name);
+cur_file_name[l]= '/';
+if((cur_file= fopen(cur_file_name,"r"))!=NULL){
+cur_line= 0;print_where= true;
+goto restart;
+}
+}
+include_depth--;err_print("! Cannot open include file");goto restart;
+}
+
+/*:39*/
+#line 432 "common.w"
+
+}
+return true;
+}
+
+/*:38*//*42:*/
+#line 546 "common.w"
+
+void
+check_complete(void){
+if(change_limit!=change_buffer){
+strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1));
+limit= buffer+(ptrdiff_t)(change_limit-change_buffer);
+changing= true;change_depth= include_depth;loc= buffer;
+err_print("! Change file entry did not match");
+
+}
+}
+
+/*:42*//*48:*/
+#line 639 "common.w"
+
+name_pointer
+id_lookup(
+const char*first,
+const char*last,
+char t)
+{
+const char*i= first;
+int h;
+int l;
+name_pointer p;
+if(last==NULL)for(last= first;*last!='\0';last++);
+l= (int)(last-first);
+/*49:*/
+#line 662 "common.w"
+
+h= (eight_bits)*i;
+while(++i<last)h= (h+h+(int)((eight_bits)*i))%hash_size;
+
+
+/*:49*/
+#line 652 "common.w"
+
+/*50:*/
+#line 670 "common.w"
+
+p= hash[h];
+while(p&&!names_match(p,first,l,t))p= p->link;
+if(p==NULL){
+p= name_ptr;
+p->link= hash[h];hash[h]= p;
+}
+
+/*:50*/
+#line 653 "common.w"
+
+if(p==name_ptr)/*51:*/
+#line 681 "common.w"
+{
+if(byte_ptr+l> byte_mem_end)overflow("byte memory");
+if(name_ptr>=name_dir_end)overflow("name");
+strncpy(byte_ptr,first,l);
+(++name_ptr)->byte_start= byte_ptr+= l;
+init_p(p,t);
+}
+
+/*:51*/
+#line 654 "common.w"
+
+return p;
+}
+
+/*:48*//*52:*/
+#line 713 "common.w"
+
+void
+print_section_name(
+name_pointer p)
+{
+char*ss,*s= first_chunk(p);
+name_pointer q= p+1;
+while(p!=name_dir){
+ss= (p+1)->byte_start-1;
+if(*ss==' '&&ss>=s){
+term_write(s,(size_t)(ss-s));p= q->link;q= p;
+}else{
+term_write(s,(size_t)(ss+1-s));p= name_dir;q= NULL;
+}
+s= p->byte_start;
+}
+if(q)term_write("...",3);
+}
+
+/*:52*//*53:*/
+#line 732 "common.w"
+
+void
+sprint_section_name(
+char*dest,
+name_pointer p)
+{
+char*ss,*s= first_chunk(p);
+name_pointer q= p+1;
+while(p!=name_dir){
+ss= (p+1)->byte_start-1;
+if(*ss==' '&&ss>=s){
+p= q->link;q= p;
+}else{
+ss++;p= name_dir;
+}
+strncpy(dest,s,(size_t)(ss-s)),dest+= ss-s;
+s= p->byte_start;
+}
+*dest= '\0';
+}
+
+/*:53*//*54:*/
+#line 753 "common.w"
+
+void
+print_prefix_name(
+name_pointer p)
+{
+char*s= first_chunk(p);
+int l= prefix_length(p);
+term_write(s,l);
+if(s+l<(p+1)->byte_start)term_write("...",3);
+}
+
+/*:54*//*56:*/
+#line 779 "common.w"
+
+static int web_strcmp(
+char*j,
+int j_len,
+char*k,
+int k_len)
+{
+char*j1= j+j_len,*k1= k+k_len;
+while(k<k1&&j<j1&&*j==*k)k++,j++;
+if(k==k1)if(j==j1)return equal;
+else return extension;
+else if(j==j1)return prefix;
+else if(*j<*k)return less;
+else return greater;
+}
+
+/*:56*//*57:*/
+#line 808 "common.w"
+
+static name_pointer
+add_section_name(
+name_pointer par,
+int c,
+char*first,
+char*last,
+int ispref)
+{
+name_pointer p= name_ptr;
+char*s= first_chunk(p);
+int name_len= (int)(last-first)+ispref;
+if(s+name_len> byte_mem_end)overflow("byte memory");
+if(name_ptr+1>=name_dir_end)overflow("name");
+(++name_ptr)->byte_start= byte_ptr= s+name_len;
+if(ispref){
+*(byte_ptr-1)= ' ';
+name_len--;
+name_ptr->link= name_dir;
+(++name_ptr)->byte_start= byte_ptr;
+}
+set_prefix_length(p,name_len);
+strncpy(s,first,name_len);
+p->llink= NULL;
+p->rlink= NULL;
+init_node(p);
+return par==NULL?(root= p):c==less?(par->llink= p):(par->rlink= p);
+}
+
+/*:57*//*58:*/
+#line 837 "common.w"
+
+static void
+extend_section_name(
+name_pointer p,
+char*first,
+char*last,
+int ispref)
+{
+char*s;
+name_pointer q= p+1;
+int name_len= (int)(last-first)+ispref;
+if(name_ptr>=name_dir_end)overflow("name");
+while(q->link!=name_dir)q= q->link;
+q->link= name_ptr;
+s= name_ptr->byte_start;
+name_ptr->link= name_dir;
+if(s+name_len> byte_mem_end)overflow("byte memory");
+(++name_ptr)->byte_start= byte_ptr= s+name_len;
+strncpy(s,first,name_len);
+if(ispref)*(byte_ptr-1)= ' ';
+}
+
+/*:58*//*59:*/
+#line 865 "common.w"
+
+name_pointer
+section_lookup(
+char*first,char*last,
+int ispref)
+{
+int c= 0;
+name_pointer p= root;
+name_pointer q= NULL;
+name_pointer r= NULL;
+name_pointer par= NULL;
+
+int name_len= (int)(last-first)+1;
+/*60:*/
+#line 889 "common.w"
+
+while(p){
+c= web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
+if(c==less||c==greater){
+if(r==NULL)
+par= p;
+p= (c==less?p->llink:p->rlink);
+}else{
+if(r!=NULL){
+fputs("\n! Ambiguous prefix: matches <",stdout);
+
+print_prefix_name(p);
+fputs(">\n and <",stdout);
+print_prefix_name(r);
+err_print(">");
+return name_dir;
+}
+r= p;
+p= p->llink;
+q= r->rlink;
+}
+if(p==NULL)
+p= q,q= NULL;
+}
+
+/*:60*/
+#line 879 "common.w"
+
+/*61:*/
+#line 914 "common.w"
+
+if(r==NULL)
+return add_section_name(par,c,first,last+1,ispref);
+
+/*:61*/
+#line 880 "common.w"
+
+/*62:*/
+#line 922 "common.w"
+
+switch(section_name_cmp(&first,name_len,r)){
+
+case prefix:
+if(!ispref){
+fputs("\n! New name is a prefix of <",stdout);
+
+print_section_name(r);
+err_print(">");
+}
+else if(name_len<prefix_length(r))set_prefix_length(r,name_len);
+
+case equal:return r;
+case extension:if(!ispref||first<=last)
+extend_section_name(r,first,last+1,ispref);
+return r;
+case bad_extension:
+fputs("\n! New name extends <",stdout);
+
+print_section_name(r);
+err_print(">");
+return r;
+default:
+fputs("\n! Section name incompatible with <",stdout);
+
+print_prefix_name(r);
+fputs(">,\n which abbreviates <",stdout);
+print_section_name(r);
+err_print(">");
+return r;
+}
+
+/*:62*/
+#line 881 "common.w"
+
+}
+
+/*:59*//*63:*/
+#line 970 "common.w"
+
+static int section_name_cmp(
+char**pfirst,
+int len,
+name_pointer r)
+{
+char*first= *pfirst;
+name_pointer q= r+1;
+char*ss,*s= first_chunk(r);
+int c;
+int ispref;
+while(true){
+ss= (r+1)->byte_start-1;
+if(*ss==' '&&ss>=r->byte_start)ispref= 1,q= q->link;
+else ispref= 0,ss++,q= name_dir;
+switch(c= web_strcmp(first,len,s,ss-s)){
+case equal:if(q==name_dir)
+if(ispref){
+*pfirst= first+(ptrdiff_t)(ss-s);
+return extension;
+}else return equal;
+else return(q->byte_start==(q+1)->byte_start)?equal:prefix;
+case extension:
+if(!ispref)return bad_extension;
+first+= ss-s;
+if(q!=name_dir){len-= (int)(ss-s);s= q->byte_start;r= q;continue;}
+*pfirst= first;return extension;
+default:return c;
+}
+}
+}
+
+/*:63*//*66:*/
+#line 1024 "common.w"
+
+void
+err_print(
+const char*s)
+{
+char*k,*l;
+printf(*s=='!'?"\n%s":"%s",s);
+if(web_file_open)/*67:*/
+#line 1044 "common.w"
+
+{if(changing&&include_depth==change_depth)
+printf(". (l. %d of change file)\n",change_line);
+else if(include_depth==0)printf(". (l. %d)\n",cur_line);
+else printf(". (l. %d of include file %s)\n",cur_line,cur_file_name);
+l= (loc>=limit?limit:loc);
+if(l> buffer){
+for(k= buffer;k<l;k++)
+if(*k=='\t')putchar(' ');
+else putchar(*k);
+putchar('\n');
+for(k= buffer;k<l;k++)putchar(' ');
+}
+for(k= l;k<limit;k++)putchar(*k);
+if(*limit=='|')putchar('|');
+putchar(' ');
+}
+
+/*:67*/
+#line 1031 "common.w"
+
+update_terminal;mark_error;
+}
+
+/*:66*//*68:*/
+#line 1076 "common.w"
+
+int wrap_up(void){
+if(show_progress)new_line;
+if(show_stats)
+print_stats();
+/*69:*/
+#line 1086 "common.w"
+
+switch(history){
+case spotless:if(show_happiness)puts("(No errors were found.)");break;
+case harmless_message:
+puts("(Did you see the warning message above?)");break;
+case error_message:
+puts("(Pardon me, but I think I spotted something wrong.)");break;
+case fatal_message:puts("(That was a fatal error, my friend.)");
+}
+
+/*:69*/
+#line 1081 "common.w"
+
+if(history> harmless_message)return EXIT_FAILURE;
+else return EXIT_SUCCESS;
+}
+
+/*:68*//*70:*/
+#line 1102 "common.w"
+void
+fatal(
+const char*s,const char*t)
+{
+if(*s)err_print(s);
+err_print(t);
+history= fatal_message;exit(wrap_up());
+}
+
+/*:70*//*71:*/
+#line 1113 "common.w"
+void
+overflow(
+const char*t)
+{
+printf("\n! Sorry, %s capacity exceeded",t);fatal("","");
+}
+
+
+/*:71*//*75:*/
+#line 1167 "common.w"
+
+static void
+scan_args(void)
+{
+char*dot_pos;
+char*name_pos;
+register char*s;
+boolean found_web= false,found_change= false,found_out= false;
+
+
+strcpy(change_file_name,"/dev/null");
+while(--argc> 0){
+if((**(++argv)=='-'||**argv=='+')&&*(*argv+1))/*80:*/
+#line 1258 "common.w"
+
+{
+for(dot_pos= *argv+1;*dot_pos> '\0';dot_pos++)
+flags[(eight_bits)*dot_pos]= flag_change;
+}
+
+/*:80*/
+#line 1179 "common.w"
+
+else{
+s= name_pos= *argv;dot_pos= NULL;
+while(*s){
+if(*s=='.')dot_pos= s++;
+else if(*s=='/')dot_pos= NULL,name_pos= ++s;
+else s++;
+}
+if(!found_web)/*77:*/
+#line 1206 "common.w"
+
+{
+if(s-*argv> max_file_name_length-5)
+/*82:*/
+#line 1276 "common.w"
+fatal("! Filename too long\n",*argv);
+
+
+/*:82*/
+#line 1209 "common.w"
+
+if(dot_pos==NULL)
+sprintf(web_file_name,"%s.w",*argv);
+else{
+strcpy(web_file_name,*argv);
+*dot_pos= 0;
+}
+sprintf(alt_web_file_name,"%s.web",*argv);
+sprintf(tex_file_name,"%s.tex",name_pos);
+sprintf(idx_file_name,"%s.idx",name_pos);
+sprintf(scn_file_name,"%s.scn",name_pos);
+sprintf(C_file_name,"%s.c",name_pos);
+found_web= true;
+}
+
+/*:77*/
+#line 1188 "common.w"
+
+else if(!found_change)/*78:*/
+#line 1224 "common.w"
+
+{
+if(strcmp(*argv,"-")!=0){
+if(s-*argv> max_file_name_length-4)
+/*82:*/
+#line 1276 "common.w"
+fatal("! Filename too long\n",*argv);
+
+
+/*:82*/
+#line 1228 "common.w"
+
+if(dot_pos==NULL)
+sprintf(change_file_name,"%s.ch",*argv);
+else strcpy(change_file_name,*argv);
+}
+found_change= true;
+}
+
+/*:78*/
+#line 1189 "common.w"
+
+else if(!found_out)/*79:*/
+#line 1236 "common.w"
+
+{
+if(s-*argv> max_file_name_length-5)
+/*82:*/
+#line 1276 "common.w"
+fatal("! Filename too long\n",*argv);
+
+
+/*:82*/
+#line 1239 "common.w"
+
+if(dot_pos==NULL){
+sprintf(tex_file_name,"%s.tex",*argv);
+sprintf(idx_file_name,"%s.idx",*argv);
+sprintf(scn_file_name,"%s.scn",*argv);
+sprintf(C_file_name,"%s.c",*argv);
+}else{
+strcpy(tex_file_name,*argv);
+strcpy(C_file_name,*argv);
+if(make_xrefs){
+*dot_pos= 0;
+sprintf(idx_file_name,"%s.idx",*argv);
+sprintf(scn_file_name,"%s.scn",*argv);
+}
+}
+found_out= true;
+}
+
+/*:79*/
+#line 1190 "common.w"
+
+else/*81:*/
+#line 1264 "common.w"
+
+{
+if(program==ctangle)
+fatal(
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+,"");
+
+else fatal(
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+,"");
+}
+
+/*:81*/
+#line 1191 "common.w"
+
+}
+}
+if(!found_web)/*81:*/
+#line 1264 "common.w"
+
+{
+if(program==ctangle)
+fatal(
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+,"");
+
+else fatal(
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+,"");
+}
+
+/*:81*/
+#line 1194 "common.w"
+
+}
+
+/*:75*/
diff --git a/Build/source/texk/web2c/cwebdir/common.h b/Build/source/texk/web2c/cwebdir/common.h
new file mode 100644
index 00000000000..425239f1c75
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/common.h
@@ -0,0 +1,243 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 4.2 --- February 2021 (works also with later versions)
+
+% Copyright (C) 1987,1990,1993 Silvio Levy and Donald E. Knuth
+
+% 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.
+
+% Amendments to 'common.h' resulting in this updated version were created
+% by numerous collaborators over the course of many years.
+
+% Please send comments, suggestions, etc. to tex-k@@tug.org.
+
+% The next few sections contain stuff from the file |"common.w"| that has
+% to be included in both |"ctangle.w"| and |"cweave.w"|. It appears in this
+% file |"common.h"|, which is also included in |"common.w"| to propagate
+% possible changes from this single source consistently.
+
+First comes general stuff:
+
+@s boolean int
+@s uint8_t int
+@s uint16_t int
+
+@d ctangle false
+@d cweave true
+
+@<Common code...@>=
+typedef bool boolean;
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+extern boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */
+extern int phase; /* which phase are we in? */
+
+@ Interface to the standard \CEE/ library:
+
+@<Include files@>=
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
+
+@ Code related to the character set:
+@^ASCII code dependencies@>
+
+@d and_and 04 /* `\.{\&\&}'\,; corresponds to MIT's {\tentex\char'4} */
+@d lt_lt 020 /* `\.{<<}'\,; corresponds to MIT's {\tentex\char'20} */
+@d gt_gt 021 /* `\.{>>}'\,; corresponds to MIT's {\tentex\char'21} */
+@d plus_plus 013 /* `\.{++}'\,; corresponds to MIT's {\tentex\char'13} */
+@d minus_minus 01 /* `\.{--}'\,; corresponds to MIT's {\tentex\char'1} */
+@d minus_gt 031 /* `\.{->}'\,; corresponds to MIT's {\tentex\char'31} */
+@d non_eq 032 /* `\.{!=}'\,; corresponds to MIT's {\tentex\char'32} */
+@d lt_eq 034 /* `\.{<=}'\,; corresponds to MIT's {\tentex\char'34} */
+@d gt_eq 035 /* `\.{>=}'\,; corresponds to MIT's {\tentex\char'35} */
+@d eq_eq 036 /* `\.{==}'\,; corresponds to MIT's {\tentex\char'36} */
+@d or_or 037 /* `\.{\v\v}'\,; corresponds to MIT's {\tentex\char'37} */
+@d dot_dot_dot 016 /* `\.{...}'\,; corresponds to MIT's {\tentex\char'16} */
+@d colon_colon 06 /* `\.{::}'\,; corresponds to MIT's {\tentex\char'6} */
+@d period_ast 026 /* `\.{.*}'\,; corresponds to MIT's {\tentex\char'26} */
+@d minus_gt_ast 027 /* `\.{->*}'\,; corresponds to MIT's {\tentex\char'27} */
+
+@<Common code...@>=
+extern char section_text[]; /* text being sought for */
+extern char *section_text_end; /* end of |section_text| */
+extern char *id_first; /* where the current identifier begins in the buffer */
+extern char *id_loc; /* just after the current identifier in the buffer */
+
+@ Code related to input routines:
+@d xisalpha(c) (isalpha((eight_bits)c)&&((eight_bits)c<0200))
+@d xisdigit(c) (isdigit((eight_bits)c)&&((eight_bits)c<0200))
+@d xisspace(c) (isspace((eight_bits)c)&&((eight_bits)c<0200))
+@d xislower(c) (islower((eight_bits)c)&&((eight_bits)c<0200))
+@d xisupper(c) (isupper((eight_bits)c)&&((eight_bits)c<0200))
+@d xisxdigit(c) (isxdigit((eight_bits)c)&&((eight_bits)c<0200))
+
+@<Common code...@>=
+extern char buffer[]; /* where each line of input goes */
+extern char *buffer_end; /* end of |buffer| */
+extern char *loc; /* points to the next character to be read from the buffer */
+extern char *limit; /* points to the last character in the buffer */
+
+@ Code related to file handling:
+@f line x /* make |line| an unreserved word */
+@d max_include_depth 10 /* maximum number of source files open
+ simultaneously, not counting the change file */
+@d max_file_name_length 1024
+@d cur_file file[include_depth] /* current file */
+@d cur_file_name file_name[include_depth] /* current file name */
+@d cur_line line[include_depth] /* number of current line in current file */
+@d web_file file[0] /* main source file */
+@d web_file_name file_name[0] /* main source file name */
+
+@<Common code...@>=
+extern int include_depth; /* current level of nesting */
+extern FILE *file[]; /* stack of non-change files */
+extern FILE *change_file; /* change file */
+extern char file_name[][max_file_name_length];
+ /* stack of non-change file names */
+extern char change_file_name[]; /* name of change file */
+extern int line[]; /* number of current line in the stacked files */
+extern int change_line; /* number of current line in change file */
+extern int change_depth; /* where \.{@@y} originated during a change */
+extern boolean input_has_ended; /* if there is no more input */
+extern boolean changing; /* if the current line is from |change_file| */
+extern boolean web_file_open; /* if the web file is being read */
+
+@ @<Predecl...@>=
+extern boolean get_line(void); /* inputs the next line */
+extern void check_complete(void); /* checks that all changes were picked up */
+extern void reset_input(void); /* initialize to read the web file and change file */
+
+@ Code related to section numbers:
+@<Common code...@>=
+extern sixteen_bits section_count; /* the current section number */
+extern boolean changed_section[]; /* is the section changed? */
+extern boolean change_pending; /* is a decision about change still unclear? */
+extern boolean print_where; /* tells \.{CTANGLE} to print line and file info */
+
+@ Code related to identifier and section name storage:
+@d length(c) (size_t)((c+1)->byte_start-(c)->byte_start) /* the length of a name */
+@d print_id(c) term_write((c)->byte_start,length((c))) /* print identifier */
+@d llink link /* left link in binary search tree for section names */
+@d rlink dummy.Rlink /* right link in binary search tree for section names */
+@d root name_dir->rlink /* the root of the binary search tree
+ for section names */
+
+@<Common code...@>=
+typedef struct name_info {
+ char *byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ void *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char byte_mem[]; /* characters of names */
+extern char *byte_mem_end; /* end of |byte_mem| */
+extern char *byte_ptr; /* first unused position in |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+
+@ @<Predecl...@>=
+extern boolean names_match(name_pointer,const char *,size_t,eight_bits);@/
+extern name_pointer id_lookup(const char *,const char *,char);
+ /* looks up a string in the identifier table */
+extern name_pointer section_lookup(char *,char *,int); /* finds section name */
+extern void init_node(name_pointer);@/
+extern void init_p(name_pointer,eight_bits);@/
+extern void print_prefix_name(name_pointer);@/
+extern void print_section_name(name_pointer);@/
+extern void sprint_section_name(char *,name_pointer);
+
+@ Code related to error handling:
+@d spotless 0 /* |history| value for normal jobs */
+@d harmless_message 1 /* |history| value when non-serious info was printed */
+@d error_message 2 /* |history| value when an error was noted */
+@d fatal_message 3 /* |history| value when we had to stop prematurely */
+@d mark_harmless {if (history==spotless) history=harmless_message;}
+@d mark_error history=error_message
+@d confusion(s) fatal("! This can't happen: ",s)
+@.This can't happen@>
+
+@<Common code...@>=
+extern int history; /* indicates how bad this run was */
+
+@ @<Predecl...@>=
+extern int wrap_up(void); /* indicate |history| and exit */
+extern void err_print(const char *); /* print error message and context */
+extern void fatal(const char *,const char *); /* issue error message and die */
+extern void overflow(const char *); /* succumb because a table has overflowed */
+
+@ Code related to command line arguments:
+@d show_banner flags['b'] /* should the banner line be printed? */
+@d show_progress flags['p'] /* should progress reports be printed? */
+@d show_stats flags['s'] /* should statistics be printed at end of run? */
+@d show_happiness flags['h'] /* should lack of errors be announced? */
+@d make_xrefs flags['x'] /* should cross references be output? */
+
+@<Common code...@>=
+extern int argc; /* copy of |ac| parameter to |main| */
+extern char **argv; /* copy of |av| parameter to |main| */
+extern char C_file_name[]; /* name of |C_file| */
+extern char tex_file_name[]; /* name of |tex_file| */
+extern char idx_file_name[]; /* name of |idx_file| */
+extern char scn_file_name[]; /* name of |scn_file| */
+extern boolean flags[]; /* an option for each 7-bit code */
+
+@ Code related to output:
+@d update_terminal fflush(stdout) /* empty the terminal output buffer */
+@d new_line putchar('\n') @d putxchar putchar
+@d term_write(a,b) fflush(stdout),fwrite(a,sizeof(char),b,stdout)
+@d C_printf(c,a) fprintf(C_file,c,a)
+@d C_putc(c) putc(c,C_file) /* isn't \CEE/ wonderfully consistent? */
+
+@<Common code...@>=
+extern FILE *C_file; /* where output of \.{CTANGLE} goes */
+extern FILE *tex_file; /* where output of \.{CWEAVE} goes */
+extern FILE *idx_file; /* where index from \.{CWEAVE} goes */
+extern FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+extern FILE *active_file; /* currently active file for \.{CWEAVE} output */
+
+@ The procedure that gets everything rolling:
+@<Predecl...@>=
+extern void common_init(void);@/
+extern void print_stats(void);
+
+@ The following parameters were sufficient in the original \.{WEB} to
+handle \TEX/, so they should be sufficient for most applications of
+\.{CWEB}.
+
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+ index entries, and section names */
+@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */
+@d max_names 10239 /* number of identifiers, strings, section names;
+ must be less than 10240 */
+@d max_sections 4000 /* greater than the total number of sections */
+@d max_texts 10239 /* number of replacement texts, must be less than 10240 */
+@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */
+@d stack_size 500 /* number of simultaneous levels of macro expansion */
+@d buf_size 1000 /* maximum length of input line, plus one */
+@d long_buf_size (buf_size+longest_name) /* for \.{CWEAVE} */
+
+@ End of \.{COMMON} interface.
diff --git a/Build/source/texk/web2c/cwebdir/common.w b/Build/source/texk/web2c/cwebdir/common.w
new file mode 100644
index 00000000000..15e93c2c5e6
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/common.w
@@ -0,0 +1,1301 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 4.2 --- February 2021
+
+% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
+
+% 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.
+
+% Amendments to 'common.w' resulting in this updated version were created
+% by numerous collaborators over the course of many years.
+
+% Please send comments, suggestions, etc. to tex-k@@tug.org.
+
+\def\v{\char'174} % vertical (|) in typewriter font
+
+\def\title{Common code for CTANGLE and CWEAVE (Version 4.2)}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont Common code for {\ttitlefont CTANGLE} and
+ {\ttitlefont CWEAVE}}
+ \vskip 15pt
+ \centerline{(Version 4.2)}
+ \vfill}
+\def\botofcontents{\vfill
+\noindent
+Copyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth
+\bigskip\noindent
+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.
+
+\smallskip\noindent
+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.
+}
+
+\pageno=\contentspagenumber \advance\pageno by 1
+\let\maybe=\iftrue
+
+@s boolean int
+@s uint8_t int
+@s uint16_t int
+
+@** Introduction. This file contains code common
+to both \.{CTANGLE} and \.{CWEAVE}, which roughly concerns the following
+problems: character uniformity, input routines, error handling and
+parsing of command line. We have tried to concentrate in this file
+all the system dependencies, so as to maximize portability.
+
+In the texts below we will
+sometimes use \.{CWEB} to refer to either of the two component
+programs, if no confusion can arise.
+
+The file begins with a few basic definitions.
+
+@c
+@<Include files@>@/
+@h
+@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
+@<Global variables@>@/
+@<Predeclaration of procedures@>
+
+@ The details will be filled in due course. The interface of this module
+is included first. It is also used by the main programs.
+
+@i common.h
+
+@ In certain cases \.{CTANGLE} and \.{CWEAVE} should do almost, but not
+quite, the same thing. In these cases we've written common code for
+both, differentiating between the two by means of the global variable
+|program|.
+
+@<Global var...@>=
+boolean program; /* \.{CWEAVE} or \.{CTANGLE}? */
+
+@ \.{CWEAVE} 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, and finally it sorts and outputs the index.
+Similarly, \.{CTANGLE} operates in two phases.
+The global variable |phase| tells which phase we are in.
+
+@<Global var...@>=
+int phase; /* which phase are we in? */
+
+@ There's an initialization procedure that gets both \.{CTANGLE} and
+\.{CWEAVE} off to a good start. We will fill in the details of this
+procedure later.
+
+@c
+void
+common_init(void)
+{
+ @<Initialize pointers@>@;
+ @<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>@;
+ @<Scan arguments and open output files@>@;
+}
+
+@* The character set.
+\.{CWEB} uses the conventions of \CEE/ programs found in the standard
+\.{ctype.h} header file.
+
+A few character pairs are encoded internally as single characters,
+using the definitions in the interface sections above. These definitions
+are consistent with an extension of ASCII code originally developed at
+MIT and explained in Appendix~C of {\sl The \TEX/book\/}; thus, users
+who have such a character set can type things like \.{\char'32} and
+\.{\char'4} instead of \.{!=} and \.{\&\&}. (However, their files will
+not be too portable until more people adopt the extended code.)
+
+If the character set is not ASCII, the definitions given may conflict
+with existing characters; in such cases, other arbitrary codes should be
+substituted. The indexes to \.{CTANGLE} and \.{CWEAVE} mention every
+case where similar codes may have to be changed in order to
+avoid character conflicts. Look for the entry ``ASCII code dependencies''
+in those indexes.
+
+@^ASCII code dependencies@>
+@^system dependencies@>
+
+@<Global var...@>=
+char section_text[longest_name+1]; /* text being sought for */
+char *section_text_end = section_text+longest_name; /* end of |section_text| */
+char *id_first; /* where the current identifier begins in the buffer */
+char *id_loc; /* just after the current identifier in the buffer */
+
+@** Input routines. The lowest level of input to the \.{CWEB} programs
+is performed by |input_ln|, which must be told which file to read from.
+The return value of |input_ln| is |true| if the read is successful and
+|false| if not (generally this means the file has ended). The conventions
+of \TEX/ are followed; i.e., the characters of the next line of the file
+are copied into the |buffer| array,
+and the global variable |limit| is set to the first unoccupied position.
+Trailing blanks are ignored. The value of |limit| must be strictly less
+than |buf_size|, so that |buffer[buf_size-1]| is never filled.
+
+Since |buf_size| is strictly less than |long_buf_size|,
+some of \.{CWEB}'s routines use the fact that it is safe to refer to
+|*(limit+2)| without overstepping the bounds of the array.
+
+@<Global var...@>=
+char buffer[long_buf_size]; /* where each line of input goes */
+char *buffer_end=buffer+buf_size-2; /* end of |buffer| */
+char *loc=buffer; /* points to the next character to be read from the buffer */
+char *limit=buffer; /* points to the last character in the buffer */
+
+@ In the unlikely event that your standard I/O library does not
+support |feof|, |getc|, and |ungetc| you may have to change things here.
+@^system dependencies@>
+
+@c
+static boolean input_ln(@t\1\1@> /* copies a line into |buffer| or returns |false| */
+FILE *fp@t\2\2@>) /* what file to read from */
+{
+ register int c=EOF; /* character read; initialized so some compilers won't complain */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return false; /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
+ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')
+ if ((*(k++) = c) != ' ') limit = k;
+ if (k>buffer_end)
+ if ((c=getc(fp))!=EOF && c!='\n') {
+ ungetc(c,fp); loc=buffer; err_print("! Input line too long");
+@.Input line too long@>
+ }
+ if (c==EOF && limit==buffer) return false; /* there was nothing after
+ the last newline */
+ return true;
+}
+
+@ @<Predecl...@>=@+static boolean input_ln(FILE *);
+
+@ Now comes the problem of deciding which file to read from next.
+Recall that the actual text that \.{CWEB} should process comes from two
+streams: a |web_file|, which can contain possibly nested include
+commands \.{@@i}, and a |change_file|, which might also contain
+includes. The |web_file| together with the currently open include
+files form a stack |file|, whose names are stored in a parallel stack
+|file_name|. The boolean |changing| tells whether or not we're reading
+from the |change_file|.
+
+The line number of each open file is also kept for error reporting and
+for the benefit of \.{CTANGLE}.
+
+@<Global var...@>=
+int include_depth; /* current level of nesting */
+FILE *file[max_include_depth]; /* stack of non-change files */
+FILE *change_file; /* change file */
+char file_name[max_include_depth][max_file_name_length];
+ /* stack of non-change file names */
+char change_file_name[max_file_name_length]; /* name of change file */
+static char alt_web_file_name[max_file_name_length]; /* alternate name to try */
+int line[max_include_depth]; /* number of current line in the stacked files */
+int change_line; /* number of current line in change file */
+int change_depth; /* where \.{@@y} originated during a change */
+boolean input_has_ended; /* if there is no more input */
+boolean changing; /* if the current line is from |change_file| */
+boolean web_file_open=false; /* if the web file is being read */
+
+@ When |changing==false|, the next line of |change_file| is kept in
+|change_buffer|, for purposes of comparison with the next
+line of |cur_file|. After the change file has been completely input, we
+set |change_limit=change_buffer|,
+so that no further matches will be made.
+
+Here's a shorthand expression for inequality between the two lines:
+
+@d lines_dont_match (change_limit-change_buffer != limit-buffer || @|
+ strncmp(buffer, change_buffer, (size_t)(limit-buffer)))
+
+@<Global var...@>=
+static char change_buffer[buf_size]; /* next line of |change_file| */
+static char *change_limit; /* points to the last character in |change_buffer| */
+
+@ Procedure |prime_the_change_buffer|
+sets |change_buffer| in preparation for the next matching operation.
+Since blank lines in the change file are not used for matching, we have
+|(change_limit==change_buffer && !changing)| if and only if
+the change file is exhausted. This procedure is called only when
+|changing| is |true|; hence error messages will be reported correctly.
+
+@c
+static void
+prime_the_change_buffer(void)
+{
+ change_limit=change_buffer; /* this value is used if the change file ends */
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
+ @<Skip to the next nonblank line; |return| if end of file@>@;
+ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>@;
+}
+
+@ @<Predecl...@>=@+static void prime_the_change_buffer(void);
+
+@ While looking for a line that begins with \.{@@x} in the change file, we
+allow lines that begin with \.{@@}, as long as they don't begin with \.{@@y},
+\.{@@z}, or \.{@@i} (which would probably mean that the change file is fouled up).
+
+@<Skip over comment lines in the change file...@>=
+while(true) {
+ change_line++;
+ if (!input_ln(change_file)) return;
+ if (limit<buffer+2) continue;
+ if (buffer[0]!='@@') continue;
+ if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+ if (buffer[1]=='x') break;
+ if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
+ loc=buffer+2;
+ err_print("! Missing @@x in change file");
+@.Missing @@x...@>
+ }
+}
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do {
+ change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended after @@x");
+@.Change file ended...@>
+ return;
+ }
+} while (limit==buffer);
+
+@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
+{
+ change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
+ strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+}
+
+@ The following procedure is used to see if the next change entry should
+go into effect; it is called only when |changing| is |false|.
+The idea is to test whether or not the current
+contents of |buffer| matches the current contents of |change_buffer|.
+If not, there's nothing more to do; but if so, a change is called for:
+All of the text down to the \.{@@y} is supposed to match. An error
+message is issued if any discrepancy is found. Then the procedure
+prepares to read the next line from |change_file|.
+
+When a match is found, the current section is marked as changed unless
+the first line after the \.{@@x} and after the \.{@@y} both start with
+either `\.{@@*}' or `\.{@@\ }' (possibly preceded by whitespace).
+
+This procedure is called only when |buffer<limit|, i.e., when the
+current line is nonempty.
+
+@d if_section_start_make_pending(b) {@+*limit='!';
+ for (loc=buffer;xisspace(*loc);loc++) ;
+ *limit=' ';
+ if (*loc=='@@' && (xisspace(*(loc+1)) || *(loc+1)=='*')) change_pending=b;
+}
+
+@c
+static void
+check_change(void) /* switches to |change_file| if the buffers match */
+{
+ int n=0; /* the number of discrepancies found */
+ if (lines_dont_match) return;
+ change_pending=false;
+ if (!changed_section[section_count]) {
+ if_section_start_make_pending(true);
+ if (!change_pending) changed_section[section_count]=true;
+ }
+ while (true) {
+ changing=true; print_where=true; change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended before @@y");
+@.Change file ended...@>
+ change_limit=change_buffer; changing=false;
+ return;
+ }
+ if (limit>buffer+1 && buffer[0]=='@@') {
+ char xyz_code=xisupper(buffer[1])? tolower((eight_bits)buffer[1]): buffer[1];
+ @<If the current line starts with \.{@@y},
+ report any discrepancies and |return|@>@;
+ }
+ @<Move |buffer| and |limit|...@>@;
+ changing=false; cur_line++;
+ while (!input_ln(cur_file)) { /* pop the stack or quit */
+ if (include_depth==0) {
+ err_print("! CWEB file ended during a change");
+@.CWEB file ended...@>
+ input_has_ended=true; return;
+ }
+ include_depth--; cur_line++;
+ }
+ if (lines_dont_match) n++;
+ }
+}
+
+@ @<Predecl...@>=@+static void check_change(void);
+
+@ @<If the current line starts with \.{@@y}...@>=
+if (xyz_code=='x' || xyz_code=='z') {
+ loc=buffer+2; err_print("! Where is the matching @@y?");
+@.Where is the match...@>
+ }
+else if (xyz_code=='y') {
+ if (n>0) {
+ loc=buffer+2;
+ printf("\n! Hmm... %d ",n);
+ err_print("of the preceding lines failed to match");
+@.Hmm... n of the preceding...@>
+ }
+ change_depth=include_depth;
+ return;
+}
+
+@ The |reset_input| procedure, which gets \.{CWEB} ready to read the
+user's \.{CWEB} input, is used at the beginning of phase one of \.{CTANGLE},
+phases one and two of \.{CWEAVE}.
+
+@c
+void
+reset_input(void)
+{
+ limit=buffer; loc=buffer+1; buffer[0]=' ';
+ @<Open input files@>@;
+ include_depth=0; cur_line=0; change_line=0;
+ change_depth=include_depth;
+ changing=1; prime_the_change_buffer(); changing=!changing;
+ limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=false;
+}
+
+@ The following code opens the input files.
+@^system dependencies@>
+
+@<Open input files@>=
+if ((web_file=fopen(web_file_name,"r"))==NULL) {
+ strcpy(web_file_name,alt_web_file_name);
+ if ((web_file=fopen(web_file_name,"r"))==NULL)
+ fatal("! Cannot open input file ", web_file_name);
+}
+@.Cannot open input file@>
+@.Cannot open change file@>
+web_file_open=true;
+if ((change_file=fopen(change_file_name,"r"))==NULL)
+ fatal("! Cannot open change file ", change_file_name);
+
+@ The |get_line| procedure is called when |loc>limit|; it puts the next
+line of merged input into the buffer and updates the other variables
+appropriately. A space is placed at the right end of the line.
+This procedure returns |!input_has_ended| because we often want to
+check the value of that variable after calling the procedure.
+
+If we've just changed from the |cur_file| to the |change_file|, or if
+the |cur_file| has changed, we tell \.{CTANGLE} to print this
+information in the \CEE/ file by means of the |print_where| flag.
+
+@<Global var...@>=
+sixteen_bits section_count; /* the current section number */
+boolean changed_section[max_sections]; /* is the section changed? */
+boolean change_pending; /* if the current change is not yet recorded in
+ |changed_section[section_count]| */
+boolean print_where=false; /* should \.{CTANGLE} print line and file info? */
+
+@ @c
+boolean get_line(void) /* inputs the next line */
+{
+ restart:
+ if (changing && include_depth==change_depth)
+ @<Read from |change_file| and maybe turn off |changing|@>@;
+ if (! changing || include_depth>change_depth) {
+ @<Read from |cur_file| and maybe turn on |changing|@>@;
+ if (changing && include_depth==change_depth) goto restart;
+ }
+ if (input_has_ended) return false;
+ loc=buffer; *limit=' ';
+ if (buffer[0]=='@@' && (buffer[1]=='i' || buffer[1]=='I')) {
+ loc=buffer+2; *limit='"';
+ while (*loc==' '||*loc=='\t') loc++;
+ if (loc>=limit) {
+ err_print("! Include file name not given");
+@.Include file name ...@>
+ goto restart;
+ }
+ if (include_depth>=max_include_depth-1) {
+ err_print("! Too many nested includes");
+@.Too many nested includes@>
+ goto restart;
+ }
+ include_depth++; /* push input stack */
+ @<Try to open include file, abort push if unsuccessful, go to |restart|@>@;
+ }
+ return true;
+}
+
+@ When an \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without
+double quotes.
+If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
+of the same name was defined at compile time,
+\.{CWEB} will look for include files in the directory thus named, if
+it cannot find them in the current directory.
+(Colon-separated paths are not supported.)
+The remainder of the \.{@@i} line after the file name is ignored.
+
+@d too_long() {include_depth--;
+ err_print("! Include file name too long"); goto restart;}
+
+@.CWEBINPUTS@>@<Try to open...@>= {
+ char temp_file_name[max_file_name_length];
+ char *cur_file_name_end=cur_file_name+max_file_name_length-1;
+ char *k=cur_file_name, *kk;
+ int l; /* length of file name */
+
+ if (*loc=='"') {
+ loc++;
+ while (*loc!='"' && k<=cur_file_name_end) *k++=*loc++;
+ if (loc==limit) k=cur_file_name_end+1; /* unmatched quote is `too long' */
+ } else
+ while (*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end) *k++=*loc++;
+ if (k>cur_file_name_end) too_long();
+@.Include file name ...@>
+ *k='\0';
+ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
+ cur_line=0; print_where=true;
+ goto restart; /* success */
+ }
+ kk=getenv("CWEBINPUTS");
+ if (kk!=NULL) {
+ if ((l=strlen(kk))>max_file_name_length-2) too_long();
+ strcpy(temp_file_name,kk);
+ }
+ else {
+#ifdef CWEBINPUTS
+ if ((l=strlen(CWEBINPUTS))>max_file_name_length-2) too_long();
+ strcpy(temp_file_name,CWEBINPUTS);
+#else
+ l=0;
+#endif /* |CWEBINPUTS| */
+ }
+ if (l>0) {
+ if (k+l+2>=cur_file_name_end) too_long();
+@.Include file name ...@>
+ for (; k>= cur_file_name; k--) *(k+l+1)=*k;
+ strcpy(cur_file_name,temp_file_name);
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
+ cur_line=0; print_where=true;
+ goto restart; /* success */
+ }
+ }
+ include_depth--; err_print("! Cannot open include file"); goto restart;
+}
+
+@ @<Read from |cur_file|...@>= {
+ cur_line++;
+ while (!input_ln(cur_file)) { /* pop the stack or quit */
+ print_where=true;
+ if (include_depth==0) {input_has_ended=true; break;}
+ else {
+ fclose(cur_file); include_depth--;
+ if (changing && include_depth==change_depth) break;
+ cur_line++;
+ }
+ }
+ if (!changing && !input_has_ended)
+ if (limit-buffer==change_limit-change_buffer)
+ if (buffer[0]==change_buffer[0])
+ if (change_limit>change_buffer) check_change();
+}
+
+@ @<Read from |change_file|...@>= {
+ change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended without @@z");
+@.Change file ended...@>
+ buffer[0]='@@'; buffer[1]='z'; limit=buffer+2;
+ }
+ if (limit>buffer) { /* check if the change has ended */
+ if (change_pending) {
+ if_section_start_make_pending(false);
+ if (change_pending) {
+ changed_section[section_count]=true; change_pending=false;
+ }
+ }
+ *limit=' ';
+ if (buffer[0]=='@@') {
+ if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+ if (buffer[1]=='x' || buffer[1]=='y') {
+ loc=buffer+2;
+ err_print("! Where is the matching @@z?");
+@.Where is the match...@>
+ }
+ else if (buffer[1]=='z') {
+ prime_the_change_buffer(); changing=!changing; print_where=true;
+ }
+ }
+ }
+}
+
+@ At the end of the program, we will tell the user if the change file
+had a line that didn't match any relevant line in |web_file|.
+
+@c
+void
+check_complete(void) {
+ if (change_limit!=change_buffer) { /* |changing| is |false| */
+ strncpy(buffer,change_buffer,(size_t)(change_limit-change_buffer+1));
+ limit=buffer+(ptrdiff_t)(change_limit-change_buffer);
+ changing=true; change_depth=include_depth; loc=buffer;
+ err_print("! Change file entry did not match");
+@.Change file entry did not match@>
+ }
+}
+
+@** Storage of names and strings.
+Both \.{CWEAVE} and \.{CTANGLE} store identifiers, section names and
+other strings in a large array of |char|s, called |byte_mem|.
+Information about the names is kept in the array |name_dir|, whose
+elements are structures of type |name_info|, containing a pointer into
+the |byte_mem| array (the address where the name begins) and other data.
+A |name_pointer| variable is a pointer into |name_dir|. You find the
+complete layout of |name_info| in the interface sections above.
+
+The actual sequence of characters in the name pointed to by a |name_pointer
+p| appears in positions |p->byte_start| to |(p+1)->byte_start-1|, inclusive.
+
+The names of identifiers are found by computing a hash address |h| and
+then looking at strings of bytes signified by the |name_pointer|s
+|hash[h]|, |hash[h]->link|, |hash[h]->link->link|, \dots,
+until either finding the desired name or encountering the null pointer.
+
+The names of sections are stored in |byte_mem| together
+with the identifier names, but a hash table is not used for them because
+\.{CTANGLE} needs to be able to recognize a section name when given a prefix of
+that name. A conventional binary search tree is used to retrieve section names,
+with fields called |llink| and |rlink| (where |llink| takes the place
+of |link|). The root of this tree is stored in |name_dir->rlink|;
+this will be the only information in |name_dir[0]|.
+
+Since the space used by |rlink| has a different function for
+identifiers than for section names, we declare it as a |union|.
+
+The last component of |name_info| is different for \.{CTANGLE} and
+\.{CWEAVE}. In \.{CTANGLE}, if |p| is a pointer to a section name,
+|p->equiv| is a pointer to its replacement text, an element of the
+array |text_info|. In \.{CWEAVE}, on the other hand, if
+|p| points to an identifier, |p->xref| is a pointer to its
+list of cross-references, an element of the array |xmem|. The make-up
+of |text_info| and |xmem| is discussed in the \.{CTANGLE} and \.{CWEAVE}
+source files, respectively; here we just declare a common field
+|equiv_or_xref| as a pointer to |void|.
+
+@<Global var...@>=
+char byte_mem[max_bytes]; /* characters of names */
+char *byte_mem_end = byte_mem+max_bytes-1; /* end of |byte_mem| */
+name_info name_dir[max_names]; /* information about names */
+name_pointer name_dir_end = name_dir+max_names-1; /* end of |name_dir| */
+
+@ The first unused position in |byte_mem| and |name_dir| is
+kept in |byte_ptr| and |name_ptr|, respectively. Thus we
+usually have |name_ptr->byte_start==byte_ptr|, and certainly
+we want to keep |name_ptr<=name_dir_end| and |byte_ptr<=byte_mem_end|.
+
+@<Global var...@>=
+char *byte_ptr; /* first unused position in |byte_mem| */
+name_pointer name_ptr; /* first unused position in |name_dir| */
+
+@ @<Init...@>=
+name_dir->byte_start=byte_ptr=byte_mem; /* position zero in both arrays */
+name_ptr=name_dir+1; /* |name_dir[0]| will be used only for error recovery */
+name_ptr->byte_start=byte_mem; /* this makes name 0 of length zero */
+root=NULL; /* the binary search tree starts out with nothing in it */
+
+@ The hash table itself
+consists of |hash_size| entries of type |name_pointer|, and is
+updated by the |id_lookup| procedure, which finds a given identifier
+and returns the appropriate |name_pointer|. The matching is done by the
+function |names_match|, which is slightly different in
+\.{CWEAVE} and \.{CTANGLE}. If there is no match for the identifier,
+it is inserted into the table.
+
+@d hash_size 8501 /* should be prime */
+
+@<Global var...@>=
+name_pointer hash[hash_size]; /* heads of hash lists */
+hash_pointer hash_end = hash+hash_size-1; /* end of |hash| */
+hash_pointer h; /* index into hash-head array */
+
+@ Initially all the hash lists are empty.
+
+@<Init...@>=
+for (h=hash; h<=hash_end; *h++=NULL) ;
+
+@ Here is the main procedure for finding identifiers:
+
+@c
+name_pointer
+id_lookup(@t\1\1@> /* looks up a string in the identifier table */
+const char *first, /* first character of string */
+const char *last, /* last character of string plus one */
+char t@t\2\2@>) /* the |ilk|; used by \.{CWEAVE} only */
+{
+ const char *i=first; /* position in |buffer| */
+ int h; /* hash code */
+ int l; /* length of the given identifier */
+ name_pointer p; /* where the identifier is being sought */
+ if (last==NULL) for (last=first; *last!='\0'; last++);
+ l=(int)(last-first); /* compute the length */
+ @<Compute the hash code |h|@>@;
+ @<Compute the name location |p|@>@;
+ if (p==name_ptr) @<Enter a new name into the table at position |p|@>@;
+ return p;
+}
+
+@ A simple hash code is used: If the sequence of
+character codes is $c_1c_2\ldots c_n$, its hash value will be
+$$(2^{n-1}c_1+2^{n-2}c_2+\cdots+c_n)\,\bmod\,|hash_size|.$$
+
+@<Compute the hash...@>=
+h=(eight_bits)*i;
+while (++i<last) h=(h+h+(int)((eight_bits)*i)) % hash_size;
+@^high-bit character handling@>
+
+@ If the identifier is new, it will be placed in position |p=name_ptr|,
+otherwise |p| will point to its existing location.
+
+@<Compute the name location...@>=
+p=hash[h];
+while (p && !names_match(p,first,l,t)) p=p->link;
+if (p==NULL) {
+ p=name_ptr; /* the current identifier is new */
+ p->link=hash[h]; hash[h]=p; /* insert |p| at beginning of hash list */
+}
+
+@ The information associated with a new identifier must be initialized
+in a slightly different way in \.{CWEAVE} than in \.{CTANGLE}; hence the
+|init_p| procedure.
+@<Enter a new name...@>= {
+ if (byte_ptr+l>byte_mem_end) overflow("byte memory");
+ if (name_ptr>=name_dir_end) overflow("name");
+ strncpy(byte_ptr,first,l);
+ (++name_ptr)->byte_start=byte_ptr+=l;
+ init_p(p,t);
+}
+
+@ If |p| is a |name_pointer| variable, as we have seen,
+|p->byte_start| is the beginning of the area where the name
+corresponding to |p| is stored. However, if |p| refers to a section
+name, the name may need to be stored in chunks, because it may
+``grow'': a prefix of the section name may be encountered before
+the full name. Furthermore we need to know the length of the shortest
+prefix of the name that was ever encountered.
+
+We solve this problem by inserting two extra bytes at |p->byte_start|,
+representing the length of the shortest prefix, when |p| is a
+section name. Furthermore, the last byte of the name will be a blank
+space if |p| is a prefix. In the latter case, the name pointer
+|p+1| will allow us to access additional chunks of the name:
+The second chunk will begin at the name pointer |(p+1)->link|,
+and if it too is a prefix (ending with blank) its |link| will point
+to additional chunks in the same way. Null links are represented by
+|name_dir|.
+
+@d first_chunk(p) ((p)->byte_start+2)
+@d prefix_length(p) (int)((eight_bits)*((p)->byte_start)*256 +
+ (eight_bits)*((p)->byte_start+1))
+@d set_prefix_length(p,m) (*((p)->byte_start)=(m)/256,
+ *((p)->byte_start+1)=(m)%256)
+
+@c
+void
+print_section_name(
+name_pointer p)
+{
+ char *ss, *s = first_chunk(p);
+ name_pointer q = p+1;
+ while (p!=name_dir) {
+ ss = (p+1)->byte_start-1;
+ if (*ss==' ' && ss>=s) {
+ term_write(s,(size_t)(ss-s)); p=q->link; q=p;
+ } else {
+ term_write(s,(size_t)(ss+1-s)); p=name_dir; q=NULL;
+ }
+ s = p->byte_start;
+ }
+ if (q) term_write("...",3); /* complete name not yet known */
+}
+
+@ @c
+void
+sprint_section_name(
+ char *dest,
+ name_pointer p)
+{
+ char *ss, *s = first_chunk(p);
+ name_pointer q = p+1;
+ while (p!=name_dir) {
+ ss = (p+1)->byte_start-1;
+ if (*ss==' ' && ss>=s) {
+ p=q->link; q=p;
+ } else {
+ ss++; p=name_dir;
+ }
+ strncpy(dest,s,(size_t)(ss-s)), dest+=ss-s;
+ s = p->byte_start;
+ }
+ *dest='\0';
+}
+
+@ @c
+void
+print_prefix_name(
+name_pointer p)
+{
+ char *s = first_chunk(p);
+ int l = prefix_length(p);
+ term_write(s,l);
+ if (s+l<(p+1)->byte_start) term_write("...",3);
+}
+
+@ When we compare two section names, we'll need a function analogous to
+|strcmp|. But we do not assume the strings
+are null-terminated, and we keep an eye open for prefixes and extensions.
+
+@d less 0 /* the first name is lexicographically less than the second */
+@d equal 1 /* the first name is equal to the second */
+@d greater 2 /* the first name is lexicographically greater than the second */
+@d prefix 3 /* the first name is a proper prefix of the second */
+@d extension 4 /* the first name is a proper extension of the second */
+
+@<Predecl...@>=
+static int web_strcmp(char *,int,char *,int);@/
+static name_pointer add_section_name(name_pointer,int,char *,char *,int);@/
+static void extend_section_name(name_pointer,char *,char *,int);
+
+@ @c
+static int web_strcmp(@t\1\1@> /* fuller comparison than |strcmp| */
+ char *j, /* beginning of first string */
+ int j_len, /* length of first string */
+ char *k, /* beginning of second string */
+ int k_len@t\2\2@>) /* length of second string */
+{
+ char *j1=j+j_len, *k1=k+k_len;
+ while (k<k1 && j<j1 && *j==*k) k++, j++;
+ if (k==k1) if (j==j1) return equal;
+ else return extension;
+ else if (j==j1) return prefix;
+ else if (*j<*k) return less;
+ else return greater;
+}
+
+@ Adding a section name to the tree is straightforward if we know its
+parent and whether it's the |rlink| or |llink| of the parent. As a
+special case, when the name is the first section being added, we set the
+``parent'' to |NULL|. When a section name is created, it has only one
+chunk, which however may be just a prefix; the full name will
+hopefully be unveiled later. Obviously, |prefix_length| starts
+out as the length of the first chunk, though it may decrease later.
+
+The information associated with a new node must be initialized
+differently in \.{CWEAVE} and \.{CTANGLE}; hence the
+|init_node| procedure, which is defined differently in \.{cweave.w}
+and \.{ctangle.w}.
+
+@c
+static name_pointer
+add_section_name(@t\1\1@> /* install a new node in the tree */
+name_pointer par, /* parent of new node */
+int c, /* right or left? */
+char *first, /* first character of section name */
+char *last, /* last character of section name, plus one */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+{
+ name_pointer p=name_ptr; /* new node */
+ char *s=first_chunk(p);
+ int name_len=(int)(last-first)+ispref; /* length of section name */
+ if (s+name_len>byte_mem_end) overflow("byte memory");
+ if (name_ptr+1>=name_dir_end) overflow("name");
+ (++name_ptr)->byte_start=byte_ptr=s+name_len;
+ if (ispref) {
+ *(byte_ptr-1)=' ';
+ name_len--;
+ name_ptr->link=name_dir;
+ (++name_ptr)->byte_start=byte_ptr;
+ }
+ set_prefix_length(p,name_len);
+ strncpy(s,first,name_len);
+ p->llink=NULL;
+ p->rlink=NULL;
+ init_node(p);
+ return par==NULL ? (root=p) : c==less ? (par->llink=p) : (par->rlink=p);
+}
+
+@ @c
+static void
+extend_section_name(@t\1\1@>
+name_pointer p, /* name to be extended */
+char *first, /* beginning of extension text */
+char *last, /* one beyond end of extension text */
+int ispref@t\2\2@>) /* are we adding a prefix or a full name? */
+{
+ char *s;
+ name_pointer q=p+1;
+ int name_len=(int)(last-first)+ispref;
+ if (name_ptr>=name_dir_end) overflow("name");
+ while (q->link!=name_dir) q=q->link;
+ q->link=name_ptr;
+ s=name_ptr->byte_start;
+ name_ptr->link=name_dir;
+ if (s+name_len>byte_mem_end) overflow("byte memory");
+ (++name_ptr)->byte_start=byte_ptr=s+name_len;
+ strncpy(s,first,name_len);
+ if (ispref) *(byte_ptr-1)=' ';
+}
+
+@ The |section_lookup| procedure is supposed to find a
+section name that matches a new name, installing the new name if
+it doesn't match an existing one. The new name is the string
+between |first| and |last|; a ``match'' means that the new name
+exactly equals or is a prefix or extension of a name in the tree.
+
+@c
+name_pointer
+section_lookup(@t\1\1@> /* find or install section name in tree */
+char *first,char *last, /* first and last characters of new name */
+int ispref@t\2\2@>) /* is the new name a prefix or a full name? */
+{
+ int c=0; /* comparison between two names; initialized so some compilers won't complain */
+ name_pointer p=root; /* current node of the search tree */
+ name_pointer q=NULL; /* another place to look in the tree */
+ name_pointer r=NULL; /* where a match has been found */
+ name_pointer par=NULL; /* parent of |p|, if |r| is |NULL|;
+ otherwise parent of |r| */
+ int name_len=(int)(last-first)+1;
+ @<Look for matches for new name among shortest prefixes, complaining
+ if more than one is found@>@;
+ @<If no match found, add new name to tree@>@;
+ @<If one match found, check for compatibility and return match@>@;
+}
+
+@ A legal new name matches an existing section name if and only if it
+matches the shortest prefix of that section name. Therefore we can
+limit our search for matches to shortest prefixes, which eliminates
+the need for chunk-chasing at this stage.
+
+@<Look for matches for new name among...@>=
+while (p) { /* compare shortest prefix of |p| with new name */
+ c=web_strcmp(first,name_len,first_chunk(p),prefix_length(p));
+ if (c==less || c==greater) { /* new name does not match |p| */
+ if (r==NULL) /* no previous matches have been found */
+ par=p;
+ p=(c==less?p->llink:p->rlink);
+ } else { /* new name matches |p| */
+ if (r!=NULL) { /* and also |r|: illegal */
+ fputs("\n! Ambiguous prefix: matches <",stdout);
+@.Ambiguous prefix ... @>
+ print_prefix_name(p);
+ fputs(">\n and <",stdout);
+ print_prefix_name(r);
+ err_print(">");
+ return name_dir; /* the unsection */
+ }
+ r=p; /* remember match */
+ p=p->llink; /* try another */
+ q=r->rlink; /* we'll get back here if the new |p| doesn't match */
+ }
+ if (p==NULL)
+ p=q, q=NULL; /* |q| held the other branch of |r| */
+}
+
+@ @<If no match ...@>=
+ if (r==NULL) /* no matches were found */
+ return add_section_name(par,c,first,last+1,ispref);
+
+@ Although error messages are given in anomalous cases, we do return the
+unique best match when a discrepancy is found, because users often
+change a title in one place while forgetting to change it elsewhere.
+
+@<If one match found, check for compatibility and return match@>=
+switch(section_name_cmp(&first,name_len,r)) {
+ /* compare all of |r| with new name */
+ case prefix:
+ if (!ispref) {
+ fputs("\n! New name is a prefix of <",stdout);
+@.New name is a prefix...@>
+ print_section_name(r);
+ err_print(">");
+ }
+ else if (name_len<prefix_length(r)) set_prefix_length(r,name_len);
+ /* fall through */
+ case equal: return r;
+ case extension: if (!ispref || first<=last)
+ extend_section_name(r,first,last+1,ispref);
+ return r;
+ case bad_extension:
+ fputs("\n! New name extends <",stdout);
+@.New name extends...@>
+ print_section_name(r);
+ err_print(">");
+ return r;
+ default: /* no match: illegal */
+ fputs("\n! Section name incompatible with <",stdout);
+@.Section name incompatible...@>
+ print_prefix_name(r);
+ fputs(">,\n which abbreviates <",stdout);
+ print_section_name(r);
+ err_print(">");
+ return r;
+}
+
+@ The return codes of |section_name_cmp|, which compares a string with
+the full name of a section, are those of |web_strcmp| plus
+|bad_extension|, used when the string is an extension of a
+supposedly already complete section name. This function has a side
+effect when the comparison string is an extension: It advances the
+address of the first character of the string by an amount equal to
+the length of the known part of the section name.
+
+The name \.{@@<foo...@@>} should be an acceptable ``abbreviation''
+for \.{@@<foo@@>}. If such an abbreviation comes after the complete
+name, there's no trouble recognizing it. If it comes before the
+complete name, we simply append a null chunk. This logic requires
+us to regard \.{@@<foo...@@>} as an ``extension'' of itself.
+
+@d bad_extension 5
+
+@c
+static int section_name_cmp(@t\1\1@>
+char **pfirst, /* pointer to beginning of comparison string */
+int len, /* length of string */
+name_pointer r@t\2\2@>) /* section name being compared */
+{
+ char *first=*pfirst; /* beginning of comparison string */
+ name_pointer q=r+1; /* access to subsequent chunks */
+ char *ss, *s=first_chunk(r);
+ int c; /* comparison */
+ int ispref; /* is chunk |r| a prefix? */
+ while (true) {
+ ss=(r+1)->byte_start-1;
+ if (*ss==' ' && ss>=r->byte_start) ispref=1,q=q->link;
+ else ispref=0,ss++,q=name_dir;
+ switch(c=web_strcmp(first,len,s,ss-s)) {
+ case equal: if (q==name_dir)
+ if (ispref) {
+ *pfirst=first+(ptrdiff_t)(ss-s);
+ return extension; /* null extension */
+ } else return equal;
+ else return (q->byte_start==(q+1)->byte_start)? equal: prefix;
+ case extension:
+ if (!ispref) return bad_extension;
+ first += ss-s;
+ if (q!=name_dir) {len -= (int)(ss-s); s=q->byte_start; r=q; continue;}
+ *pfirst=first; return extension;
+ default: return c;
+ }
+ }
+}
+
+@ @<Predec...@>=@+static int section_name_cmp(char **,int,name_pointer);
+
+@** Reporting errors to the user.
+A global variable called |history| will contain one of four values
+at the end of every run: |spotless| means that no unusual messages were
+printed; |harmless_message| means that a message of possible interest
+was printed but no serious errors were detected; |error_message| means that
+at least one error was found; |fatal_message| means that the program
+terminated abnormally. The value of |history| does not influence the
+behavior of the program; it is simply computed for the convenience
+of systems that might want to use such information.
+
+@<Global var...@>=
+int history=spotless; /* indicates how bad this run was */
+
+@ The command `|err_print("! Error message")|' will report a syntax error to
+the user, by printing the error message at the beginning of a new line and
+then giving an indication of where the error was spotted in the source file.
+Note that no period follows the error message, since the error routine
+will automatically supply a period. A newline is automatically supplied
+if the string begins with |"!"|.
+
+@c
+void
+err_print(@t\1\1@> /* prints `\..' and location of error message */
+const char *s@t\2\2@>)
+{
+ char *k,*l; /* pointers into |buffer| */
+ printf(*s=='!'? "\n%s" : "%s",s);
+ if(web_file_open) @<Print error location based on input buffer@>@;
+ update_terminal; mark_error;
+}
+
+@ The error locations can be indicated by using the global variables
+|loc|, |cur_line|, |cur_file_name| and |changing|,
+which tell respectively the first
+unlooked-at position in |buffer|, the current line number, the current
+file, and whether the current line is from |change_file| or |cur_file|.
+This routine should be modified on systems whose standard text editor
+has special line-numbering conventions.
+@^system dependencies@>
+
+@<Print error location based on input buffer@>=
+{if (changing && include_depth==change_depth)
+ printf(". (l. %d of change file)\n", change_line);
+else if (include_depth==0) printf(". (l. %d)\n", cur_line);
+ else printf(". (l. %d of include file %s)\n", cur_line, cur_file_name);
+l= (loc>=limit? limit: loc);
+if (l>buffer) {
+ for (k=buffer; k<l; k++)
+ if (*k=='\t') putchar(' ');
+ else putchar(*k); /* print the characters already read */
+ putchar('\n');
+ for (k=buffer; k<l; k++) putchar(' '); /* space out the next line */
+}
+for (k=l; k<limit; k++) putchar(*k); /* print the part not yet read */
+if (*limit=='|') putchar('|'); /* end of \CEE/ text in section names */
+putchar(' '); /* to separate the message from future asterisks */
+}
+
+@ When no recovery from some error has been provided, we have to wrap
+up and quit as graciously as possible. This is done by calling the
+function |wrap_up| at the end of the code.
+
+\.{CTANGLE} and \.{CWEAVE} have their own notions about how to
+print the job statistics. See the function(s) |print_stats| in the
+interface above and in the index.
+
+Some implementations may wish to pass the |history| value to the
+operating system so that it can be used to govern whether or not other
+programs are started. Here, for instance, we pass the operating system
+a status of 0 if and only if only harmless messages were printed.
+@^system dependencies@>
+
+@c
+int wrap_up(void) {
+ if (show_progress) new_line;
+ if (show_stats)
+ print_stats(); /* print statistics about memory usage */
+ @<Print the job |history|@>@;
+ if (history > harmless_message) return EXIT_FAILURE;
+ else return EXIT_SUCCESS;
+}
+
+@ @<Print the job |history|@>=
+switch (history) {
+case spotless: if (show_happiness) puts("(No errors were found.)"); break;
+case harmless_message:
+ puts("(Did you see the warning message above?)"); break;
+case error_message:
+ puts("(Pardon me, but I think I spotted something wrong.)"); break;
+case fatal_message: puts("(That was a fatal error, my friend.)");
+} /* there are no other cases */
+
+@ When there is no way to recover from an error, the |fatal| subroutine is
+invoked. This happens most often when |overflow| occurs.
+
+The two parameters to |fatal| are strings that are essentially
+concatenated to print the final error message.
+
+@c void
+fatal(
+ const char *s,const char *t)
+{
+ if (*s) err_print(s);
+ err_print(t);
+ history=fatal_message; exit(wrap_up());
+}
+
+@ An overflow stop occurs if \.{CWEB}'s tables aren't large enough.
+
+@c void
+overflow(
+ const char *t)
+{
+ printf("\n! Sorry, %s capacity exceeded",t); fatal("","");
+}
+@.Sorry, capacity exceeded@>
+
+@ Sometimes the program's behavior is far different from what it should be,
+and \.{CWEB} prints an error message that is really for the \.{CWEB}
+maintenance person, not the user. In such cases the program says
+|confusion("indication of where we are")|.
+
+@** Command line arguments.
+The user calls \.{CWEAVE} and \.{CTANGLE} with arguments on the command line.
+These are either file names or flags to be turned off (beginning with |"-"|)
+or flags to be turned on (beginning with |"+"|).
+The following globals are for communicating the user's desires to the rest
+of the program. The various file name variables contain strings with
+the names of those files. Most of the 128 flags are undefined but available
+for future extensions.
+
+@<Global var...@>=
+int argc; /* copy of |ac| parameter to |main| */
+char **argv; /* copy of |av| parameter to |main| */
+char C_file_name[max_file_name_length]; /* name of |C_file| */
+char tex_file_name[max_file_name_length]; /* name of |tex_file| */
+char idx_file_name[max_file_name_length]; /* name of |idx_file| */
+char scn_file_name[max_file_name_length]; /* name of |scn_file| */
+boolean flags[128]; /* an option for each 7-bit code */
+
+@ The |flags| will be initially |false|. Some of them are set to~|true| before
+scanning the arguments; if additional flags are |true| by default they
+should be set before calling |common_init|.
+
+@<Set the default options common to \.{CTANGLE} and \.{CWEAVE}@>=
+show_banner=show_happiness=show_progress=make_xrefs=true;@/
+show_stats=false;
+
+@ We now must look at the command line arguments and set the file names
+accordingly. At least one file name must be present: the \.{CWEB}
+file. It may have an extension, or it may omit the extension to get |".w"| or
+|".web"| added. The \TEX/ output file name is formed by replacing the \.{CWEB}
+file name extension by |".tex"|, and the \CEE/ file name by replacing
+the extension by |".c"|, after removing the directory name (if any).
+
+If there is a second file name present among the arguments, it is the
+change file, again either with an extension or without one to get |".ch"|.
+An omitted change file argument means that |"/dev/null"| should be used,
+when no changes are desired.
+@^system dependencies@>
+
+If there's a third file name, it will be the output file.
+
+@c
+static void
+scan_args(void)
+{
+ char *dot_pos; /* position of |'.'| in the argument */
+ char *name_pos; /* file name beginning, sans directory */
+ register char *s; /* register for scanning strings */
+ boolean found_web=false,found_change=false,found_out=false;
+ /* have these names been seen? */
+
+ strcpy(change_file_name,"/dev/null");
+ while (--argc > 0) {
+ if ((**(++argv)=='-'||**argv=='+')&&*(*argv+1)) @<Handle flag argument@>@;
+ else {
+ s=name_pos=*argv;@+dot_pos=NULL;
+ while (*s) {
+ if (*s=='.') dot_pos=s++;
+ else if (*s=='/') dot_pos=NULL,name_pos=++s;
+ else s++;
+ }
+ if (!found_web) @<Make
+ |web_file_name|, |tex_file_name|, and |C_file_name|@>@;
+ else if (!found_change) @<Make |change_file_name| from |fname|@>@;
+ else if (!found_out) @<Override |tex_file_name| and |C_file_name|@>@;
+ else @<Print usage error message and quit@>@;
+ }
+ }
+ if (!found_web) @<Print usage error message and quit@>@;
+}
+
+@ @<Pred...@>=@+static void scan_args(void);
+
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|. If this file can't be opened, we prepare an
+|alt_web_file_name| by adding |"web"| after the dot.
+The other file names come from adding other things
+after the dot. We must check that there is enough room in
+|web_file_name| and the other arrays for the argument.
+
+@<Make |web_file_name|...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL)
+ sprintf(web_file_name,"%s.w",*argv);
+ else {
+ strcpy(web_file_name,*argv);
+ *dot_pos=0; /* string now ends where the dot was */
+ }
+ sprintf(alt_web_file_name,"%s.web",*argv);
+ sprintf(tex_file_name,"%s.tex",name_pos); /* strip off directory name */
+ sprintf(idx_file_name,"%s.idx",name_pos);
+ sprintf(scn_file_name,"%s.scn",name_pos);
+ sprintf(C_file_name,"%s.c",name_pos);
+ found_web=true;
+}
+
+@ @<Make |change_file_name|...@>=
+{
+ if (strcmp(*argv,"-")!=0) {
+ if (s-*argv > max_file_name_length-4)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL)
+ sprintf(change_file_name,"%s.ch",*argv);
+ else strcpy(change_file_name,*argv);
+ }
+ found_change=true;
+}
+
+@ @<Override...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>@;
+ if (dot_pos==NULL) {
+ sprintf(tex_file_name,"%s.tex",*argv);
+ sprintf(idx_file_name,"%s.idx",*argv);
+ sprintf(scn_file_name,"%s.scn",*argv);
+ sprintf(C_file_name,"%s.c",*argv);
+ } else {
+ strcpy(tex_file_name,*argv);
+ strcpy(C_file_name,*argv);
+ if (make_xrefs) { /* indexes will be generated */
+ *dot_pos=0;
+ sprintf(idx_file_name,"%s.idx",*argv);
+ sprintf(scn_file_name,"%s.scn",*argv);
+ }
+ }
+ found_out=true;
+}
+
+@ @d flag_change (**argv!='-')
+@<Handle flag...@>=
+{
+ for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
+ flags[(eight_bits)*dot_pos]=flag_change;
+}
+
+@ @<Print usage error message and quit@>=
+{
+if (program==ctangle)
+ fatal(
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+ ,"");
+@.Usage:@>
+else fatal(
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+ ,"");
+}
+
+@ @<Complain about arg...@>= fatal("! Filename too long\n", *argv);
+@.Filename too long@>
+
+@** Output. Here is the code that opens the output file:
+@^system dependencies@>
+
+@<Global var...@>=
+FILE *C_file; /* where output of \.{CTANGLE} goes */
+FILE *tex_file; /* where output of \.{CWEAVE} goes */
+FILE *idx_file; /* where index from \.{CWEAVE} goes */
+FILE *scn_file; /* where list of sections from \.{CWEAVE} goes */
+FILE *active_file; /* currently active file for \.{CWEAVE} output */
+
+@ @<Scan arguments and open output files@>=
+scan_args();
+if (program==ctangle) {
+ if ((C_file=fopen(C_file_name,"wb"))==NULL)
+ fatal("! Cannot open output file ", C_file_name);
+@.Cannot open output file@>
+}
+else {
+ if ((tex_file=fopen(tex_file_name,"wb"))==NULL)
+ fatal("! Cannot open output file ", tex_file_name);
+}
+
+@** Index.
diff --git a/Build/source/texk/web2c/cwebdir/ctang-bs.ch b/Build/source/texk/web2c/cwebdir/ctang-bs.ch
new file mode 100644
index 00000000000..55cc27cd00e
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-bs.ch
@@ -0,0 +1,192 @@
+Changes for CTANGLE for MSDOS and Borland C++ 3.1 using the following
+options (and perhaps others):
+
+ -mc -w-pro -Ff=5000 -Z- -O-p
+
+The options -Z- and -O-p explicitly turn off optimizations that break
+the code. (See makefile.bs.)
+
+The main purpose of these changes is to support MSDOS with full-size arrays
+by using "huge" pointers.
+
+(This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94;
+ revised 24 Jul 94.)
+
+
+@x Section 1.
+The ``banner line'' defined here should be changed whenever \.{CTANGLE}
+is modified.
+
+@d banner "This is CTANGLE (Version 4.2)"
+@y
+The ``banner line'' defined here should be changed whenever \.{CTANGLE}
+is modified.
+
+@d banner "This is CTANGLE (Version 4.2pc/big)"
+@z
+
+
+@x Section 9.
+ for section names */
+
+@<Common code...@>=
+typedef struct name_info {
+ char *byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ void *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char byte_mem[]; /* characters of names */
+extern char *byte_mem_end; /* end of |byte_mem| */
+extern char *byte_ptr; /* first unused position in |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+@y
+ for section names */
+
+@f huge extern
+
+@<Common code...@>=
+typedef struct name_info {
+ char huge* byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ union {
+ char *equiv_member;
+ char huge* xref_member;
+ } ptr_union; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char huge byte_mem[]; /* characters of names */
+extern char huge* byte_mem_end; /* end of |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern char huge* byte_ptr; /* first unused position in |byte_mem| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+@z
+
+
+@x Section 17.
+@ The following parameters were sufficient in the original \.{WEB} to
+handle \TEX/, so they should be sufficient for most applications of
+\.{CWEB}.
+
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+ index entries, and section names */
+@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */
+@d max_names 10239 /* number of identifiers, strings, section names;
+ must be less than 10240 */
+@d max_sections 4000 /* greater than the total number of sections */
+@d max_texts 10239 /* number of replacement texts, must be less than 10240 */
+@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */
+@d stack_size 500 /* number of simultaneous levels of macro expansion */
+@d buf_size 1000 /* maximum length of input line, plus one */
+@y
+@ The following parameters were sufficient in the original \.{WEB} to
+handle \TEX/, so they should be sufficient for most applications of
+\.{CWEB}.
+
+(This is a modified version of \.{CTANGLE}, and in fact one of the parameters
+has been reduced in value. The parameter |max_toks|
+has been reduced from 270000 [which
+was sufficient to handle \TEX/] to
+170000, so that \.{CTANGLE}
+may be run on {\mc MSDOS}
+systems that are tight on memory. Consider, for
+instance, an 80286-based machine with several TSRs and drivers, trying
+to run \.{CTANGLE} from a makefile.)
+
+@d max_bytes 90000 /* the number of bytes in identifiers,
+ index entries, and section names */
+@d max_toks 170000 /* number of bytes in compressed \CEE/ code */
+@d max_names 4000 /* number of identifiers, strings, section names;
+ must be less than 10240 */
+@d max_sections 4000 /* greater than the total number of sections */
+@d max_texts 2500 /* number of replacement texts, must be less than 10240 */
+@d longest_name 10000 /* file and section names and section texts shouldn't be longer than this */
+@d stack_size 50 /* number of simultaneous levels of macro expansion */
+@d buf_size 100 /* for \.{CWEAVE} */
+@z
+
+
+@x Section 16.
+ eight_bits *tok_start; /* pointer into |tok_mem| */
+ sixteen_bits text_link; /* relates replacement texts */
+} text;
+typedef text *text_pointer;
+@y
+ eight_bits huge* tok_start; /* pointer into |tok_mem| */
+ sixteen_bits text_link; /* relates replacement texts */
+} text;
+typedef text *text_pointer;
+@z
+
+
+@x Section 17.
+static eight_bits tok_mem[max_toks];
+static eight_bits *tok_mem_end=tok_mem+max_toks-1;
+static eight_bits *tok_ptr; /* first unused position in |tok_mem| */
+@y
+static eight_bits huge tok_mem[max_toks];
+static eight_bits huge* tok_mem_end;
+static eight_bits huge* tok_ptr; /* first unused position in |tok_mem| */
+@z
+
+
+@x Section 18.
+text_info->tok_start=tok_ptr=tok_mem;
+text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
+ /* this makes replacement text 0 of length zero */
+@y
+tok_mem_end=tok_mem+max_toks-1;
+text_info->tok_start=tok_ptr=tok_mem;
+text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
+ /* this makes replacement text 0 of length zero */
+@z
+
+
+@x Section 19.
+@d equiv equiv_or_xref /* info corresponding to names */
+@y
+@d equiv ptr_union.equiv_member /* info corresponding to names */
+@z
+
+
+@x Section 27.
+ eight_bits *end_field; /* ending location of replacement text */
+ eight_bits *byte_field; /* present location within replacement text */
+@y
+ eight_bits huge* end_field; /* ending location of replacement text */
+ eight_bits huge* byte_field; /* present location within replacement text */
+@z
+
+
+@x Section 49.
+out_char(
+eight_bits cur_char)
+{
+ char *j, *k; /* pointer into |byte_mem| */
+@y
+out_char(cur_char)
+eight_bits cur_char;
+{
+ char huge* j, huge* k; /* pointer into |byte_mem| */
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctang-man.ch b/Build/source/texk/web2c/cwebdir/ctang-man.ch
new file mode 100644
index 00000000000..5b4d06c88b1
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-man.ch
@@ -0,0 +1,22 @@
+Change file to help make Appendix E of the full CWEB manual
+@x
+\def\botofcontents{\vfill
+\noindent
+Copyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth
+\bigskip\noindent
+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.
+
+\smallskip\noindent
+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.
+}
+@y
+\def\botofcontents{\vfill\titlefalse}
+\def\contentspagenumber{66}
+\def\title{APPENDIX E: CTANGLE}
+\let\K=\leftarrow
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctang-pc.ch b/Build/source/texk/web2c/cwebdir/ctang-pc.ch
new file mode 100644
index 00000000000..ddf281b3fc6
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-pc.ch
@@ -0,0 +1,24 @@
+This is the change file for CWEB's CTANGLE under DOS
+(Contributed by Lee Wittenberg, March 1993)
+
+Changes necessary for compiling with Borland C/C++
+Use compilation switches -mc -w-pro -Ff=5000
+
+Note: The changes to section 4 are not necessary if using a compiler
+that allows >64K arrays. If you need lots of bytes and toks, try the
+alternate change files with -bs suffix instead of -pc.
+
+@x section 1
+@d banner "This is CTANGLE (Version 4.2)"
+@y
+@d banner "This is CTANGLE (Version 4.2pc)"
+@z
+@x section 4
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+ index entries, and section names */
+@d max_toks 1000000 /* number of bytes in compressed \CEE/ code */
+@y (note that CWEAVE itself needs only about 42K toks)
+@d max_bytes (unsigned)60000 /* the number of bytes in identifiers,
+ index entries, and section names */
+@d max_toks (unsigned)60000 /* number of bytes in compressed \CEE/ code */
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctang-ql.ch b/Build/source/texk/web2c/cwebdir/ctang-ql.ch
new file mode 100644
index 00000000000..64f0e81a723
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-ql.ch
@@ -0,0 +1,25 @@
+This is the change file for CWEB's CTANGLE under QDOS/SMSQ
+(Contributed by Robert H. Klein, September 1994)
+
+This change file is intended for use with C68 v4.13 (or later).
+compile with
+ex <dev_>cc;"-v -h -c -=500000 ctangle_c"
+
+
+@x
+\def\title{CTANGLE (Version 4.2)}
+@y
+\def\title{CTANGLE (QL Version 4.2)}
+@z
+
+@x section 1
+@d banner "This is CTANGLE (Version 4.2)"
+@y
+@d banner "This is CTANGLE (QL Version 4.2)"
+@z
+
+@x
+@i common.h
+@y
+@i common_h
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctang-vms.ch b/Build/source/texk/web2c/cwebdir/ctang-vms.ch
new file mode 100644
index 00000000000..5686c66b9ad
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-vms.ch
@@ -0,0 +1,35 @@
+This is the change file for CWEB's CTANGLE for VAX/VMS.
+
+created:
+ 01-FEB-1992 ST (Stephan Trebels <trebels@ams02.dnet.gwdg.de>)
+ > include ctype,stdio from textlibrary SYS$SHARE:VAXCDEF.TLB
+ > change banner line to include (VAX/VMS)
+ ? will someone make a CLD interface? (should be easy)
+
+(also modified by Don Knuth to keep version numbers uptodate)
+(these changes not necessary for initial bootstrapping)
+
+@x section 1 (01-FEB-1992 ST)
+@d banner "This is CTANGLE (Version 4.2)"
+@y
+@d banner "This is CTANGLE (VAX/VMS Version 4.2)"
+@z
+
+@x section 3 (01-FEB-1992 ST)
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
+@y
+#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */
+ /* VMS searches text libraries faster */
+#include stdbool /* definition of |@!bool|, |@!true| and |@!false| */
+#include stddef /* definition of |@!ptrdiff_t| */
+#include stdint /* definition of |@!uint8_t| and |@!uint16_t| */
+#include stdlib /* definition of |@!getenv| and |@!exit| */
+#include stdio /* definition of |@!printf| and friends */
+#include string /* definition of |@!strlen|, |@!strcmp| and so on */
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctang-w2c.ch b/Build/source/texk/web2c/cwebdir/ctang-w2c.ch
new file mode 100644
index 00000000000..4fcbe7b1607
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-w2c.ch
@@ -0,0 +1,481 @@
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
+
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
+
+@q This stripped change file {comm,ctang,cweav,ctwill,cwebman}-w2c.ch @>
+@q has been created from the elaborate set of change files @>
+@q {comm,ctang,cweav,cwebman}-patch.ch, @>
+@q {comm,cweav,cwebman}-extensions.ch, {comm,ctang,cweav}-output.ch, @>
+@q {comm,ctang,cweav}-i18n.ch, and cweav-twill.ch for CTWILL, and @>
+@q {comm,ctang,cweav,ctwill,cwebman}-texlive.ch with the 'tie' processor @>
+@q and is used as a monolithic changefile for {common,ctangle,cweave}.w @>
+@q and cwebman.tex in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
+\def\title{CTANGLE (Version 4.2)}
+@y
+\def\title{CTANGLE (Version 4.2 [\TeX~Live])}
+@z
+
+@x
+ \centerline{(Version 4.2)}
+@y
+ \centerline{(Version 4.2 [\TeX~Live])}
+@z
+
+@x
+\def\botofcontents{\vfill
+@y
+\def\covernote{\vbox{%
+@z
+
+@x
+}
+@y
+}}\datecontentspage
+@z
+
+@x
+@d banner "This is CTANGLE (Version 4.2)"
+@y
+@d banner "This is CTANGLE, Version 4.2"
+ /* will be extended by the \TeX~Live |versionstring| */
+@z
+
+@x
+ if (show_banner) puts(banner); /* print a ``banner line'' */
+@y
+ if (show_banner) cb_show_banner(); /* print a ``banner line'' */
+@z
+
+@x
+@i common.h
+@y
+@i comm-w2c.h
+@z
+
+@x
+ if (tok_ptr+2>tok_mem_end) overflow("token");
+@y
+ if (tok_ptr+2>tok_mem_end) overflow(_("token"));
+@z
+
+@x
+ if (stack_ptr==stack_end) overflow("stack");
+@y
+ if (stack_ptr==stack_end) overflow(_("stack"));
+@z
+
+@x
+ fputs("\n! Not present: <",stdout);
+@y
+ fputs(_("\n! Not present: <"),stdout);
+@z
+
+@x
+ overflow("output files");
+@y
+ overflow(_("output files"));
+@z
+
+@x
+ fputs("\n! No program text was specified.",stdout); mark_harmless;
+@y
+ fputs(_("\n! No program text was specified."),stdout); mark_harmless;
+@z
+
+@x
+ printf("\nWriting the output file (%s):",C_file_name);
+@y
+ printf(_("\nWriting the output file (%s):"),C_file_name);
+@z
+
+@x
+ fputs("\nWriting the output files:",stdout);
+@y
+ fputs(_("\nWriting the output files:"),stdout);
+@z
+
+@x
+ fputs("Done.",stdout);
+@y
+ fputs(_("Done."),stdout);
+@z
+
+@x
+@<Write all the named output files@>=
+for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
+ an_output_file--;
+ sprint_section_name(output_file_name,*an_output_file);
+ fclose(C_file);
+ C_file=fopen(output_file_name,"wb");
+ if (C_file ==0) fatal("! Cannot open output file ",output_file_name);
+@.Cannot open output file@>
+ if (show_progress) { printf("\n(%s)",output_file_name); update_terminal; }
+ cur_line=1;
+ stack_ptr=stack+1;
+ cur_name= (*an_output_file);
+ cur_repl= (text_pointer)cur_name->equiv;
+ cur_byte=cur_repl->tok_start;
+ cur_end=(cur_repl+1)->tok_start;
+ while (stack_ptr > stack) get_output();
+ flush_buffer();
+}
+@y
+@<Write all the named output files@>=
+fclose(C_file); C_file=NULL;
+@<Update the primary result when it has changed@>@;
+for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
+ an_output_file--;
+ sprint_section_name(output_file_name,*an_output_file);
+ if ((C_file=fopen(output_file_name,"a"))==NULL)
+ fatal(_("! Cannot open output file "),output_file_name);
+@.Cannot open output file@>
+ else fclose(C_file); /* Test accessability */
+ if((C_file=fopen(check_file_name,"wb"))==NULL)
+ fatal(_("! Cannot open output file "),check_file_name);
+ if (show_progress) { printf("\n(%s)",output_file_name); update_terminal; }
+ cur_line=1;
+ stack_ptr=stack+1;
+ cur_name= (*an_output_file);
+ cur_repl= (text_pointer)cur_name->equiv;
+ cur_byte=cur_repl->tok_start;
+ cur_end=(cur_repl+1)->tok_start;
+ while (stack_ptr > stack) get_output();
+ flush_buffer(); fclose(C_file); C_file=NULL;
+ @<Update the secondary results when they have changed@>@;
+}
+strcpy(check_file_name,""); /* We want to get rid of the temporary file */
+@z
+
+@x
+ else if (a<050000) { confusion("macro defs have strange char");}
+@y
+ else if (a<050000) { confusion(_("macro defs have strange char"));}
+@z
+
+@x
+ err_print("! Input ended in mid-comment");
+@y
+ err_print(_("! Input ended in mid-comment"));
+@z
+
+@x
+ err_print("! Section name ended in mid-comment"); loc--;
+@y
+ err_print(_("! Section name ended in mid-comment")); loc--;
+@z
+
+@x
+ err_print("! String didn't end"); loc=limit; break;
+@y
+ err_print(_("! String didn't end")); loc=limit; break;
+@z
+
+@x
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@y
+ err_print(_("! Input ended in middle of string")); loc=buffer; break;
+@z
+
+@x
+ fputs("\n! String too long: ",stdout);
+@y
+ fputs(_("\n! String too long: "),stdout);
+@z
+
+@x
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+ case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
+
+@x
+ err_print("! Double @@ should be used in control text");
+@y
+ err_print(_("! Double @@ should be used in control text"));
+@z
+
+@x
+ err_print("! Double @@ should be used in ASCII constant");
+@y
+ err_print(_("! Double @@ should be used in ASCII constant"));
+@z
+
+@x
+ err_print("! String didn't end"); loc=limit-1; break;
+@y
+ err_print(_("! String didn't end")); loc=limit-1; break;
+@z
+
+@x
+ err_print("! Input ended in section name");
+@y
+ err_print(_("! Input ended in section name"));
+@z
+
+@x
+ fputs("\n! Section name too long: ",stdout);
+@y
+ fputs(_("\n! Section name too long: "),stdout);
+@z
+
+@x
+ err_print("! Section name didn't end"); break;
+@y
+ err_print(_("! Section name didn't end")); break;
+@z
+
+@x
+ err_print("! Nesting of section names not allowed"); break;
+@y
+ err_print(_("! Nesting of section names not allowed")); break;
+@z
+
+@x
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@y
+ if (loc>=limit) err_print(_("! Verbatim string didn't end"));
+@z
+
+@x
+@d app_repl(c) {if (tok_ptr==tok_mem_end) overflow("token"); *tok_ptr++=c;}
+@y
+@d app_repl(c) {if (tok_ptr==tok_mem_end) overflow(_("token")); *tok_ptr++=c;}
+@z
+
+@x
+ if (text_ptr>text_info_end) overflow("text");
+@y
+ if (text_ptr>text_info_end) overflow(_("text"));
+@z
+
+@x
+case output_defs_code: if (t!=section_name) err_print("! Misplaced @@h");
+@y
+case output_defs_code: if (t!=section_name) err_print(_("! Misplaced @@h"));
+@z
+
+@x
+ err_print("! @@d, @@f and @@c are ignored in C text"); continue;
+@y
+ err_print(_("! @@d, @@f and @@c are ignored in C text")); continue;
+@z
+
+@x
+ if (*try_loc=='=') err_print ("! Missing `@@ ' before a named section");
+@y
+ if (*try_loc=='=') err_print (_("! Missing `@@ ' before a named section"));
+@z
+
+@x
+ else err_print("! Double @@ should be used in string");
+@y
+ else err_print(_("! Double @@ should be used in string"));
+@z
+
+@x
+ default: err_print("! Unrecognized escape sequence");
+@y
+ default: err_print(_("! Unrecognized escape sequence"));
+@z
+
+@x
+ err_print("! Definition flushed, must start with identifier");
+@y
+ err_print(_("! Definition flushed, must start with identifier"));
+@z
+
+@x
+ err_print("! Double @@ should be used in control text");
+@y
+ err_print(_("! Double @@ should be used in control text"));
+@z
+
+@x
+ default: err_print("! Double @@ should be used in limbo");
+@y
+ default: err_print(_("! Double @@ should be used in limbo"));
+@z
+
+@x
+ err_print("! Improper hex number following @@l");
+@y
+ err_print(_("! Improper hex number following @@l"));
+@z
+
+@x
+ err_print("! Replacement string in @@l too long");
+@y
+ err_print(_("! Replacement string in @@l too long"));
+@z
+
+@x
+ puts("\nMemory usage statistics:");
+ printf("%ld names (out of %ld)\n",
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf("%ld replacement texts (out of %ld)\n",
+ (ptrdiff_t)(text_ptr-text_info),(long)max_texts);
+ printf("%ld bytes (out of %ld)\n",
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ printf("%ld tokens (out of %ld)\n",
+@y
+ puts(_("\nMemory usage statistics:"));
+ printf(_("%ld names (out of %ld)\n"),
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf(_("%ld replacement texts (out of %ld)\n"),
+ (ptrdiff_t)(text_ptr-text_info),(long)max_texts);
+ printf(_("%ld bytes (out of %ld)\n"),
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ printf(_("%ld tokens (out of %ld)\n"),
+@z
+
+@x
+@** Index.
+@y
+@** Extensions to \.{CWEB}. The following sections introduce new or improved
+features that have been created by numerous contributors over the course of a
+quarter century.
+
+Care has been taken to keep the original section numbering intact, so this new
+material should nicely integrate with the original ``\&{104.~Index}.''
+
+@* Output file update. Most \CEE/ projects are controlled by a
+\.{Makefile} that automatically takes care of the temporal dependecies
+between the different source modules. It is suitable that \.{CWEB} doesn't
+create new output for all existing files, when there are only changes to
+some of them. Thus the \.{make} process will only recompile those modules
+where necessary. The idea and basic implementation of this mechanism can
+be found in the program \.{NUWEB} by Preston Briggs, to whom credit is due.
+
+@<Update the primary result...@>=
+if((C_file=fopen(C_file_name,"r"))!=NULL) {
+ @<Set up the comparison of temporary output@>@;
+ @<Create the primary output depending on the comparison@>@;
+} else
+ rename(check_file_name,C_file_name); /* This was the first run */
+
+@ @<Set up the comparison of temporary output@>=
+ char x[BUFSIZ],y[BUFSIZ];
+ int x_size,y_size,comparison=false;
+
+ if((check_file=fopen(check_file_name,"r"))==NULL)
+ fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+
+ if (temporary_output) @<Compare the temporary output...@>@;
+
+ fclose(C_file); C_file=NULL;
+ fclose(check_file); check_file=NULL;
+
+@ We hope that this runs fast on most systems.
+
+@<Compare the temporary output to the previous output@>=
+do {
+ x_size = fread(x,1,BUFSIZ,C_file);
+ y_size = fread(y,1,BUFSIZ,check_file);
+ comparison = (x_size == y_size); /* Do not merge these statements! */
+ if(comparison) comparison = !memcmp(x,y,x_size);
+} while(comparison && !feof(C_file) && !feof(check_file));
+
+@ Note the superfluous call to |remove| before |rename|. We're using it to
+get around a bug in some implementations of |rename|.
+
+@<Create the primary output...@>=
+if(comparison)
+ remove(check_file_name); /* The output remains untouched */
+else {
+ remove(C_file_name);
+ rename(check_file_name,C_file_name);
+}
+
+@ The author of a \.{CWEB} program may want to write the \\{secondary} output
+instead of to a file (in \.{@@(...@@>}) to \.{/dev/null} or \.{/dev/stdout} or
+\.{/dev/stderr}. We must take care of the \\{temporary} output already written
+to a file and finally get rid of that file.
+
+@<Update the secondary results...@>=
+if(0==strcmp("/dev/stdout",output_file_name))
+ @<Redirect temporary output to \.{/dev/stdout}@>@;
+else if(0==strcmp("/dev/stderr",output_file_name))
+ @<Redirect temporary output to \.{/dev/stderr}@>@;
+else if(0==strcmp("/dev/null",output_file_name))
+ @<Redirect temporary output to \.{/dev/null}@>@;
+else { /* Hopefully a \\{regular} output file */
+ if((C_file=fopen(output_file_name,"r"))!=NULL) {
+ @<Set up the comparison of temporary output@>@;
+ @<Create the secondary output depending on the comparison@>@;
+ } else
+ rename(check_file_name,output_file_name); /* This was the first run */
+}
+
+@ Again, we use a call to |remove| before |rename|.
+
+@<Create the secondary output...@>=
+if(comparison)
+ remove(check_file_name); /* The output remains untouched */
+else {
+ remove(output_file_name);
+ rename(check_file_name,output_file_name);
+}
+
+@ Copy secondary output to |stdout|.
+
+@<Redirect temporary output to \.{/dev/stdout}@>={
+ @<Setup system redirection@>@;
+ do {
+ in_size = fread(in_buf,1,BUFSIZ,check_file);
+ in_buf[in_size]='\0';
+ fprintf(stdout,"%s",in_buf);
+ } while(!feof(check_file));@/
+ fclose(check_file); check_file=NULL;
+ @<Create the secondary output...@>@;
+}
+
+@ Copy secondary output to |stderr|.
+
+@<Redirect temporary output to \.{/dev/stderr}@>={
+ @<Setup system redirection@>@;
+ do {
+ in_size = fread(in_buf,1,BUFSIZ,check_file);
+ in_buf[in_size]='\0';
+ fprintf(stderr,"%s",in_buf);
+ } while(!feof(check_file));@/
+ fclose(check_file); check_file=NULL;
+ @<Create the secondary output...@>@;
+}
+
+@ No copying necessary, just remove the temporary output file.
+
+@<Redirect temporary output to \.{/dev/null}@>={
+ int comparison=true;
+ @<Create the secondary output...@>@;
+}
+
+@ @<Setup system redirection@>=
+char in_buf[BUFSIZ+1];
+int in_size,comparison=true;
+if((check_file=fopen(check_file_name,"r"))==NULL)
+ fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+
+@* Put ``version'' information in a single spot.
+Don't do this at home, kids! Push our local macro to the variable in \.{COMMON}
+for printing the |banner| and the |versionstring| from there.
+
+@d max_banner 50
+
+@<Common code...@>=
+extern char cb_banner[];
+
+@ @<Set init...@>=
+ strncpy(cb_banner,banner,max_banner-1);
+
+@** Index.
+@z
+
diff --git a/Build/source/texk/web2c/cwebdir/ctang-w32.ch b/Build/source/texk/web2c/cwebdir/ctang-w32.ch
new file mode 100644
index 00000000000..1c687e5eb67
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctang-w32.ch
@@ -0,0 +1,44 @@
+This is the change file for CWEB's CTANGLE under Win32
+(Contributed by Fabrice Popineau, February 2002)
+
+Changes necessary for compiling with Borland C/C++
+
+@x section 1
+@d banner "This is CTANGLE (Version 4.2)"
+@y
+@d banner "This is CTANGLE (Version 4.2win32)"
+@z
+
+@x
+boolean names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */
+@y
+boolean __cdecl names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */
+@z
+
+@x
+void
+init_node(
+name_pointer node)
+{
+ node->equiv=(void *)text_info;
+}
+void
+init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+}
+@y
+void
+init_node(
+name_pointer node)
+{
+ node->equiv=(void *)text_info;
+}
+void __cdecl
+init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+}
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctangle.c b/Build/source/texk/web2c/cwebdir/ctangle.c
new file mode 100644
index 00000000000..d955da9d573
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctangle.c
@@ -0,0 +1,1626 @@
+/*1:*/
+#line 66 "ctangle.w"
+
+/*4:*/
+#line 46 "common.h"
+
+#include <ctype.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/*:4*/
+#line 67 "ctangle.w"
+
+#define banner "This is CTANGLE (Version 4.2)" \
+
+#define ctangle false
+#define cweave true \
+
+#define and_and 04
+#define lt_lt 020
+#define gt_gt 021
+#define plus_plus 013
+#define minus_minus 01
+#define minus_gt 031
+#define non_eq 032
+#define lt_eq 034
+#define gt_eq 035
+#define eq_eq 036
+#define or_or 037
+#define dot_dot_dot 016
+#define colon_colon 06
+#define period_ast 026
+#define minus_gt_ast 027 \
+
+#define xisalpha(c) (isalpha((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisdigit(c) (isdigit((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisspace(c) (isspace((eight_bits) c) &&((eight_bits) c<0200) )
+#define xislower(c) (islower((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisupper(c) (isupper((eight_bits) c) &&((eight_bits) c<0200) )
+#define xisxdigit(c) (isxdigit((eight_bits) c) &&((eight_bits) c<0200) ) \
+
+#define max_include_depth 10 \
+
+#define max_file_name_length 1024
+#define cur_file file[include_depth]
+#define cur_file_name file_name[include_depth]
+#define cur_line line[include_depth]
+#define web_file file[0]
+#define web_file_name file_name[0] \
+
+#define length(c) (size_t) ((c+1) ->byte_start-(c) ->byte_start)
+#define print_id(c) term_write((c) ->byte_start,length((c) ) )
+#define llink link
+#define rlink dummy.Rlink
+#define root name_dir->rlink \
+ \
+
+#define spotless 0
+#define harmless_message 1
+#define error_message 2
+#define fatal_message 3
+#define mark_harmless {if(history==spotless) history= harmless_message;}
+#define mark_error history= error_message
+#define confusion(s) fatal("! This can't happen: ",s) \
+ \
+
+#define show_banner flags['b']
+#define show_progress flags['p']
+#define show_stats flags['s']
+#define show_happiness flags['h']
+#define make_xrefs flags['x'] \
+
+#define update_terminal fflush(stdout)
+#define new_line putchar('\n')
+#define putxchar putchar
+#define term_write(a,b) fflush(stdout) ,fwrite(a,sizeof(char) ,b,stdout)
+#define C_printf(c,a) fprintf(C_file,c,a)
+#define C_putc(c) putc(c,C_file) \
+
+#define max_bytes 1000000 \
+
+#define max_toks 1000000
+#define max_names 10239 \
+
+#define max_sections 4000
+#define max_texts 10239
+#define longest_name 10000
+#define stack_size 500
+#define buf_size 1000
+#define long_buf_size (buf_size+longest_name) \
+
+#define equiv equiv_or_xref \
+
+#define section_flag max_texts \
+
+#define string 02
+#define join 0177
+#define output_defs_flag (2*024000-1) \
+
+#define cur_end cur_state.end_field
+#define cur_byte cur_state.byte_field
+#define cur_name cur_state.name_field
+#define cur_repl cur_state.repl_field
+#define cur_section cur_state.section_field \
+
+#define section_number 0201
+#define identifier 0202 \
+
+#define normal 0
+#define num_or_id 1
+#define post_slash 2
+#define unbreakable 3
+#define verbatim 4 \
+
+#define max_files 256
+#define translit_length 10 \
+
+#define ignore 0
+#define ord 0302
+#define control_text 0303
+#define translit_code 0304
+#define output_defs_code 0305
+#define format_code 0306
+#define definition 0307
+#define begin_C 0310
+#define section_name 0311
+#define new_section 0312 \
+
+#define constant 03 \
+
+#define isxalpha(c) ((c) =='_'||(c) =='$') \
+
+#define ishigh(c) ((eight_bits) (c) > 0177) \
+ \
+
+#define compress(c) if(loc++<=limit) return c \
+
+#define macro 0
+#define app_repl(c) {if(tok_ptr==tok_mem_end) overflow("token") ;*tok_ptr++= c;} \
+
+
+#line 68 "ctangle.w"
+
+/*3:*/
+#line 37 "common.h"
+
+typedef bool boolean;
+typedef uint8_t eight_bits;
+typedef uint16_t sixteen_bits;
+extern boolean program;
+extern int phase;
+
+/*:3*//*5:*/
+#line 74 "common.h"
+
+extern char section_text[];
+extern char*section_text_end;
+extern char*id_first;
+extern char*id_loc;
+
+/*:5*//*6:*/
+#line 88 "common.h"
+
+extern char buffer[];
+extern char*buffer_end;
+extern char*loc;
+extern char*limit;
+
+/*:6*//*7:*/
+#line 105 "common.h"
+
+extern int include_depth;
+extern FILE*file[];
+extern FILE*change_file;
+extern char file_name[][max_file_name_length];
+
+extern char change_file_name[];
+extern int line[];
+extern int change_line;
+extern int change_depth;
+extern boolean input_has_ended;
+extern boolean changing;
+extern boolean web_file_open;
+
+/*:7*//*9:*/
+#line 125 "common.h"
+
+extern sixteen_bits section_count;
+extern boolean changed_section[];
+extern boolean change_pending;
+extern boolean print_where;
+
+/*:9*//*10:*/
+#line 139 "common.h"
+
+typedef struct name_info{
+char*byte_start;
+struct name_info*link;
+union{
+struct name_info*Rlink;
+
+char Ilk;
+}dummy;
+void*equiv_or_xref;
+}name_info;
+typedef name_info*name_pointer;
+typedef name_pointer*hash_pointer;
+extern char byte_mem[];
+extern char*byte_mem_end;
+extern char*byte_ptr;
+extern name_info name_dir[];
+extern name_pointer name_dir_end;
+extern name_pointer name_ptr;
+extern name_pointer hash[];
+extern hash_pointer hash_end;
+extern hash_pointer h;
+
+/*:10*//*12:*/
+#line 183 "common.h"
+
+extern int history;
+
+/*:12*//*14:*/
+#line 199 "common.h"
+
+extern int argc;
+extern char**argv;
+extern char C_file_name[];
+extern char tex_file_name[];
+extern char idx_file_name[];
+extern char scn_file_name[];
+extern boolean flags[];
+
+/*:14*//*15:*/
+#line 215 "common.h"
+
+extern FILE*C_file;
+extern FILE*tex_file;
+extern FILE*idx_file;
+extern FILE*scn_file;
+extern FILE*active_file;
+
+/*:15*/
+#line 69 "ctangle.w"
+
+/*19:*/
+#line 122 "ctangle.w"
+
+typedef struct{
+eight_bits*tok_start;
+sixteen_bits text_link;
+}text;
+typedef text*text_pointer;
+
+/*:19*//*31:*/
+#line 269 "ctangle.w"
+
+typedef struct{
+eight_bits*end_field;
+eight_bits*byte_field;
+name_pointer name_field;
+text_pointer repl_field;
+sixteen_bits section_field;
+}output_state;
+typedef output_state*stack_pointer;
+
+/*:31*/
+#line 70 "ctangle.w"
+
+/*20:*/
+#line 129 "ctangle.w"
+
+static text text_info[max_texts];
+static text_pointer text_info_end= text_info+max_texts-1;
+static text_pointer text_ptr;
+static eight_bits tok_mem[max_toks];
+static eight_bits*tok_mem_end= tok_mem+max_toks-1;
+static eight_bits*tok_ptr;
+
+/*:20*//*26:*/
+#line 198 "ctangle.w"
+
+static text_pointer last_unnamed;
+
+/*:26*//*32:*/
+#line 285 "ctangle.w"
+
+static output_state cur_state;
+
+static output_state stack[stack_size+1];
+static stack_pointer stack_end= stack+stack_size;
+static stack_pointer stack_ptr;
+
+/*:32*//*37:*/
+#line 361 "ctangle.w"
+
+static int cur_val;
+
+/*:37*//*42:*/
+#line 452 "ctangle.w"
+
+static eight_bits out_state;
+static boolean protect;
+
+/*:42*//*45:*/
+#line 483 "ctangle.w"
+
+static name_pointer output_files[max_files];
+static name_pointer*cur_out_file,*end_output_files,*an_output_file;
+static char cur_section_name_char;
+static char output_file_name[longest_name+1];
+
+/*:45*//*52:*/
+#line 582 "ctangle.w"
+
+static boolean output_defs_seen= false;
+
+/*:52*//*57:*/
+#line 691 "ctangle.w"
+
+static char translit[128][translit_length];
+
+/*:57*//*62:*/
+#line 770 "ctangle.w"
+
+static eight_bits ccode[256];
+
+/*:62*//*66:*/
+#line 830 "ctangle.w"
+
+static boolean comment_continues= false;
+
+/*:66*//*68:*/
+#line 869 "ctangle.w"
+
+static name_pointer cur_section_name;
+static boolean no_where;
+
+/*:68*//*82:*/
+#line 1182 "ctangle.w"
+
+static text_pointer cur_text;
+static eight_bits next_control;
+
+/*:82*/
+#line 71 "ctangle.w"
+
+/*8:*/
+#line 119 "common.h"
+
+extern boolean get_line(void);
+extern void check_complete(void);
+extern void reset_input(void);
+
+/*:8*//*11:*/
+#line 162 "common.h"
+
+extern boolean names_match(name_pointer,const char*,size_t,eight_bits);
+extern name_pointer id_lookup(const char*,const char*,char);
+
+extern name_pointer section_lookup(char*,char*,int);
+extern void init_node(name_pointer);
+extern void init_p(name_pointer,eight_bits);
+extern void print_prefix_name(name_pointer);
+extern void print_section_name(name_pointer);
+extern void sprint_section_name(char*,name_pointer);
+
+/*:11*//*13:*/
+#line 186 "common.h"
+
+extern int wrap_up(void);
+extern void err_print(const char*);
+extern void fatal(const char*,const char*);
+extern void overflow(const char*);
+
+/*:13*//*16:*/
+#line 223 "common.h"
+
+extern void common_init(void);
+extern void print_stats(void);
+
+/*:16*//*30:*/
+#line 241 "ctangle.w"
+static void store_two_bytes(sixteen_bits);
+
+/*:30*//*35:*/
+#line 324 "ctangle.w"
+
+static void push_level(name_pointer);
+static void pop_level(boolean);
+
+/*:35*//*39:*/
+#line 397 "ctangle.w"
+static void get_output(void);
+
+/*:39*//*44:*/
+#line 473 "ctangle.w"
+static void flush_buffer(void);
+
+/*:44*//*49:*/
+#line 549 "ctangle.w"
+static void phase_two(void);
+
+/*:49*//*53:*/
+#line 585 "ctangle.w"
+
+static void output_defs(void);
+static void out_char(eight_bits);
+
+/*:53*//*65:*/
+#line 810 "ctangle.w"
+
+static eight_bits skip_ahead(void);
+static boolean skip_comment(boolean);
+
+/*:65*//*70:*/
+#line 924 "ctangle.w"
+static eight_bits get_next(void);
+
+/*:70*//*84:*/
+#line 1208 "ctangle.w"
+static void scan_repl(eight_bits);
+
+/*:84*//*91:*/
+#line 1379 "ctangle.w"
+static void scan_section(void);
+
+/*:91*//*99:*/
+#line 1460 "ctangle.w"
+static void phase_one(void);
+
+/*:99*//*101:*/
+#line 1494 "ctangle.w"
+static void skip_limbo(void);
+
+/*:101*/
+#line 72 "ctangle.w"
+
+
+/*:1*//*2:*/
+#line 81 "ctangle.w"
+
+int main(
+int ac,
+char**av)
+{
+argc= ac;argv= av;
+program= ctangle;
+/*21:*/
+#line 137 "ctangle.w"
+
+text_info->tok_start= tok_ptr= tok_mem;
+text_ptr= text_info+1;text_ptr->tok_start= tok_mem;
+
+
+/*:21*//*23:*/
+#line 147 "ctangle.w"
+
+init_node(name_dir);
+
+/*:23*//*27:*/
+#line 201 "ctangle.w"
+last_unnamed= text_info;text_info->text_link= 0;
+
+/*:27*//*46:*/
+#line 493 "ctangle.w"
+
+cur_out_file= end_output_files= output_files+max_files;
+
+/*:46*//*58:*/
+#line 694 "ctangle.w"
+
+{
+int i;
+for(i= 0;i<128;i++)sprintf(translit[i],"X%02X",(unsigned int)(128+i));
+}
+
+/*:58*//*63:*/
+#line 773 "ctangle.w"
+{
+int c;
+for(c= 0;c<256;c++)ccode[c]= ignore;
+ccode[' ']= ccode['\t']= ccode['\n']= ccode['\v']= ccode['\r']= ccode['\f']
+= ccode['*']= new_section;
+ccode['@']= '@';ccode['=']= string;
+ccode['d']= ccode['D']= definition;
+ccode['f']= ccode['F']= ccode['s']= ccode['S']= format_code;
+ccode['c']= ccode['C']= ccode['p']= ccode['P']= begin_C;
+ccode['^']= ccode[':']= ccode['.']= ccode['t']= ccode['T']=
+ccode['q']= ccode['Q']= control_text;
+ccode['h']= ccode['H']= output_defs_code;
+ccode['l']= ccode['L']= translit_code;
+ccode['&']= join;
+ccode['<']= ccode['(']= section_name;
+ccode['\'']= ord;
+}
+
+/*:63*//*78:*/
+#line 1103 "ctangle.w"
+section_text[0]= ' ';
+
+/*:78*/
+#line 88 "ctangle.w"
+
+common_init();
+if(show_banner)puts(banner);
+phase_one();
+phase_two();
+return wrap_up();
+}
+
+/*:2*//*24:*/
+#line 153 "ctangle.w"
+
+boolean names_match(
+name_pointer p,
+const char*first,
+size_t l,
+eight_bits t)
+{(void)t;
+if(length(p)!=l)return false;
+return!strncmp(first,p->byte_start,l);
+}
+
+/*:24*//*25:*/
+#line 169 "ctangle.w"
+
+void
+init_node(
+name_pointer node)
+{
+node->equiv= (void*)text_info;
+}
+void
+init_p(name_pointer p,eight_bits t){(void)p;(void)t;}
+
+/*:25*//*29:*/
+#line 231 "ctangle.w"
+
+static void
+store_two_bytes(
+sixteen_bits x)
+{
+if(tok_ptr+2> tok_mem_end)overflow("token");
+*tok_ptr++= x>>8;
+*tok_ptr++= x&0377;
+}
+
+/*:29*//*34:*/
+#line 309 "ctangle.w"
+
+static void
+push_level(
+name_pointer p)
+{
+if(stack_ptr==stack_end)overflow("stack");
+*stack_ptr= cur_state;
+stack_ptr++;
+if(p!=NULL){
+cur_name= p;cur_repl= (text_pointer)p->equiv;
+cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;
+cur_section= 0;
+}
+}
+
+/*:34*//*36:*/
+#line 332 "ctangle.w"
+
+static void
+pop_level(
+boolean flag)
+{
+if(flag&&cur_repl->text_link<section_flag){
+cur_repl= cur_repl->text_link+text_info;
+cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;
+return;
+}
+stack_ptr--;
+if(stack_ptr> stack)cur_state= *stack_ptr;
+}
+
+/*:36*//*38:*/
+#line 368 "ctangle.w"
+
+static void
+get_output(void)
+{
+sixteen_bits a;
+restart:if(stack_ptr==stack)return;
+if(cur_byte==cur_end){
+cur_val= -((int)cur_section);
+pop_level(true);
+if(cur_val==0)goto restart;
+out_char(section_number);return;
+}
+a= *cur_byte++;
+if(out_state==verbatim&&a!=string&&a!=constant&&a!='\n')
+C_putc(a);
+else if(a<0200)out_char(a);
+else{
+a= (a-0200)*0400+*cur_byte++;
+switch(a/024000){
+case 0:cur_val= a;out_char(identifier);break;
+case 1:if(a==output_defs_flag)output_defs();
+else/*40:*/
+#line 402 "ctangle.w"
+
+{
+a-= 024000;
+if((a+name_dir)->equiv!=(void*)text_info)push_level(a+name_dir);
+else if(a!=0){
+fputs("\n! Not present: <",stdout);
+print_section_name(a+name_dir);err_print(">");
+
+}
+goto restart;
+}
+
+/*:40*/
+#line 389 "ctangle.w"
+
+break;
+default:cur_val= a-050000;if(cur_val> 0)cur_section= cur_val;
+out_char(section_number);
+}
+}
+}
+
+/*:38*//*43:*/
+#line 460 "ctangle.w"
+
+static void
+flush_buffer(void)
+{
+C_putc('\n');
+if(cur_line%100==0&&show_progress){
+printf(".");
+if(cur_line%500==0)printf("%d",cur_line);
+update_terminal;
+}
+cur_line++;
+}
+
+/*:43*//*48:*/
+#line 514 "ctangle.w"
+
+static void
+phase_two(void){
+web_file_open= false;
+cur_line= 1;
+/*33:*/
+#line 298 "ctangle.w"
+
+stack_ptr= stack+1;cur_name= name_dir;cur_repl= text_info->text_link+text_info;
+cur_byte= cur_repl->tok_start;cur_end= (cur_repl+1)->tok_start;cur_section= 0;
+
+/*:33*/
+#line 519 "ctangle.w"
+
+/*51:*/
+#line 578 "ctangle.w"
+
+if(!output_defs_seen)
+output_defs();
+
+/*:51*/
+#line 520 "ctangle.w"
+
+if(text_info->text_link==0&&cur_out_file==end_output_files){
+fputs("\n! No program text was specified.",stdout);mark_harmless;
+
+}
+else{
+if(cur_out_file==end_output_files){
+if(show_progress)
+printf("\nWriting the output file (%s):",C_file_name);
+}
+else{
+if(show_progress){
+fputs("\nWriting the output files:",stdout);
+
+printf(" (%s)",C_file_name);
+update_terminal;
+}
+if(text_info->text_link==0)goto writeloop;
+}
+while(stack_ptr> stack)get_output();
+flush_buffer();
+writeloop:/*50:*/
+#line 555 "ctangle.w"
+
+for(an_output_file= end_output_files;an_output_file> cur_out_file;){
+an_output_file--;
+sprint_section_name(output_file_name,*an_output_file);
+fclose(C_file);
+C_file= fopen(output_file_name,"wb");
+if(C_file==0)fatal("! Cannot open output file ",output_file_name);
+
+if(show_progress){printf("\n(%s)",output_file_name);update_terminal;}
+cur_line= 1;
+stack_ptr= stack+1;
+cur_name= (*an_output_file);
+cur_repl= (text_pointer)cur_name->equiv;
+cur_byte= cur_repl->tok_start;
+cur_end= (cur_repl+1)->tok_start;
+while(stack_ptr> stack)get_output();
+flush_buffer();
+}
+
+/*:50*/
+#line 541 "ctangle.w"
+
+if(show_happiness){
+if(show_progress)new_line;
+fputs("Done.",stdout);
+}
+}
+}
+
+/*:48*//*54:*/
+#line 589 "ctangle.w"
+
+static void
+output_defs(void)
+{
+sixteen_bits a;
+push_level(NULL);
+for(cur_text= text_info+1;cur_text<text_ptr;cur_text++)
+if(cur_text->text_link==0){
+cur_byte= cur_text->tok_start;
+cur_end= (cur_text+1)->tok_start;
+C_printf("%s","#define ");
+out_state= normal;
+protect= true;
+while(cur_byte<cur_end){
+a= *cur_byte++;
+if(cur_byte==cur_end&&a=='\n')break;
+if(out_state==verbatim&&a!=string&&a!=constant&&a!='\n')
+C_putc(a);
+
+else if(a<0200)out_char(a);
+else{
+a= (a-0200)*0400+*cur_byte++;
+if(a<024000){
+cur_val= a;out_char(identifier);
+}
+else if(a<050000){confusion("macro defs have strange char");}
+else{
+cur_val= a-050000;cur_section= cur_val;out_char(section_number);
+}
+
+}
+}
+protect= false;
+flush_buffer();
+}
+pop_level(false);
+}
+
+/*:54*//*55:*/
+#line 632 "ctangle.w"
+
+static void
+out_char(
+eight_bits cur_char)
+{
+char*j,*k;
+restart:
+switch(cur_char){
+case'\n':if(protect&&out_state!=verbatim)C_putc(' ');
+if(protect||out_state==verbatim)C_putc('\\');
+flush_buffer();if(out_state!=verbatim)out_state= normal;break;
+/*59:*/
+#line 700 "ctangle.w"
+
+case identifier:
+if(out_state==num_or_id)C_putc(' ');
+j= (cur_val+name_dir)->byte_start;
+k= (cur_val+name_dir+1)->byte_start;
+while(j<k){
+if((eight_bits)(*j)<0200)C_putc(*j);
+
+else C_printf("%s",translit[(eight_bits)(*j)-0200]);
+j++;
+}
+out_state= num_or_id;break;
+
+/*:59*/
+#line 643 "ctangle.w"
+
+/*60:*/
+#line 713 "ctangle.w"
+
+case section_number:
+if(cur_val> 0)C_printf("/*%d:*/",cur_val);
+else if(cur_val<0)C_printf("/*:%d*/",-cur_val);
+else if(protect){
+cur_byte+= 4;
+cur_char= '\n';
+goto restart;
+}else{
+sixteen_bits a;
+a= 0400**cur_byte++;
+a+= *cur_byte++;
+C_printf("\n#line %d \"",a);
+
+cur_val= *cur_byte++;
+cur_val= 0400*(cur_val-0200)+*cur_byte++;
+for(j= (cur_val+name_dir)->byte_start,k= (cur_val+name_dir+1)->byte_start;
+j<k;j++){
+if(*j=='\\'||*j=='"')C_putc('\\');
+C_putc(*j);
+}
+C_printf("%s","\"\n");
+}
+break;
+
+/*:60*/
+#line 644 "ctangle.w"
+
+/*56:*/
+#line 662 "ctangle.w"
+
+case plus_plus:C_putc('+');C_putc('+');out_state= normal;break;
+case minus_minus:C_putc('-');C_putc('-');out_state= normal;break;
+case minus_gt:C_putc('-');C_putc('>');out_state= normal;break;
+case gt_gt:C_putc('>');C_putc('>');out_state= normal;break;
+case eq_eq:C_putc('=');C_putc('=');out_state= normal;break;
+case lt_lt:C_putc('<');C_putc('<');out_state= normal;break;
+case gt_eq:C_putc('>');C_putc('=');out_state= normal;break;
+case lt_eq:C_putc('<');C_putc('=');out_state= normal;break;
+case non_eq:C_putc('!');C_putc('=');out_state= normal;break;
+case and_and:C_putc('&');C_putc('&');out_state= normal;break;
+case or_or:C_putc('|');C_putc('|');out_state= normal;break;
+case dot_dot_dot:C_putc('.');C_putc('.');C_putc('.');out_state= normal;
+break;
+case colon_colon:C_putc(':');C_putc(':');out_state= normal;break;
+case period_ast:C_putc('.');C_putc('*');out_state= normal;break;
+case minus_gt_ast:C_putc('-');C_putc('>');C_putc('*');out_state= normal;
+break;
+
+/*:56*/
+#line 645 "ctangle.w"
+
+case'=':case'>':C_putc(cur_char);C_putc(' ');
+out_state= normal;break;
+case join:out_state= unbreakable;break;
+case constant:if(out_state==verbatim){
+out_state= num_or_id;break;
+}
+if(out_state==num_or_id)C_putc(' ');out_state= verbatim;break;
+case string:if(out_state==verbatim)out_state= normal;
+else out_state= verbatim;break;
+case'/':C_putc('/');out_state= post_slash;break;
+case'*':if(out_state==post_slash)C_putc(' ');
+
+default:C_putc(cur_char);out_state= normal;break;
+}
+}
+
+/*:55*//*64:*/
+#line 794 "ctangle.w"
+
+static eight_bits
+skip_ahead(void)
+{
+eight_bits c;
+while(true){
+if(loc> limit&&(get_line()==false))return new_section;
+*(limit+1)= '@';
+while(*loc!='@')loc++;
+if(loc<=limit){
+loc++;c= ccode[(eight_bits)*loc];loc++;
+if(c!=ignore||*(loc-1)=='>')return c;
+}
+}
+}
+
+/*:64*//*67:*/
+#line 833 "ctangle.w"
+
+static boolean skip_comment(
+boolean is_long_comment)
+{
+char c;
+while(true){
+if(loc> limit){
+if(is_long_comment){
+if(get_line())return comment_continues= true;
+else{
+err_print("! Input ended in mid-comment");
+
+return comment_continues= false;
+}
+}
+else return comment_continues= false;
+}
+c= *(loc++);
+if(is_long_comment&&c=='*'&&*loc=='/'){
+loc++;return comment_continues= false;
+}
+if(c=='@'){
+if(ccode[(eight_bits)*loc]==new_section){
+err_print("! Section name ended in mid-comment");loc--;
+
+return comment_continues= false;
+}
+else loc++;
+}
+}
+}
+
+/*:67*//*69:*/
+#line 881 "ctangle.w"
+
+static eight_bits
+get_next(void)
+{
+static int preprocessing= 0;
+eight_bits c;
+while(true){
+if(loc> limit){
+if(preprocessing&&*(limit-1)!='\\')preprocessing= 0;
+if(get_line()==false)return new_section;
+else if(print_where&&!no_where){
+print_where= false;
+/*85:*/
+#line 1214 "ctangle.w"
+
+store_two_bytes(0150000);
+if(changing&&include_depth==change_depth){
+id_first= change_file_name;
+store_two_bytes((sixteen_bits)change_line);
+}else{
+id_first= cur_file_name;
+store_two_bytes((sixteen_bits)cur_line);
+}
+id_loc= id_first+strlen(id_first);
+{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
+app_repl(a_l%0400);}
+
+/*:85*/
+#line 893 "ctangle.w"
+
+}
+else return'\n';
+}
+c= *loc;
+if(comment_continues||(c=='/'&&(*(loc+1)=='*'||*(loc+1)=='/'))){
+skip_comment(comment_continues||*(loc+1)=='*');
+
+if(comment_continues)return'\n';
+else continue;
+}
+loc++;
+if(xisdigit(c)||c=='.')/*73:*/
+#line 964 "ctangle.w"
+{
+id_first= loc-1;
+if(*id_first=='.'&&!xisdigit(*loc))goto mistake;
+if(*id_first=='0'){
+if(*loc=='x'||*loc=='X'){
+loc++;while(xisxdigit(*loc))loc++;goto found;
+}
+}
+while(xisdigit(*loc))loc++;
+if(*loc=='.'){
+loc++;
+while(xisdigit(*loc))loc++;
+}
+if(*loc=='e'||*loc=='E'){
+if(*++loc=='+'||*loc=='-')loc++;
+while(xisdigit(*loc))loc++;
+}
+found:while(*loc=='u'||*loc=='U'||*loc=='l'||*loc=='L'
+||*loc=='f'||*loc=='F')loc++;
+id_loc= loc;
+return constant;
+}
+
+/*:73*/
+#line 905 "ctangle.w"
+
+else if(c=='\''||c=='"'
+||((c=='L'||c=='u'||c=='U')&&(*loc=='\''||*loc=='"'))
+||((c=='u'&&*loc=='8')&&(*(loc+1)=='\''||*(loc+1)=='"')))
+/*74:*/
+#line 992 "ctangle.w"
+{
+char delim= c;
+id_first= section_text+1;
+id_loc= section_text;*++id_loc= delim;
+if(delim=='L'||delim=='u'||delim=='U'){
+if(delim=='u'&&*loc=='8'){*++id_loc= *loc++;}
+delim= *loc++;*++id_loc= delim;
+}
+while(true){
+if(loc>=limit){
+if(*(limit-1)!='\\'){
+err_print("! String didn't end");loc= limit;break;
+
+}
+if(get_line()==false){
+err_print("! Input ended in middle of string");loc= buffer;break;
+
+}
+else if(++id_loc<=section_text_end)*id_loc= '\n';
+
+}
+if((c= *loc++)==delim){
+if(++id_loc<=section_text_end)*id_loc= c;
+break;
+}
+if(c=='\\'){
+if(loc>=limit)continue;
+if(++id_loc<=section_text_end)*id_loc= '\\';
+c= *loc++;
+}
+if(++id_loc<=section_text_end)*id_loc= c;
+}
+if(id_loc>=section_text_end){
+fputs("\n! String too long: ",stdout);
+
+term_write(section_text+1,25);
+err_print("...");
+}
+id_loc++;
+return string;
+}
+
+/*:74*/
+#line 909 "ctangle.w"
+
+else if(isalpha(c)||isxalpha(c)||ishigh(c))
+/*72:*/
+#line 957 "ctangle.w"
+{
+id_first= --loc;
+while(isalpha((eight_bits)*++loc)||isdigit((eight_bits)*loc)
+||isxalpha((eight_bits)*loc)||ishigh((eight_bits)*loc));
+id_loc= loc;return identifier;
+}
+
+/*:72*/
+#line 911 "ctangle.w"
+
+else if(c=='@')/*75:*/
+#line 1037 "ctangle.w"
+{
+c= ccode[(eight_bits)*loc++];
+switch(c){
+case ignore:continue;
+case translit_code:err_print("! Use @l in limbo only");continue;
+
+case control_text:while((c= skip_ahead())=='@');
+
+if(*(loc-1)!='>')
+err_print("! Double @ should be used in control text");
+
+continue;
+case section_name:
+cur_section_name_char= *(loc-1);
+/*77:*/
+#line 1085 "ctangle.w"
+{
+char*k;
+/*79:*/
+#line 1105 "ctangle.w"
+
+k= section_text;
+while(true){
+if(loc> limit&&get_line()==false){
+err_print("! Input ended in section name");
+
+loc= buffer+1;break;
+}
+c= *loc;
+/*80:*/
+#line 1129 "ctangle.w"
+
+if(c=='@'){
+c= *(loc+1);
+if(c=='>'){
+loc+= 2;break;
+}
+if(ccode[(eight_bits)c]==new_section){
+err_print("! Section name didn't end");break;
+
+}
+if(ccode[(eight_bits)c]==section_name){
+err_print("! Nesting of section names not allowed");break;
+
+}
+*(++k)= '@';loc++;
+}
+
+/*:80*/
+#line 1114 "ctangle.w"
+
+loc++;if(k<section_text_end)k++;
+if(xisspace(c)){
+c= ' ';if(*(k-1)==' ')k--;
+}
+*k= c;
+}
+if(k>=section_text_end){
+fputs("\n! Section name too long: ",stdout);
+
+term_write(section_text+1,25);
+printf("...");mark_harmless;
+}
+if(*k==' '&&k> section_text)k--;
+
+/*:79*/
+#line 1087 "ctangle.w"
+
+if(k-section_text> 3&&strncmp(k-2,"...",3)==0)
+cur_section_name= section_lookup(section_text+1,k-3,1);
+else cur_section_name= section_lookup(section_text+1,k,0);
+if(cur_section_name_char=='(')
+/*47:*/
+#line 497 "ctangle.w"
+
+{
+for(an_output_file= cur_out_file;
+an_output_file<end_output_files;an_output_file++)
+if(*an_output_file==cur_section_name)break;
+if(an_output_file==end_output_files){
+if(cur_out_file> output_files)
+*--cur_out_file= cur_section_name;
+else{
+overflow("output files");
+}
+}
+}
+
+/*:47*/
+#line 1093 "ctangle.w"
+
+return section_name;
+}
+
+/*:77*/
+#line 1051 "ctangle.w"
+
+case string:/*81:*/
+#line 1151 "ctangle.w"
+{
+id_first= loc++;*(limit+1)= '@';*(limit+2)= '>';
+while(*loc!='@'||*(loc+1)!='>')loc++;
+if(loc>=limit)err_print("! Verbatim string didn't end");
+
+id_loc= loc;loc+= 2;
+return string;
+}
+
+/*:81*/
+#line 1052 "ctangle.w"
+
+case ord:/*76:*/
+#line 1064 "ctangle.w"
+
+id_first= loc;
+if(*loc=='\\'){
+if(*++loc=='\'')loc++;
+}
+while(*loc!='\''){
+if(*loc=='@'){
+if(*(loc+1)!='@')
+err_print("! Double @ should be used in ASCII constant");
+
+else loc++;
+}
+loc++;
+if(loc> limit){
+err_print("! String didn't end");loc= limit-1;break;
+
+}
+}
+loc++;
+return ord;
+
+/*:76*/
+#line 1053 "ctangle.w"
+
+default:return c;
+}
+}
+
+/*:75*/
+#line 912 "ctangle.w"
+
+else if(xisspace(c)){
+if(!preprocessing||loc> limit)continue;
+
+else return' ';
+}
+else if(c=='#'&&loc==buffer+1)preprocessing= 1;
+mistake:/*71:*/
+#line 935 "ctangle.w"
+
+switch(c){
+case'+':if(*loc=='+')compress(plus_plus);break;
+case'-':if(*loc=='-'){compress(minus_minus);}
+else{if(*loc=='>'){if(*(loc+1)=='*'){loc++;compress(minus_gt_ast);}
+else compress(minus_gt);}}break;
+case'.':if(*loc=='*'){compress(period_ast);}
+else if(*loc=='.'&&*(loc+1)=='.'){
+loc++;compress(dot_dot_dot);
+}
+break;
+case':':if(*loc==':')compress(colon_colon);break;
+case'=':if(*loc=='=')compress(eq_eq);break;
+case'>':if(*loc=='='){compress(gt_eq);}
+else if(*loc=='>')compress(gt_gt);break;
+case'<':if(*loc=='='){compress(lt_eq);}
+else if(*loc=='<')compress(lt_lt);break;
+case'&':if(*loc=='&')compress(and_and);break;
+case'|':if(*loc=='|')compress(or_or);break;
+case'!':if(*loc=='=')compress(non_eq);break;
+}
+
+/*:71*/
+#line 919 "ctangle.w"
+
+return c;
+}
+}
+
+/*:69*//*83:*/
+#line 1186 "ctangle.w"
+
+static void
+scan_repl(
+eight_bits t)
+{
+sixteen_bits a;
+if(t==section_name){/*85:*/
+#line 1214 "ctangle.w"
+
+store_two_bytes(0150000);
+if(changing&&include_depth==change_depth){
+id_first= change_file_name;
+store_two_bytes((sixteen_bits)change_line);
+}else{
+id_first= cur_file_name;
+store_two_bytes((sixteen_bits)cur_line);
+}
+id_loc= id_first+strlen(id_first);
+{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
+app_repl(a_l%0400);}
+
+/*:85*/
+#line 1192 "ctangle.w"
+}
+while(true)switch(a= get_next()){
+/*86:*/
+#line 1227 "ctangle.w"
+
+case identifier:a= id_lookup(id_first,id_loc,0)-name_dir;
+app_repl((a/0400)+0200);
+app_repl(a%0400);break;
+case section_name:if(t!=section_name)goto done;
+else{
+/*87:*/
+#line 1260 "ctangle.w"
+{
+char*try_loc= loc;
+while(*try_loc==' '&&try_loc<limit)try_loc++;
+if(*try_loc=='+'&&try_loc<limit)try_loc++;
+while(*try_loc==' '&&try_loc<limit)try_loc++;
+if(*try_loc=='=')err_print("! Missing `@ ' before a named section");
+
+
+
+}
+
+/*:87*/
+#line 1233 "ctangle.w"
+
+a= cur_section_name-name_dir;
+app_repl((a/0400)+0250);
+app_repl(a%0400);
+/*85:*/
+#line 1214 "ctangle.w"
+
+store_two_bytes(0150000);
+if(changing&&include_depth==change_depth){
+id_first= change_file_name;
+store_two_bytes((sixteen_bits)change_line);
+}else{
+id_first= cur_file_name;
+store_two_bytes((sixteen_bits)cur_line);
+}
+id_loc= id_first+strlen(id_first);
+{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
+app_repl(a_l%0400);}
+
+/*:85*/
+#line 1237 "ctangle.w"
+break;
+}
+case output_defs_code:if(t!=section_name)err_print("! Misplaced @h");
+
+else{
+output_defs_seen= true;
+a= output_defs_flag;
+app_repl((a/0400)+0200);
+app_repl(a%0400);
+/*85:*/
+#line 1214 "ctangle.w"
+
+store_two_bytes(0150000);
+if(changing&&include_depth==change_depth){
+id_first= change_file_name;
+store_two_bytes((sixteen_bits)change_line);
+}else{
+id_first= cur_file_name;
+store_two_bytes((sixteen_bits)cur_line);
+}
+id_loc= id_first+strlen(id_first);
+{int a_l= id_lookup(id_first,id_loc,0)-name_dir;app_repl((a_l/0400)+0200);
+app_repl(a_l%0400);}
+
+/*:85*/
+#line 1246 "ctangle.w"
+
+}
+break;
+case constant:case string:
+/*88:*/
+#line 1271 "ctangle.w"
+
+app_repl(a);
+while(id_first<id_loc){
+if(*id_first=='@'){
+if(*(id_first+1)=='@')id_first++;
+else err_print("! Double @ should be used in string");
+
+}
+app_repl(*id_first++);
+}
+app_repl(a);break;
+
+/*:88*/
+#line 1250 "ctangle.w"
+
+case ord:
+/*89:*/
+#line 1287 "ctangle.w"
+{
+int c= (eight_bits)*id_first;
+if(c=='\\'){
+c= *++id_first;
+if(c>='0'&&c<='7'){
+c-= '0';
+if(*(id_first+1)>='0'&&*(id_first+1)<='7'){
+c= 8*c+*(++id_first)-'0';
+if(*(id_first+1)>='0'&&*(id_first+1)<='7'&&c<32)
+c= 8*c+*(++id_first)-'0';
+}
+}
+else switch(c){
+case't':c= '\t';break;
+case'n':c= '\n';break;
+case'b':c= '\b';break;
+case'f':c= '\f';break;
+case'v':c= '\v';break;
+case'r':c= '\r';break;
+case'a':c= '\7';break;
+case'?':c= '?';break;
+case'x':
+if(xisdigit(*(id_first+1)))c= *(++id_first)-'0';
+else if(xisxdigit(*(id_first+1))){
+++id_first;
+c= toupper((eight_bits)*id_first)-'A'+10;
+}
+if(xisdigit(*(id_first+1)))c= 16*c+*(++id_first)-'0';
+else if(xisxdigit(*(id_first+1))){
+++id_first;
+c= 16*c+toupper((eight_bits)*id_first)-'A'+10;
+}
+break;
+case'\\':c= '\\';break;
+case'\'':c= '\'';break;
+case'\"':c= '\"';break;
+default:err_print("! Unrecognized escape sequence");
+
+}
+}
+
+app_repl(constant);
+if(c>=100)app_repl('0'+c/100);
+if(c>=10)app_repl('0'+(c/10)%10);
+app_repl('0'+c%10);
+app_repl(constant);
+}
+break;
+
+/*:89*/
+#line 1252 "ctangle.w"
+
+case definition:case format_code:case begin_C:if(t!=section_name)goto done;
+else{
+err_print("! @d, @f and @c are ignored in C text");continue;
+
+}
+case new_section:goto done;
+
+/*:86*/
+#line 1197 "ctangle.w"
+
+case')':app_repl(a);
+if(t==macro)app_repl(' ');
+break;
+default:app_repl(a);
+}
+done:next_control= (eight_bits)a;
+if(text_ptr> text_info_end)overflow("text");
+cur_text= text_ptr;(++text_ptr)->tok_start= tok_ptr;
+}
+
+/*:83*//*90:*/
+#line 1346 "ctangle.w"
+
+static void
+scan_section(void)
+{
+name_pointer p;
+text_pointer q;
+sixteen_bits a;
+section_count++;no_where= true;
+if(*(loc-1)=='*'&&show_progress){
+printf("*%d",section_count);update_terminal;
+}
+next_control= 0;
+while(true){
+/*92:*/
+#line 1387 "ctangle.w"
+
+while(next_control<definition)
+
+if((next_control= skip_ahead())==section_name){
+loc-= 2;next_control= get_next();
+}
+
+/*:92*/
+#line 1360 "ctangle.w"
+
+if(next_control==definition){
+/*93:*/
+#line 1394 "ctangle.w"
+{
+while((next_control= get_next())=='\n');
+if(next_control!=identifier){
+err_print("! Definition flushed, must start with identifier");
+
+continue;
+}
+app_repl(((a= id_lookup(id_first,id_loc,0)-name_dir)/0400)+0200);
+
+app_repl(a%0400);
+if(*loc!='('){
+app_repl(string);app_repl(' ');app_repl(string);
+}
+scan_repl(macro);
+cur_text->text_link= macro;
+}
+
+/*:93*/
+#line 1362 "ctangle.w"
+
+continue;
+}
+if(next_control==begin_C){
+p= name_dir;break;
+}
+if(next_control==section_name){
+p= cur_section_name;
+/*94:*/
+#line 1419 "ctangle.w"
+
+while((next_control= get_next())=='+');
+if(next_control!='='&&next_control!=eq_eq)
+continue;
+
+/*:94*/
+#line 1370 "ctangle.w"
+
+break;
+}
+return;
+}
+no_where= print_where= false;
+/*95:*/
+#line 1424 "ctangle.w"
+
+/*96:*/
+#line 1429 "ctangle.w"
+
+store_two_bytes((sixteen_bits)(0150000+section_count));
+
+
+/*:96*/
+#line 1425 "ctangle.w"
+
+scan_repl(section_name);
+/*97:*/
+#line 1433 "ctangle.w"
+
+if(p==name_dir||p==0){
+(last_unnamed)->text_link= cur_text-text_info;last_unnamed= cur_text;
+}
+else if(p->equiv==(void*)text_info)p->equiv= (void*)cur_text;
+
+else{
+q= (text_pointer)p->equiv;
+while(q->text_link<section_flag)
+q= q->text_link+text_info;
+q->text_link= cur_text-text_info;
+}
+cur_text->text_link= section_flag;
+
+
+/*:97*/
+#line 1427 "ctangle.w"
+
+
+/*:95*/
+#line 1376 "ctangle.w"
+
+}
+
+/*:90*//*98:*/
+#line 1448 "ctangle.w"
+
+static void
+phase_one(void){
+phase= 1;
+section_count= 0;
+reset_input();
+skip_limbo();
+while(!input_has_ended)scan_section();
+check_complete();
+phase= 2;
+}
+
+/*:98*//*100:*/
+#line 1465 "ctangle.w"
+
+static void
+skip_limbo(void)
+{
+char c;
+while(true){
+if(loc> limit&&get_line()==false)return;
+*(limit+1)= '@';
+while(*loc!='@')loc++;
+if(loc++<=limit){
+c= *loc++;
+if(ccode[(eight_bits)c]==new_section)break;
+switch(ccode[(eight_bits)c]){
+case translit_code:/*102:*/
+#line 1496 "ctangle.w"
+
+while(xisspace(*loc)&&loc<limit)loc++;
+loc+= 3;
+if(loc> limit||!xisxdigit(*(loc-3))||!xisxdigit(*(loc-2))
+||(*(loc-3)>='0'&&*(loc-3)<='7')||!xisspace(*(loc-1)))
+err_print("! Improper hex number following @l");
+
+else{
+unsigned int i;
+char*beg;
+sscanf(loc-3,"%x",&i);
+while(xisspace(*loc)&&loc<limit)loc++;
+beg= loc;
+while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_'))loc++;
+if(loc-beg>=translit_length)
+err_print("! Replacement string in @l too long");
+
+else{
+strncpy(translit[i-0200],beg,(size_t)(loc-beg));
+translit[i-0200][loc-beg]= '\0';
+}
+}
+
+/*:102*/
+#line 1478 "ctangle.w"
+break;
+case format_code:case'@':break;
+case control_text:if(c=='q'||c=='Q'){
+while((c= skip_ahead())=='@');
+if(*(loc-1)!='>')
+err_print("! Double @ should be used in control text");
+
+break;
+}
+default:err_print("! Double @ should be used in limbo");
+
+}
+}
+}
+}
+
+/*:100*//*103:*/
+#line 1522 "ctangle.w"
+
+void
+print_stats(void){
+puts("\nMemory usage statistics:");
+printf("%ld names (out of %ld)\n",
+(ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+printf("%ld replacement texts (out of %ld)\n",
+(ptrdiff_t)(text_ptr-text_info),(long)max_texts);
+printf("%ld bytes (out of %ld)\n",
+(ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+printf("%ld tokens (out of %ld)\n",
+(ptrdiff_t)(tok_ptr-tok_mem),(long)max_toks);
+}
+
+/*:103*/
diff --git a/Build/source/texk/web2c/cwebdir/ctangle.w b/Build/source/texk/web2c/cwebdir/ctangle.w
new file mode 100644
index 00000000000..e7e2d311fe5
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctangle.w
@@ -0,0 +1,1543 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 4.2 --- February 2021
+
+% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
+
+% 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.
+
+% Amendments to 'ctangle.w' resulting in this updated version were created
+% by numerous collaborators over the course of many years.
+
+% Please send comments, suggestions, etc. to tex-k@@tug.org.
+
+% Here is TeX material that gets inserted after \input cwebmac
+\def\hang{\hangindent 3em\indent\ignorespaces}
+\def\pb{$\.|\ldots\.|$} % C brackets (|...|)
+\def\v{\char'174} % vertical (|) in typewriter font
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+
+\def\title{CTANGLE (Version 4.2)}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont The {\ttitlefont CTANGLE} processor}
+ \vskip 15pt
+ \centerline{(Version 4.2)}
+ \vfill}
+\def\botofcontents{\vfill
+\noindent
+Copyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth
+\bigskip\noindent
+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.
+
+\smallskip\noindent
+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.
+}
+\pageno=\contentspagenumber \advance\pageno by 1
+\let\maybe=\iftrue
+
+@** Introduction.
+This is the \.{CTANGLE} program by Silvio Levy and Donald E. Knuth,
+based on \.{TANGLE} by Knuth.
+We are thankful to
+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 \.{CTANGLE}
+is modified.
+
+@d banner "This is CTANGLE (Version 4.2)"
+
+@c
+@<Include files@>@/
+@h
+@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
+@<Typedef declarations@>@/
+@<Private variables@>@/
+@<Predeclaration of procedures@>
+
+@ \.{CTANGLE} has a fairly straightforward outline. It operates in
+two phases: First it reads the source file, saving the \CEE/ code in
+compressed form; then it shuffles and outputs the code.
+
+Please read the documentation for \.{common}, the set of routines common
+to \.{CTANGLE} and \.{CWEAVE}, before proceeding further.
+
+@c
+int main (
+int ac,
+char **av)
+{
+ argc=ac; argv=av;
+ program=ctangle;
+ @<Set initial values@>@;
+ common_init();
+ if (show_banner) puts(banner); /* print a ``banner line'' */
+ phase_one(); /* read all the user's text and compress it into |tok_mem| */
+ phase_two(); /* output the contents of the compressed tables */
+ return wrap_up(); /* and exit gracefully */
+}
+
+@ The next few sections contain stuff from the file |"common.w"| that must
+be included in both |"ctangle.w"| and |"cweave.w"|. It appears in
+file |"common.h"|, which is also included in |"common.w"| to propagate
+possible changes from this \.{COMMON} interface consistently.
+
+@i common.h
+
+@* Data structures exclusive to {\tt CTANGLE}.
+We've already seen that the |byte_mem| array holds the names of identifiers,
+strings, and sections;
+the |tok_mem| array holds the replacement texts
+for sections. Allocation is sequential, since things are deleted only
+during Phase II, and only in a last-in-first-out manner.
+
+A \&{text} variable is a structure containing a pointer into
+|tok_mem|, which tells where the corresponding text starts, and an
+integer |text_link|, which, as we shall see later, is used to connect
+pieces of text that have the same name. All the \&{text}s are stored in
+the array |text_info|, and we use a \&{text\_pointer} variable to refer
+to them.
+
+The first position of |tok_mem| that is unoccupied by
+replacement text is called |tok_ptr|, and the first unused location of
+|text_info| is called |text_ptr|. Thus we usually have the identity
+|text_ptr->tok_start==tok_ptr|.
+
+@<Typed...@>=
+typedef struct {
+ eight_bits *tok_start; /* pointer into |tok_mem| */
+ sixteen_bits text_link; /* relates replacement texts */
+} text;
+typedef text *text_pointer;
+
+@ @<Private...@>=
+static text text_info[max_texts];
+static text_pointer text_info_end=text_info+max_texts-1;
+static text_pointer text_ptr; /* first unused position in |text_info| */
+static eight_bits tok_mem[max_toks];
+static eight_bits *tok_mem_end=tok_mem+max_toks-1;
+static eight_bits *tok_ptr; /* first unused position in |tok_mem| */
+
+@ @<Set init...@>=
+text_info->tok_start=tok_ptr=tok_mem;
+text_ptr=text_info+1; text_ptr->tok_start=tok_mem;
+ /* this makes replacement text 0 of length zero */
+
+@ If |p| is a pointer to a section name, |p->equiv| is a pointer to its
+replacement text, an element of the array |text_info|.
+
+@d equiv equiv_or_xref /* info corresponding to names */
+
+@ @<Set init...@>=
+init_node(name_dir); /* the undefined section has no replacement text */
+
+@ Here's the procedure that decides whether a name of length |l|
+starting at position |first| equals the identifier pointed to by |p|:
+
+@c
+boolean names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* not used by \.{TANGLE} */
+{@+(void)t;
+ if (length(p)!=l) return false;
+ return !strncmp(first,p->byte_start,l);
+}
+
+@ The common lookup routine refers to separate routines |init_node| and
+|init_p| when the data structure grows. Actually |init_p| is called only by
+\.{CWEAVE}, but we need to declare a dummy version so that
+the loader won't complain of its absence.
+
+@c
+void
+init_node(
+name_pointer node)
+{
+ node->equiv=(void *)text_info;
+}
+void
+init_p(name_pointer p,eight_bits t) {@+(void)p;@+(void)t;@+}
+
+@* Tokens.
+Replacement texts, which represent \CEE/ code in a compressed format,
+appear in |tok_mem| as mentioned above. The codes in
+these texts are called `tokens'; some tokens occupy two consecutive
+eight-bit byte positions, and the others take just one byte.
+
+If $p$ points to a replacement text, |p->tok_start| is the |tok_mem| position
+of the first eight-bit code of that text. If |p->text_link==0|,
+this is the replacement text for a macro, otherwise it is the replacement
+text for a section. In the latter case |p->text_link| is either equal to
+|section_flag|, which means that there is no further text for this section, or
+|p->text_link| points to a continuation of this replacement text; such
+links are created when several sections have \CEE/ texts with the same
+name, and they also tie together all the \CEE/ texts of unnamed sections.
+The replacement text pointer for the first unnamed section appears in
+|text_info->text_link|, and the most recent such pointer is |last_unnamed|.
+
+@d section_flag max_texts /* final |text_link| in section replacement texts */
+
+@<Private...@>=
+static text_pointer last_unnamed; /* most recent replacement text of unnamed section */
+
+@ @<Set init...@>= last_unnamed=text_info; text_info->text_link=0;
+
+@ If the first byte of a token is less than |0200|, the token occupies a
+single byte. Otherwise we make a sixteen-bit token by combining two consecutive
+bytes |a| and |b|. If |0200<=a<0250|, then |(a-0200)@t${}\times2^8$@>+b|
+points to an identifier; if |0250<=a<0320|, then
+|(a-0250)@t${}\times2^8$@>+b| points to a section name
+(or, if it has the special value |output_defs_flag|,
+to the area where the preprocessor definitions are stored); and if
+|0320<=a<0400|, then |(a-0320)@t${}\times2^8$@>+b| is the number of the section
+in which the current replacement text appears.
+
+Codes less than |0200| are 7-bit |char| codes that represent themselves.
+Some of the 7-bit codes will not be present, however, so we can
+use them for special purposes. The following symbolic names are used:
+
+\yskip \hang |join| denotes the concatenation of adjacent items with no
+space or line breaks allowed between them (the \.{@@\&} operation of \.{CWEB}).
+
+\hang |string| denotes the beginning or end of a string, verbatim
+construction or numerical constant.
+@^ASCII code dependencies@>
+
+@d string 02 /* takes the place of extended ASCII \.{\char2} */
+@d join 0177 /* takes the place of ASCII delete */
+@d output_defs_flag (2*024000-1)
+
+@ The following procedure is used to enter a two-byte value into
+|tok_mem| when a replacement text is being generated.
+
+@c
+static void
+store_two_bytes(
+sixteen_bits x)
+{
+ if (tok_ptr+2>tok_mem_end) overflow("token");
+ *tok_ptr++=x>>8; /* store high byte */
+ *tok_ptr++=x&0377; /* store low byte */
+}
+
+@ @<Predecl...@>=@+static void store_two_bytes(sixteen_bits);
+
+@** Stacks for output. The output process uses a stack to keep track
+of what is going on at different ``levels'' as the sections are being
+written out. Entries on this stack have five parts:
+
+\yskip\hang |end_field| is the |tok_mem| location where the replacement
+text of a particular level will end;
+
+\hang |byte_field| is the |tok_mem| location from which the next token
+on a particular level will be read;
+
+\hang |name_field| points to the name corresponding to a particular level;
+
+\hang |repl_field| points to the replacement text currently being read
+at a particular level;
+
+\hang |section_field| is the section number, or zero if this is a macro.
+
+\yskip\noindent The current values of these five quantities are referred to
+quite frequently, so they are stored in a separate place instead of in
+the |stack| array. We call the current values |cur_end|, |cur_byte|,
+|cur_name|, |cur_repl|, and |cur_section|.
+
+The global variable |stack_ptr| tells how many levels of output are
+currently in progress. The end of all output occurs when the stack is
+empty, i.e., when |stack_ptr==stack|.
+
+@<Typed...@>=
+typedef struct {
+ eight_bits *end_field; /* ending location of replacement text */
+ eight_bits *byte_field; /* present location within replacement text */
+ name_pointer name_field; /* |byte_start| index for text being output */
+ text_pointer repl_field; /* |tok_start| index for text being output */
+ sixteen_bits section_field; /* section number or zero if not a section */
+} output_state;
+typedef output_state *stack_pointer;
+
+@ @d cur_end cur_state.end_field /* current ending location in |tok_mem| */
+@d cur_byte cur_state.byte_field /* location of next output byte in |tok_mem|*/
+@d cur_name cur_state.name_field /* pointer to current name being expanded */
+@d cur_repl cur_state.repl_field /* pointer to current replacement text */
+@d cur_section cur_state.section_field /* current section number being expanded */
+
+@<Private...@>=
+static output_state cur_state; /* |cur_end|, |cur_byte|, |cur_name|, |cur_repl|,
+ and |cur_section| */
+static output_state stack[stack_size+1]; /* info for non-current levels */
+static stack_pointer stack_end=stack+stack_size; /* end of |stack| */
+static stack_pointer stack_ptr; /* first unused location in the output state stack */
+
+@ To get the output process started, we will perform the following
+initialization steps. We may assume that |text_info->text_link| is nonzero,
+since it points to the \CEE/ text in the first unnamed section that generates
+code; if there are no such sections, there is nothing to output, and an
+error message will have been generated before we do any of the initialization.
+
+@<Initialize the output stacks@>=
+stack_ptr=stack+1; cur_name=name_dir; cur_repl=text_info->text_link+text_info;
+cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start; cur_section=0;
+
+@ When the replacement text for name |p| is to be inserted into the output,
+the following subroutine is called to save the old level of output and get
+the new one going.
+
+We assume that the \CEE/ compiler can copy structures.
+@^system dependencies@>
+
+@c
+static void
+push_level(@t\1\1@> /* suspends the current level */
+name_pointer p@t\2\2@>)
+{
+ if (stack_ptr==stack_end) overflow("stack");
+ *stack_ptr=cur_state;
+ stack_ptr++;
+ if (p!=NULL) { /* |p==NULL| means we are in |output_defs| */
+ cur_name=p; cur_repl=(text_pointer)p->equiv;
+ cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start;
+ cur_section=0;
+ }
+}
+
+@ @<Predecl...@>=
+static void push_level(name_pointer);@/
+static void pop_level(boolean);
+
+@ When we come to the end of a replacement text, the |pop_level| subroutine
+does the right thing: It either moves to the continuation of this replacement
+text or returns the state to the most recently stacked level.
+
+@c
+static void
+pop_level(@t\1\1@> /* do this when |cur_byte| reaches |cur_end| */
+boolean flag@t\2\2@>) /* |flag==false| means we are in |output_defs| */
+{
+ if (flag && cur_repl->text_link<section_flag) { /* link to a continuation */
+ cur_repl=cur_repl->text_link+text_info; /* stay on the same level */
+ cur_byte=cur_repl->tok_start; cur_end=(cur_repl+1)->tok_start;
+ return;
+ }
+ stack_ptr--; /* go down to the previous level */
+ if (stack_ptr>stack) cur_state=*stack_ptr;
+}
+
+@ The heart of the output procedure is the function |get_output|,
+which produces the next token of output and sends it on to the lower-level
+function |out_char|. The main purpose of |get_output| is to handle the
+necessary stacking and unstacking. It sends the value |section_number|
+if the next output begins or ends the replacement text of some section,
+in which case |cur_val| is that section's number (if beginning) or the
+negative of that value (if ending). (A section number of 0 indicates
+not the beginning or ending of a section, but a \&{\#line} command.)
+And it sends the value |identifier|
+if the next output is an identifier, in which case
+|cur_val| points to that identifier name.
+
+@d section_number 0201 /* code returned by |get_output| for section numbers */
+@d identifier 0202 /* code returned by |get_output| for identifiers */
+
+@<Private...@>=
+static int cur_val; /* additional information corresponding to output token */
+
+@ If |get_output| finds that no more output remains, it returns with
+|stack_ptr==stack|.
+@^high-bit character handling@>
+
+@c
+static void
+get_output(void) /* sends next token to |out_char| */
+{
+ sixteen_bits a; /* value of current byte */
+ restart: if (stack_ptr==stack) return;
+ if (cur_byte==cur_end) {
+ cur_val=-((int)cur_section); /* cast needed because of sign extension */
+ pop_level(true);
+ if (cur_val==0) goto restart;
+ out_char(section_number); return;
+ }
+ a=*cur_byte++;
+ if (out_state==verbatim && a!=string && a!=constant && a!='\n')
+ C_putc(a); /* a high-bit character can occur in a string */
+ else if (a<0200) out_char(a); /* one-byte token */
+ else {
+ a=(a-0200)*0400+*cur_byte++;
+ switch (a/024000) { /* |024000==(0250-0200)*0400| */
+ case 0: cur_val=a; out_char(identifier); break;
+ case 1: if (a==output_defs_flag) output_defs();
+ else @<Expand section |a-024000|, |goto restart|@>@;
+ break;
+ default: cur_val=a-050000; if (cur_val>0) cur_section=cur_val;
+ out_char(section_number);
+ }
+ }
+}
+
+@ @<Predecl...@>=@+static void get_output(void);
+
+@ The user may have forgotten to give any \CEE/ text for a section name,
+or the \CEE/ text may have been associated with a different name by mistake.
+
+@<Expand section |a-...@>=
+{
+ a-=024000;
+ if ((a+name_dir)->equiv!=(void *)text_info) push_level(a+name_dir);
+ else if (a!=0) {
+ fputs("\n! Not present: <",stdout);
+ print_section_name(a+name_dir); err_print(">");
+@.Not present: <section name>@>
+ }
+ goto restart;
+}
+
+@* Producing the output.
+The |get_output| routine above handles most of the complexity of output
+generation, but there are two further considerations that have a nontrivial
+effect on \.{CTANGLE}'s algorithms.
+
+@ First,
+we want to make sure that the output has spaces and line breaks in
+the right places (e.g., not in the middle of a string or a constant or an
+identifier, not at a `\.{@@\&}' position
+where quantities are being joined together, and certainly after an \.=
+because the \CEE/ compiler thinks \.{=-} is ambiguous).
+
+The output process can be in one of following states:
+
+\yskip\hang |num_or_id| means that the last item in the buffer is a number or
+identifier, hence a blank space or line break must be inserted if the next
+item is also a number or identifier.
+
+\yskip\hang |unbreakable| means that the last item in the buffer was followed
+by the \.{@@\&} operation that inhibits spaces between it and the next item.
+
+\yskip\hang |verbatim| means we're copying only character tokens, and
+that they are to be output exactly as stored. This is the case during
+strings, verbatim constructions and numerical constants.
+
+\yskip\hang |post_slash| means we've just output a slash.
+
+\yskip\hang |normal| means none of the above.
+
+\yskip\noindent Furthermore, if the variable |protect| is |true|, newlines
+are preceded by a `\.\\'.
+
+@d normal 0 /* non-unusual state */
+@d num_or_id 1 /* state associated with numbers and identifiers */
+@d post_slash 2 /* state following a \./ */
+@d unbreakable 3 /* state associated with \.{@@\&} */
+@d verbatim 4 /* state in the middle of a string */
+
+@<Private...@>=
+static eight_bits out_state; /* current status of partial output */
+static boolean protect; /* should newline characters be quoted? */
+
+@ Here is a routine that is invoked when we want to output the current line.
+During the output process, |cur_line| equals the number of the next line
+to be output.
+
+@c
+static void
+flush_buffer(void) /* writes one line to output file */
+{
+ C_putc('\n');
+ if (cur_line % 100 == 0 && show_progress) {
+ printf(".");
+ if (cur_line % 500 == 0) printf("%d",cur_line);
+ update_terminal; /* progress report */
+ }
+ cur_line++;
+}
+
+@ @<Predecl...@>=@+static void flush_buffer(void);
+
+@ Second, we have modified the original \.{TANGLE} so that it will write output
+on multiple files.
+If a section name is introduced in at least one place by \.{@@(}
+instead of \.{@@<}, we treat it as the name of a file.
+All these special sections are saved on a stack, |output_files|.
+We write them out after we've done the unnamed section.
+
+@d max_files 256
+@<Private...@>=
+static name_pointer output_files[max_files];
+static name_pointer *cur_out_file, *end_output_files, *an_output_file;
+static char cur_section_name_char; /* is it |'<'| or |'('| */
+static char output_file_name[longest_name+1]; /* name of the file */
+
+@ We make |end_output_files| point just beyond the end of
+|output_files|. The stack pointer
+|cur_out_file| starts out there. Every time we see a new file, we
+decrement |cur_out_file| and then write it in.
+@<Set initial...@>=
+cur_out_file=end_output_files=output_files+max_files;
+
+@ @<If it's not there, add |cur_section_name| to the output file stack, or
+complain we're out of room@>=
+{
+ for (an_output_file=cur_out_file;
+ an_output_file<end_output_files; an_output_file++)
+ if (*an_output_file==cur_section_name) break;
+ if (an_output_file==end_output_files) {
+ if (cur_out_file>output_files)
+ *--cur_out_file=cur_section_name;
+ else {
+ overflow("output files");
+ }
+ }
+}
+
+@* The big output switch. Here then is the routine that does the
+output.
+
+@c
+static void
+phase_two (void) {
+ web_file_open=false;
+ cur_line=1;
+ @<Initialize the output stacks@>@;
+ @<Output macro definitions if appropriate@>@;
+ if (text_info->text_link==0 && cur_out_file==end_output_files) {
+ fputs("\n! No program text was specified.",stdout); mark_harmless;
+@.No program text...@>
+ }
+ else {
+ if(cur_out_file==end_output_files) {
+ if(show_progress)
+ printf("\nWriting the output file (%s):",C_file_name);
+ }
+ else {
+ if (show_progress) {
+ fputs("\nWriting the output files:",stdout);
+@.Writing the output...@>
+ printf(" (%s)",C_file_name);
+ update_terminal;
+ }
+ if (text_info->text_link==0) goto writeloop;
+ }
+ while (stack_ptr>stack) get_output();
+ flush_buffer();
+writeloop: @<Write all the named output files@>@;
+ if (show_happiness) {
+ if (show_progress) new_line;
+ fputs("Done.",stdout);
+ }
+ }
+}
+
+@ @<Predecl...@>=@+static void phase_two(void);
+
+@ To write the named output files, we proceed as for the unnamed
+section.
+The only subtlety is that we have to open each one.
+
+@<Write all the named output files@>=
+for (an_output_file=end_output_files; an_output_file>cur_out_file;) {
+ an_output_file--;
+ sprint_section_name(output_file_name,*an_output_file);
+ fclose(C_file);
+ C_file=fopen(output_file_name,"wb");
+ if (C_file ==0) fatal("! Cannot open output file ",output_file_name);
+@.Cannot open output file@>
+ if (show_progress) { printf("\n(%s)",output_file_name); update_terminal; }
+ cur_line=1;
+ stack_ptr=stack+1;
+ cur_name= (*an_output_file);
+ cur_repl= (text_pointer)cur_name->equiv;
+ cur_byte=cur_repl->tok_start;
+ cur_end=(cur_repl+1)->tok_start;
+ while (stack_ptr > stack) get_output();
+ flush_buffer();
+}
+
+@ If a \.{@@h} was not encountered in the input,
+we go through the list of replacement texts and copy the ones
+that refer to macros, preceded by the \.{\#define} preprocessor command.
+
+@<Output macro definitions if appropriate@>=
+ if (!output_defs_seen)
+ output_defs();
+
+@ @<Private...@>=
+static boolean output_defs_seen=false;
+
+@ @<Predecl...@>=
+static void output_defs(void);@/
+static void out_char(eight_bits);
+
+@ @c
+static void
+output_defs(void)
+{
+ sixteen_bits a;
+ push_level(NULL);
+ for (cur_text=text_info+1; cur_text<text_ptr; cur_text++)
+ if (cur_text->text_link==0) { /* |cur_text| is the text for a macro */
+ cur_byte=cur_text->tok_start;
+ cur_end=(cur_text+1)->tok_start;
+ C_printf("%s","#define ");
+ out_state=normal;
+ protect=true; /* newlines should be preceded by |'\\'| */
+ while (cur_byte<cur_end) {
+ a=*cur_byte++;
+ if (cur_byte==cur_end && a=='\n') break; /* disregard a final newline */
+ if (out_state==verbatim && a!=string && a!=constant && a!='\n')
+ C_putc(a); /* a high-bit character can occur in a string */
+@^high-bit character handling@>
+ else if (a<0200) out_char(a); /* one-byte token */
+ else {
+ a=(a-0200)*0400+*cur_byte++;
+ if (a<024000) { /* |024000==(0250-0200)*0400| */
+ cur_val=a; out_char(identifier);
+ }
+ else if (a<050000) { confusion("macro defs have strange char");}
+ else {
+ cur_val=a-050000; cur_section=cur_val; out_char(section_number);
+ }
+ /* no other cases */
+ }
+ }
+ protect=false;
+ flush_buffer();
+ }
+ pop_level(false);
+}
+
+@ A many-way switch is used to send the output. Note that this function
+is not called if |out_state==verbatim|, except perhaps with arguments
+|'\n'| (protect the newline), |string| (end the string), or |constant|
+(end the constant).
+
+@c
+static void
+out_char(
+eight_bits cur_char)
+{
+ char *j, *k; /* pointer into |byte_mem| */
+restart:
+ switch (cur_char) {
+ case '\n': if (protect && out_state!=verbatim) C_putc(' ');
+ if (protect || out_state==verbatim) C_putc('\\');
+ flush_buffer(); if (out_state!=verbatim) out_state=normal; break;
+ @/@t\4@>@<Case of an identifier@>@;
+ @/@t\4@>@<Case of a section number@>@;
+ @/@t\4@>@<Cases like \.{!=}@>@;
+ case '=': case '>': C_putc(cur_char); C_putc(' ');
+ out_state=normal; break;
+ case join: out_state=unbreakable; break;
+ case constant: if (out_state==verbatim) {
+ out_state=num_or_id; break;
+ }
+ if(out_state==num_or_id) C_putc(' '); out_state=verbatim; break;
+ case string: if (out_state==verbatim) out_state=normal;
+ else out_state=verbatim; break;
+ case '/': C_putc('/'); out_state=post_slash; break;
+ case '*': if (out_state==post_slash) C_putc(' ');
+ /* fall through */
+ default: C_putc(cur_char); out_state=normal; break;
+ }
+}
+
+@ @<Cases like \.{!=}@>=
+case plus_plus: C_putc('+');@+C_putc('+'); out_state=normal; break;
+case minus_minus: C_putc('-');@+C_putc('-'); out_state=normal; break;
+case minus_gt: C_putc('-');@+C_putc('>'); out_state=normal; break;
+case gt_gt: C_putc('>');@+C_putc('>'); out_state=normal; break;
+case eq_eq: C_putc('=');@+C_putc('='); out_state=normal; break;
+case lt_lt: C_putc('<');@+C_putc('<'); out_state=normal; break;
+case gt_eq: C_putc('>');@+C_putc('='); out_state=normal; break;
+case lt_eq: C_putc('<');@+C_putc('='); out_state=normal; break;
+case non_eq: C_putc('!');@+C_putc('='); out_state=normal; break;
+case and_and: C_putc('&');@+C_putc('&'); out_state=normal; break;
+case or_or: C_putc('|');@+C_putc('|'); out_state=normal; break;
+case dot_dot_dot: C_putc('.');@+C_putc('.');@+C_putc('.'); out_state=normal;
+ break;
+case colon_colon: C_putc(':');@+C_putc(':'); out_state=normal; break;
+case period_ast: C_putc('.');@+C_putc('*'); out_state=normal; break;
+case minus_gt_ast: C_putc('-');@+C_putc('>');@+C_putc('*'); out_state=normal;
+ break;
+
+@ When an identifier is output to the \CEE/ file, characters in the
+range 128--255 must be changed into something else, so the \CEE/
+compiler won't complain. By default, \.{CTANGLE} converts the
+character with code $16 x+y$ to the three characters `\.X$xy$', but
+a different transliteration table can be specified. Thus a German
+might want {\it gr\"un\/} to appear as a still readable \.{gruen}.
+This makes debugging a lot less confusing.
+
+@d translit_length 10
+
+@<Private...@>=
+static char translit[128][translit_length];
+
+@ @<Set init...@>=
+{
+ int i;
+ for (i=0;i<128;i++) sprintf(translit[i],"X%02X",(unsigned int)(128+i));
+}
+
+@ @<Case of an identifier@>=
+case identifier:
+ if (out_state==num_or_id) C_putc(' ');
+ j=(cur_val+name_dir)->byte_start;
+ k=(cur_val+name_dir+1)->byte_start;
+ while (j<k) {
+ if ((eight_bits)(*j)<0200) C_putc(*j);
+@^high-bit character handling@>
+ else C_printf("%s",translit[(eight_bits)(*j)-0200]);
+ j++;
+ }
+ out_state=num_or_id; break;
+
+@ @<Case of a sec...@>=
+case section_number:
+ if (cur_val>0) C_printf("/*%d:*/",cur_val);
+ else if(cur_val<0) C_printf("/*:%d*/",-cur_val);
+ else if (protect) {
+ cur_byte +=4; /* skip line number and file name */
+ cur_char = '\n';
+ goto restart;
+ } else {
+ sixteen_bits a;
+ a=0400* *cur_byte++;
+ a+=*cur_byte++; /* gets the line number */
+ C_printf("\n#line %d \"",a);
+@:line}{\.{\#line}@>
+ cur_val=*cur_byte++;
+ cur_val=0400*(cur_val-0200)+ *cur_byte++; /* points to the file name */
+ for (j=(cur_val+name_dir)->byte_start, k=(cur_val+name_dir+1)->byte_start;
+ j<k; j++) {
+ if (*j=='\\' || *j=='"') C_putc('\\');
+ C_putc(*j);
+ }
+ C_printf("%s","\"\n");
+ }
+ break;
+
+@** Introduction to the input phase.
+We have now seen that \.{CTANGLE} will be able to output the full
+\CEE/ program, if we can only get that program into the byte memory in
+the proper format. The input process is something like the output process
+in reverse, since we compress the text as we read it in and we expand it
+as we write it out.
+
+There are three main input routines. The most interesting is the one that gets
+the next token of a \CEE/ text; the other two are used to scan rapidly past
+\TEX/ text in the \.{CWEB} source code. One of the latter routines will jump to
+the next token that starts with `\.{@@}', and the other skips to the end
+of a \CEE/ comment.
+
+@ Control codes in \.{CWEB} begin with `\.{@@}', and the next character
+identifies the code. Some of these are of interest only to \.{CWEAVE},
+so \.{CTANGLE} ignores them; the others are converted by \.{CTANGLE} into
+internal code numbers by the |ccode| table below. The ordering
+of these internal code numbers has been chosen to simplify the program logic;
+larger numbers are given to the control codes that denote more significant
+milestones.
+
+@d ignore 0 /* control code of no interest to \.{CTANGLE} */
+@d ord 0302 /* control code for `\.{@@'}' */
+@d control_text 0303 /* control code for `\.{@@t}', `\.{@@\^}', etc. */
+@d translit_code 0304 /* control code for `\.{@@l}' */
+@d output_defs_code 0305 /* control code for `\.{@@h}' */
+@d format_code 0306 /* control code for `\.{@@f}' */
+@d definition 0307 /* control code for `\.{@@d}' */
+@d begin_C 0310 /* control code for `\.{@@c}' */
+@d section_name 0311 /* control code for `\.{@@<}' */
+@d new_section 0312 /* control code for `\.{@@\ }' and `\.{@@*}' */
+
+@<Private...@>=
+static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
+
+@ @<Set ini...@>= {
+ int c; /* must be |int| so the |for| loop will end */
+ for (c=0; c<256; c++) ccode[c]=ignore;
+ ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
+ =ccode['*']=new_section;
+ ccode['@@']='@@'; ccode['=']=string;
+ ccode['d']=ccode['D']=definition;
+ ccode['f']=ccode['F']=ccode['s']=ccode['S']=format_code;
+ ccode['c']=ccode['C']=ccode['p']=ccode['P']=begin_C;
+ ccode['^']=ccode[':']=ccode['.']=ccode['t']=ccode['T']=
+ ccode['q']=ccode['Q']=control_text;
+ ccode['h']=ccode['H']=output_defs_code;
+ ccode['l']=ccode['L']=translit_code;
+ ccode['&']=join;
+ ccode['<']=ccode['(']=section_name;
+ ccode['\'']=ord;
+}
+
+@ The |skip_ahead| procedure reads through the input at fairly high speed
+until finding the next non-ignorable control code, which it returns.
+
+@c
+static eight_bits
+skip_ahead(void) /* skip to next control code */
+{
+ eight_bits c; /* control code found */
+ while (true) {
+ if (loc>limit && (get_line()==false)) return new_section;
+ *(limit+1)='@@';
+ while (*loc!='@@') loc++;
+ if (loc<=limit) {
+ loc++; c=ccode[(eight_bits)*loc]; loc++;
+ if (c!=ignore || *(loc-1)=='>') return c;
+ }
+ }
+}
+
+@ @<Predecl...@>=
+static eight_bits skip_ahead(void);@/
+static boolean skip_comment(boolean);
+
+@ The |skip_comment| procedure reads through the input at somewhat high
+speed in order to pass over comments, which \.{CTANGLE} does not transmit
+to the output. If the comment is introduced by \.{/*}, |skip_comment|
+proceeds until finding the end-comment token \.{*/} or a newline; in the
+latter case |skip_comment| will be called again by |get_next|, since the
+comment is not finished. This is done so that each newline in the
+\CEE/ part of a section is copied to the output; otherwise the \&{\#line}
+commands inserted into the \CEE/ file by the output routines become useless.
+On the other hand, if the comment is introduced by \.{//} (i.e., if it
+is a \CPLUSPLUS/ ``short comment''), it always is simply delimited by the next
+newline. The boolean argument |is_long_comment| distinguishes between
+the two types of comments.
+
+If |skip_comment| comes to the end of the section, it prints an error message.
+No comment, long or short, is allowed to contain `\.{@@\ }' or `\.{@@*}'.
+
+@<Private...@>=
+static boolean comment_continues=false; /* are we scanning a comment? */
+
+@ @c
+static boolean skip_comment(@t\1\1@> /* skips over comments */
+boolean is_long_comment@t\2\2@>)
+{
+ char c; /* current character */
+ while (true) {
+ if (loc>limit) {
+ if (is_long_comment) {
+ if(get_line()) return comment_continues=true;
+ else{
+ err_print("! Input ended in mid-comment");
+@.Input ended in mid-comment@>
+ return comment_continues=false;
+ }
+ }
+ else return comment_continues=false;
+ }
+ c=*(loc++);
+ if (is_long_comment && c=='*' && *loc=='/') {
+ loc++; return comment_continues=false;
+ }
+ if (c=='@@') {
+ if (ccode[(eight_bits)*loc]==new_section) {
+ err_print("! Section name ended in mid-comment"); loc--;
+@.Section name ended in mid-comment@>
+ return comment_continues=false;
+ }
+ else loc++;
+ }
+ }
+}
+
+@* Inputting the next token.
+
+@d constant 03
+
+@<Private...@>=
+static name_pointer cur_section_name; /* name of section just scanned */
+static boolean no_where; /* suppress |print_where|? */
+
+@ As one might expect, |get_next| consists mostly of a big switch
+that branches to the various special cases that can arise.
+
+@d isxalpha(c) ((c)=='_' || (c)=='$')
+ /* non-alpha characters allowed in identifier */
+@d ishigh(c) ((eight_bits)(c)>0177)
+@^high-bit character handling@>
+
+@c
+static eight_bits
+get_next(void) /* produces the next input token */
+{
+ static int preprocessing=0;
+ eight_bits c; /* the current character */
+ while (true) {
+ if (loc>limit) {
+ if (preprocessing && *(limit-1)!='\\') preprocessing=0;
+ if (get_line()==false) return new_section;
+ else if (print_where && !no_where) {
+ print_where=false;
+ @<Insert the line number into |tok_mem|@>@;
+ }
+ else return '\n';
+ }
+ c=*loc;
+ if (comment_continues || (c=='/' && (*(loc+1)=='*' || *(loc+1)=='/'))) {
+ skip_comment(comment_continues||*(loc+1)=='*');
+ /* scan to end of comment or newline */
+ if (comment_continues) return '\n';
+ else continue;
+ }
+ loc++;
+ if (xisdigit(c) || c=='.') @<Get a constant@>@;
+ else if (c=='\'' || c=='"'@|
+ || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@|
+ || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"')))
+ @<Get a string@>@;
+ else if (isalpha(c) || isxalpha(c) || ishigh(c))
+ @<Get an identifier@>@;
+ else if (c=='@@') @<Get control code and possible section name@>@;
+ else if (xisspace(c)) {
+ if (!preprocessing || loc>limit) continue;
+ /* we don't want a blank after a final backslash */
+ else return ' '; /* ignore spaces and tabs, unless preprocessing */
+ }
+ else if (c=='#' && loc==buffer+1) preprocessing=1;
+ mistake: @<Compress two-symbol operator@>@;
+ return c;
+ }
+}
+
+@ @<Predecl...@>=@+static eight_bits get_next(void);
+
+@ The following code assigns values to the combinations \.{++},
+\.{--}, \.{->}, \.{>=}, \.{<=}, \.{==}, \.{<<}, \.{>>}, \.{!=}, \.{||} and
+\.{\&\&}, and to the \CPLUSPLUS/
+combinations \.{...}, \.{::}, \.{.*} and \.{->*}.
+The compound assignment operators (e.g., \.{+=}) are
+treated as separate tokens.
+
+@d compress(c) if (loc++<=limit) return c
+
+@<Compress tw...@>=
+switch(c) {
+ case '+': if (*loc=='+') compress(plus_plus); break;
+ case '-': if (*loc=='-') {compress(minus_minus);}
+ else { if (*loc=='>') { if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
+ else compress(minus_gt); } } break;
+ case '.': if (*loc=='*') {compress(period_ast);}
+ else if (*loc=='.' && *(loc+1)=='.') {
+ loc++; compress(dot_dot_dot);
+ }
+ break;
+ case ':': if (*loc==':') compress(colon_colon); break;
+ case '=': if (*loc=='=') compress(eq_eq); break;
+ case '>': if (*loc=='=') {compress(gt_eq);}
+ else if (*loc=='>') compress(gt_gt); break;
+ case '<': if (*loc=='=') {compress(lt_eq);}
+ else if (*loc=='<') compress(lt_lt); break;
+ case '&': if (*loc=='&') compress(and_and); break;
+ case '|': if (*loc=='|') compress(or_or); break;
+ case '!': if (*loc=='=') compress(non_eq); break;
+}
+
+@ @<Get an identifier@>= {
+ id_first=--loc;
+ while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
+ || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
+ id_loc=loc; return identifier;
+}
+
+@ @<Get a constant@>= {
+ id_first=loc-1;
+ if (*id_first=='.' && !xisdigit(*loc)) goto mistake; /* not a constant */
+ if (*id_first=='0') {
+ if (*loc=='x' || *loc=='X') { /* hex constant */
+ loc++; while (xisxdigit(*loc)) loc++; goto found;
+ }
+ }
+ while (xisdigit(*loc)) loc++;
+ if (*loc=='.') {
+ loc++;
+ while (xisdigit(*loc)) loc++;
+ }
+ if (*loc=='e' || *loc=='E') { /* float constant */
+ if (*++loc=='+' || *loc=='-') loc++;
+ while (xisdigit(*loc)) loc++;
+ }
+ found: while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L'
+ || *loc=='f' || *loc=='F') loc++;
+ id_loc=loc;
+ return constant;
+}
+
+@ \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 |longest_name|.
+
+@<Get a string@>= {
+ char delim = c; /* what started the string */
+ id_first = section_text+1;
+ id_loc = section_text; *++id_loc=delim;
+ if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */
+ if (delim=='u' && *loc=='8') { *++id_loc=*loc++; }
+ delim=*loc++; *++id_loc=delim;
+ }
+ while (true) {
+ if (loc>=limit) {
+ if(*(limit-1)!='\\') {
+ err_print("! String didn't end"); loc=limit; break;
+@.String didn't end@>
+ }
+ if(get_line()==false) {
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@.Input ended in middle of string@>
+ }
+ else if (++id_loc<=section_text_end) *id_loc='\n'; /* will print as
+ \.{"\\\\\\n"} */
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=section_text_end) *id_loc=c;
+ break;
+ }
+ if (c=='\\') {
+ if (loc>=limit) continue;
+ if (++id_loc<=section_text_end) *id_loc = '\\';
+ c=*loc++;
+ }
+ if (++id_loc<=section_text_end) *id_loc=c;
+ }
+ if (id_loc>=section_text_end) {
+ fputs("\n! String too long: ",stdout);
+@.String too long@>
+ term_write(section_text+1,25);
+ err_print("...");
+ }
+ id_loc++;
+ return string;
+}
+
+@ After an \.{@@} sign has been scanned, the next character tells us
+whether there is more work to do.
+
+@<Get control code and possible section name@>= {
+ c=ccode[(eight_bits)*loc++];
+ switch(c) {
+ case ignore: continue;
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@.Use @@l in limbo...@>
+ case control_text: while ((c=skip_ahead())=='@@');
+ /* only \.{@@@@} and \.{@@>} are expected */
+ if (*(loc-1)!='>')
+ err_print("! Double @@ should be used in control text");
+@.Double @@ should be used...@>
+ continue;
+ case section_name:
+ cur_section_name_char=*(loc-1);
+ @<Scan the section name and make |cur_section_name| point to it@>@;
+ case string: @<Scan a verbatim string@>@;
+ case ord: @<Scan an ASCII constant@>@;
+ default: return c;
+ }
+}
+
+@ After scanning a valid ASCII constant that follows
+\.{@@'}, this code plows ahead until it finds the next single quote.
+(Special care is taken if the quote is part of the constant.)
+Anything after a valid ASCII constant is ignored;
+thus, \.{@@'\\nopq'} gives the same result as \.{@@'\\n'}.
+
+@<Scan an ASCII constant@>=
+ id_first=loc;
+ if (*loc=='\\') {
+ if (*++loc=='\'') loc++;
+ }
+ while (*loc!='\'') {
+ if (*loc=='@@') {
+ if (*(loc+1)!='@@')
+ err_print("! Double @@ should be used in ASCII constant");
+@.Double @@ should be used...@>
+ else loc++;
+ }
+ loc++;
+ if (loc>limit) {
+ err_print("! String didn't end"); loc=limit-1; break;
+@.String didn't end@>
+ }
+ }
+ loc++;
+ return ord;
+
+@ @<Scan the section name...@>= {
+ char *k; /* pointer into |section_text| */
+ @<Put section name into |section_text|@>@;
+ if (k-section_text>3 && strncmp(k-2,"...",3)==0)
+ cur_section_name=section_lookup(section_text+1,k-3,1); /* 1 means is a prefix */
+ else cur_section_name=section_lookup(section_text+1,k,0);
+ if (cur_section_name_char=='(')
+ @<If it's not there, add |cur_section_name| to the output file stack, or
+ complain we're out of room@>@;
+ return section_name;
+}
+
+@ Section names are placed into the |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 |section_text[0]=' '| to facilitate
+this, since the |section_lookup| routine uses |section_text[1]| as the first
+character of the name.)
+
+@<Set init...@>=section_text[0]=' ';
+
+@ @<Put section name...@>=
+k=section_text;
+while (true) {
+ if (loc>limit && get_line()==false) {
+ err_print("! Input ended in section name");
+@.Input ended in section name@>
+ loc=buffer+1; break;
+ }
+ c=*loc;
+ @<If end of name or erroneous nesting, |break|@>@;
+ loc++; if (k<section_text_end) k++;
+ if (xisspace(c)) {
+ c=' '; if (*(k-1)==' ') k--;
+ }
+*k=c;
+}
+if (k>=section_text_end) {
+ fputs("\n! Section name too long: ",stdout);
+@.Section name too long@>
+ term_write(section_text+1,25);
+ printf("..."); mark_harmless;
+}
+if (*k==' ' && k>section_text) k--;
+
+@ @<If end of name or erroneous nesting,...@>=
+if (c=='@@') {
+ c=*(loc+1);
+ if (c=='>') {
+ loc+=2; break;
+ }
+ if (ccode[(eight_bits)c]==new_section) {
+ err_print("! Section name didn't end"); break;
+@.Section name didn't end@>
+ }
+ if (ccode[(eight_bits)c]==section_name) {
+ err_print("! Nesting of section names not allowed"); break;
+@.Nesting of section names...@>
+ }
+ *(++k)='@@'; loc++; /* now |c==*loc| again */
+}
+
+@ At the present point in the program we
+have |*(loc-1)==string|; we set |id_first| to the beginning
+of the string itself, and |id_loc| to its ending-plus-one location in the
+buffer. We also set |loc| to the position just after the ending delimiter.
+
+@<Scan a verbatim string@>= {
+ id_first=loc++; *(limit+1)='@@'; *(limit+2)='>';
+ while (*loc!='@@' || *(loc+1)!='>') loc++;
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@.Verbatim string didn't end@>
+ id_loc=loc; loc+=2;
+ return string;
+}
+
+@* Scanning a macro definition.
+The rules for generating the replacement texts corresponding to macros and
+\CEE/ texts of a section are almost identical; the only differences are that
+
+\yskip \item{a)}Section names are not allowed in macros;
+in fact, the appearance of a section name terminates such macros and denotes
+the name of the current section.
+
+\item{b)}The symbols \.{@@d} and \.{@@f} and \.{@@c} are not allowed after
+section names, while they terminate macro definitions.
+
+\item{c)}Spaces are inserted after right parentheses in macros, because the
+ANSI \CEE/ preprocessor sometimes requires it.
+
+\yskip Therefore there is a single procedure |scan_repl| whose parameter
+|t| specifies either |macro| or |section_name|. After |scan_repl| has
+acted, |cur_text| will point to the replacement text just generated, and
+|next_control| will contain the control code that terminated the activity.
+
+@d macro 0
+@d app_repl(c) {if (tok_ptr==tok_mem_end) overflow("token"); *tok_ptr++=c;}
+
+@<Private...@>=
+static text_pointer cur_text; /* replacement text formed by |scan_repl| */
+static eight_bits next_control;
+
+@ @c
+static void
+scan_repl(@t\1\1@> /* creates a replacement text */
+eight_bits t@t\2\2@>)
+{
+ sixteen_bits a; /* the current token */
+ if (t==section_name) {@<Insert the line number into |tok_mem|@>@;}
+ while (true) switch (a=get_next()) {
+ @<In cases that |a| is a non-|char| token (|identifier|,
+ |section_name|, etc.), either process it and change |a| to a byte
+ that should be stored, or |continue| if |a| should be ignored,
+ or |goto done| if |a| signals the end of this replacement text@>@;
+ case ')': app_repl(a);
+ if (t==macro) app_repl(' ');
+ break;
+ default: app_repl(a); /* store |a| in |tok_mem| */
+ }
+ done: next_control=(eight_bits) a;
+ if (text_ptr>text_info_end) overflow("text");
+ cur_text=text_ptr; (++text_ptr)->tok_start=tok_ptr;
+}
+
+@ @<Predecl...@>=@+static void scan_repl(eight_bits);
+
+@ Here is the code for the line number: first a |sixteen_bits| equal
+to |0150000|; then the numeric line number; then a pointer to the
+file name.
+
+@<Insert the line...@>=
+store_two_bytes(0150000);
+if (changing && include_depth==change_depth) { /* correction made Feb 2017 */
+ id_first=change_file_name;
+ store_two_bytes((sixteen_bits)change_line);
+}@+else {
+ id_first=cur_file_name;
+ store_two_bytes((sixteen_bits)cur_line);
+}
+id_loc=id_first+strlen(id_first);
+{int a_l=id_lookup(id_first,id_loc,0)-name_dir; app_repl((a_l / 0400)+0200);
+ app_repl(a_l % 0400);}
+
+@ @<In cases that |a| is...@>=
+case identifier: a=id_lookup(id_first,id_loc,0)-name_dir;
+ app_repl((a / 0400)+0200);
+ app_repl(a % 0400); break;
+case section_name: if (t!=section_name) goto done;
+ else {
+ @<Was an `\.{@@}' missed here?@>@;
+ a=cur_section_name-name_dir;
+ app_repl((a / 0400)+0250);
+ app_repl(a % 0400);
+ @<Insert the line number into |tok_mem|@>@; break;
+ }
+case output_defs_code: if (t!=section_name) err_print("! Misplaced @@h");
+@.Misplaced @@h@>
+ else {
+ output_defs_seen=true;
+ a=output_defs_flag;
+ app_repl((a / 0400)+0200);
+ app_repl(a % 0400);
+ @<Insert the line number into |tok_mem|@>@;
+ }
+ break;
+case constant: case string:
+ @<Copy a string or verbatim construction or numerical constant@>@;
+case ord:
+ @<Copy an ASCII constant@>@;
+case definition: case format_code: case begin_C: if (t!=section_name) goto done;
+ else {
+ err_print("! @@d, @@f and @@c are ignored in C text"); continue;
+@.@@d, @@f and @@c are ignored in C text@>
+ }
+case new_section: goto done;
+
+@ @<Was an `\.{@@}'...@>= {
+ char *try_loc=loc;
+ while (*try_loc==' ' && try_loc<limit) try_loc++;
+ if (*try_loc=='+' && try_loc<limit) try_loc++;
+ while (*try_loc==' ' && try_loc<limit) try_loc++;
+ if (*try_loc=='=') err_print ("! Missing `@@ ' before a named section");
+@.Missing `@@ '...@>
+ /* user who isn't defining a section should put newline after the name,
+ as explained in the manual */
+}
+
+@ @<Copy a string...@>=
+ app_repl(a); /* |string| or |constant| */
+ while (id_first < id_loc) { /* simplify \.{@@@@} pairs */
+ if (*id_first=='@@') {
+ if (*(id_first+1)=='@@') id_first++;
+ else err_print("! Double @@ should be used in string");
+@.Double @@ should be used...@>
+ }
+ app_repl(*id_first++);
+ }
+ app_repl(a); break;
+
+@ This section should be rewritten on machines that don't use ASCII
+code internally.
+@^ASCII code dependencies@>
+
+@<Copy an ASCII constant@>= {
+ int c=(eight_bits) *id_first;
+ if (c=='\\') {
+ c=*++id_first;
+ if (c>='0' && c<='7') {
+ c-='0';
+ if (*(id_first+1)>='0' && *(id_first+1)<='7') {
+ c=8*c+*(++id_first) - '0';
+ if (*(id_first+1)>='0' && *(id_first+1)<='7' && c<32)
+ c=8*c+*(++id_first)- '0';
+ }
+ }
+ else switch (c) {
+ case 't':c='\t';@+break;
+ case 'n':c='\n';@+break;
+ case 'b':c='\b';@+break;
+ case 'f':c='\f';@+break;
+ case 'v':c='\v';@+break;
+ case 'r':c='\r';@+break;
+ case 'a':c='\7';@+break;
+ case '?':c='?';@+break;
+ case 'x':
+ if (xisdigit(*(id_first+1))) c=*(++id_first)-'0';
+ else if (xisxdigit(*(id_first+1))) {
+ ++id_first;
+ c=toupper((eight_bits)*id_first)-'A'+10;
+ }
+ if (xisdigit(*(id_first+1))) c=16*c+*(++id_first)-'0';
+ else if (xisxdigit(*(id_first+1))) {
+ ++id_first;
+ c=16*c+toupper((eight_bits)*id_first)-'A'+10;
+ }
+ break;
+ case '\\':c='\\';@+break;
+ case '\'':c='\'';@+break;
+ case '\"':c='\"';@+break;
+ default: err_print("! Unrecognized escape sequence");
+@.Unrecognized escape sequence@>
+ }
+ }@/
+ /* at this point |c| should have been converted to its ASCII code number */
+ app_repl(constant);
+ if (c>=100) app_repl('0'+c/100);
+ if (c>=10) app_repl('0'+(c/10)%10);
+ app_repl('0'+c%10);
+ app_repl(constant);
+}
+break;
+
+@* Scanning a section.
+The |scan_section| procedure starts when `\.{@@\ }' or `\.{@@*}' has been
+sensed in the input, and it proceeds until the end of that section. It
+uses |section_count| to keep track of the current section number; with luck,
+\.{CWEAVE} and \.{CTANGLE} will both assign the same numbers to sections.
+
+The body of |scan_section| is a loop where we look for control codes
+that are significant to \.{CTANGLE}: those
+that delimit a definition, the \CEE/ part of a module, or a new module.
+
+@c
+static void
+scan_section(void)
+{
+ name_pointer p; /* section name for the current section */
+ text_pointer q; /* text for the current section */
+ sixteen_bits a; /* token for left-hand side of definition */
+ section_count++; @+ no_where=true;
+ if (*(loc-1)=='*' && show_progress) { /* starred section */
+ printf("*%d",section_count); update_terminal;
+ }
+ next_control=0;
+ while (true) {
+ @<Skip ahead until |next_control| corresponds to \.{@@d}, \.{@@<},
+ \.{@@\ } or the like@>@;
+ if (next_control == definition) { /* \.{@@d} */
+ @<Scan a definition@>@;
+ continue;
+ }
+ if (next_control == begin_C) { /* \.{@@c} or \.{@@p} */
+ p=name_dir; break;
+ }
+ if (next_control == section_name) { /* \.{@@<} or \.{@@(} */
+ p=cur_section_name;
+ @<If section is not being defined, |continue| @>@;
+ break;
+ }
+ return; /* \.{@@\ } or \.{@@*} */
+ }
+ no_where=print_where=false;
+ @<Scan the \CEE/ part of the current section@>@;
+}
+
+@ @<Predecl...@>=@+static void scan_section(void);
+
+@ At the top of this loop, if |next_control==section_name|, the
+section name has already been scanned (see |@<Get control code
+and...@>|). Thus, if we encounter |next_control==section_name| in the
+skip-ahead process, we should likewise scan the section name, so later
+processing will be the same in both cases.
+
+@<Skip ahead until |next_control| ...@>=
+while (next_control<definition)
+ /* |definition| is the lowest of the ``significant'' codes */
+ if((next_control=skip_ahead())==section_name){
+ loc-=2; next_control=get_next();
+ }
+
+@ @<Scan a definition@>= {
+ while ((next_control=get_next())=='\n'); /* allow newline before definition */
+ if (next_control!=identifier) {
+ err_print("! Definition flushed, must start with identifier");
+@.Definition flushed...@>
+ continue;
+ }
+ app_repl(((a=id_lookup(id_first,id_loc,0)-name_dir) / 0400)+0200);
+ /* append the lhs */
+ app_repl(a % 0400);
+ if (*loc!='(') { /* identifier must be separated from replacement text */
+ app_repl(string); app_repl(' '); app_repl(string);
+ }
+ scan_repl(macro);
+ cur_text->text_link=macro;
+}
+
+@ If the section name is not followed by \.{=} or \.{+=}, no \CEE/
+code is forthcoming: the section is being cited, not being
+defined. This use is illegal after the definition part of the
+current section has started, except inside a comment, but
+\.{CTANGLE} does not enforce this rule; it simply ignores the offending
+section name and everything following it, up to the next significant
+control code.
+
+@<If section is not being defined, |continue| @>=
+while ((next_control=get_next())=='+'); /* allow optional \.{+=} */
+if (next_control!='=' && next_control!=eq_eq)
+ continue;
+
+@ @<Scan the \CEE/...@>=
+@<Insert the section number into |tok_mem|@>@;
+scan_repl(section_name); /* now |cur_text| points to the replacement text */
+@<Update the data structure so that the replacement text is accessible@>@;
+
+@ @<Insert the section number...@>=
+store_two_bytes((sixteen_bits)(0150000+section_count));
+ /* |0150000==0320*0400| */
+
+@ @<Update the data...@>=
+if (p==name_dir||p==0) { /* unnamed section, or bad section name */
+ (last_unnamed)->text_link=cur_text-text_info; last_unnamed=cur_text;
+}
+else if (p->equiv==(void *)text_info) p->equiv=(void *)cur_text;
+ /* first section of this name */
+else {
+ q=(text_pointer)p->equiv;
+ while (q->text_link<section_flag)
+ q=q->text_link+text_info; /* find end of list */
+ q->text_link=cur_text-text_info;
+}
+cur_text->text_link=section_flag;
+ /* mark this replacement text as a nonmacro */
+
+@ @c
+static void
+phase_one(void) {
+ phase=1;
+ section_count=0;
+ reset_input();
+ skip_limbo();
+ while (!input_has_ended) scan_section();
+ check_complete();
+ phase=2;
+}
+
+@ @<Predec...@>=@+static void phase_one(void);
+
+@ Only a small subset of the control codes is legal in limbo, so limbo
+processing is straightforward.
+
+@c
+static void
+skip_limbo(void)
+{
+ char c;
+ while (true) {
+ if (loc>limit && get_line()==false) return;
+ *(limit+1)='@@';
+ while (*loc!='@@') loc++;
+ if (loc++<=limit) {
+ c=*loc++;
+ if (ccode[(eight_bits)c]==new_section) break;
+ switch (ccode[(eight_bits)c]) {
+ case translit_code: @<Read in transliteration of a character@>@; break;
+ case format_code: case '@@': break;
+ case control_text: if (c=='q' || c=='Q') {
+ while ((c=skip_ahead())=='@@');
+ if (*(loc-1)!='>')
+ err_print("! Double @@ should be used in control text");
+@.Double @@ should be used...@>
+ break;
+ } /* otherwise fall through */
+ default: err_print("! Double @@ should be used in limbo");
+@.Double @@ should be used...@>
+ }
+ }
+ }
+}
+
+@ @<Predecl...@>=@+static void skip_limbo(void);
+
+@ @<Read in transliteration of a character@>=
+ while(xisspace(*loc)&&loc<limit) loc++;
+ loc+=3;
+ if (loc>limit || !xisxdigit(*(loc-3)) || !xisxdigit(*(loc-2)) @|
+ || (*(loc-3)>='0' && *(loc-3)<='7') || !xisspace(*(loc-1)))
+ err_print("! Improper hex number following @@l");
+@.Improper hex number...@>
+ else {
+ unsigned int i;
+ char *beg;
+ sscanf(loc-3,"%x",&i);
+ while(xisspace(*loc)&&loc<limit) loc++;
+ beg=loc;
+ while(loc<limit&&(xisalpha(*loc)||xisdigit(*loc)||*loc=='_')) loc++;
+ if (loc-beg>=translit_length)
+ err_print("! Replacement string in @@l too long");
+@.Replacement string in @@l...@>
+ else{
+ strncpy(translit[i-0200],beg,(size_t)(loc-beg));
+ translit[i-0200][loc-beg]='\0';
+ }
+ }
+
+@ Because on some systems the difference between two pointers is a |ptrdiff_t|
+but not an |int|, we use \.{\%ld} to print these quantities.
+
+@c
+void
+print_stats(void) {
+ puts("\nMemory usage statistics:");
+ printf("%ld names (out of %ld)\n",
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf("%ld replacement texts (out of %ld)\n",
+ (ptrdiff_t)(text_ptr-text_info),(long)max_texts);
+ printf("%ld bytes (out of %ld)\n",
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ printf("%ld tokens (out of %ld)\n",
+ (ptrdiff_t)(tok_ptr-tok_mem),(long)max_toks);
+}
+
+@** Index.
+Here is a cross-reference table for \.{CTANGLE}.
+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 and
+a few other things like ``ASCII code dependencies'' are indexed here too.
diff --git a/Build/source/texk/web2c/cwebdir/ctproofmac.tex b/Build/source/texk/web2c/cwebdir/ctproofmac.tex
new file mode 100644
index 00000000000..29533b84b4d
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctproofmac.tex
@@ -0,0 +1,353 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 3.6 --- May 2000
+% Modified for proofs in CTWILL
+\ifx\documentstyle\undefined\else\endinput\fi % LaTeX will use other macros
+\xdef\fmtversion{\fmtversion+CWEB3.6+PROOFS}
+
+\let\:=\. % preserve a way to get the dot accent
+ % (all other accents will still work as usual)
+
+\parskip 0pt % no stretch between paragraphs
+\parindent 1em % for paragraphs and for the first line of C text
+
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\CEE/{{\mc C\spacefactor1000}}
+\def\UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\def\TEX/{\TeX}
+\def\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\def\Cee{\CEE/} % for backward compatibility
+\def\9#1{}
+\font\eightrm=cmr8
+\let\sc=\eightrm % small caps (NOT a caps-and-small-caps font)
+\let\mainfont=\tenrm
+\let\cmntfont\tenrm
+%\font\tenss=cmss10 \let\cmntfont\tenss % alternative comment font
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+\font\tentex=cmtex10 % TeX extended character set (used in strings)
+\fontdimen7\tentex=0pt % no double space after sentences
+
+\def\\#1{\leavevmode\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\leavevmode\hbox{$#1$}} % one-letter identifiers look better this way
+\def\&#1{\leavevmode\hbox{\bf
+ \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+ #1\/\kern.05em}} % boldface type for reserved words
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+\def\){{\tentex\kern-.05em}\discretionary{\hbox{\tentex\BS}}{}{}}
+\def\AT{@} % at sign for control text (not needed in versions >= 2.9)
+\def\ATL{\par\noindent\bgroup\catcode`\_=12 \postATL} % print @l in limbo
+\def\postATL#1 #2 {\bf letter \\{\uppercase{\char"#1}}
+ tangles as \tentex "#2"\egroup\par}
+\def\noATL#1 #2 {}
+\def\noatl{\let\ATL=\noATL} % suppress output from @l
+\def\ATH{\X\kern-.5em:Preprocessor definitions\X}
+\let\PB=\relax % hook for program brackets |...| in TeX part or section name
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\chardef\RB=`\} % right brace in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+\chardef\CF=`\^ % circumflex character in a string
+
+\newbox\PPbox % symbol for ++
+\setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+\def\PP{\copy\PPbox}
+\newbox\MMbox \setbox\MMbox=\hbox{\kern.5pt\raise1pt\hbox{\sevensy\char0
+ \kern-1pt\char0}\kern.5pt}
+\def\MM{\copy\MMbox}
+\newbox\MGbox % symbol for ->
+\setbox\MGbox=\hbox{\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+\def\MG{\copy\MGbox}
+\def\MRL#1{\mathrel{\let\K==#1}}
+\let\GG=\gg
+\let\LL=\ll
+\let\NULL=\Lambda
+\mathchardef\AND="2026 % bitwise and; also \& (unary operator)
+\let\OR=\mid % bitwise or
+\let\XOR=\oplus % bitwise exclusive or
+\def\CM{{\sim}} % bitwise complement
+\newbox\MODbox \setbox\MODbox=\hbox{\eightrm\%}
+\def\MOD{\mathbin{\copy\MODbox}}
+\def\DC{\kern.1em{::}\kern.1em} % symbol for ::
+\def\PA{\mathbin{.*}} % symbol for .*
+\def\MGA{\mathbin{\MG*}} % symbol for ->*
+\def\this{\&{this}}
+
+\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+\def\8{\hskip-\ind em\hskip 2em} % no indentation
+
+\newcount\gdepth % depth of current major group, plus one
+\newcount\secpagedepth
+\secpagedepth=3 % page breaks will occur for depths -1, 0, and 1
+\newtoks\gtitle % title of current major group
+\newskip\intersecskip \intersecskip=12pt minus 3pt % space between sections
+\let\yskip=\smallskip
+\def\?{\mathrel?}
+\def\note#1#2.{\Y\noindent{\hangindent2em\baselineskip10pt\eightrm#1~#2.\par}}
+\def\lapstar{\rlap{*}}
+\def\stsec{\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent{\let\*=\lapstar\bf\secstar.\quad}}
+\let\startsection=\stsec
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 } } % begin `define' or `format'
+\def\A{\note{See also section}} % xref for doubly defined section name
+\def\As{\note{See also sections}} % xref for multiply defined section name
+\def\B{\rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\C#1{\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$}
+\let\SHC\C % "// short comments" treated like "/* ordinary comments */"
+%\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+%\def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+\def\D{\defin{\#define}} % macro definition
+\let\E=\equiv % equivalence sign
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+% \H is long Hungarian umlaut accent
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K== % assignment operator
+%\let\K=\leftarrow % "honest" alternative to standard assignment operator
+% \L is Polish letter suppressed-L
+\outer\def\M#1{\MN{#1}\ifon\vfil\penalty-100\vfilneg % beginning of section
+ \vskip\intersecskip\startsection\ignorespaces}
+\outer\def\N#1#2#3.{\gdepth=#1\gtitle={#3}\MN{#2}% beginning of starred section
+ \ifon\ifnum#1<\secpagedepth \vfil\eject % force page break if depth is small
+ \else\vfil\penalty-100\vfilneg\vskip\intersecskip\fi\fi
+ \message{*\secno} % progress report
+ \edef\next{\write\cont{\ZZ{#3}{#1}{\secno}% write to contents file
+ {\noexpand\the\pageno}}}\next % \ZZ{title}{depth}{sec}{page}
+ \ifon\startsection{\bf#3.\quad}\ignorespaces}
+\def\MN#1{\par % common code for \M, \N
+ {\xdef\secstar{#1}\let\*=\empty\xdef\secno{#1}}% remove \* from section name
+ \ifx\secno\secstar \onmaybe \else\ontrue \fi
+ \mark{{{\tensy x}\secno}{\the\gdepth}{\the\gtitle}}}
+% each \mark is {section reference or null}{depth plus 1}{group title}
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+\def\Q{\note{This code is cited in section}} % xref for mention of a section
+\def\Qs{\note{This code is cited in sections}} % xref for mentions of a section
+\let\R=\lnot % logical not
+% \S is section sign
+\def\T#1{\leavevmode % octal, hex or decimal constant
+ \hbox{$\def\?{\kern.2em}%
+ \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct \let\^=\hex {#1}$}}
+\def\U{\note{This code is used in section}} % xref for use of a section
+\def\Us{\note{This code is used in sections}} % xref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,${\let\I=\ne#2\eightrm\kern.5em#1}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\le
+\let\ZZ=\let % now you can \write the control sequence \ZZ
+\let\*=*
+
+%\def\oct{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}} % WEB style
+%\def\hex{\hbox{\rm\char"7D\tt\aftergroup}} % WEB style
+\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}% CWEB style
+\def\hex{\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} % CWEB style
+\def\vb#1{\leavevmode\hbox{\kern2pt\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule\kern2pt}} % verbatim string
+
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+\newif\ifon \newif\iftitle \newif\ifpagesaved
+
+\def\lheader{\mainfont\the\pageno\eightrm\qquad\grouptitle\hfill\title\qquad
+ \mainfont\topsecno} % top line on left-hand pages
+\def\rheader{\mainfont\topsecno\eightrm\qquad\title\hfill\grouptitle
+ \qquad\mainfont\the\pageno} % top line on right-hand pages
+\def\grouptitle{\let\i=I\let\j=J\uppercase\expandafter{\expandafter
+ \takethree\topmark}}
+\def\topsecno{\expandafter\takeone\topmark}
+\def\takeone#1#2#3{#1}
+\def\taketwo#1#2#3{#2}
+\def\takethree#1#2#3{#3}
+\def\nullsec{\eightrm\kern-2em} % the \kern-2em cancels \qquad in headers
+
+\def\page{\box255 }
+\def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
+ \shipout\vbox{
+ \vbox to\fullpageheight{
+ \iftitle\global\titlefalse
+ \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
+ \vfill#1}} % parameter #1 is the page itself
+ \global\advance\pageno by1}
+
+\gtitle={\.{CWEB} output} % this running head is reset by starred sections
+\mark{\noexpand\nullsec0{\the\gtitle}}
+\def\title{\expandafter\uppercase\expandafter{\jobname}}
+\def\topofcontents{\centerline{\titlefont\title}\vskip.7in
+ \vfill} % this material will start the table of contents page
+\def\botofcontents{\vfill
+ \centerline{\covernote}} % this material will end the table of contents page
+\def\covernote{}
+\def\contentspagenumber{0} % default page number for table of contents
+\newdimen\pagewidth \pagewidth=6.5in % the width of each page
+\newdimen\pageheight \pageheight=8.7in % the height of each page
+\newdimen\fullpageheight \fullpageheight=9in % page height including headlines
+\newdimen\pageshift \pageshift=0in % shift righthand pages wrt lefthand ones
+\def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
+ \fullpageheight=9truein\setpage}
+\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+\def\contentsfile{\jobname.toc} % file that gets table of contents info
+\def\readcontents{\input \contentsfile}
+\def\readindex{\input \jobname.idx}
+\def\readsections{\input \jobname.scn}
+
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
+ \global\output{\normaloutput\page\lheader\rheader}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+
+\def\mini{\Y\bgroup\obeylines}
+{\obeylines
+ \gdef\[#1 #2 #3
+{\noindent\kern.5\hsize #2\miniform#3, \S#1.\par}%
+ \gdef\]#1 #2 #3
+{\noindent\kern.5\hsize #2\miniform#3, \extref#1.\par}}
+\def\miniform{\futurelet\next\miniforma}
+\def\miniforma{\ifx\next\zip
+ \else\if=\noexpand\next \let\next\gobbleq
+ \else\let\next\colon\fi\fi\next}
+\def\zip{}
+\def\gobbleq={\,=\,}
+\def\colon{: }
+\def\extref{\futurelet\next\extrefa}
+\def\extrefa{\if"\next\let\next\gobblest\else\let\next\cite\fi\next}
+\def\gobblest"#1"{{\tentex#1}}
+\def\cite#1#2.{{\sc#1}\,\S#2.}
+\let\FI=\fi
+\let\shortpage=\relax
+\let\forcebr=\relax
+\def\uninitialized{???}
+
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \write\cont{} % ensure that the contents file isn't empty
+ \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Index:}
+ \parskip 0pt plus .5pt
+ \outer\def\I##1, {\par\hangindent2em\noindent##1:\kern1em} % index entry
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt
+ \readindex}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \parfillskip 0pt plus 1fil
+ \def\grouptitle{NAMES OF THE SECTIONS}
+ \let\topsecno=\nullsec
+ \message{Section names:}
+ \output={\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1~##2.}}
+ \def\Q{\note{Cited in section}} % crossref for mention of a section
+ \def\Qs{\note{Cited in sections}} % crossref for mentions of a section
+ \def\U{\note{Used in section}} % crossref for use of a section
+ \def\Us{\note{Used in sections}} % crossref for uses of a section
+ \def\I{\par\hangindent 2em}\let\*=*
+ \readsections}
+\def\con{\par\vfill\eject % finish the section names
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage \output={\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber
+ \def\grouptitle{TABLE OF CONTENTS}
+ \message{Table of contents:}
+ \topofcontents
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \let\ZZ=\contentsline
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+\def\contentsline#1#2#3#4{\ifnum#2=0 \smallbreak\fi
+ \line{\consetup{#2}#1
+ \rm\leaders\hbox to .5em{.\hfil}\hfil\ #3\hbox to3em{\hss#4}}}
+\def\consetup#1{\ifcase#1 \bf % depth -1 (@**)
+ \or % depth 0 (@*)
+ \or \hskip2em % depth 1 (@*1)
+ \or \hskip4em % depth 2 (@*2)
+ \or \hskip6em % depth 3 (@*3)
+ \or \hskip8em % depth 4 (@*4)
+ \or \hskip10em % depth 5 (@*5)
+ \else \hskip12em \fi} % depth 6 or more
+\def\noinx{\let\inx=\end} % no indexes or table of contents
+\def\nosecs{\let\FIN=\fin \def\fin{\let\parfillskip=\end \FIN}}
+ % no index of section names or table of contents
+\def\nocon{\let\con=\end} % no table of contents
+\def\today{\ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\day, \number\year}
+\newcount\twodigits
+\def\hours{\twodigits=\time \divide\twodigits by 60 \printtwodigits
+ \multiply\twodigits by-60 \advance\twodigits by\time :\printtwodigits}
+\def\gobbleone1{}
+\def\printtwodigits{\advance\twodigits100
+ \expandafter\gobbleone\number\twodigits
+ \advance\twodigits-100 }
+\def\TeX{{\ifmmode\it\fi
+ \leavevmode\hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
+\def\datethis{\def\startsection{\leftline{\sc\today\ at \hours}\bigskip
+ \let\startsection=\stsec\stsec}}
+ % say `\datethis' in limbo, to get your listing timestamped before section 1
+\def\datecontentspage{%
+ \def\topofcontents{\leftline{\sc\today\ at \hours}\bigskip
+ \centerline{\titlefont\title}\vfill}} % timestamps the contents page
+\def\formatoff{\gdef\F##1\par{\setbox0=\lastbox\par}} % omits output of @f
+\def\formaton{\gdef\F{\defin{format}}} % restores output of @f
+ % hack: you can say @t}\par\formaton{@> at end of an @f being suppressed
diff --git a/Build/source/texk/web2c/cwebdir/cttwinxmac.tex b/Build/source/texk/web2c/cwebdir/cttwinxmac.tex
new file mode 100644
index 00000000000..99ae6047ab4
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cttwinxmac.tex
@@ -0,0 +1,319 @@
+% macros for index produced by twinx
+
+\let\:=\. % preserve a way to get the dot accent
+ % (all other accents will still work as usual)
+\def\TeX{{\ifmmode\it\fi
+ \hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
+\let\mc=\ninerm % medium caps
+\def\CEE/{{\mc C\spacefactor1000}}
+\def\UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\def\TEX/{\TeX}
+\def\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\def\9#1{}
+
+\newdimen\em \em=10pt % this "em" will not change with font size
+\parskip 0pt plus .1pt % almost no stretch between paragraphs
+\parindent 1\em % for paragraphs and for the first line of C text
+
+\font\ninerm=cmr9
+\font\eightrm=cmr8
+\font\sixrm=cmr6
+\font\ninei=cmmi9
+\font\eighti=cmmi8
+\font\sixi=cmmi6
+\skewchar\ninei='177 \skewchar\eighti='177 \skewchar\sixi='177
+\font\ninesy=cmsy9
+\font\eightsy=cmsy8
+\font\sixsy=cmsy6
+\skewchar\ninesy='60 \skewchar\eightsy='60 \skewchar\sixsy='60
+\font\ninebf=cmbx9
+\font\eightbf=cmbx8
+\font\sixbf=cmbx6
+\font\ninett=cmtt9
+\font\eighttt=cmtt8
+\hyphenchar\ninett=-1 \hyphenchar\eighttt=-1
+\font\ninesl=cmsl9
+\font\eightsl=cmsl8
+\font\nineit=cmti9
+\font\eightit=cmti8
+\font\tentex=cmtex10
+\font\ninetex=cmtex9 % TeX extended character set (used in strings)
+\font\eighttex=cmtex8
+\fontdimen7\tentex=0pt % no double space after sentences
+\fontdimen7\ninetex=0pt
+\fontdimen7\eighttex=0pt
+
+\newif\iftenpoint
+\def\tenpoint{\tenpointtrue
+ \def\rm{\fam0\tenrm}%
+ \textfont0=\tenrm \scriptfont0=\sevenrm \scriptscriptfont0=\fiverm
+ \textfont1=\teni \scriptfont1=\seveni \scriptscriptfont1=\fivei
+ \textfont2=\tensy \scriptfont2=\sevensy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\tenit}%
+ \textfont\itfam=\tenit
+ \def\sl{\fam\slfam\tensl}%
+ \textfont\slfam=\tensl
+ \def\bf{\fam\bffam\tenbf}%
+ \textfont\bffam=\tenbf \scriptfont\bffam=\sevenbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\tentt}%
+ \textfont\ttfam=\tentt
+ \def\ttx{\tentex}%
+ \normalbaselineskip=12pt
+ \let\mc=\ninerm
+ \let\sc=\eightrm
+ \let\big=\tenbig
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width 0pt}%
+ \normalbaselines\rm}
+
+\def\ninepoint{\tenpointfalse
+ \def\rm{\fam0\ninerm}%
+ \textfont0=\ninerm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\ninei \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\ninesy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\nineit}%
+ \textfont\itfam=\nineit
+ \def\sl{\fam\slfam\ninesl}%
+ \textfont\slfam=\ninesl
+ \def\bf{\fam\bffam\ninebf}%
+ \textfont\bffam=\ninebf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\ninett}%
+ \textfont\ttfam=\ninett
+ \def\ttx{\ninetex}%
+ \normalbaselineskip=11pt
+ \let\mc=\eightrm
+ \let\sc=\sevenrm
+ \let\big=\ninebig
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width 0pt}%
+ \normalbaselines\rm}
+
+\def\eightpoint{%
+ \def\rm{\fam0\eightrm}%
+ \textfont0=\eightrm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\eighti \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\eightsy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\eightit}%
+ \textfont\itfam=\eightit
+ \def\sl{\fam\slfam\eightsl}%
+ \textfont\slfam=\eightsl
+ \def\bf{\fam\bffam\eightbf}%
+ \textfont\bffam=\eightbf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\eighttt}%
+ \textfont\ttfam=\eighttt
+ \def\ttx{\eighttex}%
+ \normalbaselineskip=9pt
+ \let\mc=\sevenrm
+ \let\sc=\sixrm
+ \let\big=\eightbig
+ \setbox\strutbox=\hbox{\vrule height7pt depth2pt width 0pt}%
+ \normalbaselines\rm}
+
+\tenpoint
+\def\tenbig#1{{\hbox{$\left#1\vbox to8.5pt{}\right.\nulldelimiterspace=0pt$}}}
+\def\ninebig#1{{\hbox{$\textfont0=\tenrm\textfont2=\tensy
+ \left#1\vbox to7.25pt{}\right.\nulldelimiterspace=0pt$}}}
+\def\eightbig#1{{\hbox{$\textfont0=\ninerm\textfont2=\ninesy
+ \left#1\vbox to6.5pt{}\right.\nulldelimiterspace=0pt$}}}
+
+\def\Cee{{\mc C\spacefactor1000}}
+\def\UNIX{{\mc UNIX\spacefactor1000}}
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+
+\def\\#1{\leavevmode\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\leavevmode\hbox{$#1$}} % one-letter identifiers look better this way
+\def\&#1{\leavevmode\hbox{\bf
+ \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+ #1\/\kern.05em}} % boldface type for reserved words
+\def\.#1{\leavevmode\hbox{\ttx % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.2em}}
+\def\){\discretionary{\hbox{\tentex\BS}}{}{}}
+\def\AT{@} % at sign for control text
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\chardef\RB=`\} % right brace in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+\chardef\CF=`\^ % circumflex character in a string
+
+\newbox\PPbox % symbol for ++
+\setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+\def\PP{\copy\PPbox}
+\newbox\MMbox \setbox\MMbox=\hbox{\kern.5pt\raise1pt\hbox{\sevensy\char0
+ \kern-1pt\char0}\kern.5pt}
+\def\MM{\copy\MMbox}
+\newbox\MGbox % symbol for ->
+\setbox\MGbox=\hbox{\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+\def\MG{\copy\MGbox}
+\let\GG=\gg
+\let\LL=\ll
+\let\NULL=\Lambda
+\mathchardef\AND="2026 % bitwise and; also \& (unary operator)
+\let\OR=\mid % bitwise or
+\let\XOR=\oplus % bitwise exclusive or
+\def\CM{{\sim}} % bitwise complement
+\newbox\MODbox \setbox\MODbox=\hbox{\eightrm\%}
+\def\MOD{\mathbin{\copy\MODbox}}
+
+\newbox\bak \setbox\bak=\hbox to -1\em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2\em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind \em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5\em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind \em\noindent\kern\ind \em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+\def\8{\hskip-\ind \em\hskip 2\em} % no indentation
+
+\let\yskip=\smallskip
+\def\?{\mathrel?}
+\def\note#1#2.{\par\penalty5000
+ \Y\noindent{\hangindent2\em\baselineskip10pt\eightrm#1~#2.\par}}
+\def\lapstar{\rlap{*}}
+\def\stsec{\tenpoint
+ \rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent\strut{\bf\modno.\quad}}
+\let\startsection=\stsec
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 } } % begin `define' or `format'
+\def\A{\note{See also section}} % xref for doubly defined section name
+\def\As{\note{See also sections}} % xref for multiply defined section name
+\def\B{\iftenpoint\ninepoint\fi
+ \rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 9999 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\C#1{\5\5\quad$/\ast\,$#1$\,\ast/$}
+\def\D{\defin{\#define}} % macro definition
+\let\E=\equiv % equivalence sign
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+% \H is long Hungarian umlaut accent
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K== % can be changed to left arrow, if desired
+% \L is Polish letter suppressed-L; we have no shorthand for \le
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+% \Q is not used
+\let\R=\lnot % logical not
+% \S is section sign
+\def\T#1{\leavevmode % octal, hex or decimal constant
+ \hbox{${\def\?{\kern.2em}%
+ \def\${\ell}% long constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct \let\^=\hex #1}$}}
+\def\U{\note{This code is used in section}} % xref for use of a section
+\def\Us{\note{This code is used in sections}} % xref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,${#2\sevenrm\kern.5em#1}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\let % now you can \send the control sequence \Z
+\let\*=*
+
+%\def\oct{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}} % WEB style
+%\def\hex{\hbox{\rm\char"7D\tt\aftergroup}} % WEB style
+\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}% CWEB style
+\def\hex{\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} % CWEB style
+\def\vb#1{\leavevmode\hbox{\kern2pt\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule\kern2pt}} % verbatim string
+
+\def\normaloutput#1{\shipout\vbox{
+ \vbox to 3pc{\ifodd\pageno\rightheadline\else\leftheadline\fi\vfill}
+ \nointerlineskip#1}
+ \global\advance\pageno 1 }
+\def\page{\box255 }
+
+\newif\ifpagesaved \newif\iftitle
+\def\leftheadline{\hbox to\pagewd{\vbox to10pt{}%
+ \iftitle\global\titlefalse\else\ninesl\rhead\fi
+ \hfil\eightrm\folio}}
+\def\rightheadline{\hbox to\pagewd{\vbox to10pt{}%
+ \eightrm\folio\hfil\ninesl\rhead\/}}
+\def\rhead{MASTER INDEX}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+
+\newdimen\pageht \pageht=19cm
+\newdimen\pagewd \pagewd=13cm
+\newdimen\colwd \colwd=\pagewd
+ \advance\colwd by -1pc \divide\colwd by 2 % for two columns
+
+% Usually some text will be inserted at the beginning, preceded by
+% \preinx and followed by \inx
+\def\preinx{\tenpoint \hsize=\pagewd
+ \output{\ifpagesaved\normaloutput{\box\sbox}\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \rightskip0pt \tolerance 200
+ \pagesavedfalse \parindent=20pt}
+\def\inx{\parindent=0pt
+ \vskip 15pt plus 1fil
+ \eject\setbox\sbox\vbox{\unvbox\sbox} % take text out of its box
+ \vsize=\pageht \advance\vsize by -\ht\sbox % the remaining height
+ \rightskip0pt plus 2.5em \tolerance 10000
+ \hsize=\colwd
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \output{\twocolout} \eightpoint}
+\vsize=\pageht
+\eightpoint
+\def\lr{L} % this tells whether the left or right column is next
+\def\twocolout{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageht{\box\sbox\vss
+ \hbox to\pagewd{\box\lbox\hfil\page}}}
+ \global\vsize=\pageht\gdef\lr{L}\global\pagesavedfalse\fi}
+\output{\twocolout}
+\parskip 0pt plus .5pt
+\outer\def\I#1\unskip, {\par\hangindent2em\noindent#1:\kern1em} % index entry
+\def\[#1]{$\underline{#1}$} % underlined index item
+\rm \rightskip0pt plus 2.5em \tolerance 10000
+\hyphenpenalty 10000
+\parindent0pt
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \end}
+
+\input twinx-startup % custom IDs, \preinx copy, etc.
+
+% To produce only a subset of pages, put the page numbers on separate
+% lines in a file called pages.tex
+\let\Shipout=\shipout
+\newread\pages \newcount\nextpage \openin\pages=pages
+\def\getnextpage{\ifeof\pages\else
+ {\endlinechar=-1\read\pages to\next
+ \ifx\next\empty % in this case we should have eof now
+ \else\global\nextpage=\next\fi}\fi}
+\ifeof\pages\else\message{OK, I'll ship only the requested pages!}
+ \getnextpage\fi
+\def\shipout{\ifeof\pages\let\next=\Shipout
+ \else\ifnum\pageno=\nextpage\getnextpage\let\next=\Shipout
+ \else\let\next=\Tosspage\fi\fi \next}
+\newbox\garbage \def\Tosspage{\deadcycles=0\setbox\garbage=}
diff --git a/Build/source/texk/web2c/cwebdir/ctwill-mini.ch b/Build/source/texk/web2c/cwebdir/ctwill-mini.ch
new file mode 100644
index 00000000000..a3569f3442d
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctwill-mini.ch
@@ -0,0 +1,1151 @@
+Section 1.
+
+@x
+@** Introduction.
+@y
+\ifacro \ifx\undefined\pdfpagewidth\else
+ \pdfpagewidth=\pagewd \advance\pdfpagewidth by 2cm
+ \pdfpageheight=\pageht \advance\pdfpageheight by 5cm
+ \ifpdftex \pdfhorigin=1cm \pdfvorigin=1cm
+ \else \global\hoffset=-1.54cm \global\voffset=-1.54cm \fi
+\fi\fi
+
+@** Introduction.
+@z
+
+@x
+@d banner "This is CTWILL, Version 4.2"
+@y
+\bigskip
+{\font\itt=cmitt10 \font\bit=cmbxti10
+\noindent \bit Editor's Note: \it Although {\itt CTWILL} is based on
+{\itt cweave.w}, new and modified material is incorporated all over the place,
+without taking special care to keep the original section numbering intact.
+\smallskip
+\noindent Moreover, this heavily redacted version of {\itt ctwill.pdf} had to
+meddle with the section numbering even more, spreading tabular material over
+several sections and splitting long sections into smaller chunks in order to
+fix overful pages---both horizontally and vertically---, to make the overall
+appearance of the {\itt CTWILL} documentation most pleasing to the
+readers'~eyes.
+\smallskip
+\noindent Please do not try to compare this {\itt ctwill.pdf} to the one
+created by {\itt CWEAVE} instead of {\itt CTWILL}; the section numbering will
+be even more ``off'' from {\itt cweave.w}. Care has been taken to give a
+faithful overall rendering of {\itt CTWILL}'s code, though. \hfill
+---Enjoy!\bigskip}
+
+@d banner "This is CTWILL, Version 4.2"
+@z
+
+Section 2.
+
+@x
+@ Here is a sort of user manual for \.{CTWILL}---which is exactly like
+@y
+@* \.{CTWILL} user manual.
+Here is a sort of user manual for \.{CTWILL}---which is exactly like
+@z
+
+@x
+give it the necessary hints in other places via your change file.
+@y
+give it the necessary hints in other places via your change file.
+@-f@>
+@-x@>
+@z
+
+Section 3.
+
+@x
+The current meaning of every identifier is initially `\.{\\uninitialized}'.
+@y
+@ The current meaning of every identifier is initially `\.{\\uninitialized}'.
+@z
+
+@x
+must have fewer than 50 characters. If the \TeX\ part starts
+@y
+must have fewer than 50 characters.
+
+@d max_tex_chars 50 /* limit on the \TeX\ part of a meaning */
+
+@ If the \TeX\ part starts
+@z
+
+Section 4.
+
+@x
+@d max_tex_chars 50 /* limit on the \TeX\ part of a meaning */
+@y
+@z
+
+Section 5.
+
+@x
+@ \.{CWEAVE} has a fairly straightforward outline. It operates in
+@y
+@* Introduction (continued). \.{CWEAVE} has a fairly straightforward outline.
+It operates in
+@z
+
+Section 7.
+
+@x
+internationalization.
+@y
+internationalization.
+@-A@>
+@-HAVE_GETTEXT@>
+@-S@>
+@z
+
+Section 9.
+
+@x
+@ Code related to input routines:
+@y
+@ Code related to input routines:
+@-c@>
+@z
+
+Section 13.
+
+@x
+@ Code related to identifier and section name storage:
+@y
+@ Code related to identifier and section name storage:
+@-c@>
+@z
+
+Section 15.
+
+@x
+@ Code related to error handling:
+@y
+@ Code related to error handling:
+@-s@>
+@z
+
+Section 17.
+
+@x
+extern const char *use_language; /* prefix to \.{cwebmac.tex} in \TEX/ output */
+@y
+extern const char *use_language; /* prefix to \.{ctwimac.tex} in \TEX/ output */
+@z
+
+Section 18.
+
+@x
+@ Code related to output:
+@y
+@ Code related to output:
+@-a@>
+@-b@>
+@-c@>
+@z
+
+Section 23.
+
+@x
+@* Data structures exclusive to {\tt CWEAVE}.
+@y
+@* Data structures exclusive to {\tt CWEAVE}.
+@-a@>
+@z
+
+Section 25.
+
+@x
+@ The other large memory area in \.{CWEAVE} keeps the cross-reference data.
+@y
+@ The other large memory area in \.{CWEAVE} keeps the cross-reference data.
+@-p@>
+@-x@>
+@z
+
+Section 27.
+
+@x
+@ \.{CTWILL} also has special data structures to keep track of current
+@y
+@r @ \.{CTWILL} also has special data structures to keep track of current
+@z
+
+Section 32.
+
+@x
+@ The |new_meaning| routine changes the current ``permanent meaning''
+@y
+@r @ The |new_meaning| routine changes the current ``permanent meaning''
+@z
+
+Section 35.
+
+@x
+@ A new cross-reference for an identifier is formed by calling |new_xref|,
+@y
+@ A new cross-reference for an identifier is formed by calling |new_xref|,
+@-a@>
+@-c@>
+@z
+
+Section 44.
+
+@x
+@ We have to get \CEE/'s
+@y
+@r @ We have to get \CEE/'s
+@z
+
+Section 45.
+
+@x
+id_lookup("goto",NULL,case_like);
+@y
+@ @<Store all...@>=
+id_lookup("goto",NULL,case_like);
+@z
+
+Section 49.
+
+@x
+@ Control codes are converted to \.{CWEAVE}'s internal
+@y
+@r @ Control codes are converted to \.{CWEAVE}'s internal
+@z
+
+Section 55.
+
+@x
+\yskip\hang |xref_roman|, |xref_wildcard|, |xref_typewriter|, |TeX_string|,
+|meaning|, |suppress|,
+|verbatim|: The values of |id_first| and |id_loc| will have been set to
+the beginning and ending-plus-one locations in the buffer.
+
+\yskip\hang |section_name|: In this case the global variable |cur_section| will
+point to the |byte_start| entry for the section name that has just been scanned.
+The value of |cur_section_char| will be |'('| if the section name was
+preceded by \.{@@(} instead of \.{@@<}.
+@y
+{\raggedright
+\yskip\hang |xref_roman|, |xref_wildcard|, |xref_typewriter|, |TeX_string|,
+|meaning|, |suppress|,
+and |verbatim|: The values of |id_first| and |id_loc| will have been set to
+the beginning and ending-plus-one locations in the buffer.
+
+\yskip\hang |section_name|: In this case the global variable |cur_section| will
+point to the\hfil\break |byte_start| entry for the section name that has just been scanned.
+The value of |cur_section_char| will be |'('| if the section name was
+preceded by \.{@@(} instead of \.{@@<}.\par}
+@z
+
+Section 56.
+
+@x
+@ As one might expect, |get_next| consists mostly of a big switch
+@y
+@ As one might expect, |get_next| consists mostly of a big switch
+@-c@>
+@z
+
+Section 63.
+
+@x
+@ The following code assigns values to the combinations \.{++},
+@y
+@ The following code assigns values to the combinations \.{++},
+@-c@>
+@z
+
+Section 66.
+
+@x
+@<Get a string@>= {
+@y
+@<Get a string@>= {@+
+@z
+
+Section 70.
+
+@x
+@ @<Put section name...@>=
+@y
+@r @ @<Put section name...@>=
+@z
+
+Section 84.
+
+@x
+with |next_control!='|'| and ends with |next_control>=format_code|. Thus, it
+@y
+with |next_control| |!='|'| and ends with |next_control>=format_code|.
+Thus, it
+@z
+
+Section 91.
+
+@x
+@ Finally, when the \TEX/ and definition parts have been treated, we have
+|next_control>=begin_C|.
+@y
+@ Finally, when the \TEX/ and definition parts have been treated, we have
+\hfil\break|next_control>=begin_C|.
+@z
+
+Section 97.
+
+@x
+@ The |flush_buffer| routine empties the buffer up to a given breakpoint,
+@y
+@ The |flush_buffer| routine empties the buffer up to a given breakpoint,
+@-c@>
+@z
+
+Section 99.
+
+@x
+@ When we are copying \TEX/ source material, we retain line breaks
+@y
+@r @ When we are copying \TEX/ source material, we retain line breaks
+@z
+
+Section 101.
+
+@x
+@ When we wish to append one character |c| to the output buffer, we write
+@y
+@ When we wish to append one character |c| to the output buffer, we write
+@-c@>
+@z
+
+Section 105.
+
+@x
+@ We get to this section only in the unusual case that the entire output line
+@y
+@r @ We get to this section only in the unusual case that the entire output line
+@z
+
+Section 111.
+
+@x
+@ The |copy_TeX| routine processes the \TEX/ code at the beginning of a
+@y
+@r @ The |copy_TeX| routine processes the \TEX/ code at the beginning of a
+@z
+
+@x
+static eight_bits
+copy_TeX(void)
+{
+@y
+static eight_bits
+copy_TeX(void)
+{@+
+@z
+
+Section 112.
+
+@x
+@ The |copy_comment| function issues a warning if more braces are opened than
+@y
+@ The |copy_comment| function issues a warning if more braces are opened than
+@-t@>
+@z
+
+@x
+int bal@t\2\2@>) /* brace balance */
+{
+ char c; /* current character being copied */
+@y
+int bal@t\2\2@>) /* brace balance */
+{@+
+ char c; /* current character being copied */
+@z
+
+Section 117.
+
+@x
+@ Here is a list of the category codes that scraps can have.
+@y
+@r @ Here is a list of the category codes that scraps can have.
+@z
+
+Section 121.
+
+@x
+@ The token lists for translated \TEX/ output contain some special control
+@y
+@r @ The token lists for translated \TEX/ output contain some special control
+@-n@>
+@z
+
+Section 122.
+
+@x
+\yskip\noindent All of these tokens are removed from the \TEX/ output that
+@y
+@ All of these tokens are removed from the \TEX/ output that
+@-n@>
+@z
+
+Section 123.
+
+@x
+@ The raw input is converted into scraps according to the following table,
+@y
+@* From raw input to scraps.
+@-c@>
+\advance \hsize by 4cm
+\ifx\undefined\pdfpagewidth \else \advance \pdfpagewidth by 4cm \fi
+The raw input is converted into scraps according to the following table,
+@z
+
+@x
+\yskip\halign{\quad#\hfil&\quad#\hfil&\quad\hfil#\hfil\cr
+@y
+\yskip\halign{\quad#\hfil&\quad\hbox to11cm{#\hfil}&\quad\hfil#\hfil\cr
+@z
+
+Section 124.
+
+@x
+\.>&|prerangle|: \.{\\rangle}&yes\cr
+@y
+\.>&|prerangle|: \.{\\rangle}&yes\cr}
+
+@ Cont.
+
+\yskip\halign{\quad#\hfil&\quad#\hfil&\quad\hfil#\hfil\cr
+@z
+
+Section 125.
+
+@x
+\.{continue}&|case_like|: \stars&maybe\cr
+@y
+\.{continue}&|case_like|: \stars&maybe\cr}
+
+@r @ Cont.
+
+\yskip\halign{\quad#\hfil&\quad#\hfil&\quad\hfil#\hfil\cr
+@z
+
+Section 126.
+
+@x
+\.{long}&|raw_int|: \stars&maybe\cr
+@y
+\.{long}&|raw_int|: \stars&maybe\cr}
+
+@ Cont.
+
+\yskip\halign{\quad#\hfil&\quad#\hfil&\quad\hfil#\hfil\cr
+@z
+
+Section 127.
+
+@x
+\.{try}&|else_like|: \stars&maybe\cr
+@y
+\.{try}&|else_like|: \stars&maybe\cr}
+
+@r @ Cont.
+
+\yskip\halign{\quad#\hfil&\quad#\hfil&\quad\hfil#\hfil\cr
+@z
+
+Sections 128--135.
+
+@x l.7 line numbers refer to 'prod.w'
+@ Here is a table of all the productions. Each production that
+@y
+@* Table of all productions. Each production that
+@z
+
+TeX reports 'extra \fi' when running on twilled 'ctwill.w'.
+
+@x l.14
+\fi \newcount\prodno \newdimen\midcol \let\+\relax \ifon
+@y
+\newcount\prodno \newdimen\midcol \let\+\relax
+@z
+
+@x l.78
+\+& |lpar| |rpar| & |exp| \hfill $L\.{\\,}R$ & functions, declarations\cr
+@y
+\+& |lpar| |rpar| & |exp| \hfill $L\.{\\,}R$ & functions, declarations\cr
+\endgroup
+@-in@>@-f@>@-x@>@-y@>
+
+@r @ Cont.
+\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@-in@>@-x@>@-y@>
+\prodno=13 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}}
+@z
+
+@x l.45
+ |int_like| \alt|raw_int| |struct_like| & |extern "Ada" int|\cr
+@y
+ |int_like| \alt|raw_int| |struct_like| & |extern "Ada" int|\cr
+\endgroup
+
+@ Cont.
+\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@-in@>
+\prodno=27 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}}
+@z
+
+@x l.75
+ \&{struct} \&{name\_info} $\{$\cr
+@y
+ \&{struct} \&{name\_info} $\{$\cr
+\endgroup
+
+@r @ Cont.@-z@>@-in@>
+\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@-in@>
+\prodno=47 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}}
+@z
+
+@x l.164
+ $|force|\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|$ & |else x=0;|\cr
+@y
+ $|force|\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|$ & |else x=0;|\cr
+\endgroup
+
+@ Cont.
+\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@-any@>@-z@>@-g@>@-a@>@-x@>@-y@>@-f@>
+\prodno=61 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}}
+\advance\midcol20pt
+@z
+
+@x l.211
+\+& |prerangle| & |binop| \hfill \.> & $>$ not in template\cr
+@y
+\+& |prerangle| & |binop| \hfill \.> & $>$ not in template\cr
+\endgroup
+
+@r @ Cont.
+\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@-any@>@-z@>@-g@>@-a@>
+\prodno=86 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}}
+@z
+
+@x l.232
+\+\dagit& |new_exp| & |exp| & |new int;|\cr
+@y
+\+\dagit& |new_exp| & |exp| & |new int;|\cr
+\endgroup
+
+@ Cont.
+\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@-any_other@>@-z@>@-f@>@-x@>@-p@>
+\prodno=100 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}}
+\advance\midcol20pt
+@z
+
+@x
+\advance\midcol-3pt
+\+\dag200\enspace& |typedef_like| |decl_head| \alt|exp| |int_like| &
+ |typedef_like| |decl_head| \hfill $D=D$\alt $E^{**}$ $I^{**}$ \unskip &
+ \&{typedef} \&{char} \&{ch};\cr
+\advance\midcol+3pt
+\+201\enspace& |typedef_like| |decl_head| |semi| & |decl| \hfill $T\.\ D$ &
+ \&{typedef} \&{int} $\&x,\&y$;\cr
+\+\dag202\enspace& |typedef_like| |int_like| |raw_int| & |typedef_like| |int_like| |exp| &
+ \&{typedef} \&{int} \&{foo}\cr
+@y
+@z
+
+@x l.272
+\+& |any_other| |end_arg| & |end_arg| & \&{char}$*$\.{@@]}\cr
+\yskip
+\yskip
+\yskip
+\parindent=0pt
+\dag{\bf Notes}
+@y
+\+& |any_other| |end_arg| & |end_arg| & \&{char}$*$\.{@@]}\cr
+\advance\midcol-3pt
+\+\dag200\enspace& |typedef_like| |decl_head| \alt|exp| |int_like| &
+ |typedef_like| |decl_head| \hfill $D=D$\alt $E^{**}$ $I^{**}$ \unskip &
+ \&{typedef} \&{char} \&{ch};\cr
+\advance\midcol+3pt
+\+201\enspace& |typedef_like| |decl_head| |semi| & |decl| \hfill $T\.\ D$ &
+ \&{typedef} \&{int} $\&x,\&y$;\cr
+\+\dag202\enspace& |typedef_like| |int_like| |raw_int| & |typedef_like| |int_like| |exp| &
+ \&{typedef} \&{int} \&{foo}\cr
+\endgroup
+
+@r @-any_other@>@-z@>@ \begingroup\dag{\bf Notes}
+@z
+
+Section 136.
+
+@x
+@* Implementing the productions.
+@y
+@* Implementing the productions. \advance \hsize by -4cm
+\ifx\undefined\pdfpagewidth \else \advance \pdfpagewidth by -4cm \fi
+@z
+
+@x
+the category codes |pp->cat,@,@,(pp+1)->cat|$,\,\,\ldots\,$
+@y
+the category codes |pp->cat|, |(pp+1)->cat|, $\,\ldots\,$
+@z
+
+Section 139.
+
+@x
+@ Token lists in |@!tok_mem| are composed of the following kinds of
+@y
+@ Token lists in |@!tok_mem| are composed of the following kinds of
+@-p@>
+@z
+
+Section 141.
+
+@x
+@ @<Print token |r|...@>=
+@y
+@r @ @<Print token |r|...@>=
+@z
+
+Section 142.
+
+@x
+@ The production rules listed above are embedded directly into \.{CWEAVE},
+@y
+@ The production rules listed above are embedded directly into \.{CWEAVE},
+@-a@>
+@-c@>
+@-d@>
+@-j@>
+@-k@>
+@-n@>
+@-pp@>
+@z
+
+Section 143.
+
+@x
+The code below is an exact translation of the production rules into
+@y
+@r @ The code below is an exact translation of the production rules into
+@-a@>
+@z
+
+Section 146.
+
+@x
+@ Let us consider the big switch for productions now, before looking
+@y
+@r @ Let us consider the big switch for productions now, before looking
+@z
+
+Section 147.
+
+@x
+ switch (pp->cat) {
+ case exp: @<Cases for |exp|@>@; @+break;
+ case lpar: @<Cases for |lpar|@>@; @+break;
+ case unop: @<Cases for |unop|@>@; @+break;
+ case ubinop: @<Cases for |ubinop|@>@; @+break;
+ case binop: @<Cases for |binop|@>@; @+break;
+ case cast: @<Cases for |cast|@>@; @+break;
+ case sizeof_like: @<Cases for |sizeof_like|@>@; @+break;
+ case int_like: @<Cases for |int_like|@>@; @+break;
+ case public_like: @<Cases for |public_like|@>@; @+break;
+ case colcol: @<Cases for |colcol|@>@; @+break;
+ case decl_head: @<Cases for |decl_head|@>@; @+break;
+ case decl: @<Cases for |decl|@>@; @+break;
+ case base: @<Cases for |base|@>@; @+break;
+ case struct_like: @<Cases for |struct_like|@>@; @+break;
+ case struct_head: @<Cases for |struct_head|@>@; @+break;
+ case fn_decl: @<Cases for |fn_decl|@>@; @+break;
+ case function: @<Cases for |function|@>@; @+break;
+ case lbrace: @<Cases for |lbrace|@>@; @+break;
+ case if_like: @<Cases for |if_like|@>@; @+break;
+ case else_like: @<Cases for |else_like|@>@; @+break;
+ case else_head: @<Cases for |else_head|@>@; @+break;
+ case if_clause: @<Cases for |if_clause|@>@; @+break;
+ case if_head: @<Cases for |if_head|@>@; @+break;
+ case do_like: @<Cases for |do_like|@>@; @+break;
+ case case_like: @<Cases for |case_like|@>@; @+break;
+ case catch_like: @<Cases for |catch_like|@>@; @+break;
+ case tag: @<Cases for |tag|@>@; @+break;
+ case stmt: @<Cases for |stmt|@>@; @+break;
+ case semi: @<Cases for |semi|@>@; @+break;
+ case lproc: @<Cases for |lproc|@>@; @+break;
+ case section_scrap: @<Cases for |section_scrap|@>@; @+break;
+ case insert: @<Cases for |insert|@>@; @+break;
+ case prelangle: @<Cases for |prelangle|@>@; @+break;
+ case prerangle: @<Cases for |prerangle|@>@; @+break;
+ case langle: @<Cases for |langle|@>@; @+break;
+ case template_like: @<Cases for |template_like|@>@; @+break;
+ case new_like: @<Cases for |new_like|@>@; @+break;
+ case new_exp: @<Cases for |new_exp|@>@; @+break;
+ case ftemplate: @<Cases for |ftemplate|@>@; @+break;
+ case for_like: @<Cases for |for_like|@>@; @+break;
+ case raw_ubin: @<Cases for |raw_ubin|@>@; @+break;
+ case const_like: @<Cases for |const_like|@>@; @+break;
+ case raw_int: @<Cases for |raw_int|@>@; @+break;
+ case operator_like: @<Cases for |operator_like|@>@; @+break;
+ case typedef_like: @<Cases for |typedef_like|@>@; @+break;
+ case delete_like: @<Cases for |delete_like|@>@; @+break;
+ case question: @<Cases for |question|@>@; @+break;
+ }
+ pp++; /* if no match was found, we move to the right */
+}
+@y
+ switch (pp->cat) {
+ @<Cases for |pp->cat|@>@;
+ }
+ pp++; /* if no match was found, we move to the right */
+}
+
+@ @<Cases for |pp->cat|@>=
+ case exp: @<Cases for |exp|@>@; @+break;
+ case lpar: @<Cases for |lpar|@>@; @+break;
+ case unop: @<Cases for |unop|@>@; @+break;
+ case ubinop: @<Cases for |ubinop|@>@; @+break;
+ case binop: @<Cases for |binop|@>@; @+break;
+ case cast: @<Cases for |cast|@>@; @+break;
+ case sizeof_like: @<Cases for |sizeof_like|@>@; @+break;
+ case int_like: @<Cases for |int_like|@>@; @+break;
+ case public_like: @<Cases for |public_like|@>@; @+break;
+ case colcol: @<Cases for |colcol|@>@; @+break;
+ case decl_head: @<Cases for |decl_head|@>@; @+break;
+ case decl: @<Cases for |decl|@>@; @+break;
+ case base: @<Cases for |base|@>@; @+break;
+ case struct_like: @<Cases for |struct_like|@>@; @+break;
+ case struct_head: @<Cases for |struct_head|@>@; @+break;
+ case fn_decl: @<Cases for |fn_decl|@>@; @+break;
+ case function: @<Cases for |function|@>@; @+break;
+ case lbrace: @<Cases for |lbrace|@>@; @+break;
+ case if_like: @<Cases for |if_like|@>@; @+break;
+ case else_like: @<Cases for |else_like|@>@; @+break;
+ case else_head: @<Cases for |else_head|@>@; @+break;
+ case if_clause: @<Cases for |if_clause|@>@; @+break;
+ case if_head: @<Cases for |if_head|@>@; @+break;
+ case do_like: @<Cases for |do_like|@>@; @+break;
+ case case_like: @<Cases for |case_like|@>@; @+break;
+ case catch_like: @<Cases for |catch_like|@>@; @+break;
+ case tag: @<Cases for |tag|@>@; @+break;
+ case stmt: @<Cases for |stmt|@>@; @+break;
+ case semi: @<Cases for |semi|@>@; @+break;
+ case lproc: @<Cases for |lproc|@>@; @+break;
+ case section_scrap: @<Cases for |section_scrap|@>@; @+break;
+ case insert: @<Cases for |insert|@>@; @+break;
+ case prelangle: @<Cases for |prelangle|@>@; @+break;
+ case prerangle: @<Cases for |prerangle|@>@; @+break;
+ case langle: @<Cases for |langle|@>@; @+break;
+ case template_like: @<Cases for |template_like|@>@; @+break;
+ case new_like: @<Cases for |new_like|@>@; @+break;
+ case new_exp: @<Cases for |new_exp|@>@; @+break;
+ case ftemplate: @<Cases for |ftemplate|@>@; @+break;
+ case for_like: @<Cases for |for_like|@>@; @+break;
+ case raw_ubin: @<Cases for |raw_ubin|@>@; @+break;
+ case const_like: @<Cases for |const_like|@>@; @+break;
+ case raw_int: @<Cases for |raw_int|@>@; @+break;
+ case operator_like: @<Cases for |operator_like|@>@; @+break;
+ case typedef_like: @<Cases for |typedef_like|@>@; @+break;
+ case delete_like: @<Cases for |delete_like|@>@; @+break;
+ case question: @<Cases for |question|@>@; @+break;
+@z
+
+Section 148.
+
+@x
+of identifiers in case labels.
+
+If the first identifier is the keyword `\&{operator}', we give up;
+@y
+of identifiers in case labels.
+If the first identifier is the keyword `\&{operator}', we give up;
+@z
+
+Section 150.
+
+@x
+@ The scraps currently being parsed must be inspected for any
+@y
+@r @ The scraps currently being parsed must be inspected for any
+@z
+
+@x
+|make_reserved|, hence |tok_loc| has been set.
+@y
+\hfil\break|make_reserved|, hence |tok_loc| has been set.
+@z
+
+Section 154.
+
+@x
+@ \.{CTWILL} needs the following procedure, which appends tokens of a
+@y
+@r @ \.{CTWILL} needs the following procedure, which appends tokens of a
+@z
+
+Section 155.
+
+@x
+@ The trickiest part of \.{CTWILL} is the procedure |make_ministring(l)|,
+@y
+@ The trickiest part of \.{CTWILL} is the procedure |make_ministring(l)|,
+@-b@>
+@z
+
+@x
+ int l) /* 0, 1, or 2 */
+{
+@y
+ int l) /* 0, 1, or 2 */
+{@+
+@z
+
+Section 159.
+
+@x
+@ @<Cases for |lpar|@>=
+@y
+@r @ @<Cases for |lpar|@>=
+@z
+
+Section 168.
+
+@x
+@ @<Cases for |decl_head|@>=
+@y
+@r @ @<Cases for |decl_head|@>=
+@z
+
+Section 173.
+
+@x
+@ @<Cases for |fn_decl|@>=
+@y
+@r @ @<Cases for |fn_decl|@>=
+@z
+
+Section 208.
+
+@x
+@ Here's the |squash| procedure, which
+@y
+@r @ Here's the |squash| procedure, which
+@z
+
+Section 212.
+
+@x
+@ @<Print a snapsh...@>=
+@y
+@r @ @<Print a snapsh...@>=
+@z
+
+Section 220.
+
+@x
+@ The following macro is used to append a scrap whose tokens have just
+@y
+@ The following macro is used to append a scrap whose tokens have just
+@-b@>
+@-c@>
+@z
+
+Section 229.
+
+@x
+@ The |outer_parse| routine is to |C_parse| as |outer_xref|
+@y
+@r @ The |outer_parse| routine is to |C_parse| as |outer_xref|
+@z
+
+Section 235.
+
+@x
+@ To insert token-list |p| into the output, the |push_level| subroutine
+@y
+@r @ To insert token-list |p| into the output, the |push_level| subroutine
+@z
+
+Section 237.
+
+@x
+called when |stack_ptr==1|.
+@y
+called when |stack_ptr| |==1|.
+@z
+
+Section 241.
+
+@x
+ text_pointer save_text_ptr;
+ sixteen_bits save_next_control; /* values to be restored */
+ text_pointer p; /* translation of the \CEE/ text */
+@y
+ text_pointer save_text_ptr, p; /* translation of the \CEE/ text */
+ sixteen_bits save_next_control; /* values to be restored */
+@z
+
+Section 244.
+
+@x
+else @<Look ahead for strongest line break, |goto reswitch|@>
+@y
+else {@<Look ahead for strongest line break, |goto reswitch|@>}
+@z
+
+Section 245.
+
+@x
+@<Look ahead for st...@>= {
+@y
+@<Look ahead for st...@>=
+@z
+
+@x
+}
+@y
+@z
+
+Section 246.
+
+@x
+@ @<Output saved...@>=
+@y
+@r @ @<Output saved...@>=
+@z
+
+Section 250.
+
+@x
+@ The \CEE/ text enclosed in \pb\ should not contain `\.{\v}' characters,
+@y
+@r @ The \CEE/ text enclosed in \pb\ should not contain `\.{\v}' characters,
+@z
+
+Section 256.
+
+@x
+@ The output file will contain the control sequence \.{\\Y} between non-null
+@y
+@r @ The output file will contain the control sequence \.{\\Y} between non-null
+@z
+
+Section 259.
+
+@x
+@<Translate the \T...@>= do {
+@y
+@<Translate the \T...@>= do {@+
+@z
+
+Section 267.
+
+@x
+|next_control>=begin_C|. We will make the global variable |this_section|
+@y
+\hfil\break|next_control>=begin_C|. We will make the global variable |this_section|
+@z
+
+Section 268.
+
+@x
+@ @<Translate the \CEE/...@>=
+@y
+@r @ @<Translate the \CEE/...@>=
+@z
+
+Section 272.
+
+@x
+@ The |footnote| procedure gives cross-reference information about
+@y
+@r @ The |footnote| procedure gives cross-reference information about
+@z
+
+Section 284.
+
+@x
+@ A left-to-right radix sorting method is used, since this makes it easy to
+@y
+@ A left-to-right radix sorting method is used, since this makes it easy to
+@-c@>
+@z
+
+Section 286.
+
+@x
+@ During the sorting phase we shall use the |cat| and |trans| arrays from
+@y
+@ During the sorting phase we shall use the |cat| and |trans| arrays from
+@-j@>
+@-k@>
+@z
+
+Section 289.
+
+@x
+$|collate|[0]<|collate|[1]<\cdots<|collate|[100]$.
+@y
+|collate[0]| $<$|collate[1]|$<\cdots<$|collate[100]|.
+@z
+
+Section 296.
+
+@x
+ else {char *j;
+@y
+ else {@+char *j;
+@z
+
+Section 303.
+
+@x
+@ Because on some systems the difference between two pointers is a |ptrdiff_t|
+rather than an |int|, we use \.{\%ld} to print these quantities.
+@y
+@r @ Because on some systems the difference between two pointers is a
+|ptrdiff_t| rather than an |int|, we use \.{\%ld} to print these quantities.
+@z
+
+Section 304.
+
+@x
+\bigskip
+\font\itt=cmitt10
+{\noindent \it Although \.{\itt CTWILL} is based on \.{\itt cweave.w}, new and
+modified material is incorporated all over the place, without taking special
+care for keeping the original section numbering intact.}
+@y
+@z
+
+Section 312.
+
+@x
+@** 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.
+@y
+@z
diff --git a/Build/source/texk/web2c/cwebdir/ctwill-w2c.ch b/Build/source/texk/web2c/cwebdir/ctwill-w2c.ch
new file mode 100644
index 00000000000..777c3c28484
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctwill-w2c.ch
@@ -0,0 +1,1996 @@
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
+
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
+
+@q This stripped change file {comm,ctang,cweav,ctwill,cwebman}-w2c.ch @>
+@q has been created from the elaborate set of change files @>
+@q {comm,ctang,cweav,cwebman}-patch.ch, @>
+@q {comm,cweav,cwebman}-extensions.ch, {comm,ctang,cweav}-output.ch, @>
+@q {comm,ctang,cweav}-i18n.ch, and cweav-twill.ch for CTWILL, and @>
+@q {comm,ctang,cweav,ctwill,cwebman}-texlive.ch with the 'tie' processor @>
+@q and is used as a monolithic changefile for {common,ctangle,cweave}.w @>
+@q and cwebman.tex in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+@y
+% This program by Don Knuth is based on CWEAVE by Levy and Knuth.
+% It's somewhat flaky, so you probably shouldn't try to use it.
+@z
+
+@x
+% Here is TeX material that gets inserted after \input cwebmac
+@y
+% Here is TeX material that gets inserted after \input ctwimac
+\def\contentspagenumber{0} % default page number for table of contents
+@z
+
+@x
+\def\title{CWEAVE (Version 4.2)}
+@y
+\def\title{CTWILL (Version 4.2 [\TeX~Live])}
+@z
+
+@x
+ \centerline{\titlefont The {\ttitlefont CWEAVE} processor}
+@y
+ \centerline{\titlefont The {\ttitlefont CTWILL} processor}
+@z
+
+@x
+ \centerline{(Version 4.2)}
+@y
+ \centerline{(Version 4.2 [\TeX~Live])}
+@z
+
+@x
+\def\botofcontents{\vfill
+@y
+\def\covernote{\vbox{%
+@z
+
+@x
+}
+@y
+}}\datecontentspage
+@z
+
+@x
+This is the \.{CWEAVE} program by Silvio Levy and Donald E. Knuth,
+based on \.{WEAVE} by Knuth.
+We are thankful to Steve Avery,
+Nelson Beebe, Hans-Hermann Bode (to whom the original \CPLUSPLUS/ adaptation
+is due), Klaus Guntermann, Norman Ramsey, Tomas Rokicki, Joachim Schnitter,
+Joachim Schrod, Lee Wittenberg, Saroj Mahapatra, Cesar Augusto Rorato
+Crusius, and others who have contributed improvements.
+
+The ``banner line'' defined here should be changed whenever \.{CWEAVE}
+is modified.
+
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+This is the \.{CTWILL} program by D. E. Knuth, based
+on \.{CWEAVE} by Silvio Levy and D.~E. Knuth. It is also based on
+\.{TWILL}, a private \.{WEB} program that Knuth wrote to produce
+Volumes B and~D of {\sl Computers {\char`\&} Typesetting\/} in 1985.
+\.{CTWILL} was hacked together hastily in June, 1992, to generate pages for
+Knuth's book about the Stanford GraphBase, and updated even more hastily
+in March, 1993 to generate final copy for that book. The main idea was to
+extend \.{CWEAVE} so that ``mini-indexes'' could appear.
+No time was available to make \.{CTWILL} into a refined or complete system,
+nor even to fully update the program documentation below. Subsequent changes
+were made only to maintain compatibility with \.{CWEAVE}. Further information
+can be found in Knuth's article ``Mini-indexes for literate programs,''
+reprinted in {\sl Digital Typography\/} (1999), 225--245.
+
+The ``banner line'' defined here should be changed whenever \.{CTWILL} is
+modified. The version number parallels the corresponding version of \.{CWEAVE}.
+
+@d banner "This is CTWILL, Version 4.2"
+ /* will be extended by the \TeX~Live |versionstring| */
+@z
+
+@x
+@<Predeclaration of procedures@>
+@y
+@<Predeclaration of procedures@>
+
+@ Here is a sort of user manual for \.{CTWILL}---which is exactly like
+\.{CWEAVE} except that it produces much better documentation, for which you
+must work harder. As with \.{CWEAVE}, input comes from a source file
+\.{foo.w} and from an optional (but now almost mandatory) change file
+\.{foo.ch}; output goes to \.{foo.tex}, \.{foo.idx}, and \.{foo.scn}.
+Unlike \.{CWEAVE}, there is an additional output file, \.{foo.aux},
+which records all nonexternal definitions. The \.{.aux} file also
+serves as an input file on subsequent runs. You should run \.{CTWILL}
+twice, once to prime the pump and once to get decent answers.
+
+Moreover, you must run the output twice through \TeX. (This double duplicity
+suggested the original name \.{TWILL}.) After `\.{tex} \.{foo}' you
+will have output that looks like final pages except that the entries
+of mini-indexes won't be alphabetized. \TeX\ will say `This is the first
+pass', and it will produce a weird file called \.{foo.ref}. Say
+$$\.{refsort < foo.ref > foo.sref}$$
+and then another `\.{tex} \.{foo}' will produce alphabetized output.
+While \TeX\ runs it emits messages filled with numeric data, indicating how
+much space is consumed by each program section. If you can decipher these
+numbers (see \.{ctwimac.tex}), you can use them to fine-tune the page
+layout. You might be tempted to do fine tuning by editing \.{foo.tex}
+directly, but it's better to incorporate all changes into \.{foo.ch}.
+
+The mini-indexes list identifiers that are used but not defined on
+each two-page spread. At the end of each section, \.{CTWILL} gives
+\TeX\ a list of identifiers used in that section and information
+about where they are defined. The macros in \.{ctwimac.tex} figure out
+which identifiers should go in each mini-index, based on how the pages
+break. (Yes, those macros are pretty hairy.)
+
+The information that \.{CTWILL} concocts from \.{foo.w} is not always
+correct. Sometimes you'll use an identifier that you don't want
+indexed; for example, your exposition might talk about |f(x)| when you
+don't mean to refer to program variables |f| or |x|. Sometimes you'll
+use an identifier that's defined in a header file, unknown to
+\.{CTWILL}. Sometimes you'll define a single identifier in several
+different places, and \.{CTWILL} won't know which definition to choose.
+But all is not lost. \.{CTWILL} guesses right most of the time, and you can
+give it the necessary hints in other places via your change file.
+
+If you think it's easy to write a completely automatic system that doesn't
+make \.{CTWILL}'s mistakes and doesn't depend so much on change files,
+please do so.
+
+\.{CTWILL} uses a very simple method to generate mini-index info. By
+understanding this method, you will understand how to fix it when things
+go wrong. Every identifier has a current ``meaning,'' consisting of its
+abstract type and the number of the section in which it was most recently
+defined. For example, if your \Cee\ program says `|char *s|' in section~3,
+the meaning of~|s| gets changed to `\&{char} $*$, \S3' while \.{CTWILL}
+is processing that section. If you refer to~|s| in section~10, and if
+|s|~hasn't been redefined in the meantime, and if section~10 doesn't
+wind up on the same two-page spread as section~3, the mini-index generated
+by section~10 will say ``|s|: \&{char}~$*$, \S3.''
+
+The current meaning of every identifier is initially `\.{\\uninitialized}'.
+Then \.{CTWILL} reads the \.{.aux} file for your job, if any; this
+\.{.aux} file contains all definitions of new meanings in the previous
+run, so it tells \.{CTWILL} about definitions that will be occurring
+in the future. If all identifiers have a unique definition, they will
+have a unique and appropriate meaning in the mini-indexes.
+
+But some identifiers, like parameters to procedures, may be defined
+several times. Others may not be defined at all, because they are
+defined elsewhere and mentioned in header files included by the \Cee\
+preprocessor. To solve this problem, \.{CTWILL} provides mechanisms by which
+the current meaning of an identifier can be temporarily or permanently
+changed.
+
+For example, the operation
+$$\.{@@\$s \{FOO\}3 \\\&\{char\} \$*\$@@>}$$
+changes the current meaning of |s| to the \TeX\ output of `\.{\\\&\{char\}}
+\.{\$*\$}' in section~3 of program {\sc FOO}. All entries in the \.{.aux}
+file are expressed in the form of this \.{@@\$} operator; therefore you
+can use a text editor to paste such entries into a \.{.ch} file, whenever
+you want to tell \.{CTWILL} about definitions that are out of order
+or from other programs.
+
+Before reading the \.{.aux} file, \.{CTWILL} actually looks for a file
+called \.{system.bux}, which will be read if present. And after
+\.{foo.aux}, a third possibility is \.{foo.bux}. The general
+convention is to put definitions of system procedures such as |printf|
+into \.{system.bux}, and to put definitions found in specifically
+foo-ish header files into \.{foo.bux}. Like the \.{.aux}
+files, \.{.bux} files should contain only \.{@@\$} specifications;
+this rule corresponds to the fact that `bux' is the plural of `\$'.
+The \.{.bux} files may also contain \.{@@i} includes.
+
+A companion operation \.{@@\%} signifies that all \.{@@\$}
+specifications from the present point to the beginning of the next
+section will define {\it temporary\/} meanings instead of permanent
+ones. Temporary meanings are placed into the
+mini-index of the current section; the permanent (current) meaning of
+the identifier will not be changed, nor will it appear in the
+mini-index of the section. If several temporary meanings are assigned
+to the same identifier in a section, all will appear in the mini-index.
+Each \.{@@\%} toggles the temporary/permanent convention; thus, after
+an even number of \.{@@\%} operations in a section, meanings specified
+by \.{@@\$} are permanent.
+
+The operation \.{@@-} followed by an identifier followed by \.{@@>}
+specifies that the identifier should not generate a mini-index entry
+in the current section (unless, of course, a temporary meaning is assigned).
+
+If \.{@@-foo@@>} appears in a section where a new permanent meaning is
+later defined by the semantics of~\Cee, the current meaning of \\{foo}
+will not be redefined; moreover, this current meaning, which may have
+been changed by \.{@@\$foo ...@@>}, will also be written to the
+\.{.aux} file. Therefore you can control what \.{CTWILL} outputs; you
+can keep it from repeatedly contaminating the \.{.aux} file with
+things you don't like.
+
+The meaning specified by \.{@@\$...@@>} generally has four components:
+an identifier (followed by space), a program name (enclosed in braces),
+a section number (followed by space), and a \TeX\ part. The \TeX\ part
+must have fewer than 50 characters. If the \TeX\ part starts
+with `\.=', the mini-index entry will contain an equals sign instead
+of a colon; for example,
+$$\.{@@\$buf\_size \{PROG\}10 =\\T\{200\}@@>}$$
+generates either `$\\{buf\_size}=200$, \S10' or
+`$\\{buf\_size}=200$, {\sc PROG}\S10', depending on whether
+`{\sc PROG}' is or isn't the title of the current program. If the
+\TeX\ part is `\.{\\zip}', the mini-index entry will contain neither
+colon nor equals, just a comma. The program name and section number
+can also be replaced by a string. For example,
+$$\.{@@\$printf "<stdio.h>" \\zip@@>}$$
+will generate a mini-index entry like `\\{printf}, \.{<stdio.h>}.'.
+
+A special ``proofmode'' is provided so that you can check \.{CTWILL}'s
+conclusions about cross-references. Run \.{CTWILL} with the
+flag \.{+P}, and \TeX\ will produce a specially formatted document
+({\it without\/} mini-indexes)
+in which you can check that your specifications are correct.
+You should always do this before generating mini-indexes, because
+mini-indexes can mask errors if page breaks are favorable but the
+errors might reveal themselves later after your program has changed.
+The proofmode output is much easier to check than the mini-indexes themselves.
+
+The control code \.{@@r} or \.{@@R} causes \.{CTWILL} to emit
+the \TeX\ macro `\.{\\shortpage}' just before starting the next
+section of the program. This causes the section to appear at the top of
+a right-hand page, if it would ordinarily have appeared near the bottom
+of a left-hand page and split across the pages. (The \.{\\shortpage} macro
+is fragile and should be used only in cases where it will not mess up
+the output; insert it only when fine-tuning a set of pages.) If the
+next section is a starred section, the behavior is slightly different
+(but still fragile): The starred section will either be postponed to
+a left-hand page, if it normally would begin on a right-hand page,
+or vice versa. In other words, \.{@@r@@*} inverts the left/right logic.
+
+\.{CTANGLE} does not recognize the operations \.{@@\$}, \.{@@\%}, \.{@@-},
+and \.{@@r}, which are unique to \.{CTWILL}. But that is no problem,
+since you use them only in change files set up for book publishing,
+which are quite different from the change files you set up for tangling.
+
+(End of user manual. We now resume the program for \.{CWEAVE}, with occasional
+outbursts of new code.)
+
+@d max_tex_chars 50 /* limit on the \TeX\ part of a meaning */
+@z
+
+@x
+ program=cweave;
+@y
+ program=ctwill;
+@z
+
+@x
+ if (show_banner) puts(banner); /* print a ``banner line'' */
+@y
+ if (show_banner) cb_show_banner(); /* print a ``banner line'' */
+@z
+
+@x
+@i common.h
+@y
+@i comm-w2c.h
+@z
+
+@x
+turned on during the first phase.
+
+@<Private...@>=
+static boolean change_exists; /* has any section changed? */
+@y
+turned on during the first phase---NOT!
+@z
+
+@x
+static sixteen_bits xref_switch,section_xref_switch; /* either zero or |def_flag| */
+@y
+static sixteen_bits xref_switch,section_xref_switch; /* either zero or |def_flag| */
+
+@ \.{CTWILL} also has special data structures to keep track of current
+and temporary meanings. These structures were not designed for maximum
+efficiency; they were designed to be easily grafted into \.{CWEAVE}'s
+existing code without major surgery.
+
+@d max_meanings 100 /* max temporary meanings per section */
+@d max_titles 100 /* max distinct program or header names in meanings */
+
+@<Type...@>=
+typedef struct {
+ name_pointer id; /* identifier whose meaning is being recorded */
+ sixteen_bits prog_no; /* title of program or header in which defined */
+ sixteen_bits sec_no; /* section number in which defined */
+ char tex_part[max_tex_chars]; /* \TeX\ part of meaning */
+} meaning_struct;
+
+@ @<Private...@>=
+struct perm_meaning {
+ meaning_struct perm; /* current meaning of an identifier */
+ int stamp; /* last section number in which further output suppressed */
+ struct perm_meaning *link; /* another meaning to output in this section */
+} cur_meaning[max_names]; /* the current ``permanent'' meanings */
+static struct perm_meaning *top_usage; /* first meaning to output in this section */
+static meaning_struct temp_meaning_stack[max_meanings]; /* the current ``temporary'' meanings */
+static meaning_struct *temp_meaning_ptr; /* first available slot in |temp_meaning_stack| */
+static meaning_struct *max_temp_meaning_ptr; /* its maximum value so far */
+static name_pointer title_code[max_titles]; /* program names seen so far */
+static name_pointer *title_code_ptr; /* first available slot in |title_code| */
+static char ministring_buf[max_tex_chars]; /* \TeX\ code being generated */
+static char *ministring_ptr; /* first available slot in |ministring_buf| */
+static boolean ms_mode; /* are we outputting to |ministring_buf|? */
+
+@ @<Set init...@>=
+max_temp_meaning_ptr=temp_meaning_stack;
+title_code_ptr=title_code;
+ms_mode=false;
+
+@ Here's a routine that converts a program title from the buffer
+into an internal number for the |prog_no| field of a meaning.
+It advances |loc| past the title found.
+
+@c static sixteen_bits title_lookup(void)
+{
+ char *first,*last; /* boundaries */
+ int balance; /* excess of left over right */
+ register name_pointer *p;
+ first=loc;
+ if (*loc=='"') {
+ while (++loc<=limit && *loc!='"') if (*loc=='\\') loc++;
+ } else if (*loc=='{') {
+ balance=1;
+ while (++loc<=limit) {
+ if (*loc=='}' && --balance==0) break;
+ if (*loc=='{') balance++;
+ }
+ } else err_print(_("! Title should be enclosed in braces or doublequotes"));
+ last=++loc;
+ if (last>limit) err_print(_("! Title name didn't end"));
+ if (title_code_ptr==&title_code[max_titles]) overflow(_("titles"));
+ *title_code_ptr=id_lookup(first,last,title);
+ for (p=title_code;;p++) if (*p==*title_code_ptr) break;
+ if (p==title_code_ptr) title_code_ptr++;
+ return p-title_code;
+}
+
+@ @<Give a default title to the program, if necessary@>=
+if (title_code_ptr==title_code) { /* no \.{\\def\\title} found in limbo */
+ char *saveloc=loc,*savelimit=limit;
+ loc=limit+1; limit=loc;
+ *limit++='{';
+ memcpy(limit,tex_file_name,strlen(tex_file_name)-4);
+ limit+=strlen(tex_file_name)-4;
+ *limit++='}';
+ title_lookup();
+ loc=saveloc; limit=savelimit;
+}
+
+@ The |new_meaning| routine changes the current ``permanent meaning''
+when an identifier is redeclared. It gets the |tex_part| from
+|ministring_buf|.
+
+@c
+static void
+new_meaning(
+ name_pointer p)
+{
+ struct perm_meaning *q=p-name_dir+cur_meaning;
+ ms_mode=false;
+ if (q->stamp!=section_count) {
+ if (*(ministring_ptr-1)==' ') ministring_ptr--;
+ if (ministring_ptr>=&ministring_buf[max_tex_chars])
+ strcpy(ministring_buf,"\\zip"); /* ignore |tex_part| if too long */
+@.\\zip@>
+ else *ministring_ptr='\0';
+ q->perm.prog_no=0; /* |q->perm.id=p| */
+ q->perm.sec_no=section_count;
+ strcpy(q->perm.tex_part,ministring_buf);
+ }
+ @<Write the new meaning to the \.{.aux} file@>;
+}
+
+@ @<Write the new meaning to the \.{.aux} file@>=
+{@+int n=q->perm.prog_no;
+ fprintf(aux_file,"@@$%.*s %.*s",@|
+ (int)((p+1)->byte_start-p->byte_start),p->byte_start,@|
+ (int)((title_code[n]+1)->byte_start-title_code[n]->byte_start),
+ title_code[n]->byte_start);
+ if (*(title_code[n]->byte_start)=='{') fprintf(aux_file,"%d",q->perm.sec_no);
+ fprintf(aux_file," %s@@>\n",q->perm.tex_part);
+}
+@z
+
+@x
+@d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference");
+@y
+@d append_xref(c) if (xref_ptr==xmem_end) overflow(_("cross-reference"));
+@z
+
+@x
+ p->ilk=t; init_node(p);
+@y
+ struct perm_meaning *q=p-name_dir+cur_meaning;
+ p->ilk=t; init_node(p);
+ q->stamp=0;
+ q->link=NULL;
+ q->perm.id=p;
+ q->perm.prog_no=q->perm.sec_no=0;
+ strcpy(q->perm.tex_part,"\\uninitialized");
+@z
+
+@x
+id_lookup("extern",NULL,int_like);
+@y
+ext_loc=id_lookup("extern",NULL,int_like)-name_dir;
+@z
+
+@x
+id_lookup("int",NULL,raw_int);
+@y
+int_loc=id_lookup("int",NULL,raw_int)-name_dir;
+@z
+
+@x
+id_lookup("make_pair",NULL,func_template);
+@y
+id_lookup("make_pair",NULL,func_template);
+
+@ @<Private...@>=
+static sixteen_bits int_loc, ext_loc; /* locations of special reserved words */
+@z
+
+@x
+@d ord 0207 /* control code for `\.{@@'}' */
+@d join 0210 /* control code for `\.{@@\&}' */
+@d thin_space 0211 /* control code for `\.{@@,}' */
+@d math_break 0212 /* control code for `\.{@@\v}' */
+@d line_break 0213 /* control code for `\.{@@/}' */
+@d big_line_break 0214 /* control code for `\.{@@\#}' */
+@d no_line_break 0215 /* control code for `\.{@@+}' */
+@d pseudo_semi 0216 /* control code for `\.{@@;}' */
+@d macro_arg_open 0220 /* control code for `\.{@@[}' */
+@d macro_arg_close 0221 /* control code for `\.{@@]}' */
+@d trace 0222 /* control code for `\.{@@0}', `\.{@@1}' and `\.{@@2}' */
+@d translit_code 0223 /* control code for `\.{@@l}' */
+@d output_defs_code 0224 /* control code for `\.{@@h}' */
+@d format_code 0225 /* control code for `\.{@@f}' and `\.{@@s}' */
+@d definition 0226 /* control code for `\.{@@d}' */
+@d begin_C 0227 /* control code for `\.{@@c}' */
+@d section_name 0230 /* control code for `\.{@@<}' */
+@d new_section 0231 /* control code for `\.{@@\ }' and `\.{@@*}' */
+@y
+@d meaning 0207 /* control code for `\.{@@\$}' */
+@d suppress 0210 /* control code for `\.{@@-}' */
+@d temp_meaning 0211 /* control code for `\.{@@\%}' */
+@d right_start 0212 /* control code for `\.{@@r}' */
+@d ord 0213 /* control code for `\.{@@'}' */
+@d join 0214 /* control code for `\.{@@\&}' */
+@d thin_space 0215 /* control code for `\.{@@,}' */
+@d math_break 0216 /* control code for `\.{@@\v}' */
+@d line_break 0217 /* control code for `\.{@@/}' */
+@d big_line_break 0220 /* control code for `\.{@@\#}' */
+@d no_line_break 0221 /* control code for `\.{@@+}' */
+@d pseudo_semi 0222 /* control code for `\.{@@;}' */
+@d macro_arg_open 0224 /* control code for `\.{@@[}' */
+@d macro_arg_close 0225 /* control code for `\.{@@]}' */
+@d trace 0226 /* control code for `\.{@@0}', `\.{@@1}' and `\.{@@2}' */
+@d translit_code 0227 /* control code for `\.{@@l}' */
+@d output_defs_code 0230 /* control code for `\.{@@h}' */
+@d format_code 0231 /* control code for `\.{@@f}' and `\.{@@s}' */
+@d definition 0232 /* control code for `\.{@@d}' */
+@d begin_C 0233 /* control code for `\.{@@c}' */
+@d section_name 0234 /* control code for `\.{@@<}' */
+@d new_section 0235 /* control code for `\.{@@\ }' and `\.{@@*}' */
+@z
+
+@x
+ccode['\'']=ord;
+@y
+ccode['\'']=ord;
+ccode['$']=meaning; ccode['%']=temp_meaning; ccode['-']=suppress;
+ccode['r']=ccode['R']=right_start;
+@z
+
+@x
+static eight_bits skip_TeX(void);
+
+@ @c
+@y
+static eight_bits skip_TeX(void);
+
+@ We look for a clue about the program's title, because this will become
+part of all meanings.
+
+@c
+@z
+
+@x
+ if (loc>limit && get_line()==false) return;
+@y
+ if (loc>limit && get_line()==false) return;
+ if (loc==buffer && strncmp(buffer,"\\def\\title{",11)==0) {
+ loc=buffer+10;
+ title_lookup(); /* this program's title will be code zero */
+ }
+@z
+
+@x
+skip_TeX(void) /* skip past pure \TEX/ code */
+@y
+skip_TeX(void)
+@z
+
+@x
+\yskip\hang |xref_roman|, |xref_wildcard|, |xref_typewriter|, |TeX_string|,
+@y
+\yskip\hang |xref_roman|, |xref_wildcard|, |xref_typewriter|, |TeX_string|,
+|meaning|, |suppress|,
+@z
+
+@x
+@d right_preproc 0217 /* ends a preprocessor command */
+@y
+@d right_preproc 0223 /* ends a preprocessor command */
+@z
+
+@x
+ err_print("! String didn't end"); loc=limit; break;
+@y
+ err_print(_("! String didn't end")); loc=limit; break;
+@z
+
+@x
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@y
+ err_print(_("! Input ended in middle of string")); loc=buffer; break;
+@z
+
+@x
+ fputs("\n! String too long: ",stdout);
+@y
+ fputs(_("\n! String too long: "),stdout);
+@z
+
+@x
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+ case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
+
+@x
+ case underline: xref_switch=def_flag; continue;
+@y
+ case underline: xref_switch=def_flag; continue;
+ case temp_meaning: temp_switch=true-temp_switch; continue;
+ case right_start: right_start_switch=true; continue;
+@z
+
+@x
+ case xref_roman: case xref_wildcard: case xref_typewriter: case noop:
+@y
+ case xref_roman: case xref_wildcard: case xref_typewriter: case noop:
+ case meaning: case suppress:
+@z
+
+@x
+ err_print("! Input ended in section name");
+@y
+ err_print(_("! Input ended in section name"));
+@z
+
+@x
+ fputs("\n! Section name too long: ",stdout);
+@y
+ fputs(_("\n! Section name too long: "),stdout);
+@z
+
+@x
+ err_print("! Section name didn't end"); break;
+@y
+ err_print(_("! Section name didn't end")); break;
+@z
+
+@x
+ err_print("! Control codes are forbidden in section name"); break;
+@y
+ err_print(_("! Control codes are forbidden in section name")); break;
+@z
+
+@x
+static void
+skip_restricted(void)
+{
+@y
+static void
+skip_restricted(void)
+{ int c=ccode[(eight_bits)*(loc-1)];
+@z
+
+@x
+ err_print("! Control text didn't end"); loc=limit;
+@y
+ err_print(_("! Control text didn't end")); loc=limit;
+@z
+
+@x
+ err_print("! Control codes are forbidden in control text");
+@y
+ err_print(_("! Control codes are forbidden in control text"));
+@z
+
+@x
+@.Control codes are forbidden...@>
+@y
+@.Control codes are forbidden...@>
+ if (c==meaning && phase==2) @<Process a user-generated meaning@>@;
+ else if (c==suppress && phase==2) @<Suppress mini-index entry@>;
+ }
+}
+
+@ @<Suppress mini-index entry@>=
+{ char *first=id_first,*last=id_loc;
+ while (xisspace(*first)) first++;
+ while (xisspace(*(last-1))) last--;
+ if (first<last) {
+ struct perm_meaning *q=id_lookup(first,last,normal)-name_dir+cur_meaning;
+ q->stamp=section_count; /* this is what actually suppresses output */
+ }
+}
+
+@ @<Process a user-generated meaning@>=
+{ char *first=id_first;
+ while (xisspace(*first)) first++;
+ loc=first;
+ while (xisalpha(*loc)||xisdigit(*loc)||*loc=='_') loc++;
+ if (*loc++!=' ')
+ err_print(_("! Identifier in meaning should be followed by space"));
+ else { name_pointer p=id_lookup(first,loc-1,normal);
+ sixteen_bits t; int n=0;
+ t=title_lookup();
+ if (*(loc-1)=='}')
+ while (xisdigit(*loc)) n=10*n+(*loc++)-'0';
+ if (*loc++!=' ')
+ err_print(_("! Location in meaning should be followed by space"));
+ else @<Digest the meaning of |p|, |t|, |n|@>;
+ }
+ loc=id_loc+2;
+}
+
+@ @<Digest...@>=
+{ meaning_struct *m;
+ struct perm_meaning *q=p-name_dir+cur_meaning;
+ if (temp_switch) {
+ m=temp_meaning_ptr++;
+ if (temp_meaning_ptr>max_temp_meaning_ptr) {
+ if (temp_meaning_ptr>&temp_meaning_stack[max_meanings])
+ overflow(_("temp meanings"));
+ max_temp_meaning_ptr=temp_meaning_ptr;
+ }
+ } else m=&(q->perm);
+ m->id=p;
+ m->prog_no=t;
+ m->sec_no=n;
+ if (id_loc-loc>=max_tex_chars) strcpy(m->tex_part,"\\zip");
+@.\\zip@>
+ else { char *q=m->tex_part;
+ while (loc<id_loc) *q++=*loc++;
+ *q='\0';
+@z
+
+@x
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@y
+ if (loc>=limit) err_print(_("! Verbatim string didn't end"));
+@z
+
+@x
+ skip_limbo(); change_exists=false;
+@y
+ skip_limbo();
+ @<Give a default title to the program, if necessary@>;
+@z
+
+@x
+ changed_section[section_count]=change_exists;
+ /* the index changes if anything does */
+@y
+@z
+
+@x
+ if (++section_count==max_sections) overflow("section number");
+@y
+ if (++section_count==max_sections) overflow(_("section number"));
+@z
+
+@x
+ changed_section[section_count]=changing;
+ /* it will become |true| if any line changes */
+@y
+@z
+
+@x
+ if (changed_section[section_count]) change_exists=true;
+@y
+@z
+
+@x
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+ case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
+
+@x
+ case xref_roman: case xref_wildcard: case xref_typewriter:
+@y
+ case xref_roman: case xref_wildcard: case xref_typewriter:
+ case meaning: case suppress:
+@z
+
+@x
+ err_print("! Missing left identifier of @@s");
+@y
+ err_print(_("! Missing left identifier of @@s"));
+@z
+
+@x
+ err_print("! Missing right identifier of @@s");
+@y
+ err_print(_("! Missing right identifier of @@s"));
+@z
+
+@x
+ fputs("\n! Never defined: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@y
+ fputs(_("\n! Never defined: <"),stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@z
+
+@x
+ fputs("\n! Never used: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@y
+ fputs(_("\n! Never used: <"),stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@z
+
+@x
+@ In particular, the |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
+`\.{\\input cwebmac}'.
+
+@<Start \TEX/...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file;
+*out_ptr='c'; tex_printf("\\input cwebma");
+@y
+@ In particular, the |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 dependent of
+the user language set by the `\.{+l}' option and its argument. If you call
+\.{CTWILL} with `\.{+lX}' (or `\.{-lX}' as well), where `\.X' is the
+(possibly empty) string of characters to the right of~`\.l', `\.X'~will
+be prepended to `\.{ctwimac.tex}', e.g., if you call \.{CTWILL} with
+`\.{+ldeutsch}', you will receive the line `\.{\\input deutschctwimac}'.
+Without this option the first line of the output file will be
+`\.{\\input ctwimac}'. Or, if the user has specified proofing by
+saying \.{+P} on the command line, it's `\.{\\input ctproofmac}' (resp.\
+\.{\\input Xctproofmac} with option \.{+lX}), a set of macros used when
+debugging mini-index entries.
+
+@d proofing flags['P']
+
+@<Start \TEX/...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file; *out_ptr='c';
+tex_puts("\\input ");
+tex_printf(use_language);
+tex_puts(proofing?"ctproofma":"ctwima");
+@z
+
+@x
+@d out(c) {if (out_ptr>=out_buf_end) break_out(); *(++out_ptr)=c;}
+@y
+@d out(c)
+ {if (ms_mode) { /* outputting to |ministring_buf| */
+ if (ministring_ptr<&ministring_buf[max_tex_chars])
+ *ministring_ptr++=c;
+ } else {
+ if (out_ptr>=out_buf_end) break_out();
+ *(++out_ptr)=c;
+ }
+ }
+@z
+
+@x
+ printf("\n! Line had to be broken (output l. %d):\n",out_line);
+@y
+ printf(_("\n! Line had to be broken (output l. %d):\n"),out_line);
+@z
+
+@x
+|def_flag|, so it cannot have more than five decimal digits. If
+the section is changed, we output `\.{\\*}' just after the number.
+@y
+|def_flag|, so it cannot have more than five decimal digits.
+@z
+
+@x
+ if(changed_section[n]) out_str ("\\*");
+@.\\*@>
+@y
+@z
+
+@x
+ default: err_print("! Double @@ should be used in limbo");
+@y
+ case right_start: right_start_switch=true; break;
+ default: err_print(_("! Double @@ should be used in limbo"));
+@z
+
+@x
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;}
+@y
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow(_("token")); *(tok_ptr++)=c;}
+@z
+
+@x
+ err_print("! Input ended in mid-comment");
+@y
+ err_print(_("! Input ended in mid-comment"));
+@z
+
+@x
+ if (bal>1) err_print("! Missing } in comment");
+@y
+ if (bal>1) err_print(_("! Missing } in comment"));
+@z
+
+@x
+ else {err_print("! Extra } in comment");
+@y
+ else {err_print(_("! Extra } in comment"));
+@z
+
+@x
+ if (bal>1) err_print("! Missing } in comment");
+@y
+ if (bal>1) err_print(_("! Missing } in comment"));
+@z
+
+@x
+ err_print("! Illegal use of @@ in comment");
+@y
+ err_print(_("! Illegal use of @@ in comment"));
+@z
+
+@x
+@d end_arg 62 /* \.{@@]} */
+@y
+@d end_arg 62 /* \.{@@]} */
+@d title 63 /* program name or header name in a ``meaning'' */
+@z
+
+@x
+@i prod.w
+@y
+@i prod-twill.w
+@z
+
+@x
+static scrap scrap_info[max_scraps]; /* memory array for scraps */
+@y
+static scrap scrap_info[max_scraps]; /* memory array for scraps */
+static scrap null_scrap; /* a scrap with empty translation */
+@z
+
+@x
+@ @<Set init...@>=
+@y
+@ @<Set init...@>=
+null_scrap.trans=&tok_start[0];
+@z
+
+@x
+@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */
+
+@c
+static void
+print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
+@y
+@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */
+
+@c
+#if 0
+static void
+print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
+@z
+
+@x
+ update_terminal;
+@y
+ printf("|\n"); update_terminal;
+@z
+
+@x
+}
+@y
+}
+#endif
+@z
+
+@x
+@ @<Predecl...@>=@+static void print_text(text_pointer p);
+@y
+@ @<Predecl...@>=
+#if 0
+static void print_text(text_pointer p);
+#endif
+@z
+
+@x
+the |for| loop below.
+
+@c
+@y
+the |for| loop below.
+
+We use the fact that |make_underlined| has been called immediately preceding
+|make_reserved|, hence |tok_loc| has been set.
+
+@c
+static token_pointer tok_loc; /* where the first identifier appears */
+@#
+@z
+
+@x
+ token_pointer tok_loc; /* pointer to |tok_value| */
+ if ((tok_loc=find_first_ident(p->trans))<=operator_found)
+ return; /* this should not happen */
+@y
+ if (tok_loc<=operator_found) return; /* this should not happen */
+@z
+
+@x
+ token_pointer tok_loc; /* where the first identifier appears */
+@y
+@z
+
+@x
+ r->num=m; /* everything from |q| on is left undisturbed */
+@y
+ r->num=m; /* everything from |q| on is left undisturbed */
+
+@ \.{CTWILL} needs the following procedure, which appends tokens of a
+translated text until coming to |tok_loc|, then suppresses text that may
+appear between parentheses or brackets. The calling routine should set
+|ident_seen=false| first. (This is admittedly tricky.)
+
+@c boolean ident_seen;
+static boolean app_supp(
+ text_pointer p)
+{ token_pointer j;
+ text_pointer q;
+ if (ident_seen && **p>=tok_flag) {
+ q=**p-tok_flag+tok_start;
+ if (**q=='(') {
+ app('(');@+app('\\');@+app(',');@+app(')'); goto catch14;
+ }
+ if (**q=='[') {
+ app('[');@+app('\\');@+app(',');@+app(']'); goto catch14;
+ }
+ }
+ for (j=*p;j<*(p+1);j++) {
+ if (*j<tok_flag) {
+ if (*j==inserted) return false;
+ if (j==tok_loc) ident_seen=true;
+ else app(*j);
+ } else if (*j>=inner_tok_flag) confusion(_("inner"));
+ else if (app_supp(*j-tok_flag+tok_start)) goto catch14;;
+ }
+ return false;
+catch14: if (*(*(p+1)-1)=='9') return true; /* production 14 was used */
+ else return false;
+}
+
+@ The trickiest part of \.{CTWILL} is the procedure |make_ministring(l)|,
+which tries to figure out a symbolic form of definition after
+|make_underlined(pp+l)| has been called. We rely heavily on the
+existing productions, which force the translated texts to have a
+structure that's decodable even though the underlying |cat| and |mathness|
+codes have disappeared.
+
+@c static void
+make_ministring(
+ int l) /* 0, 1, or 2 */
+{
+ text_pointer q,r;
+ name_pointer cn;
+ token t;
+ int ast_count; /* asterisks preceding the expression */
+ boolean non_ast_seen; /* have we seen a non-asterisk? */
+ if (tok_loc<=operator_found) return;
+ cn=((*tok_loc)%id_flag)+name_dir;
+ @<Append the type of the declaree; |return| if it begins with \&{extern}@>;
+ null_scrap.mathness=(((pp+l)->mathness)%4)*5; big_app1(&null_scrap);
+ /* now we're ready for the mathness that follows (I think) */
+ /* (without the mod 4 times 5, comments posed a problem) */
+ /* (namely in cases like |int a(b,c)| followed by comment) */
+ ident_seen=false;@+app_supp((pp+l)->trans);
+ null_scrap.mathness=10; big_app1(&null_scrap);
+ /* now |cur_mathness==no_math| */
+ ms_mode=true; ministring_ptr=ministring_buf;
+ if (l==2) *ministring_ptr++='=';
+ make_output(); /* translate the current text into a ministring */
+ tok_ptr=*(--text_ptr); /* delete that text */
+ new_meaning(cn);
+ cur_mathness=maybe_math; /* restore it */
+}
+
+@ Here we use the fact that a |decl_head| comes from |int_like| only in
+production~27, whose translation is fairly easy to recognize. (Well,
+production 28 has been added for \CPLUSPLUS/, but we hope that doesn't
+mess us up.) And we also use other similar facts.
+
+If an identifier is given an \&{extern} definition, we don't change
+its current meaning, but we do suppress mini-index entries to its
+current meaning in other sections.
+
+@<Append the type of the declaree; |return| if it begins with \&{extern}@>=
+if (l==0) { app(int_loc+res_flag); app(' '); cur_mathness=no_math; }
+else {
+ q=(pp+l-1)->trans;
+ ast_count=0;
+ non_ast_seen=false;
+ while (true) {
+ if (*(q+1)==*q+1) {
+ r=q;@+break; /* e.g. \&{struct}; we're doing production 45 or 46 */
+ }
+ if (**q<tok_flag) confusion(_("find type"));
+ r=**q-tok_flag+tok_start;
+ if ((t=*(*(q+1)-2))>=tok_flag && **(t-tok_flag+tok_start)=='*') {
+ /* production 34 */
+ if (!non_ast_seen) ast_count++; /* count immediately preceding |*|'s */
+ } else non_ast_seen=true;
+ if (*(*q+1)==' ' && *(q+1)==*q+2) break; /* production 27 */
+ if (*(*q+1)=='{' && *(*q+2)=='}' && *(*q+3)=='$' && *(*q+4)==' '@|
+ && *(q+1)==*q+5) break; /* production 27 in disguise */
+ q=r;
+ }
+ while (**r>=tok_flag) {
+ if (*(r+1)>*r+9 && *(*r+1)=='{' && *(*r+2)=='}' && *(*r+3)=='$' @|
+ && *(*r+4)==indent) q=**r-tok_flag+tok_start; /* production 49 */
+ r=**r-tok_flag+tok_start;
+ }
+ if (**r==ext_loc+res_flag) return; /* \&{extern} gives no definition */
+ @<Append tokens for type |q|@>;
+}
+
+@ @<Append tokens for type |q|@>=
+cur_mathness=no_math; /* it was |maybe_math| */
+if (*(q+1)==*q+8 && *(*q+1)==' ' && *(*q+3)==' ') {
+ app(**q);@+app(' ');@+app(*(*q+2)); /* production 46 */
+} else if ((t=*(*(q+1)-1))>=tok_flag && **(r=t-tok_flag+tok_start)=='\\'
+ && *(*r+1)=='{') app(**q); /* |struct_like| identifier */
+else app((q-tok_start)+tok_flag);
+while (ast_count) {
+ big_app('{');@+app('*');@+app('}');@+ast_count--;
+}
+
+@z
+
+@x
+@<Cases for |exp|@>=
+if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ make_underlined(pp); big_app1(pp); big_app(indent); app(indent);
+ reduce(pp,1,fn_decl,0,1);
+}
+@y
+@<Cases for |exp|@>=
+if(cat1==lbrace || cat1==int_like || cat1==decl) {
+ make_underlined(pp);
+ make_ministring(0);
+ big_app1(pp);
+ if (indent_param_decl) {
+ big_app(indent); app(indent);
+ }
+ reduce(pp,1,fn_decl,0,1);
+}
+@z
+
+@x
+ make_underlined (pp); squash(pp,2,tag,-1,7);
+@y
+ make_underlined (pp);
+ if (tok_loc>operator_found) {
+ name_pointer cn=((*tok_loc)%id_flag)+name_dir;
+ strcpy(ministring_buf,"label");
+ new_meaning(cn);
+ }
+ squash(pp,2,tag,-1,7);
+@z
+
+@x
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+ cat3==semi || cat3==rpar))
+ squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ big_app1(pp); big_app(indent); app(indent); reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+@y
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1);
+ make_ministring(1);
+ squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+ cat3==semi || cat3==rpar))
+ squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ big_app1(pp);
+ if (indent_param_decl) {
+ big_app(indent); app(indent);
+ }
+ reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+@z
+
+@x
+@ @<Cases for |decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1);
+ reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+ big_app1(pp); big_app(big_force);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+@y
+@ @<Cases for |decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1);
+ reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+ big_app1(pp);
+ if(order_decl_stmt) big_app(big_force);
+ else big_app(force);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+@z
+
+@x
+ make_underlined(pp+1); make_reserved(pp+1);
+@y
+ make_underlined(pp+1); make_reserved(pp+1);
+ make_ministring(1);
+@z
+
+@x
+@ @<Cases for |fn_decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+ big_app1(pp); app(outdent); app(outdent); big_app(force);
+ big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+@y
+@ @<Cases for |fn_decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+ big_app1(pp);
+ if (indent_param_decl) {
+ app(outdent); app(outdent);
+ }
+ big_app(force);
+ big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+@z
+
+@x
+if (cat1==define_like) make_underlined(pp+2);
+@y
+if (cat1==define_like) { /* \.{\#define} is analogous to \&{extern} */
+ make_underlined(pp+2);
+ if (tok_loc>operator_found) {
+ /* no time to work out this case; I'll handle defines by brute force
+ in the \.{aux} file, since they usually don't go in mini-index */
+ }
+}
+@z
+
+@x
+if (cat1==prelangle) squash(pp+1,1,langle,1,100);
+else squash(pp,1,exp,-2,101);
+@y
+if (cat1==prelangle) squash(pp+1,1,langle,1,121);
+else squash(pp,1,exp,-2,122);
+@z
+
+@x
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,else_like,-2,102);
+@y
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,else_like,-2,123);
+@z
+
+@x
+@ @<Cases for |typedef_like|@>=
+if ((cat1==int_like || cat1==cast) && (cat2==comma || cat2==semi))
+ squash(pp+1,1,exp,-1,115);
+else if (cat1==int_like) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,typedef_like,0,116);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1); make_reserved(pp+1);
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,typedef_like,0,117);
+}
+else if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,typedef_like,0,118);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,119);
+else if (cat1==ubinop && (cat2==ubinop || cat2==cast)) {
+ big_app('{'); big_app1(pp+1); big_app('}'); big_app1(pp+2);
+ reduce(pp+1,2,cat2,0,120);
+}
+@y
+@ Here \.{CTWILL} deviates from the normal productions introduced in
+version 3.6, because those productions bypass |decl_head| (thereby
+confusing |make_ministring|, which depends on the |decl_head| productions
+to deduce the type). We revert to an older syntax that was
+less friendly to \CPLUSPLUS/ but good enough for me.
+
+@<Cases for |typedef_like|@>=
+if (cat1==decl_head) {
+ if ((cat2==exp&&cat3!=lpar&&cat3!=exp)||cat2==int_like) {
+ make_underlined(pp+2); make_reserved(pp+2);
+ make_ministring(2);
+ big_app2(pp+1); reduce(pp+1,2,decl_head,0,200);
+ }
+ else if (cat2==semi) {
+ big_app1(pp); big_app(' '); big_app2(pp+1); reduce(pp,3,decl,-1,201);
+ }
+} else if (cat1==int_like && cat2==raw_int &&
+ (cat3==semi || cat3==comma)) squash(pp+2,1,exp,1,202);
+@z
+
+@x
+ overflow("token");
+@y
+ overflow(_("token"));
+@z
+
+@x
+ overflow("text");
+@y
+ overflow(_("text"));
+@z
+
+@x
+ if (tok_ptr+6>tok_mem_end) overflow("token");
+@y
+ if (tok_ptr+6>tok_mem_end) overflow(_("token"));
+@z
+
+@x
+ printf("\nIrreducible scrap sequence in section %d:",section_count);
+@y
+ printf(_("\nIrreducible scrap sequence in section %d:"),section_count);
+@z
+
+@x
+ printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+@y
+ printf(_("\nTracing after l. %d:\n"),cur_line); mark_harmless;
+@z
+
+@x
+ case ignore: case xref_roman: case xref_wildcard:
+@y
+ case ignore: case xref_roman: case xref_wildcard:
+ case meaning: case suppress:
+@z
+
+@x
+ overflow("scrap/token/text");
+@y
+ overflow(_("scrap/token/text"));
+@z
+
+@x
+ else err_print("! Double @@ should be used in strings");
+@y
+ else err_print(_("! Double @@ should be used in strings"));
+@z
+
+@x
+ else app_scrap(p->ilk,maybe_math);
+ }
+ }
+@y
+ else app_scrap(p->ilk,maybe_math);
+ }
+ }
+ @<Flag the usage of this identifier, for the mini-index@>;
+@z
+
+@x
+ if (next_control!='|') err_print("! Missing '|' after C text");
+@y
+ if (next_control!='|') err_print(_("! Missing '|' after C text"));
+@z
+
+@x
+to \.{\\PB}, if the user has invoked \.{CWEAVE} with the \.{+e} flag.
+Although \.{cwebmac} ignores \.{\\PB}, other macro packages
+@y
+to \.{\\PB}, if the user has invoked \.{CTWILL} with the \.{+e} flag.
+Although \.{ctwimac} ignores \.{\\PB}, other macro packages
+@z
+
+@x
+ app(tok_flag+(int)(p-tok_start));
+@y
+ app(tok_flag+(int)(p-tok_start));
+ app(inserted);
+@z
+
+@x
+ if (stack_ptr==stack_end) overflow("stack");
+@y
+ if (stack_ptr==stack_end) overflow(_("stack"));
+@z
+
+@x
+ fputs("\n! Illegal control code in section name: <",stdout);
+@y
+ fputs(_("\n! Illegal control code in section name: <"),stdout);
+@z
+
+@x
+ fputs("\n! C text in section name didn't end: <",stdout);
+@y
+ fputs(_("\n! C text in section name didn't end: <"),stdout);
+@z
+
+@x
+ if (j>buffer+long_buf_size-3) overflow("buffer");
+@y
+ if (j>buffer+long_buf_size-3) overflow(_("buffer"));
+@z
+
+@x
+ if (j>buffer+long_buf_size-4) overflow("buffer");
+@y
+ if (j>buffer+long_buf_size-4) overflow(_("buffer"));
+@z
+
+@x
+reset_input(); if (show_progress) fputs("\nWriting the output file...",stdout);
+@y
+reset_input(); if (show_progress) fputs(_("\nWriting the output file..."),stdout);
+@z
+
+@x
+section_count=0; format_visible=true; copy_limbo();
+@y
+temp_switch=false; temp_meaning_ptr=temp_meaning_stack;
+@<Read the \.{.aux} file, if present; then open it for output@>;
+section_count=0; format_visible=true; right_start_switch=false; copy_limbo();
+@z
+
+@x
+while (!input_has_ended) @<Translate the current section@>@;
+}
+
+@y
+while (!input_has_ended) @<Translate the current section@>@;
+}
+
+@ @<Private...@>=
+static FILE *aux_file;
+static char aux_file_name[max_file_name_length]; /* name of \.{.aux} file */
+
+@ @<Read the \.{.aux} file, if present; then open it for output@>=
+memcpy(aux_file_name,tex_file_name,strlen(tex_file_name)-4);
+strcat(aux_file_name,".bux");
+include_depth=1; /* we simulate \.{@@i} */
+strcpy(cur_file_name,aux_file_name); /* first in, third out */
+if ((cur_file=fopen(cur_file_name,"r"))) { cur_line=0; include_depth++; }
+strcpy(aux_file_name+strlen(aux_file_name)-4,".aux");
+strcpy(cur_file_name,aux_file_name); /* second in, second out */
+if ((cur_file=fopen(cur_file_name,"r"))) { cur_line=0; include_depth++; }
+strcpy(cur_file_name,"system.bux"); /* third in, first out */
+if ((cur_file=fopen(cur_file_name,"r"))) cur_line=0;
+else include_depth--;
+if (include_depth) { /* at least one new file was opened */
+ while (get_next()==meaning) ; /* new meaning is digested */
+ if (include_depth) err_print(_("! Only @@$ is allowed in aux and bux files"));
+ finish_line(); loc=buffer; /* now reading beginning of line 1 */
+}
+if ((aux_file=fopen(aux_file_name,"wb"))==NULL)
+ fatal(_("! Cannot open aux output file "),aux_file_name);
+
+@z
+
+@x
+static boolean group_found=false; /* has a starred section occurred? */
+
+@ @<Translate the current section@>= {
+ section_count++;
+@y
+static boolean group_found=false; /* has a starred section occurred? */
+static boolean right_start_switch; /* has `\.{@@r}' occurred recently? */
+static boolean temp_switch; /* has `\.{@@\%}' occurred recently? */
+
+@ @d usage_sentinel (struct perm_meaning *)1
+@<Translate the current section@>= {
+ section_count++;
+ temp_switch=false; temp_meaning_ptr=temp_meaning_stack;
+ top_usage=usage_sentinel;
+@z
+
+@x
+if (*(loc-1)!='*') out_str("\\M");
+@y
+if (*(loc-1)!='*') {
+ if (right_start_switch) {
+ out_str("\\shortpage\n"); right_start_switch=false;
+@.\\shortpage@>
+ }
+ out_str("\\M");
+}
+@z
+
+@x
+@.\\N@>
+@y
+@.\\N@>
+ if (right_start_switch) {
+ out_str("N"); right_start_switch=false;
+@.\\NN@>
+ }
+@z
+
+@x
+out_str("{");out_section(section_count); out_str("}");
+@y
+out_str("{");out_section(section_count); out_str("}");
+flush_buffer(out_ptr,false,false);
+@z
+
+@x
+ case '@@': out('@@'); break;
+@y
+ case '@@': out('@@'); break;
+ case temp_meaning: temp_switch=true-temp_switch; break;
+ case right_start: right_start_switch=true; break;
+@z
+
+@x
+ case section_name: loc-=2; next_control=get_next(); /* skip to \.{@@>} */
+@y
+ case meaning: case suppress:
+ case section_name: loc-=2; next_control=get_next(); /* reprocess */
+@z
+
+@x
+ err_print("! TeX string should be in C text only"); break;
+@y
+ err_print(_("! TeX string should be in C text only")); break;
+@z
+
+@x
+ err_print("! You can't do that in TeX text"); break;
+@y
+ err_print(_("! You can't do that in TeX text")); break;
+@z
+
+@x
+ outer_parse(); finish_C(format_visible); format_visible=true;
+ doing_format=false;
+}
+@y
+ outer_parse();
+ if (is_macro) @<Make ministring for a new macro@>;
+ finish_C(format_visible); format_visible=true;
+ doing_format=false;
+}
+
+@ @<Private...@>=
+static boolean is_macro; /* it's a macro def, not a format def */
+static int def_diff; /* 0 iff the current macro has parameters */
+static name_pointer id_being_defined; /* the definee */
+@z
+
+@x
+@<Start a macro...@>= {
+@y
+@<Start a macro...@>= {
+ is_macro=true;
+@z
+
+@x
+ err_print("! Improper macro definition");
+@y
+ err_print(_("! Improper macro definition"));
+@z
+
+@x
+@.Improper macro definition@>
+ else {
+ app('$'); app_cur_id(false);
+@y
+@.Improper macro definition@>
+ else {
+ id_being_defined=id_lookup(id_first,id_loc,normal);
+ app('$'); app_cur_id(false);
+ def_diff=*loc-'(';
+@z
+
+@x
+ default: err_print("! Improper macro definition"); break;
+@y
+ default: err_print(_("! Improper macro definition")); break;
+@z
+
+@x
+@ @<Start a format...@>= {
+ doing_format=true;
+@y
+@ @<Make ministring for a new macro@>=
+{
+ ms_mode=true; ministring_ptr=ministring_buf;
+ *ministring_ptr++='=';
+ if (def_diff) { /* parameterless */
+ scrap_pointer s=scrap_ptr;
+ text_pointer t;
+ token_pointer j;
+ while (s->cat==insert) s--;
+ if ((s-1)->cat==dead && s->cat==exp && **(t=s->trans)=='\\'
+ && *(*t+1)=='T') /* it's just a constant */
+ for (j=*t;j<*(t+1);j++) *ministring_ptr++=*j;
+ else out_str("macro");
+ } else out_str("macro (\\,)");
+ new_meaning(id_being_defined);
+}
+
+@ @<Start a format...@>= {
+ doing_format=true;
+ is_macro=false;
+@z
+
+@x
+ if (scrap_ptr!=scrap_info+2) err_print("! Improper format definition");
+@y
+ if (scrap_ptr!=scrap_info+2) err_print(_("! Improper format definition"));
+@z
+
+@x
+ err_print("! You need an = sign after the section name");
+@y
+ err_print(_("! You need an = sign after the section name"));
+@z
+
+@x
+ err_print("! You can't do that in C text");
+@y
+ err_print(_("! You can't do that in C text"));
+@z
+
+@x
+out_str("\\fi"); finish_line();
+@.\\fi@>
+flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */
+@y
+finish_line(); out_str("\\mini"); finish_line();
+@.\\mini@>
+@<Output information about usage of id's defined in other sections@>;
+out_str("}\\FI"); finish_line();
+@.\\FI@>
+flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */
+
+@ The following code is performed for each identifier parsed during
+a section. Variable |top_usage| is always nonzero; it has the sentinel
+value~1 initially, then it points to each variable scheduled for
+possible citation. A variable is on this list if and only if its
+|link| field is nonzero. All variables mentioned in the section are
+placed on the list, unless they are reserved and their current
+\TeX\ meaning is uninitialized.
+
+@<Flag the usage of this identifier, for the mini-index@>=
+{ struct perm_meaning *q=p-name_dir+cur_meaning;
+ if (!(abnormal(p)) || strcmp(q->perm.tex_part,"\\uninitialized")!=0)
+ if (q->link==0) {
+ q->link=top_usage;
+ top_usage=q;
+ }
+}
+
+@ @<Output information about usage of id's defined in other sections@>=
+{ struct perm_meaning *q;
+ while (temp_meaning_ptr>temp_meaning_stack) {
+ out_mini(--temp_meaning_ptr);
+ q=temp_meaning_ptr->id-name_dir+cur_meaning;
+ q->stamp=section_count; /* suppress output from ``permanent'' data */
+ }
+ while (top_usage!=usage_sentinel) {
+ q=top_usage;
+ top_usage=q->link;
+ q->link=NULL;
+ if (q->stamp!=section_count) out_mini(&(q->perm));
+ }
+}
+
+@ @c static void
+out_mini(
+ meaning_struct *m)
+{ char s[60];
+ name_pointer cur_name=m->id;
+ if (m->prog_no==0) { /* reference within current program */
+ if (m->sec_no==section_count) return; /* defined in current section */
+ sprintf(s,"\\[%d",m->sec_no);
+ } else { name_pointer n=title_code[m->prog_no];
+ if (*(n->byte_start)=='{')
+ sprintf(s,"\\]%.*s%d",(int)((n+1)->byte_start-n->byte_start),n->byte_start,
+ m->sec_no);
+ else sprintf(s,"\\]%.*s",(int)((n+1)->byte_start-n->byte_start),n->byte_start);
+ }
+ out_str(s); out(' ');
+ @<Mini-output the name at |cur_name|@>;
+ out(' '); out_str(m->tex_part); finish_line();
+}
+
+@ @<Predec...@>=@+static void out_mini(meaning_struct *);
+
+@ @<Mini-output...@>=
+switch (cur_name->ilk) {
+ case normal: case func_template: if (length(cur_name)==1) out_str("\\|");
+ else {char *j;
+ for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
+ if (xislower(*j)) goto lowcase;
+ out_str("\\."); break;
+lowcase: out_str("\\\\");
+ }
+ break;
+@.\\|@>
+@.\\.@>
+@.\\\\@>
+ case roman: break;
+ case wildcard: out_str("\\9"); break;
+@.\\9@>
+ case typewriter: out_str("\\."); break;
+@.\\.@>
+ case custom: {char *j; out_str("$\\");
+ for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
+ out(*j=='_'? 'x': *j=='$'? 'X': *j);
+ out('$');
+ goto name_done;
+ }
+ default: out_str("\\&");
+@.\\\&@>
+}
+out_name(cur_name,true);
+name_done:
+
+@z
+
+@x
+if (no_xref) {
+ finish_line();
+ out_str("\\end");
+@.\\end@>
+ finish_line();
+}
+@y
+if (no_xref) {
+ finish_line();
+ out_str("\\end");
+@.\\end@>
+ active_file=tex_file;
+}
+@z
+
+@x
+ phase=3; if (show_progress) fputs("\nWriting the index...",stdout);
+@y
+ phase=3; if (show_progress) fputs(_("\nWriting the index..."),stdout);
+@z
+
+@x
+ fatal("! Cannot open index file ",idx_file_name);
+@y
+ fatal(_("! Cannot open index file "),idx_file_name);
+@z
+
+@x
+ if (change_exists) {
+ @<Tell about changed sections@>@; finish_line(); finish_line();
+ }
+@y
+@z
+
+@x
+ fatal("! Cannot open section file ",scn_file_name);
+@y
+ fatal(_("! Cannot open section file "),scn_file_name);
+@z
+
+@x
+@.\\end@>
+ finish_line();
+ fclose(active_file);
+}
+@y
+@.\\end@>
+}
+finish_line(); fclose(active_file); active_file=NULL;
+@<Update the result when it has changed@>@;
+@z
+
+@x
+ fputs("Done.",stdout);
+@y
+ fputs(_("Done."),stdout);
+@z
+
+@x
+the index section itself.
+
+@<Private...@>=
+static sixteen_bits k_section; /* runs through the sections */
+@y
+the index section itself---NOT!
+@z
+
+@x
+@ @<Tell about changed sections@>= {
+ /* remember that the index is already marked as changed */
+ k_section=0;
+ while (!changed_section[++k_section]);
+ out_str("\\ch ");
+@.\\ch@>
+ out_section(k_section);
+ while (k_section<section_count) {
+ while (!changed_section[++k_section]);
+ out_str(", "); out_section(k_section);
+ }
+ out('.');
+}
+
+@y
+@z
+
+@x
+ if (sort_ptr>=scrap_info_end) overflow("sorting");
+@y
+ if (sort_ptr>=scrap_info_end) overflow(_("sorting"));
+@z
+
+@x
+@ @<Output the name...@>=
+@y
+@ We don't format the index completely; the \.{twinx} program does the
+rest of the job.
+
+@<Output the name...@>=
+@z
+
+@x
+ case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
+@y
+ case normal: if (is_tiny(cur_name)) out_str("\\|");
+@z
+
+@x
+ case wildcard: out_str("\\9");@+ goto not_an_identifier;
+@y
+ case roman: out_str(" "); goto not_an_identifier;
+ case wildcard: out_str("\\9"); goto not_an_identifier;
+@z
+
+@x
+ case roman: not_an_identifier: out_name(cur_name,false); goto name_done;
+ case custom: {char *j; out_str("$\\");
+ for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
+ out(*j=='_'? 'x': *j=='$'? 'X': *j);
+ out('$');
+ goto name_done;
+ }
+@y
+not_an_identifier: out_name(cur_name,false); goto name_done;
+ case custom: out_str("\\$"); break;
+@.\\\$@>
+@z
+
+@x
+out_name(cur_name,true);
+@y
+if (proofing) out_name(cur_name,true);
+else {
+ out('{');
+ {char *j;
+ for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++) out(*j);
+ }
+ out('}');
+}
+@z
+
+@x
+ puts("\nMemory usage statistics:");
+@.Memory usage statistics:@>
+ printf("%ld names (out of %ld)\n",
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf("%ld cross-references (out of %ld)\n",
+ (ptrdiff_t)(xref_ptr-xmem),(long)max_refs);
+ printf("%ld bytes (out of %ld)\n",
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ puts("Parsing:");
+ printf("%ld scraps (out of %ld)\n",
+ (ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps);
+ printf("%ld texts (out of %ld)\n",
+ (ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts);
+ printf("%ld tokens (out of %ld)\n",
+ (ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks);
+ printf("%ld levels (out of %ld)\n",
+ (ptrdiff_t)(max_stack_ptr-stack),(long)stack_size);
+ puts("Sorting:");
+ printf("%ld levels (out of %ld)\n",
+ (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps);
+@y
+ puts(_("\nMemory usage statistics:"));
+@.Memory usage statistics:@>
+ printf(_("%ld names (out of %ld)\n"),
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf(_("%ld cross-references (out of %ld)\n"),
+ (ptrdiff_t)(xref_ptr-xmem),(long)max_refs);
+ printf(_("%ld bytes (out of %ld)\n"),
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ printf(_("%ld temp meanings (out of %ld)\n"),
+ (ptrdiff_t)(max_temp_meaning_ptr-temp_meaning_stack),
+ (long)max_meanings);
+ printf(_("%ld titles (out of %ld)\n"),
+ (ptrdiff_t)(title_code_ptr-title_code),(long)max_titles);
+ puts(_("Parsing:"));
+ printf(_("%ld scraps (out of %ld)\n"),
+ (ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps);
+ printf(_("%ld texts (out of %ld)\n"),
+ (ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts);
+ printf(_("%ld tokens (out of %ld)\n"),
+ (ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks);
+ printf(_("%ld levels (out of %ld)\n"),
+ (ptrdiff_t)(max_stack_ptr-stack),(long)stack_size);
+ puts(_("Sorting:"));
+ printf(_("%ld levels (out of %ld)\n"),
+ (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps);
+@z
+
+@x
+@** Index.
+@y
+@** Extensions to \.{CWEB}. The following sections introduce new or improved
+features that have been created by numerous contributors over the course of a
+quarter century.
+
+\bigskip
+\font\itt=cmitt10
+{\noindent \it Although \.{\itt CTWILL} is based on \.{\itt cweave.w}, new and
+modified material is incorporated all over the place, without taking special
+care for keeping the original section numbering intact.}
+
+@* Formatting alternatives.
+\.{CWEAVE} indents declarations after old-style function definitions.
+With the \.{-i} option they will come out flush left. You won't see
+any difference if you use ANSI-style function definitions.
+
+@d indent_param_decl flags['i'] /* should formal parameter declarations be indented? */
+
+@<Set init...@>=
+indent_param_decl=true;
+
+@ The original manual described the \.{-o} option for \.{CWEAVE}, but this was
+not yet present. Here is a simple implementation. The purpose is to suppress
+the extra space between local variable declarations and the first statement in
+a function block.
+
+@d order_decl_stmt flags['o'] /* should declarations and statements be separated? */
+
+@<Set init...@>=
+order_decl_stmt=true;
+
+@* Output file update. Most \CEE/ projects are controlled by a
+\.{Makefile} that automatically takes care of the temporal dependecies
+between the different source modules. It is suitable that \.{CWEB} doesn't
+create new output for all existing files, when there are only changes to
+some of them. Thus the \.{make} process will only recompile those modules
+where necessary. The idea and basic implementation of this mechanism can
+be found in the program \.{NUWEB} by Preston Briggs, to whom credit is due.
+
+@<Update the result...@>=
+if((tex_file=fopen(tex_file_name,"r"))!=NULL) {
+ char x[BUFSIZ],y[BUFSIZ];
+ int x_size,y_size,comparison=false;
+
+ if((check_file=fopen(check_file_name,"r"))==NULL)
+ fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+
+ if (temporary_output) @<Compare the temporary output...@>@;
+
+ fclose(tex_file); tex_file=NULL;
+ fclose(check_file); check_file=NULL;
+
+ @<Take appropriate action depending on the comparison@>@;
+} else
+ rename(check_file_name,tex_file_name); /* This was the first run */
+
+strcpy(check_file_name,""); /* We want to get rid of the temporary file */
+
+@ We hope that this runs fast on most systems.
+
+@<Compare the temporary output to the previous output@>=
+do {
+ x_size = fread(x,1,BUFSIZ,tex_file);
+ y_size = fread(y,1,BUFSIZ,check_file);
+ comparison = (x_size == y_size); /* Do not merge these statements! */
+ if(comparison) comparison = !memcmp(x,y,x_size);
+} while(comparison && !feof(tex_file) && !feof(check_file));
+
+@ Note the superfluous call to |remove| before |rename|. We're using it to
+get around a bug in some implementations of |rename|.
+
+@<Take appropriate action...@>=
+if(comparison)
+ remove(check_file_name); /* The output remains untouched */
+else {
+ remove(tex_file_name);
+ rename(check_file_name,tex_file_name);
+}
+
+@* Put ``version'' information in \.{COMMON}.
+Don't do this at home, kids! Push our local macro to the variable in \.{COMMON}
+for printing the |banner| and the |versionstring| from there.
+
+@d max_banner 50
+
+@<Common code...@>=
+extern char cb_banner[];
+
+@ @<Set init...@>=
+ strncpy(cb_banner,banner,max_banner-1);
+
+@** Index.
+@z
+
diff --git a/Build/source/texk/web2c/cwebdir/ctwill.bux b/Build/source/texk/web2c/cwebdir/ctwill.bux
new file mode 100644
index 00000000000..d5a678dba53
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctwill.bux
@@ -0,0 +1,88 @@
+@$program {COMMON.W}18 \&{int}@>
+@$ctangle {COMMON.W}18 \&{int}@>
+@$ctwill {COMMON.W}18 \&{int}@>
+@$cweave {COMMON.W}18 \&{int}@>
+@$phase {COMMON.W}19 \&{int}@>
+@$common_init {COMMON.W}20 \&{void} (\,)@>
+@$id_first {COMMON.W}21 \&{char} ${*}$@>
+@$id_loc {COMMON.W}21 \&{char} ${*}$@>
+@$section_text {COMMON.W}21 \&{char} [\,][\,]@>
+@$section_text_end {COMMON.W}21 \&{char} ${*}$@>
+@$buffer {COMMON.W}22 \&{char} [\,]@>
+@$buffer_end {COMMON.W}22 \&{char} ${*}$@>
+@$limit {COMMON.W}22 \&{char} ${*}$@>
+@$loc {COMMON.W}22 \&{char} ${*}$@>
+
+@$include_depth {COMMON.W}25 \&{int}@>
+@$file {COMMON.W}25 \&{FILE} ${*}$ [\,]@>
+@$change_file {COMMON.W}25 \&{FILE} ${*}$@>
+@$file_name {COMMON.W}25 \&{char} [\,][\,]@>
+@$change_file_name {COMMON.W}25 \&{char} [\,]@>
+@$alt_web_file_name {COMMON.W}25 \&{char} [\,]@>
+@$line {COMMON.W}25 \&{int} [\,]@>
+@$change_line {COMMON.W}25 \&{int}@>
+@$change_depth {COMMON.W}25 \&{int}@>
+@$input_has_ended {COMMON.W}25 \&{boolean}@>
+@$changing {COMMON.W}25 \&{boolean}@>
+@$web_file_open {COMMON.W}25 \&{boolean}@>
+
+@$reset_input {COMMON.W}35 \&{void} (\,)@>
+
+@$section_count {COMMON.W}37 \&{sixteen\_bits}@>
+@$changed_section {COMMON.W}37 \&{boolean} [\,]@>
+@$change_pending {COMMON.W}37 \&{boolean}@>
+@$print_where {COMMON.W}37 \&{boolean}@>
+@$get_line {COMMON.W}38 \&{boolean} (\,)@>
+
+@$check_complete {COMMON.W}42 \&{void} (\,)@>
+@$byte_mem {COMMON.W}43 \&{char} [\,]@>
+@$byte_mem_end {COMMON.W}43 \&{char} ${*}$@>
+@$name_dir {COMMON.W}43 \&{name\_info} [\,]@>
+@$name_dir_end {COMMON.W}43 \&{name\_pointer}@>
+
+@$byte_ptr {COMMON.W}44 \&{char} ${*}$@>
+@$name_ptr {COMMON.W}44 \&{name\_pointer}@>
+
+@$h {COMMON.W}46 \&{hash\_pointer}@>
+@$hash {COMMON.W}46 \&{name\_pointer} [\,]@>
+@$hash_end {COMMON.W}46 \&{hash\_pointer}@>
+
+@$id_lookup {COMMON.W}48 \&{name\_pointer} (\,)@>
+
+@$print_section_name {COMMON.W}52 \&{void} (\,)@>
+@$sprint_section_name {COMMON.W}53 \&{void} (\,)@>
+@$print_prefix_name {COMMON.W}54 \&{void} (\,)@>
+
+@$section_lookup {COMMON.W}59 \&{name\_pointer} (\,)@>
+
+@$history {COMMON.W}65 \&{int}@>
+
+@$err_print {COMMON.W}66 \&{void} (\,)@>
+
+@$wrap_up {COMMON.W}68 \&{int} (\,)@>
+
+@$fatal {COMMON.W}70 \&{void} (\,)@>
+@$overflow {COMMON.W}71 \&{void} (\,)@>
+
+@$argc {COMMON.W}73 \&{int}@>
+@$argv {COMMON.W}73 \&{char} ${**}$@>
+@$C_file_name {COMMON.W}73 \&{char} [\,]@>
+@$tex_file_name {COMMON.W}73 \&{char} [\,]@>
+@$idx_file_name {COMMON.W}73 \&{char} [\,]@>
+@$scn_file_name {COMMON.W}73 \&{char} [\,]@>
+@$check_file_name {COMMON.W}73 \&{char} [\,]@>
+@$flags {COMMON.W}73 \&{boolean} [\,]@>
+@$use_language {COMMON.W}86 \&{const char} ${*}$@>
+
+@$C_file {COMMON.W}83 \&{FILE} ${*}$@>
+@$tex_file {COMMON.W}83 \&{FILE} ${*}$@>
+@$idx_file {COMMON.W}83 \&{FILE} ${*}$@>
+@$scn_file {COMMON.W}83 \&{FILE} ${*}$@>
+@$check_file {COMMON.W}83 \&{FILE} ${*}$@>
+@$active_file {COMMON.W}83 \&{FILE} ${*}$@>
+
+@$cb_banner {COMMON.W}87 \&{char} [\,]@>
+
+@$cb_show_banner {COMMON.W}99 \&{void} (\,)@>
+
+@$versionstring "<lib/lib.h>" \zip@>
diff --git a/Build/source/texk/web2c/cwebdir/ctwimac.tex b/Build/source/texk/web2c/cwebdir/ctwimac.tex
new file mode 100644
index 00000000000..eddd6af3528
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/ctwimac.tex
@@ -0,0 +1,476 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 3.6 --- May 2000
+% modified for pages produced by CTWILL
+% further modified for page size of the MMIXware book
+\ifx\documentstyle\undefined\else\endinput\fi % LaTeX will use other macros
+\xdef\fmtversion{\fmtversion+CTWILL3.6+LNCS}
+
+\let\:=\. % preserve a way to get the dot accent
+ % (all other accents will still work as usual)
+
+\newdimen\em \em=10pt % this "em" will not change with font size
+\parskip 0pt plus .1pt % almost no stretch between paragraphs
+\parindent 1\em % for paragraphs and for the first line of C text
+
+\newif\ifsorted
+\newread\sreffile
+\newwrite\reffile
+\ifx\norefs\def\else
+ \openin\sreffile=\jobname.sref
+ \ifeof\sreffile \immediate\openout\reffile=\jobname.ref \sortedfalse
+ \message{This is the first pass!}
+ \else \sortedtrue \message{This is the second pass!} \fi
+\fi
+
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\CEE/{{\mc C\spacefactor1000}}
+\def\UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\def\TEX/{\TeX}
+\def\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\def\Cee{\CEE/} % for backward compatibility
+\def\9#1{}
+\font\eightrm=cmr8
+\font\sixrm=cmr6
+\font\ninei=cmmi9
+\font\eighti=cmmi8
+\font\sixi=cmmi6
+\skewchar\ninei='177 \skewchar\eighti='177 \skewchar\sixi='177
+\font\ninesy=cmsy9
+\font\eightsy=cmsy8
+\font\sixsy=cmsy6
+\skewchar\ninesy='60 \skewchar\eightsy='60 \skewchar\sixsy='60
+\font\ninebf=cmbx9
+\font\eightbf=cmbx8
+\font\sixbf=cmbx6
+\font\ninett=cmtt9
+\font\eighttt=cmtt8
+\hyphenchar\ninett=-1 \hyphenchar\eighttt=-1
+\font\ninesl=cmsl9
+\font\eightsl=cmsl8
+\font\nineit=cmti9
+\font\eightit=cmti8
+\font\tentex=cmtex10
+\font\ninetex=cmtex9 % TeX extended character set (used in strings)
+\font\eighttex=cmtex8
+\fontdimen7\tentex=0pt % no double space after sentences
+\fontdimen7\ninetex=0pt
+\fontdimen7\eighttex=0pt
+
+\newif\iftenpoint
+\def\tenpoint{\tenpointtrue
+ \def\rm{\fam0\tenrm}%
+ \textfont0=\tenrm \scriptfont0=\sevenrm \scriptscriptfont0=\fiverm
+ \textfont1=\teni \scriptfont1=\seveni \scriptscriptfont1=\fivei
+ \textfont2=\tensy \scriptfont2=\sevensy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\tenit}%
+ \textfont\itfam=\tenit
+ \def\sl{\fam\slfam\tensl}%
+ \textfont\slfam=\tensl
+ \def\bf{\fam\bffam\tenbf}%
+ \textfont\bffam=\tenbf \scriptfont\bffam=\sevenbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\tentt}%
+ \textfont\ttfam=\tentt
+ \def\ttx{\tentex}%
+ \normalbaselineskip=12pt
+ \let\cmntfont=\tenrm
+ \let\mc=\ninerm
+ \let\sc=\eightrm
+ \let\big=\tenbig
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width 0pt}%
+ \normalbaselines\rm}
+
+\def\ninepoint{\tenpointfalse
+ \def\rm{\fam0\ninerm}%
+ \textfont0=\ninerm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\ninei \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\ninesy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\nineit}%
+ \textfont\itfam=\nineit
+ \def\sl{\fam\slfam\ninesl}%
+ \textfont\slfam=\ninesl
+ \def\bf{\fam\bffam\ninebf}%
+ \textfont\bffam=\ninebf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\ninett}%
+ \textfont\ttfam=\ninett
+ \def\ttx{\ninetex}%
+ \normalbaselineskip=11pt
+ \let\cmntfont=\ninerm
+ \let\mc=\eightrm
+ \let\sc=\sevenrm
+ \let\big=\ninebig
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width 0pt}%
+ \normalbaselines\rm}
+
+\def\eightpoint{%
+ \def\rm{\fam0\eightrm}%
+ \textfont0=\eightrm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\eighti \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\eightsy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\eightit}%
+ \textfont\itfam=\eightit
+ \def\sl{\fam\slfam\eightsl}%
+ \textfont\slfam=\eightsl
+ \def\bf{\fam\bffam\eightbf}%
+ \textfont\bffam=\eightbf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\eighttt}%
+ \textfont\ttfam=\eighttt
+ \def\ttx{\eighttex}%
+ \normalbaselineskip=9pt
+ \let\cmntfont=\eightrm
+ \let\mc=\sevenrm
+ \let\sc=\sixrm
+ \let\big=\eightbig
+ \setbox\strutbox=\hbox{\vrule height7pt depth2pt width 0pt}%
+ \normalbaselines\rm}
+
+\tenpoint
+\def\tenbig#1{{\hbox{$\left#1\vbox to8.5pt{}\right.\nulldelimiterspace=0pt$}}}
+\def\ninebig#1{{\hbox{$\textfont0=\tenrm\textfont2=\tensy
+ \left#1\vbox to7.25pt{}\right.\nulldelimiterspace=0pt$}}}
+\def\eightbig#1{{\hbox{$\textfont0=\ninerm\textfont2=\ninesy
+ \left#1\vbox to6.5pt{}\right.\nulldelimiterspace=0pt$}}}
+
+%\font\tenss=cmss10 \let\cmntfont\tenss % alternative comment font
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+
+\def\\#1{\leavevmode\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\leavevmode\hbox{$#1$}} % one-letter identifiers look better this way
+\def\&#1{\leavevmode\hbox{\bf
+ \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+ #1\/\kern.05em}} % boldface type for reserved words
+\def\.#1{\leavevmode\hbox{\ttx % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+\def\){{\tentex\kern-.05em}\discretionary{\hbox{\tentex\BS}}{}{}}
+\def\AT{@} % at sign for control text (not needed in versions >= 2.9)
+\def\ATL{\par\noindent\bgroup\catcode`\_=12 \postATL} % print @l in limbo
+\def\postATL#1 #2 {\bf letter \\{\uppercase{\char"#1}}
+ tangles as \tentex "#2"\egroup\par}
+\def\noATL#1 #2 {}
+\def\noatl{\let\ATL=\noATL} % suppress output from @l
+\def\ATH{\X\kern-.5em:Preprocessor definitions\X}
+\let\PB=\relax % hook for program brackets |...| in TeX part or section name
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\chardef\RB=`\} % right brace in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+\chardef\CF=`\^ % circumflex character in a string
+
+\newbox\PPbox % symbol for ++
+\setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+\def\PP{\copy\PPbox}
+\newbox\MMbox \setbox\MMbox=\hbox{\kern.5pt\raise1pt\hbox{\sevensy\char0
+ \kern-1pt\char0}\kern.5pt}
+\def\MM{\copy\MMbox}
+\newbox\MGbox % symbol for ->
+\setbox\MGbox=\hbox{\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+\def\MG{\copy\MGbox}
+\def\MRL#1{\mathrel{\let\K==#1}}
+\let\GG=\gg
+\let\LL=\ll
+\let\NULL=\Lambda
+\mathchardef\AND="2026 % bitwise and; also \& (unary operator)
+\let\OR=\mid % bitwise or
+\let\XOR=\oplus % bitwise exclusive or
+\def\CM{{\sim}} % bitwise complement
+\newbox\MODbox \setbox\MODbox=\hbox{\eightrm\%}
+\def\MOD{\mathbin{\copy\MODbox}}
+\def\DC{\kern.1em{::}\kern.1em} % symbol for ::
+\def\PA{\mathbin{.*}} % symbol for .*
+\def\MGA{\mathbin{\MG*}} % symbol for ->*
+\def\this{\&{this}}
+
+\newbox\bak \setbox\bak=\hbox to -1\em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2\em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind\em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5\em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind\em\noindent\kern\ind\em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+\def\8{\hskip-\ind em\hskip 2\em} % no indentation
+
+\newcount\gdepth % depth of current major group, plus one
+\newtoks\gtitle % title of current major group
+\newskip\intersecskip \intersecskip=12pt minus 3pt % space between sections
+\let\yskip=\smallskip
+\def\?{\mathrel?}
+\def\note#1#2.{\par\penalty5000
+ \Y\noindent{\hangindent2\em\baselineskip10pt\eightrm#1~#2.\par}}
+\def\lapstar{\rlap{*}}
+\def\stsec{\tenpoint\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent\strut{\bf\secno.\quad}}
+\def\startsection{\titletrue
+ \line{\smash{\titlefont\title}\quad\hrulefill}\bigskip
+ \let\startsection=\stsec\stsec}
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 } } % begin `define' or `format'
+\def\A{\note{See also section}} % xref for doubly defined section name
+\def\As{\note{See also sections}} % xref for multiply defined section name
+\def\B{\iftenpoint\ninepoint\fi
+ \rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 9999 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\C#1{\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$}
+\let\SHC\C % "// short comments" treated like "/* ordinary comments */"
+%\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+%\def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+\def\D{\defin{\#define}} % macro definition
+\let\E=\equiv % equivalence sign
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+% \H is long Hungarian umlaut accent
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K== % assignment operator
+%\let\K=\leftarrow % "honest" alternative to standard assignment operator
+% \L is Polish letter suppressed-L
+\outer\def\M#1{\def\secno{#1}\startsection\ignorespaces}
+\outer\def\N{\ifvoid\partialpage\lefttrue
+ \else\ifdim\ht\partialpage<\pageht \leftfalse\else\lefttrue\fi\fi\NNN}
+\outer\def\NN{\ifvoid\partialpage\leftfalse
+ \else\ifdim\ht\partialpage<\pageht \lefttrue\else\leftfalse\fi\fi\NNN}
+\outer\def\NNN#1#2#3.{\gdepth=#1\gtitle={#3}\def\secno{#2}% starred section
+ \ifleft \flushout
+ \gdef\rlhead{\let\i=I\uppercase{\ignorespaces#3}} % running left headline
+ \global\let\rrhead=\rlhead % running right headline
+ \else\global\setbox\partialpage=\vbox{
+ \vbox to\pageht{\unvbox\partialpage\vfill}\break}
+ \gdef\rrhead{\let\i=I\uppercase{\ignorespaces#3}}
+ \fi
+ \message{*\secno} % progress report
+ \startsection{\bf\ignorespaces#3.\quad}\ignorespaces}
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+\def\Q{\note{This code is cited in section}} % xref for mention of a section
+\def\Qs{\note{This code is cited in sections}} % xref for mentions of a section
+\let\R=\lnot % logical not
+% \S is section sign
+\def\T#1{\leavevmode % octal, hex or decimal constant
+ \hbox{$\def\?{\kern.2em}%
+ \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct \let\^=\hex {#1}$}}
+\def\U{\note{This code is used in section}} % xref for use of a section
+\def\Us{\note{This code is used in sections}} % xref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi % section name
+ \XX$\langle\,${\let\I=\ne#2\sevenrm\kern.5em#1}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\le
+\let\ZZ=\let % now you can \write the control sequence \ZZ
+\let\*=*
+
+%\def\oct{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}} % WEB style
+%\def\hex{\hbox{\rm\char"7D\tt\aftergroup}} % WEB style
+\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}% CWEB style
+\def\hex{\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} % CWEB style
+\def\vb#1{\leavevmode\hbox{\kern2pt\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule\kern2pt}} % verbatim string
+
+\def\TeX{{\ifmmode\it\fi
+ \leavevmode\hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
+
+% now here's the mini-index formatting control
+\newcount\nrefs % total number of references in partial page
+\newcount\baseno % smallest section number in partial page
+\toksdef\prefs=199 % references to previous sections in current program
+\toksdef\frefs=220 % references to future sections in current program
+\toksdef\erefs=221 % references to sections in another program
+% \count and \toks registers 200--219 are also used to keep track of refs
+\catcode`\@=11
+\newcount\@n \newcount\@m \newcount\@p
+\newdimen\pageht \pageht=19cm
+\newdimen\pagewd \pagewd=13cm
+\newdimen\colwd \colwd=\pagewd
+ \advance\colwd by -2pc \divide\colwd by 3 % for three columns
+\newdimen\fullpageht \fullpageht=\pageht \advance\fullpageht by 4pc
+\newdimen\pagethresh \pagethresh=2\pageht
+\newdimen\nsize \newdimen\msize
+\newskip\intersecskip \intersecskip=8pt plus 2pt minus 3pt
+\newbox\partialpage
+\newbox\newsec
+\newtoks\newrefs
+\newtoks\ttoks
+\newdimen\ninept \ninept=9pt
+\newif\iftitle \newif\ifleft
+
+\def\flushout{\ifvoid\partialpage\else
+ \setbox0=\vsplit\partialpage to \pageht
+ \shipout\vbox{
+ \vbox to 3pc{\leftheadline\vfill}
+ \nointerlineskip\box0}
+ \global\advance\pageno 1
+ \global\let\[=\makeinref \global\let\]=\makeoutref
+ \ifsorted \let\readin=\readln \readrefs
+ \else \immediate\write\reffile{!\the\pageno}\let\readin=\readrefs \fi
+ \setbox0=\vbox{\eightpoint \hsize=\colwd
+ \rightskip=0pt plus 100pt minus 10pt
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \noindent\vbox to1pt{}\par % 1pt = \topskip - \ninept
+ \readin}
+ \shipout\vbox to\fullpageht{
+ \vbox to 3pc{\rightheadline\vfill}
+ \unvbox\partialpage
+ \vfill
+ \ifdim\ht0>1pt \kern11pt\hrule \hbox{%
+ \nsize=\ht0 \advance\nsize-\topskip
+ \divide\nsize by 3 \divide\nsize by\ninept
+ \multiply\nsize by\ninept \advance\nsize\topskip
+ \vsplit0 to\nsize \kern1pc
+ \msize=\ht0 \advance\msize-\topskip
+ \divide\msize by 2 \divide\msize by\ninept
+ \multiply\msize by\ninept \advance\msize\topskip
+ \vbox to\nsize{\vsplit0 to\msize\vss}\kern1pc
+ \vbox to\nsize{\box0\vss}} \fi}
+ \global\advance\pageno 1 \global\let\rlhead=\rrhead\fi
+ {\globaldefs=1
+ \@n=199 \loop \ifnum\@n<222 \toks\@n={} \count\@n=0 \advance\@n 1 \repeat
+ \nrefs=0
+ \baseno=\secno}}
+\def\leftheadline{\hbox to\pagewd{\vbox to10pt{}%
+ \iftitle\global\titlefalse\else\ninerm\title:\enspace \eightsl\rlhead\fi
+ \hfil\eightrm\folio}}
+\def\rightheadline{\hbox to\pagewd{\vbox to10pt{}%
+ \eightrm\folio\hfil\ninerm\title:\enspace \eightsl\rrhead\/}}
+
+\def\mini{\begingroup \obeylines \globaldefs=1 \newrefs=\bgroup}
+\def\FI{\@n=\secno \advance\@n-\baseno \advance\@n 200
+ \advance\nrefs-\count\@n \@n=\nrefs
+ \let\[=\countnewref \let\]=\cn \the\newrefs \endgroup
+ \nobreak\null\nobreak\vskip-\baselineskip\penalty-500\vfil\eject}
+\def\twillout{\setbox\newsec=\vbox{\unvbox255}
+ \ifnum\@n=0 \nsize=0pt
+ \else \nsize=3pt \multiply\nsize\@n \advance\nsize 1.25pc \fi
+ \ifvoid\partialpage\else\advance\nsize 5pt \advance\nsize\ht\partialpage\fi
+ \advance\nsize\ht\newsec
+ \message{\the\nsize} % show the page break decision amount
+ \ifbr \global\brfalse \flushout \message{/\secno}\fi
+ \ifdim\nsize>\pagethresh \flushout \message{\secno}\fi
+ \addtopartialpage}
+\def\addtopartialpage{\globaldefs=1
+ \let\[=\addnewref \let\]=\addneweref \the\newrefs
+ \setbox\partialpage=\ifvoid\partialpage \box\newsec
+ \else \vbox{\unvbox\partialpage \vfilneg
+ \vskip\intersecskip \unvbox\newsec}\fi}
+\def\shortpage{\par\vskip-2\baselineskip
+ \null\vfill\penalty-5000\message{(shortpage)}}
+\newif\ifbr
+\def\forcebr{\global\brtrue}
+
+\def\countnewref #1 {\ifnum#1<\baseno \let\next\cn
+ \else\ifnum#1>\secno \let\next\cn \else\let\next\flushref\fi\fi\next#1 }
+\def\cn #1 #2 {\begintest{#1 #2}\cnr\endtest}
+
+% here's a tricky way to present \cnr with a csname unexpanded inside:
+\def\begintest#1{\def\TEST{#1}\expandafter\expandafter\expandafter}
+\def\endtest{\csname\expandafter\gobb\meaning\TEST\endcsname}
+\expandafter\def\expandafter\gobb\meaning\empty{}
+
+{\obeylines\gdef\cnr#1#2
+ {\ifx#1\relax \advance\@n 1 \fi}}
+{\obeylines\gdef\flushref#1
+ {}}
+\def\addnewref #1 {\ifnum#1<\baseno \let\next\an \@n=199
+ \else\ifnum#1>\secno \let\next\an \@n=#1 \advance\@n-\baseno
+ \advance\@n200 \ifnum\@n>219 \@n=220 \fi
+ \else\let\next\flushref\fi\fi\next#1 }
+\def\an#1 #2 {\begintest{#1 #2}\anr\endtest\[#1 #2 }
+\def\addneweref#1 #2 {\@n=221 \begintest{#1 #2}\anr\endtest\]#1 #2 }
+{\obeylines\gdef\anr#1#2
+ {\ifx#1\relax \advance\nrefs1 \advance\count\@n 1 %
+ \def#1{#2
+ }\toks\@n=\expandafter{\the\toks\@n\lmda#1}\fi}}
+\ifsorted \def\lmda#1{\global\let#1\relax}
+\else \def\lmda#1{#1\global\let#1\relax} \fi
+{\obeylines\gdef\makeinref#1 #2 #3
+ {\ifsorted\else\ttoks={\[#1 #2 #3}\immediate\write\reffile{+ \the\ttoks}\fi %
+ \hangindent=1em \noindent #2\miniform#3, \S#1.\par}}
+{\obeylines\gdef\makeoutref#1 #2 #3
+ {\ifsorted\else\ttoks={\]#1 #2 #3}\immediate\write\reffile{+ \the\ttoks}\fi %
+ \hangindent=1em \noindent #2\miniform#3, \extref#1.\par}}
+\def\miniform{\futurelet\next\miniforma}
+\def\miniforma{\ifx\next\zip
+ \else\if=\noexpand\next \let\next\gobbleq
+ \else\let\next\colon\fi\fi\next}
+\def\zip{}
+\def\gobbleq={\,=\,}
+\def\colon{: }
+\def\extref{\futurelet\next\extrefa}
+\def\extrefa{\if"\next\let\next\gobblest\else\let\next\cite\fi\next}
+\def\gobblest"#1"{{\ttx#1}}
+\def\cite#1#2.{{\sc#1}\,\S#2.}
+\def\uninitialized{???}
+
+\def\readrefs{\the\prefs \@m=\secno \advance\@m-\baseno \advance\@m200
+ {\def\lmda##1{\global\let##1\relax}\@p=200
+ \loop\ifnum\@p<\@m \the\toks\@p \advance\@p 1 \repeat}
+ \loop\ifnum\@m<222 \the\toks\@m \advance\@m 1 \repeat}
+\def\readln{\read\sreffile to\next \expandafter\next\newline \readin}
+{\obeylines\gdef\newline{\unskip\noexpand
+ }}
+\def\donewithpage#1 {\let\readin=\relax}
+\catcode`\@=12
+
+\hsize=\pagewd \vsize=\maxdimen \output={\twillout}
+
+\def\inx{\flushout\end}
+\def\fin{\parfillskip 0pt plus 1fil
+ \let\topsecno=\nullsec
+ \message{Section names:}
+ \def\note##1##2.{\quad{\eightrm##1~##2.}}
+ \def\Q{\note{Cited in section}} % crossref for mention of a section
+ \def\Qs{\note{Cited in sections}} % crossref for mentions of a section
+ \def\U{\note{Used in section}} % crossref for use of a section
+ \def\Us{\note{Used in sections}} % crossref for uses of a section
+ \def\I{\par\hangindent 2em}\let\*=*
+ \readsections}
+\def\readsections{\input \jobname.sscn}
+\def\datethis{}
+
+% To produce only a subset of pages, put the page numbers on separate
+% lines in a file called pages.tex
+\let\Shipout=\shipout
+\newread\pages \newcount\nextpage \openin\pages=pages
+\def\getnextpage{\ifeof\pages\else
+ {\endlinechar=-1\read\pages to\next
+ \ifx\next\empty % in this case we should have eof now
+ \else\global\nextpage=\next\fi}\fi}
+\ifeof\pages\else\message{OK, I'll ship only the requested pages!}
+ \getnextpage\fi
+\def\shipout{\ifeof\pages\let\next=\Shipout
+ \else\ifnum\pageno=\nextpage\getnextpage\let\next=\Shipout
+ \else\let\next=\Tosspage\fi\fi \next}
+\newbox\garbage \def\Tosspage{\deadcycles=0\setbox\garbage=}
diff --git a/Build/source/texk/web2c/cwebdir/cweav-bs.ch b/Build/source/texk/web2c/cwebdir/cweav-bs.ch
new file mode 100644
index 00000000000..bf2752881e4
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-bs.ch
@@ -0,0 +1,236 @@
+Changes for CWEAVE for MSDOS and Borland C++ 3.1 using the following
+options (and perhaps others):
+
+ -mc -w-pro -Ff=5000 -Z- -O-p
+
+The options -Z- and -O-p explicitly turn off optimizations that break
+the code. (See makefile.bs.)
+
+The main purpose of these changes is to support MSDOS with full-size arrays
+by using "huge" pointers.
+
+This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94.
+(Includes workaround for compiler bug [pointers wrapping around at
+ segment boundaries], November 1993, contributed by Jorge Fernandez Arnaiz
+ -- arnaiz@redvax1.dgsca.unam.mx)
+(Last revised 5 Dec 94 with help of bob@microprograms.com.)
+
+
+@x Section 1.
+The ``banner line'' defined here should be changed whenever \.{CWEAVE}
+is modified.
+
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+The ``banner line'' defined here should be changed whenever \.{CWEAVE}
+is modified.
+
+@d banner "This is CWEAVE (Version 4.2pc/big)"
+@z
+
+
+@x Section 7.
+ for section names */
+
+@<Common code...@>=
+typedef struct name_info {
+ char *byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ void *equiv_or_xref; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char byte_mem[]; /* characters of names */
+extern char *byte_mem_end; /* end of |byte_mem| */
+extern char *byte_ptr; /* first unused position in |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+@y
+ for section names */
+
+@f huge extern
+
+@<Common code...@>=
+typedef struct name_info {
+ char huge* byte_start; /* beginning of the name in |byte_mem| */
+ struct name_info *link;
+ union {
+ struct name_info *Rlink; /* right link in binary search tree for section
+ names */
+ char Ilk; /* used by identifiers in \.{CWEAVE} only */
+ } dummy;
+ union {
+ char *equiv_member;
+ char huge* xref_member;
+ } ptr_union; /* info corresponding to names */
+} name_info; /* contains information about an identifier or section name */
+typedef name_info *name_pointer; /* pointer into array of \&{name\_info}s */
+typedef name_pointer *hash_pointer;
+extern char huge byte_mem[]; /* characters of names */
+extern char huge* byte_mem_end; /* end of |byte_mem| */
+extern name_info name_dir[]; /* information about names */
+extern name_pointer name_dir_end; /* end of |name_dir| */
+extern name_pointer name_ptr; /* first unused position in |name_dir| */
+extern char huge* byte_ptr; /* first unused position in |byte_mem| */
+extern name_pointer hash[]; /* heads of hash lists */
+extern hash_pointer hash_end; /* end of |hash| */
+extern hash_pointer h; /* index into hash-head array */
+@z
+
+
+@x Section 22.
+typedef struct xref_info {
+ sixteen_bits num; /* section number plus zero or |def_flag| */
+ struct xref_info *xlink; /* pointer to the previous cross-reference */
+} xref_info;
+typedef xref_info *xref_pointer;
+@y
+typedef struct xref_info {
+ sixteen_bits num; /* section number plus zero or |def_flag| */
+ struct xref_info huge* xlink; /* pointer to the previous cross-reference */
+} xref_info;
+typedef xref_info huge* xref_pointer;
+@z
+
+
+@x Section 23.
+static xref_info xmem[max_refs]; /* contains cross-reference information */
+static xref_pointer xmem_end = xmem+max_refs-1;
+@y
+static xref_info huge xmem[max_refs]; /* contains cross-reference information */
+static xref_pointer xmem_end;
+@z
+
+
+@x Section 24.
+@d xref equiv_or_xref
+@y
+@d xref ptr_union.xref_member
+@z
+
+
+@x Section 24.
+xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
+xmem->num=0; /* sentinel value */
+@y
+xmem_end = xmem + max_refs - 1;
+xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
+xmem->num=0; /* sentinel value */
+@z
+
+
+@x Section 30. (to please Borland's C++, version 4.02)
+static token tok_mem[max_toks]; /* tokens */
+static token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */
+static token_pointer tok_ptr; /* first unused position in |tok_mem| */
+static token_pointer max_tok_ptr; /* largest value of |tok_ptr| */
+static token_pointer tok_start[max_texts]; /* directory into |tok_mem| */
+static text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */
+static text_pointer text_ptr; /* first unused position in |tok_start| */
+@y
+static token tok_mem[max_toks]; /* tokens */
+static token_pointer tok_mem_end; /* end of |tok_mem| */
+static token_pointer tok_ptr; /* first unused position in |tok_mem| */
+static token_pointer max_tok_ptr; /* largest value of |tok_ptr| */
+static token_pointer tok_start[max_texts]; /* directory into |tok_mem| */
+static text_pointer tok_start_end; /* end of |tok_start| */
+static text_pointer text_ptr; /* first unused position in |tok_start| */
+@z
+
+@x Section 31. (goes with the previous change)
+tok_ptr=max_tok_ptr=tok_mem+1;@/
+tok_start[0]=tok_start[1]=tok_mem+1;@/
+text_ptr=max_text_ptr=tok_start+1;
+@y
+tok_start[1]=tok_mem+1;
+tok_mem_end=tok_mem+max_toks-1;
+tok_start_end=tok_start+max_texts-1;
+max_tok_ptr=tok_mem+1; max_text_ptr=tok_start+1;
+@z
+
+
+@x Section 32.
+ p->xref=(void *)xmem;
+@y
+ p->xref=(void huge*)xmem;
+@z
+
+
+@x Section 74.
+ if (unindexed(lhs)) { /* retain only underlined entries */
+ xref_pointer q,r=NULL;
+ for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink)
+ if (q->num<def_flag)
+ if (r) r->xlink=q->xlink;
+ else lhs->xref=(void *)q->xlink;
+ else r=q;
+ }
+@y
+ if (unindexed(lhs)) { /* retain only underlined entries */
+ xref_pointer q,r=NULL;
+ for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink)
+ if (q->num<def_flag)
+ if (r) r->xlink=q->xlink;
+ else lhs->xref=(void huge*)q->xlink;
+ else r=q;
+ }
+@z
+
+
+@x Section 93.
+ char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
+ out('{');
+ for (k=p->byte_start; k<k_end; k++) {
+@y
+ char huge* k, huge* k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
+ out('{');
+ for (k=p->byte_start; k<k_end; k++) {
+@z
+
+
+@x Section 209.
+ char *p; /* index into |byte_mem| */
+@y
+ char huge *p; /* index into |byte_mem| */
+@z
+
+
+@x Section 244.
+ if (cur_name->xref!=(void *)xmem) {
+@y
+ if (cur_name->xref!=(void huge*)xmem) {
+@z
+
+
+@x Section 246.
+static char *cur_byte; /* index into |byte_mem| */
+@y
+static char huge* cur_byte; /* index into |byte_mem| */
+@z
+
+
+@x Section 255.
+switch (cur_name->ilk) {
+ case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
+ else {char *j;
+@y
+switch (cur_name->ilk) {
+ case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
+ else {char huge* j;
+@z
+
+
+@x Section 255.
+ case custom: {char *j; out_str("$\\");
+@y
+ case custom: {char huge* j; out_str("$\\");
+@z
diff --git a/Build/source/texk/web2c/cwebdir/cweav-man.ch b/Build/source/texk/web2c/cwebdir/cweav-man.ch
new file mode 100644
index 00000000000..b72360944a2
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-man.ch
@@ -0,0 +1,22 @@
+Change file to help make Appendix F of the full CWEB manual
+@x
+\def\botofcontents{\vfill
+\noindent
+Copyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth
+\bigskip\noindent
+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.
+
+\smallskip\noindent
+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.
+}
+@y
+\def\botofcontents{\vfill\titlefalse}
+\def\contentspagenumber{111}
+\def\title{APPENDIX F: CWEAVE}
+\let\K=\leftarrow
+@z
diff --git a/Build/source/texk/web2c/cwebdir/cweav-pc.ch b/Build/source/texk/web2c/cwebdir/cweav-pc.ch
new file mode 100644
index 00000000000..b37f9f2ec35
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-pc.ch
@@ -0,0 +1,28 @@
+This is the change file for CWEB's CWEAVE under DOS
+(Contributed by Lee Wittenberg, March 1993)
+(Also includes workaround for compiler bug, November 1993,
+ contributed by Jorge Fernandez Arnaiz -- arnaiz@redvax1.dgsca.unam.mx)
+
+Changes necessary for compiling with Borland C/C++
+Use compilation switches -mc -w-pro -Ff=5000
+
+Note: The changes to section 4 are not necessary if using a compiler
+that allows >64K arrays. (If you need lots more bytes, try the alternate
+change files that have -bs in their name instead of -pc.)
+
+@x section 1
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+@d banner "This is CWEAVE (Version 4.2pc)"
+@z
+
+@x section 4
+@d max_bytes 1000000 /* the number of bytes in identifiers,
+@y
+@d max_bytes (unsigned)60000 /* the number of bytes in identifiers,
+@z
+@x
+@d max_refs 65535 /* number of cross-references; must be less than 65536 */
+@y
+@d max_refs 10000 /* number of cross-references; must be less than 65536 */
+@z
diff --git a/Build/source/texk/web2c/cwebdir/cweav-ql.ch b/Build/source/texk/web2c/cwebdir/cweav-ql.ch
new file mode 100644
index 00000000000..28053eb1588
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-ql.ch
@@ -0,0 +1,32 @@
+This is the change file for CWEB's CWEAVE under QDOS/SMSQ
+(Contributed by Robert H. Klein, September 1994)
+
+This change file is intended for use with C68 v4.14 (or later).
+compile with
+ex <dev_>cc;"-v -h -c =500000 cweave_c"
+
+
+@x
+\def\title{CWEAVE (Version 4.2)}
+@y
+\def\title{CWEAVE (QL Version 4.2)}
+@z
+
+@x section 1
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+@d banner "This is CWEAVE (QL Version 4.2)"
+@z
+
+@x
+@i common.h
+@y
+@i common_h
+@z
+
+
+@x
+@i prod.w
+@y
+@i prod_w
+@z
diff --git a/Build/source/texk/web2c/cwebdir/cweav-vms.ch b/Build/source/texk/web2c/cwebdir/cweav-vms.ch
new file mode 100644
index 00000000000..7d80d57c1e8
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-vms.ch
@@ -0,0 +1,38 @@
+This is the change file for CWEB's CWEAVE for VAX/VMS.
+
+created:
+ 1991 JM (John Mulhollen, Science Applications International Corporation)
+
+modified:
+ 01-FEB-1992 ST (Stephan Trebels <trebels@ams02.dnet.gwdg.de>)
+ > include ctype,stdio from textlibrary SYS$SHARE:VAXCDEF.TLB
+ > change banner line to include (VAX/VMS)
+ > allow $ in identifiers (*necessary* for VAX/VMS)
+ ? will someone eventally make a CLD interface? (should be easy)
+
+(also modified by Don Knuth to keep version numbers uptodate)
+
+@x section 1 (01-FEB-1992 ST)
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+@d banner "This is CWEAVE (VAX/VMS Version 4.2)"
+@z
+
+@x section 3 (01-FEB-1992 ST)
+#include <ctype.h> /* definition of |@!isalpha|, |@!isdigit| and so on */
+#include <stdbool.h> /* definition of |@!bool|, |@!true| and |@!false| */
+#include <stddef.h> /* definition of |@!ptrdiff_t| */
+#include <stdint.h> /* definition of |@!uint8_t| and |@!uint16_t| */
+#include <stdlib.h> /* definition of |@!getenv| and |@!exit| */
+#include <stdio.h> /* definition of |@!printf| and friends */
+#include <string.h> /* definition of |@!strlen|, |@!strcmp| and so on */
+@y
+#include ctype /* definition of |@!isalpha|, |@!isdigit| and so on */
+ /* VMS searches text libraries faster */
+#include stdbool /* definition of |@!bool|, |@!true| and |@!false| */
+#include stddef /* definition of |@!ptrdiff_t| */
+#include stdint /* definition of |@!uint8_t| and |@!uint16_t| */
+#include stdlib /* definition of |@!getenv| and |@!exit| */
+#include stdio /* definition of |@!printf| and friends */
+#include string /* definition of |@!strlen|, |@!strcmp| and so on */
+@z
diff --git a/Build/source/texk/web2c/cwebdir/cweav-w2c.ch b/Build/source/texk/web2c/cwebdir/cweav-w2c.ch
new file mode 100644
index 00000000000..3f63105075a
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-w2c.ch
@@ -0,0 +1,713 @@
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
+
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
+
+@q This stripped change file {comm,ctang,cweav,ctwill,cwebman}-w2c.ch @>
+@q has been created from the elaborate set of change files @>
+@q {comm,ctang,cweav,cwebman}-patch.ch, @>
+@q {comm,cweav,cwebman}-extensions.ch, {comm,ctang,cweav}-output.ch, @>
+@q {comm,ctang,cweav}-i18n.ch, and cweav-twill.ch for CTWILL, and @>
+@q {comm,ctang,cweav,ctwill,cwebman}-texlive.ch with the 'tie' processor @>
+@q and is used as a monolithic changefile for {common,ctangle,cweave}.w @>
+@q and cwebman.tex in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
+\def\title{CWEAVE (Version 4.2)}
+@y
+\def\title{CWEAVE (Version 4.2 [\TeX~Live])}
+@z
+
+@x
+ \centerline{(Version 4.2)}
+@y
+ \centerline{(Version 4.2 [\TeX~Live])}
+@z
+
+@x
+\def\botofcontents{\vfill
+@y
+\def\covernote{\vbox{%
+@z
+
+@x
+}
+@y
+}}\datecontentspage
+@z
+
+@x
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+@d banner "This is CWEAVE, Version 4.2"
+ /* will be extended by the \TeX~Live |versionstring| */
+@z
+
+@x
+ if (show_banner) puts(banner); /* print a ``banner line'' */
+@y
+ if (show_banner) cb_show_banner(); /* print a ``banner line'' */
+@z
+
+@x
+@i common.h
+@y
+@i comm-w2c.h
+@z
+
+@x
+@d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference");
+@y
+@d append_xref(c) if (xref_ptr==xmem_end) overflow(_("cross-reference"));
+@z
+
+@x
+ err_print("! String didn't end"); loc=limit; break;
+@y
+ err_print(_("! String didn't end")); loc=limit; break;
+@z
+
+@x
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@y
+ err_print(_("! Input ended in middle of string")); loc=buffer; break;
+@z
+
+@x
+ fputs("\n! String too long: ",stdout);
+@y
+ fputs(_("\n! String too long: "),stdout);
+@z
+
+@x
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+ case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
+
+@x
+ err_print("! Input ended in section name");
+@y
+ err_print(_("! Input ended in section name"));
+@z
+
+@x
+ fputs("\n! Section name too long: ",stdout);
+@y
+ fputs(_("\n! Section name too long: "),stdout);
+@z
+
+@x
+ err_print("! Section name didn't end"); break;
+@y
+ err_print(_("! Section name didn't end")); break;
+@z
+
+@x
+ err_print("! Control codes are forbidden in section name"); break;
+@y
+ err_print(_("! Control codes are forbidden in section name")); break;
+@z
+
+@x
+ err_print("! Control text didn't end"); loc=limit;
+@y
+ err_print(_("! Control text didn't end")); loc=limit;
+@z
+
+@x
+ err_print("! Control codes are forbidden in control text");
+@y
+ err_print(_("! Control codes are forbidden in control text"));
+@z
+
+@x
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@y
+ if (loc>=limit) err_print(_("! Verbatim string didn't end"));
+@z
+
+@x
+ if (++section_count==max_sections) overflow("section number");
+@y
+ if (++section_count==max_sections) overflow(_("section number"));
+@z
+
+@x
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@y
+ case translit_code: err_print(_("! Use @@l in limbo only")); continue;
+@z
+
+@x
+ err_print("! Missing left identifier of @@s");
+@y
+ err_print(_("! Missing left identifier of @@s"));
+@z
+
+@x
+ err_print("! Missing right identifier of @@s");
+@y
+ err_print(_("! Missing right identifier of @@s"));
+@z
+
+@x
+ fputs("\n! Never defined: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@y
+ fputs(_("\n! Never defined: <"),stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@z
+
+@x
+ fputs("\n! Never used: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@y
+ fputs(_("\n! Never used: <"),stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@z
+
+@x
+@ In particular, the |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
+`\.{\\input cwebmac}'.
+
+@<Start \TEX/...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file;
+*out_ptr='c'; tex_printf("\\input cwebma");
+@y
+@ In particular, the |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 dependent of
+the user language set by the `\.{+l}' option and its argument. If you call
+\.{CWEAVE} with `\.{+lX}' (or `\.{-lX}' as well), where `\.X' is the
+(possibly empty) string of characters to the right of~`\.l', `\.X'~will be
+prepended to `\.{cwebmac.tex}', e.g., if you call \.{CWEAVE} with
+`\.{+ldeutsch}', you will receive the line `\.{\\input deutschcwebmac}'.
+Without this option the first line of the output file will be
+`\.{\\input cwebmac}'.
+
+@<Start \TEX/...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file; *out_ptr='c';
+tex_puts("\\input ");
+tex_printf(use_language);
+tex_puts("cwebma");
+@z
+
+@x
+ printf("\n! Line had to be broken (output l. %d):\n",out_line);
+@y
+ printf(_("\n! Line had to be broken (output l. %d):\n"),out_line);
+@z
+
+@x
+ default: err_print("! Double @@ should be used in limbo");
+@y
+ default: err_print(_("! Double @@ should be used in limbo"));
+@z
+
+@x
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;}
+@y
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow(_("token")); *(tok_ptr++)=c;}
+@z
+
+@x
+ err_print("! Input ended in mid-comment");
+@y
+ err_print(_("! Input ended in mid-comment"));
+@z
+
+@x
+ if (bal>1) err_print("! Missing } in comment");
+@y
+ if (bal>1) err_print(_("! Missing } in comment"));
+@z
+
+@x
+ else {err_print("! Extra } in comment");
+@y
+ else {err_print(_("! Extra } in comment"));
+@z
+
+@x
+ if (bal>1) err_print("! Missing } in comment");
+@y
+ if (bal>1) err_print(_("! Missing } in comment"));
+@z
+
+@x
+ err_print("! Illegal use of @@ in comment");
+@y
+ err_print(_("! Illegal use of @@ in comment"));
+@z
+
+@x
+@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */
+
+@c
+static void
+print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
+@y
+@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */
+
+@c
+#if 0
+static void
+print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
+@z
+
+@x
+}
+@y
+}
+#endif
+@z
+
+@x
+@ @<Predecl...@>=@+static void print_text(text_pointer p);
+@y
+@ @<Predecl...@>=
+#if 0
+static void print_text(text_pointer p);
+#endif
+@z
+
+@x
+@<Cases for |exp|@>=
+if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ make_underlined(pp); big_app1(pp); big_app(indent); app(indent);
+ reduce(pp,1,fn_decl,0,1);
+}
+@y
+@<Cases for |exp|@>=
+if(cat1==lbrace || cat1==int_like || cat1==decl) {
+ make_underlined(pp); big_app1(pp);
+ if (indent_param_decl) {
+ big_app(indent); app(indent);
+ }
+ reduce(pp,1,fn_decl,0,1);
+}
+@z
+
+@x
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+ cat3==semi || cat3==rpar))
+ squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ big_app1(pp); big_app(indent); app(indent); reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+@y
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+ cat3==semi || cat3==rpar))
+ squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ big_app1(pp);
+ if (indent_param_decl) {
+ big_app(indent); app(indent);
+ }
+ reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+@z
+
+@x
+@ @<Cases for |decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1);
+ reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+ big_app1(pp); big_app(big_force);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+@y
+@ @<Cases for |decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1);
+ reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+ big_app1(pp);
+ if(order_decl_stmt) big_app(big_force);
+ else big_app(force);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+@z
+
+@x
+@ @<Cases for |fn_decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+ big_app1(pp); app(outdent); app(outdent); big_app(force);
+ big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+@y
+@ @<Cases for |fn_decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+ big_app1(pp);
+ if (indent_param_decl) {
+ app(outdent); app(outdent);
+ }
+ big_app(force);
+ big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+@z
+
+@x
+ overflow("token");
+@y
+ overflow(_("token"));
+@z
+
+@x
+ overflow("text");
+@y
+ overflow(_("text"));
+@z
+
+@x
+ if (tok_ptr+6>tok_mem_end) overflow("token");
+@y
+ if (tok_ptr+6>tok_mem_end) overflow(_("token"));
+@z
+
+@x
+ printf("\nIrreducible scrap sequence in section %d:",section_count);
+@y
+ printf(_("\nIrreducible scrap sequence in section %d:"),section_count);
+@z
+
+@x
+ printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+@y
+ printf(_("\nTracing after l. %d:\n"),cur_line); mark_harmless;
+@z
+
+@x
+ overflow("scrap/token/text");
+@y
+ overflow(_("scrap/token/text"));
+@z
+
+@x
+ else err_print("! Double @@ should be used in strings");
+@y
+ else err_print(_("! Double @@ should be used in strings"));
+@z
+
+@x
+ if (next_control!='|') err_print("! Missing '|' after C text");
+@y
+ if (next_control!='|') err_print(_("! Missing '|' after C text"));
+@z
+
+@x
+ if (stack_ptr==stack_end) overflow("stack");
+@y
+ if (stack_ptr==stack_end) overflow(_("stack"));
+@z
+
+@x
+ fputs("\n! Illegal control code in section name: <",stdout);
+@y
+ fputs(_("\n! Illegal control code in section name: <"),stdout);
+@z
+
+@x
+ fputs("\n! C text in section name didn't end: <",stdout);
+@y
+ fputs(_("\n! C text in section name didn't end: <"),stdout);
+@z
+
+@x
+ if (j>buffer+long_buf_size-3) overflow("buffer");
+@y
+ if (j>buffer+long_buf_size-3) overflow(_("buffer"));
+@z
+
+@x
+ if (j>buffer+long_buf_size-4) overflow("buffer");
+@y
+ if (j>buffer+long_buf_size-4) overflow(_("buffer"));
+@z
+
+@x
+reset_input(); if (show_progress) fputs("\nWriting the output file...",stdout);
+@y
+reset_input(); if (show_progress) fputs(_("\nWriting the output file..."),stdout);
+@z
+
+@x
+ err_print("! TeX string should be in C text only"); break;
+@y
+ err_print(_("! TeX string should be in C text only")); break;
+@z
+
+@x
+ err_print("! You can't do that in TeX text"); break;
+@y
+ err_print(_("! You can't do that in TeX text")); break;
+@z
+
+@x
+ err_print("! Improper macro definition");
+@y
+ err_print(_("! Improper macro definition"));
+@z
+
+@x
+ default: err_print("! Improper macro definition"); break;
+@y
+ default: err_print(_("! Improper macro definition")); break;
+@z
+
+@x
+ if (scrap_ptr!=scrap_info+2) err_print("! Improper format definition");
+@y
+ if (scrap_ptr!=scrap_info+2) err_print(_("! Improper format definition"));
+@z
+
+@x
+ err_print("! You need an = sign after the section name");
+@y
+ err_print(_("! You need an = sign after the section name"));
+@z
+
+@x
+ err_print("! You can't do that in C text");
+@y
+ err_print(_("! You can't do that in C text"));
+@z
+
+@x
+if (no_xref) {
+ finish_line();
+ out_str("\\end");
+@.\\end@>
+ finish_line();
+}
+@y
+if (no_xref) {
+ finish_line();
+ out_str("\\end");
+@.\\end@>
+ active_file=tex_file;
+}
+@z
+
+@x
+ phase=3; if (show_progress) fputs("\nWriting the index...",stdout);
+@y
+ phase=3; if (show_progress) fputs(_("\nWriting the index..."),stdout);
+@z
+
+@x
+ fatal("! Cannot open index file ",idx_file_name);
+@y
+ fatal(_("! Cannot open index file "),idx_file_name);
+@z
+
+@x
+ fatal("! Cannot open section file ",scn_file_name);
+@y
+ fatal(_("! Cannot open section file "),scn_file_name);
+@z
+
+@x
+@.\\end@>
+ finish_line();
+ fclose(active_file);
+}
+@y
+@.\\end@>
+}
+finish_line(); fclose(active_file); active_file=NULL;
+@<Update the result when it has changed@>@;
+@z
+
+@x
+ fputs("Done.",stdout);
+@y
+ fputs(_("Done."),stdout);
+@z
+
+@x
+ if (sort_ptr>=scrap_info_end) overflow("sorting");
+@y
+ if (sort_ptr>=scrap_info_end) overflow(_("sorting"));
+@z
+
+@x
+ puts("\nMemory usage statistics:");
+@.Memory usage statistics:@>
+ printf("%ld names (out of %ld)\n",
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf("%ld cross-references (out of %ld)\n",
+ (ptrdiff_t)(xref_ptr-xmem),(long)max_refs);
+ printf("%ld bytes (out of %ld)\n",
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ puts("Parsing:");
+ printf("%ld scraps (out of %ld)\n",
+ (ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps);
+ printf("%ld texts (out of %ld)\n",
+ (ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts);
+ printf("%ld tokens (out of %ld)\n",
+ (ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks);
+ printf("%ld levels (out of %ld)\n",
+ (ptrdiff_t)(max_stack_ptr-stack),(long)stack_size);
+ puts("Sorting:");
+ printf("%ld levels (out of %ld)\n",
+ (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps);
+@y
+ puts(_("\nMemory usage statistics:"));
+@.Memory usage statistics:@>
+ printf(_("%ld names (out of %ld)\n"),
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf(_("%ld cross-references (out of %ld)\n"),
+ (ptrdiff_t)(xref_ptr-xmem),(long)max_refs);
+ printf(_("%ld bytes (out of %ld)\n"),
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ puts(_("Parsing:"));
+ printf(_("%ld scraps (out of %ld)\n"),
+ (ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps);
+ printf(_("%ld texts (out of %ld)\n"),
+ (ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts);
+ printf(_("%ld tokens (out of %ld)\n"),
+ (ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks);
+ printf(_("%ld levels (out of %ld)\n"),
+ (ptrdiff_t)(max_stack_ptr-stack),(long)stack_size);
+ puts(_("Sorting:"));
+ printf(_("%ld levels (out of %ld)\n"),
+ (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps);
+@z
+
+@x
+@** Index.
+@y
+@** Extensions to \.{CWEB}. The following sections introduce new or improved
+features that have been created by numerous contributors over the course of a
+quarter century.
+
+Care has been taken to keep the original section numbering intact, so this new
+material should nicely integrate with the original ``\&{263.~Index}.''
+
+@* Formatting alternatives.
+\.{CWEAVE} indents declarations after old-style function definitions.
+With the \.{-i} option they will come out flush left. You won't see
+any difference if you use ANSI-style function definitions.
+
+@d indent_param_decl flags['i'] /* should formal parameter declarations be indented? */
+
+@<Set init...@>=
+indent_param_decl=true;
+
+@ The original manual described the \.{-o} option for \.{CWEAVE}, but this was
+not yet present. Here is a simple implementation. The purpose is to suppress
+the extra space between local variable declarations and the first statement in
+a function block.
+
+@d order_decl_stmt flags['o'] /* should declarations and statements be separated? */
+
+@<Set init...@>=
+order_decl_stmt=true;
+
+@* Output file update. Most \CEE/ projects are controlled by a
+\.{Makefile} that automatically takes care of the temporal dependecies
+between the different source modules. It is suitable that \.{CWEB} doesn't
+create new output for all existing files, when there are only changes to
+some of them. Thus the \.{make} process will only recompile those modules
+where necessary. The idea and basic implementation of this mechanism can
+be found in the program \.{NUWEB} by Preston Briggs, to whom credit is due.
+
+@<Update the result...@>=
+if((tex_file=fopen(tex_file_name,"r"))!=NULL) {
+ char x[BUFSIZ],y[BUFSIZ];
+ int x_size,y_size,comparison=false;
+
+ if((check_file=fopen(check_file_name,"r"))==NULL)
+ fatal(_("! Cannot open output file "),check_file_name);
+@.Cannot open output file@>
+
+ if (temporary_output) @<Compare the temporary output...@>@;
+
+ fclose(tex_file); tex_file=NULL;
+ fclose(check_file); check_file=NULL;
+
+ @<Take appropriate action depending on the comparison@>@;
+} else
+ rename(check_file_name,tex_file_name); /* This was the first run */
+
+strcpy(check_file_name,""); /* We want to get rid of the temporary file */
+
+@ We hope that this runs fast on most systems.
+
+@<Compare the temporary output to the previous output@>=
+do {
+ x_size = fread(x,1,BUFSIZ,tex_file);
+ y_size = fread(y,1,BUFSIZ,check_file);
+ comparison = (x_size == y_size); /* Do not merge these statements! */
+ if(comparison) comparison = !memcmp(x,y,x_size);
+} while(comparison && !feof(tex_file) && !feof(check_file));
+
+@ Note the superfluous call to |remove| before |rename|. We're using it to
+get around a bug in some implementations of |rename|.
+
+@<Take appropriate action...@>=
+if(comparison)
+ remove(check_file_name); /* The output remains untouched */
+else {
+ remove(tex_file_name);
+ rename(check_file_name,tex_file_name);
+}
+
+@* Put ``version'' information in a single spot.
+Don't do this at home, kids! Push our local macro to the variable in \.{COMMON}
+for printing the |banner| and the |versionstring| from there.
+
+@d max_banner 50
+
+@<Common code...@>=
+extern char cb_banner[];
+
+@ @<Set init...@>=
+ strncpy(cb_banner,banner,max_banner-1);
+
+@** Index.
+@z
+
diff --git a/Build/source/texk/web2c/cwebdir/cweav-w32.ch b/Build/source/texk/web2c/cwebdir/cweav-w32.ch
new file mode 100644
index 00000000000..346d00771aa
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweav-w32.ch
@@ -0,0 +1,34 @@
+This is the change file for CWEB's CWEAVE under Win32
+(Contributed by Fabrice Popineau, February 2002)
+
+@x section 1
+@d banner "This is CWEAVE (Version 4.2)"
+@y
+@d banner "This is CWEAVE (Version 4.2win32)"
+@z
+
+@x
+boolean names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* desired |ilk| */
+@y
+boolean __cdecl names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* desired |ilk| */
+@z
+
+@x
+void
+init_p(
+name_pointer p,
+eight_bits t)
+@y
+void __cdecl
+init_p(
+name_pointer p,
+eight_bits t)
+@z
diff --git a/Build/source/texk/web2c/cwebdir/cweave.test b/Build/source/texk/web2c/cwebdir/cweave.test
new file mode 100755
index 00000000000..b20b5b9da29
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweave.test
@@ -0,0 +1,9 @@
+#! /bin/sh -vx
+# $Id$
+# Copyright 2017 Karl Berry <tex-live@tug.org>
+# Copyright 2009 Peter Breitenlohner <tex-live@tug.org>
+# You may freely use, modify and/or distribute this file.
+
+TEXMFCNF=$srcdir/../kpathsea \
+ CWEBINPUTS=$srcdir/cwebdir ./cweave common.w || exit 1
+
diff --git a/Build/source/texk/web2c/cwebdir/cweave.w b/Build/source/texk/web2c/cwebdir/cweave.w
new file mode 100644
index 00000000000..a8e31055b23
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweave.w
@@ -0,0 +1,4696 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 4.2 --- February 2021
+
+% Copyright (C) 1987,1990,1993,2000 Silvio Levy and Donald E. Knuth
+
+% 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.
+
+% Amendments to 'cweave.w' resulting in this updated version were created
+% by numerous collaborators over the course of many years.
+
+% Please send comments, suggestions, etc. to tex-k@@tug.org.
+
+% Here is TeX material that gets inserted after \input cwebmac
+\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{CWEAVE (Version 4.2)}
+\def\topofcontents{\null\vfill
+ \centerline{\titlefont The {\ttitlefont CWEAVE} processor}
+ \vskip 15pt
+ \centerline{(Version 4.2)}
+ \vfill}
+\def\botofcontents{\vfill
+\noindent
+Copyright \copyright\ 1987, 1990, 1993, 2000 Silvio Levy and Donald E. Knuth
+\bigskip\noindent
+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.
+
+\smallskip\noindent
+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.
+}
+\pageno=\contentspagenumber \advance\pageno by 1
+\let\maybe=\iftrue
+
+@** Introduction.
+This is the \.{CWEAVE} program by Silvio Levy and Donald E. Knuth,
+based on \.{WEAVE} by Knuth.
+We are thankful to Steve Avery,
+Nelson Beebe, Hans-Hermann Bode (to whom the original \CPLUSPLUS/ adaptation
+is due), Klaus Guntermann, Norman Ramsey, Tomas Rokicki, Joachim Schnitter,
+Joachim Schrod, Lee Wittenberg, Saroj Mahapatra, Cesar Augusto Rorato
+Crusius, and others who have contributed improvements.
+
+The ``banner line'' defined here should be changed whenever \.{CWEAVE}
+is modified.
+
+@d banner "This is CWEAVE (Version 4.2)"
+
+@c @<Include files@>@/
+@h
+@<Common code for \.{CWEAVE} and \.{CTANGLE}@>@/
+@<Typedef declarations@>@/
+@<Private variables@>@/
+@<Predeclaration of procedures@>
+
+@ \.{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 \.{common}, the set of routines common
+to \.{CTANGLE} and \.{CWEAVE}, before proceeding further.
+
+@c
+int main (@t\1\1@>
+int ac, /* argument count */
+char **av@t\2\2@>) /* argument values */
+{
+ argc=ac; argv=av;
+ program=cweave;
+ @<Set initial values@>@;
+ common_init();
+ @<Start \TEX/ output@>@;
+ if (show_banner) puts(banner); /* print a ``banner line'' */
+ @<Store all the reserved words@>@;
+ phase_one(); /* read all the user's text and store the cross-references */
+ phase_two(); /* read all the text again and translate it to \TEX/ form */
+ phase_three(); /* output the cross-reference index */
+ if (tracing==2 && !show_progress) new_line;
+ return wrap_up(); /* and exit gracefully */
+}
+
+@ The next few sections contain stuff from the file |"common.w"| that must
+be included in both |"ctangle.w"| and |"cweave.w"|. It appears in
+file |"common.h"|, which is also included in |"common.w"| to propagate
+possible changes from this \.{COMMON} interface consistently.
+
+@i common.h
+
+@ The following parameters were sufficient in the original \.{WEAVE} to
+handle \TEX/, so they should be sufficient for most applications of \.{CWEAVE}.
+
+@d line_length 80 /* lines of \TEX/ output have at most this many characters;
+ should be less than 256 */
+@d max_refs 65535 /* number of cross-references; must be less than 65536 */
+@d max_texts 10239 /* number of phrases in \CEE/ texts being parsed;
+ must be less than 10240 */
+@d max_scraps 10000 /* number of tokens in \CEE/ texts being parsed */
+
+@* Data structures exclusive to {\tt CWEAVE}.
+As explained in \.{common.w}, the field of a |name_info| structure
+that contains the |rlink| of a section name is used for a completely
+different purpose in the case of identifiers. It is then called the
+|ilk| of the identifier, and it is used to
+distinguish between various types of identifiers, as follows:
+
+\yskip\hang |normal| and |func_template| identifiers are part of the
+\CEE/ program that will appear in italic type (or in typewriter type
+if all uppercase).
+
+\yskip\hang |custom| identifiers are part of the \CEE/ program that
+will be typeset in special ways.
+
+\yskip\hang |roman| identifiers are index entries that appear after
+\.{@@\^} in the \.{CWEB} file.
+
+\yskip\hang |wildcard| identifiers are index entries that appear after
+\.{@@:} in the \.{CWEB} file.
+
+\yskip\hang |typewriter| identifiers are index entries that appear after
+\.{@@.} in the \.{CWEB} file.
+
+\yskip\hang |alfop|, \dots, |template_like|
+identifiers are \CEE/ or \CPLUSPLUS/ reserved words whose |ilk|
+explains how they are to be treated when \CEE/ code is being
+formatted.
+
+@d ilk dummy.Ilk
+@d normal 0 /* ordinary identifiers have |normal| ilk */
+@d roman 1 /* normal index entries have |roman| ilk */
+@d wildcard 2 /* user-formatted index entries have |wildcard| ilk */
+@d typewriter 3 /* `typewriter type' entries have |typewriter| ilk */
+@d abnormal(a) (a->ilk>typewriter) /* tells if a name is special */
+@d func_template 4 /* identifiers that can be followed by optional template */
+@d custom 5 /* identifiers with user-given control sequence */
+@d alfop 22 /* alphabetic operators like \&{and} or \&{not\_eq} */
+@d else_like 26 /* \&{else} */
+@d public_like 40 /* \&{public}, \&{private}, \&{protected} */
+@d operator_like 41 /* \&{operator} */
+@d new_like 42 /* \&{new} */
+@d catch_like 43 /* \&{catch} */
+@d for_like 45 /* \&{for}, \&{switch}, \&{while} */
+@d do_like 46 /* \&{do} */
+@d if_like 47 /* \&{if}, \&{ifdef}, \&{endif}, \&{pragma}, \dots */
+@d delete_like 48 /* \&{delete} */
+@d raw_ubin 49 /* `\.\&' or `\.*' when looking for \&{const} following */
+@d const_like 50 /* \&{const}, \&{volatile} */
+@d raw_int 51 /* \&{int}, \&{char}, \dots; also structure and class names */
+@d int_like 52 /* same, when not followed by left parenthesis or \DC\ */
+@d case_like 53 /* \&{case}, \&{return}, \&{goto}, \&{break}, \&{continue} */
+@d sizeof_like 54 /* \&{sizeof} */
+@d struct_like 55 /* \&{struct}, \&{union}, \&{enum}, \&{class} */
+@d typedef_like 56 /* \&{typedef} */
+@d define_like 57 /* \&{define} */
+@d template_like 58 /* \&{template} */
+
+@ We keep track of the current section number in |section_count|, which
+is the total number of sections that have started. Sections which have
+been altered by a change file entry have their |changed_section| flag
+turned on during the first phase.
+
+@<Private...@>=
+static boolean change_exists; /* has any section changed? */
+
+@ The other large memory area in \.{CWEAVE} keeps the cross-reference data.
+All uses of the name |p| are recorded in a linked list beginning at
+|p->xref|, which points into the |xmem| array. The elements of |xmem|
+are structures consisting of an integer, |num|, and a pointer |xlink|
+to another element of |xmem|. If |x=p->xref| is a pointer into |xmem|,
+the value of |x->num| is either a section number where |p| is used,
+or |cite_flag| plus a section number where |p| is mentioned,
+or |def_flag| plus a section number where |p| is defined;
+and |x->xlink| points to the next such cross-reference for |p|,
+if any. This list of cross-references is in decreasing order by
+section number. The next unused slot in |xmem| is |xref_ptr|.
+The linked list ends at |&xmem[0]|.
+
+The global variable |xref_switch| is set either to |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 |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 |section_xref_switch| is either
+|def_flag| or |cite_flag| or zero, depending
+on whether a section name is being defined, cited or used in \CEE/ text.
+
+@<Type...@>=
+typedef struct xref_info {
+ sixteen_bits num; /* section number plus zero or |def_flag| */
+ struct xref_info *xlink; /* pointer to the previous cross-reference */
+} xref_info;
+typedef xref_info *xref_pointer;
+
+@ @<Private...@>=
+static xref_info xmem[max_refs]; /* contains cross-reference information */
+static xref_pointer xmem_end = xmem+max_refs-1;
+static xref_pointer xref_ptr; /* the largest occupied position in |xmem| */
+static sixteen_bits xref_switch,section_xref_switch; /* either zero or |def_flag| */
+
+@ A section that is used for multi-file output (with the \.{@@(} feature)
+has a special first cross-reference whose |num| field is |file_flag|.
+
+@d file_flag (3*cite_flag)
+@d def_flag (2*cite_flag)
+@d cite_flag 10240 /* must be strictly larger than |max_sections| */
+@d xref equiv_or_xref
+
+@<Set init...@>=
+xref_ptr=xmem; init_node(name_dir); xref_switch=0; section_xref_switch=0;
+xmem->num=0; /* sentinel value */
+
+@ A new cross-reference for an identifier is formed by calling |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 |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.
+
+@d append_xref(c) if (xref_ptr==xmem_end) overflow("cross-reference");
+ else (++xref_ptr)->num=c;
+@d no_xref (!make_xrefs)
+@d is_tiny(p) ((p+1)->byte_start==(p)->byte_start+1)
+@d unindexed(a) (a<res_wd_end && a->ilk>=custom)
+ /* tells if uses of a name are to be indexed */
+
+@<Predecl...@>=
+static void new_xref(name_pointer);@/
+static void new_section_xref(name_pointer);@/
+static void set_file_flag(name_pointer);
+
+@ @c
+static void
+new_xref(
+name_pointer p)
+{
+ xref_pointer q; /* pointer to previous cross-reference */
+ sixteen_bits m, n; /* new and previous cross-reference value */
+ if (no_xref) return;
+ if ((unindexed(p) || is_tiny(p)) && xref_switch==0) return;
+ m=section_count+xref_switch; xref_switch=0; q=(xref_pointer)p->xref;
+ if (q != xmem) {
+ n=q->num;
+ if (n==m || n==m+def_flag) return;
+ else if (m==n+def_flag) {
+ q->num=m; return;
+ }
+ }
+ append_xref(m); xref_ptr->xlink=q; update_node(p);
+}
+
+@ 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+|def_flag|$,
+\dots, $m_k+|def_flag|$, $n_1+|cite_flag|$, \dots,
+$n_l+|cite_flag|$, $p_1$, \dots, $p_j$, in this order.
+
+Although this method of storage takes quadratic time with respect to
+the length of the list, under foreseeable uses of \.{CWEAVE} this inefficiency
+is insignificant.
+
+@c
+static void
+new_section_xref(
+name_pointer p)
+{
+ xref_pointer q,r; /* pointers to previous cross-references */
+ q=(xref_pointer)p->xref; r=xmem;
+ if (q>xmem)
+ while (q->num>section_xref_switch) {r=q; q=q->xlink;}
+ if (r->num==section_count+section_xref_switch)
+ return; /* don't duplicate entries */
+ append_xref(section_count+section_xref_switch);
+ xref_ptr->xlink=q; section_xref_switch=0;
+ if (r==xmem) update_node(p);
+ else r->xlink=xref_ptr;
+}
+
+@ The cross-reference list for a section name may also begin with
+|file_flag|. Here's how that flag gets put~in.
+
+@c
+static void
+set_file_flag(
+name_pointer p)
+{
+ xref_pointer q;
+ q=(xref_pointer)p->xref;
+ if (q->num==file_flag) return;
+ append_xref(file_flag);
+ xref_ptr->xlink = q;
+ update_node(p);
+}
+
+@ A third large area of memory is used for sixteen-bit `tokens', which appear
+in short lists similar to the strings of characters in |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 \&{text\_pointer}
+variable is an index into |tok_start|.
+
+@<Typed...@>=
+typedef sixteen_bits token;
+typedef token *token_pointer;
+typedef token_pointer *text_pointer;
+
+@ The first position of |tok_mem|
+that is unoccupied by replacement text is called |tok_ptr|, and the first
+unused location of |tok_start| is called |text_ptr|.
+Thus, we usually have |*text_ptr==tok_ptr|.
+
+@<Private...@>=
+static token tok_mem[max_toks]; /* tokens */
+static token_pointer tok_mem_end = tok_mem+max_toks-1; /* end of |tok_mem| */
+static token_pointer tok_ptr; /* first unused position in |tok_mem| */
+static token_pointer max_tok_ptr; /* largest value of |tok_ptr| */
+static token_pointer tok_start[max_texts]; /* directory into |tok_mem| */
+static text_pointer tok_start_end = tok_start+max_texts-1; /* end of |tok_start| */
+static text_pointer text_ptr; /* first unused position in |tok_start| */
+static text_pointer max_text_ptr; /* largest value of |text_ptr| */
+
+@ @<Set init...@>=
+tok_ptr=max_tok_ptr=tok_mem+1;@/
+tok_start[0]=tok_start[1]=tok_mem+1;@/
+text_ptr=max_text_ptr=tok_start+1;
+
+@ Here are the three procedures needed to complete |id_lookup|:
+@c
+boolean names_match(@t\1\1@>
+name_pointer p, /* points to the proposed match */
+const char *first, /* position of first character of string */
+size_t l, /* length of identifier */
+eight_bits t@t\2\2@>) /* desired |ilk| */
+{
+ if (length(p)!=l) return false;
+ if (p->ilk!=t && !(t==normal && abnormal(p))) return false;
+ return !strncmp(first,p->byte_start,l);
+}
+
+void
+init_p(
+name_pointer p,
+eight_bits t)
+{
+ p->ilk=t; init_node(p);
+}
+
+void
+init_node(
+name_pointer p)
+{
+ p->xref=(void *)xmem;
+}
+
+static void
+update_node(
+name_pointer p)
+{
+ p->xref=(void *)xref_ptr;
+}
+
+@ @<Predecl...@>=@+static void update_node(name_pointer p);
+
+@ 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.)
+@^reserved words@>
+
+@<Store all the reserved words@>=
+id_lookup("and",NULL,alfop);
+id_lookup("and_eq",NULL,alfop);
+id_lookup("asm",NULL,sizeof_like);
+id_lookup("auto",NULL,int_like);
+id_lookup("bitand",NULL,alfop);
+id_lookup("bitor",NULL,alfop);
+id_lookup("bool",NULL,raw_int);
+id_lookup("break",NULL,case_like);
+id_lookup("case",NULL,case_like);
+id_lookup("catch",NULL,catch_like);
+id_lookup("char",NULL,raw_int);
+id_lookup("class",NULL,struct_like);
+id_lookup("clock_t",NULL,raw_int);
+id_lookup("compl",NULL,alfop);
+id_lookup("const",NULL,const_like);
+id_lookup("const_cast",NULL,raw_int);
+id_lookup("continue",NULL,case_like);
+id_lookup("default",NULL,case_like);
+id_lookup("define",NULL,define_like);
+id_lookup("defined",NULL,sizeof_like);
+id_lookup("delete",NULL,delete_like);
+id_lookup("div_t",NULL,raw_int);
+id_lookup("do",NULL,do_like);
+id_lookup("double",NULL,raw_int);
+id_lookup("dynamic_cast",NULL,raw_int);
+id_lookup("elif",NULL,if_like);
+id_lookup("else",NULL,else_like);
+id_lookup("endif",NULL,if_like);
+id_lookup("enum",NULL,struct_like);
+id_lookup("error",NULL,if_like);
+id_lookup("explicit",NULL,int_like);
+id_lookup("export",NULL,int_like);
+id_lookup("extern",NULL,int_like);
+id_lookup("FILE",NULL,raw_int);
+id_lookup("float",NULL,raw_int);
+id_lookup("for",NULL,for_like);
+id_lookup("fpos_t",NULL,raw_int);
+id_lookup("friend",NULL,int_like);
+id_lookup("goto",NULL,case_like);
+id_lookup("if",NULL,if_like);
+id_lookup("ifdef",NULL,if_like);
+id_lookup("ifndef",NULL,if_like);
+id_lookup("include",NULL,if_like);
+id_lookup("inline",NULL,int_like);
+id_lookup("int",NULL,raw_int);
+id_lookup("jmp_buf",NULL,raw_int);
+id_lookup("ldiv_t",NULL,raw_int);
+id_lookup("line",NULL,if_like);
+id_lookup("long",NULL,raw_int);
+id_lookup("mutable",NULL,int_like);
+id_lookup("namespace",NULL,struct_like);
+id_lookup("new",NULL,new_like);
+id_lookup("not",NULL,alfop);
+id_lookup("not_eq",NULL,alfop);
+id_lookup("NULL",NULL,custom);
+id_lookup("offsetof",NULL,raw_int);
+id_lookup("operator",NULL,operator_like);
+id_lookup("or",NULL,alfop);
+id_lookup("or_eq",NULL,alfop);
+id_lookup("pragma",NULL,if_like);
+id_lookup("private",NULL,public_like);
+id_lookup("protected",NULL,public_like);
+id_lookup("ptrdiff_t",NULL,raw_int);
+id_lookup("public",NULL,public_like);
+id_lookup("register",NULL,int_like);
+id_lookup("reinterpret_cast",NULL,raw_int);
+id_lookup("return",NULL,case_like);
+id_lookup("short",NULL,raw_int);
+id_lookup("sig_atomic_t",NULL,raw_int);
+id_lookup("signed",NULL,raw_int);
+id_lookup("size_t",NULL,raw_int);
+id_lookup("sizeof",NULL,sizeof_like);
+id_lookup("static",NULL,int_like);
+id_lookup("static_cast",NULL,raw_int);
+id_lookup("struct",NULL,struct_like);
+id_lookup("switch",NULL,for_like);
+id_lookup("template",NULL,template_like);
+id_lookup("this",NULL,custom);
+id_lookup("throw",NULL,case_like);
+id_lookup("time_t",NULL,raw_int);
+id_lookup("try",NULL,else_like);
+id_lookup("typedef",NULL,typedef_like);
+id_lookup("typeid",NULL,raw_int);
+id_lookup("typename",NULL,struct_like);
+id_lookup("undef",NULL,if_like);
+id_lookup("union",NULL,struct_like);
+id_lookup("unsigned",NULL,raw_int);
+id_lookup("using",NULL,int_like);
+id_lookup("va_dcl",NULL,decl); /* Berkeley's variable-arg-list convention */
+id_lookup("va_list",NULL,raw_int); /* ditto */
+id_lookup("virtual",NULL,int_like);
+id_lookup("void",NULL,raw_int);
+id_lookup("volatile",NULL,const_like);
+id_lookup("wchar_t",NULL,raw_int);
+id_lookup("while",NULL,for_like);
+id_lookup("xor",NULL,alfop);
+id_lookup("xor_eq",NULL,alfop);@+ res_wd_end=name_ptr;
+id_lookup("TeX",NULL,custom);
+id_lookup("make_pair",NULL,func_template);
+
+@* 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 |limit| and |loc| into
+the line of input currently being studied.
+
+@ 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 |new_section| should be the largest of
+all. Some of these numeric control codes take the place of |char|
+control codes that will not otherwise appear in the output of the
+scanning routines.
+@^ASCII code dependencies@>
+
+@d ignore 00 /* control code of no interest to \.{CWEAVE} */
+@d verbatim 02 /* takes the place of extended ASCII \.{\char2} */
+@d begin_short_comment 03 /* \CPLUSPLUS/ short comment */
+@d begin_comment '\t' /* tab marks will not appear */
+@d underline '\n' /* this code will be intercepted without confusion */
+@d noop 0177 /* takes the place of ASCII delete */
+@d xref_roman 0203 /* control code for `\.{@@\^}' */
+@d xref_wildcard 0204 /* control code for `\.{@@:}' */
+@d xref_typewriter 0205 /* control code for `\.{@@.}' */
+@d TeX_string 0206 /* control code for `\.{@@t}' */
+@f TeX_string TeX
+@d ord 0207 /* control code for `\.{@@'}' */
+@d join 0210 /* control code for `\.{@@\&}' */
+@d thin_space 0211 /* control code for `\.{@@,}' */
+@d math_break 0212 /* control code for `\.{@@\v}' */
+@d line_break 0213 /* control code for `\.{@@/}' */
+@d big_line_break 0214 /* control code for `\.{@@\#}' */
+@d no_line_break 0215 /* control code for `\.{@@+}' */
+@d pseudo_semi 0216 /* control code for `\.{@@;}' */
+@d macro_arg_open 0220 /* control code for `\.{@@[}' */
+@d macro_arg_close 0221 /* control code for `\.{@@]}' */
+@d trace 0222 /* control code for `\.{@@0}', `\.{@@1}' and `\.{@@2}' */
+@d translit_code 0223 /* control code for `\.{@@l}' */
+@d output_defs_code 0224 /* control code for `\.{@@h}' */
+@d format_code 0225 /* control code for `\.{@@f}' and `\.{@@s}' */
+@d definition 0226 /* control code for `\.{@@d}' */
+@d begin_C 0227 /* control code for `\.{@@c}' */
+@d section_name 0230 /* control code for `\.{@@<}' */
+@d new_section 0231 /* control code for `\.{@@\ }' and `\.{@@*}' */
+
+@ Control codes are converted to \.{CWEAVE}'s internal
+representation by means of the table |ccode|.
+
+@<Private...@>=
+static eight_bits ccode[256]; /* meaning of a char following \.{@@} */
+
+@ @<Set ini...@>=
+{int c; for (c=0; c<256; c++) ccode[c]=0;}
+ccode[' ']=ccode['\t']=ccode['\n']=ccode['\v']=ccode['\r']=ccode['\f']
+ =ccode['*']=new_section;
+ccode['@@']='@@'; /* `quoted' at sign */
+ccode['=']=verbatim;
+ccode['d']=ccode['D']=definition;
+ccode['f']=ccode['F']=ccode['s']=ccode['S']=format_code;
+ccode['c']=ccode['C']=ccode['p']=ccode['P']=begin_C;
+ccode['t']=ccode['T']=TeX_string;
+ccode['l']=ccode['L']=translit_code;
+ccode['q']=ccode['Q']=noop;
+ccode['h']=ccode['H']=output_defs_code;
+ccode['&']=join; ccode['<']=ccode['(']=section_name;
+ccode['!']=underline; ccode['^']=xref_roman;
+ccode[':']=xref_wildcard; ccode['.']=xref_typewriter; ccode[',']=thin_space;
+ccode['|']=math_break; ccode['/']=line_break; ccode['#']=big_line_break;
+ccode['+']=no_line_break; ccode[';']=pseudo_semi;
+ccode['[']=macro_arg_open; ccode[']']=macro_arg_close;
+ccode['\'']=ord;
+@<Special control codes for debugging@>@;
+
+@ Users can write
+\.{@@2}, \.{@@1}, and \.{@@0} to turn tracing fully on, partly on,
+and off, respectively.
+
+@<Special control codes...@>=
+ccode['0']=ccode['1']=ccode['2']=trace;
+
+@ The |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
+|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.
+
+@<Predec...@>=
+static void skip_limbo(void);@/
+static eight_bits skip_TeX(void);
+
+@ @c
+static void
+skip_limbo(void) {
+ while(true) {
+ if (loc>limit && get_line()==false) return;
+ *(limit+1)='@@';
+ while (*loc!='@@') loc++; /* look for `\.{@@}', then skip two chars */
+ if (loc++ <=limit) { int c=ccode[(eight_bits)*loc++];
+ if (c==new_section) return;
+ if (c==noop) skip_restricted();
+ else if (c==format_code) @<Process simple format in limbo@>@;
+ }
+ }
+}
+
+@ The |skip_TeX| 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 |new_section| is
+assumed to exist at the very end of the file.
+
+@f skip_TeX TeX
+
+@c
+static eight_bits
+skip_TeX(void) /* skip past pure \TEX/ code */
+{
+ while (true) {
+ if (loc>limit && get_line()==false) return new_section;
+ *(limit+1)='@@';
+ while (*loc!='@@' && *loc!='|') loc++;
+ if (*loc++ =='|') return '|';
+ if (loc<=limit) return ccode[(eight_bits)*(loc++)];
+ }
+}
+
+@*1 Inputting the next token.
+As stated above, \.{CWEAVE}'s most interesting lexical scanning routine is the
+|get_next| function that inputs the next token of \CEE/ input. However,
+|get_next| is not especially complicated.
+
+The result of |get_next| is either a |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 |ccode|
+table, or it is one of the following special codes:
+
+\yskip\hang |identifier|: In this case the global variables |id_first| and
+|id_loc| will have been set to the beginning and ending-plus-one locations
+in the buffer, as required by the |id_lookup| routine.
+
+\yskip\hang |string|: The string will have been copied into the array
+|section_text|; |id_first| and |id_loc| are set as above (now they are
+pointers into |section_text|).
+
+\yskip\hang |constant|: The constant is copied into |section_text|, with
+slight modifications; |id_first| and |id_loc| are set.
+
+\yskip\noindent Furthermore, some of the control codes cause
+|get_next| to take additional actions:
+
+\yskip\hang |xref_roman|, |xref_wildcard|, |xref_typewriter|, |TeX_string|,
+|verbatim|: The values of |id_first| and |id_loc| will have been set to
+the beginning and ending-plus-one locations in the buffer.
+
+\yskip\hang |section_name|: In this case the global variable |cur_section| will
+point to the |byte_start| entry for the section name that has just been scanned.
+The value of |cur_section_char| will be |'('| if the section name was
+preceded by \.{@@(} instead of \.{@@<}.
+
+\yskip\noindent If |get_next| sees `\.{@@!}'
+it sets |xref_switch| to |def_flag| and goes on to the next token.
+
+@d constant 0200 /* \CEE/ constant */
+@d string 0201 /* \CEE/ string */
+@d identifier 0202 /* \CEE/ identifier or reserved word */
+
+@<Private...@>=
+static name_pointer cur_section; /* name of section just scanned */
+static char cur_section_char; /* the character just before that name */
+
+@ As one might expect, |get_next| consists mostly of a big switch
+that branches to the various special cases that can arise.
+\CEE/ allows underscores to appear in identifiers, and some \CEE/
+compilers even allow the dollar sign.
+
+@d isxalpha(c) ((c)=='_' || (c)=='$')
+ /* non-alpha characters allowed in identifier */
+@d ishigh(c) ((eight_bits)(c)>0177)
+@^high-bit character handling@>
+
+@c
+static eight_bits
+get_next(void) /* produces the next input token */
+{
+ eight_bits c; /* the current character */
+ while (true) {
+ @<Check if we're at the end of a preprocessor command@>@;
+ if (loc>limit && get_line()==false) return new_section;
+ c=*(loc++);
+ if (xisdigit(c) || c=='.') @<Get a constant@>@;
+ else if (c=='\'' || c=='"'@|
+ || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@|
+ || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"'))@|
+ || (c=='<' && sharp_include_line==true))
+ @<Get a string@>@;
+ else if (xisalpha(c) || isxalpha(c) || ishigh(c))
+ @<Get an identifier@>@;
+ else if (c=='@@') @<Get control code and possible section name@>@;
+ else if (xisspace(c)) continue; /* ignore spaces and tabs */
+ if (c=='#' && loc==buffer+1) @<Raise preprocessor flag@>@;
+ mistake: @<Compress two-symbol operator@>@;
+ return c;
+ }
+}
+
+@ @<Predecl...@>=@+static eight_bits get_next(void);
+
+@ 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, |get_next| returns a special code
+|left_preproc| and raises a flag |preprocessing|.
+
+We can use the same internal code number for |left_preproc| as we do
+for |ord|, since |get_next| changes |ord| into a string.
+
+@d left_preproc ord /* begins a preprocessor command */
+@d right_preproc 0217 /* ends a preprocessor command */
+
+@<Private...@>=
+static boolean preprocessing=false; /* are we scanning a preprocessor command? */
+
+@ @<Raise prep...@>= {
+ preprocessing=true;
+ @<Check if next token is |include|@>@;
+ return left_preproc;
+}
+
+@ 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.
+
+@<Private...@>=
+static boolean sharp_include_line=false; /* are we scanning a \&{\#include} line? */
+
+@ @<Check if next token is |include|@>=
+while (loc<=buffer_end-7 && xisspace(*loc)) loc++;
+if (loc<=buffer_end-6 && strncmp(loc,"include",7)==0) sharp_include_line=true;
+
+@ When we get to the end of a preprocessor line,
+we lower the flag and send a code |right_preproc|, unless
+the last character was a \.\\.
+
+@<Check if we're at...@>=
+ while (loc==limit-1 && preprocessing && *loc=='\\')
+ if (get_line()==false) return new_section; /* still in preprocessor mode */
+ if (loc>=limit && preprocessing) {
+ preprocessing=sharp_include_line=false;
+ return right_preproc;
+ }
+
+@ 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.
+
+@d compress(c) if (loc++<=limit) return c
+
+@<Compress tw...@>=
+switch(c) {
+ case '/': if (*loc=='*') {compress(begin_comment);}
+ else if (*loc=='/') compress(begin_short_comment); break;
+ case '+': if (*loc=='+') compress(plus_plus); break;
+ case '-': if (*loc=='-') {compress(minus_minus);}
+ else { if (*loc=='>') { if (*(loc+1)=='*') {loc++; compress(minus_gt_ast);}
+ else compress(minus_gt); } } break;
+ case '.': if (*loc=='*') {compress(period_ast);}
+ else if (*loc=='.' && *(loc+1)=='.') {
+ loc++; compress(dot_dot_dot);
+ }
+ break;
+ case ':': if (*loc==':') compress(colon_colon); break;
+ case '=': if (*loc=='=') compress(eq_eq); break;
+ case '>': if (*loc=='=') {compress(gt_eq);}
+ else if (*loc=='>') compress(gt_gt); break;
+ case '<': if (*loc=='=') {compress(lt_eq);}
+ else if (*loc=='<') compress(lt_lt); break;
+ case '&': if (*loc=='&') compress(and_and); break;
+ case '|': if (*loc=='|') compress(or_or); break;
+ case '!': if (*loc=='=') compress(non_eq); break;
+}
+
+@ @<Get an identifier@>= {
+ id_first=--loc;
+ while (isalpha((eight_bits)*++loc) || isdigit((eight_bits)*loc) @|
+ || isxalpha((eight_bits)*loc) || ishigh((eight_bits)*loc));
+ id_loc=loc; return identifier;
+}
+
+@ 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
+with \TEX/ macros that the user can redefine to fit the context.
+In order to simplify such macros, we replace some of the characters.
+
+Notice that in this section and the next, |id_first| and |id_loc|
+are pointers into the array |section_text|, not into |buffer|.
+
+@<Get a constant@>= {
+ id_first=id_loc=section_text+1;
+ if (*(loc-1)=='0') {
+ if (*loc=='x' || *loc=='X') {*id_loc++='^'; loc++;
+ while (xisxdigit(*loc)) *id_loc++=*loc++;} /* hex constant */
+ else if (xisdigit(*loc)) {*id_loc++='~';
+ while (xisdigit(*loc)) *id_loc++=*loc++;} /* octal constant */
+ else goto dec; /* decimal constant */
+ }
+ else { /* decimal constant */
+ if (*(loc-1)=='.' && !xisdigit(*loc)) goto mistake; /* not a constant */
+ dec: *id_loc++=*(loc-1);
+ while (xisdigit(*loc) || *loc=='.') *id_loc++=*loc++;
+ if (*loc=='e' || *loc=='E') { /* float constant */
+ *id_loc++='_'; loc++;
+ if (*loc=='+' || *loc=='-') *id_loc++=*loc++;
+ while (xisdigit(*loc)) *id_loc++=*loc++;
+ }
+ }
+ while (*loc=='u' || *loc=='U' || *loc=='l' || *loc=='L'
+ || *loc=='f' || *loc=='F') {
+ *id_loc++='$'; *id_loc++=toupper((eight_bits)*loc); loc++;
+ }
+ return constant;
+}
+
+@ \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 |longest_name|.
+
+@<Get a string@>= {
+ char delim = c; /* what started the string */
+ id_first = section_text+1;
+ id_loc = section_text;
+ if (delim=='\'' && *(loc-2)=='@@') {*++id_loc='@@'; *++id_loc='@@';}
+ *++id_loc=delim;
+ if (delim=='L' || delim=='u' || delim=='U') { /* wide character constant */
+ if (delim=='u' && *loc=='8') { *++id_loc=*loc++; }
+ delim=*loc++; *++id_loc=delim;
+ }
+ if (delim=='<') delim='>'; /* for file names in \&{\#include} lines */
+ while (true) {
+ if (loc>=limit) {
+ if(*(limit-1)!='\\') {
+ err_print("! String didn't end"); loc=limit; break;
+@.String didn't end@>
+ }
+ if(get_line()==false) {
+ err_print("! Input ended in middle of string"); loc=buffer; break;
+@.Input ended in middle of string@>
+ }
+ }
+ if ((c=*loc++)==delim) {
+ if (++id_loc<=section_text_end) *id_loc=c;
+ break;
+ }
+ if (c=='\\') { if (loc>=limit) continue;
+ else { if (++id_loc<=section_text_end) {
+ *id_loc = '\\'; c=*loc++;
+ } } }
+ if (++id_loc<=section_text_end) *id_loc=c;
+ }
+ if (id_loc>=section_text_end) {
+ fputs("\n! String too long: ",stdout);
+@.String too long@>
+ term_write(section_text+1,25);
+ printf("..."); mark_error;
+ }
+ id_loc++;
+ return string;
+}
+
+@ After an \.{@@} sign has been scanned, the next character tells us
+whether there is more work to do.
+
+@<Get control code and possible section name@>= {
+ c=*loc++;
+ switch(ccode[(eight_bits)c]) {
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@.Use @@l in limbo...@>
+ case underline: xref_switch=def_flag; continue;
+ case trace: tracing=c-'0'; continue;
+ case xref_roman: case xref_wildcard: case xref_typewriter: case noop:
+ case TeX_string: c=ccode[(eight_bits)c]; skip_restricted(); return c;
+ case section_name:
+ @<Scan the section name and make |cur_section| point to it@>@;
+ case verbatim: @<Scan a verbatim string@>@;
+ case ord: @<Get a string@>@;
+ default: return ccode[(eight_bits)c];
+ }
+}
+
+@ The occurrence of a section name sets |xref_switch| to zero,
+because the section name might (for example) follow \&{int}.
+
+@<Scan the section name...@>= {
+ char *k; /* pointer into |section_text| */
+ cur_section_char=*(loc-1);
+ @<Put section name into |section_text|@>@;
+ if (k-section_text>3 && strncmp(k-2,"...",3)==0)
+ cur_section=section_lookup(section_text+1,k-3,1); /* 1 indicates a prefix */
+ else cur_section=section_lookup(section_text+1,k,0);
+ xref_switch=0; return section_name;
+}
+
+@ Section names are placed into the |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 |section_text[0]=' '| to facilitate
+this, since the |section_lookup| routine uses |section_text[1]| as the first
+character of the name.)
+
+@<Set init...@>=section_text[0]=' ';
+
+@ @<Put section name...@>=
+k=section_text;
+while (true) {
+ if (loc>limit && get_line()==false) {
+ err_print("! Input ended in section name");
+@.Input ended in section name@>
+ loc=buffer+1; break;
+ }
+ c=*loc;
+ @<If end of name or erroneous control code, |break|@>@;
+ loc++; if (k<section_text_end) k++;
+ if (xisspace(c)) {
+ c=' '; if (*(k-1)==' ') k--;
+ }
+*k=c;
+}
+if (k>=section_text_end) {
+ fputs("\n! Section name too long: ",stdout);
+@.Section name too long@>
+ term_write(section_text+1,25);
+ printf("..."); mark_harmless;
+}
+if (*k==' ' && k>section_text) k--;
+
+@ @<If end of name...@>=
+if (c=='@@') {
+ c=*(loc+1);
+ if (c=='>') {
+ loc+=2; break;
+ }
+ if (ccode[(eight_bits)c]==new_section) {
+ err_print("! Section name didn't end"); break;
+@.Section name didn't end@>
+ }
+ if (c!='@@') {
+ err_print("! Control codes are forbidden in section name"); break;
+@.Control codes are forbidden...@>
+ }
+ *(++k)='@@'; loc++; /* now |c==*loc| again */
+}
+
+@ This function skips over a restricted context at relatively high speed.
+
+@c
+static void
+skip_restricted(void)
+{
+ id_first=loc; *(limit+1)='@@';
+false_alarm:
+ while (*loc!='@@') loc++;
+ id_loc=loc;
+ if (loc++>limit) {
+ err_print("! Control text didn't end"); loc=limit;
+@.Control text didn't end@>
+ }
+ else {
+ if (*loc=='@@'&&loc<=limit) {loc++; goto false_alarm;}
+ if (*loc++!='>')
+ err_print("! Control codes are forbidden in control text");
+@.Control codes are forbidden...@>
+ }
+}
+
+@ @<Predecl...@>=@+static void skip_restricted(void);
+
+@ At the present point in the program we
+have |*(loc-1)==verbatim|; we set |id_first| to the beginning
+of the string itself, and |id_loc| to its ending-plus-one location in the
+buffer. We also set |loc| to the position just after the ending delimiter.
+
+@<Scan a verbatim string@>= {
+ id_first=loc++; *(limit+1)='@@'; *(limit+2)='>';
+ while (*loc!='@@' || *(loc+1)!='>') loc++;
+ if (loc>=limit) err_print("! Verbatim string didn't end");
+@.Verbatim string didn't end@>
+ id_loc=loc; loc+=2;
+ return verbatim;
+}
+
+@** 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 |next_control| often contains the most recent output of
+|get_next|; in interesting cases, this will be the control code that
+ended a section or part of a section.
+
+@<Private...@>=
+static eight_bits next_control; /* control code waiting to be acting upon */
+
+@ The overall processing strategy in phase one has the following
+straightforward outline.
+
+@c
+static void
+phase_one(void) {
+ phase=1; reset_input(); section_count=0;
+ skip_limbo(); change_exists=false;
+ while (!input_has_ended)
+ @<Store cross-reference data for the current section@>@;
+ changed_section[section_count]=change_exists;
+ /* the index changes if anything does */
+ phase=2; /* prepare for second phase */
+ @<Print error messages about unused or undefined section names@>@;
+}
+
+@ @<Predecl...@>=@+static void phase_one(void);
+
+@ @<Store cross-reference data...@>=
+{
+ if (++section_count==max_sections) overflow("section number");
+ changed_section[section_count]=changing;
+ /* it will become |true| if any line changes */
+ if (*(loc-1)=='*' && show_progress) {
+ printf("*%d",section_count);
+ update_terminal; /* print a progress report */
+ }
+ @<Store cross-references in the \TEX/ part of a section@>@;
+ @<Store cross-references in the definition part of a section@>@;
+ @<Store cross-references in the \CEE/ part of a section@>@;
+ if (changed_section[section_count]) change_exists=true;
+}
+
+@ The |C_xref| subroutine stores references to identifiers in
+\CEE/ text material beginning with the current value of |next_control|
+and continuing until |next_control| is `\.\{' or `\.{\v}', or until the next
+``milestone'' is passed (i.e., |next_control>=format_code|). If
+|next_control>=format_code| when |C_xref| is called, nothing will happen;
+but if |next_control=='|'| upon entry, the procedure assumes that this is
+the `\.{\v}' preceding \CEE/ text that is to be processed.
+
+The parameter |spec_ctrl| is used to change this behavior. In most cases
+|C_xref| is called with |spec_ctrl==ignore|, which triggers the default
+processing described above. If |spec_ctrl==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 |xref_roman==identifier+roman| and |xref_wildcard==identifier
++wildcard| and |xref_typewriter==identifier+typewriter|,
+as well as |normal==0|.
+
+@<Predecl...@>=
+static void C_xref(eight_bits);@/
+static void outer_xref(void);
+
+@ @c
+static void
+C_xref(@t\1\1@> /* makes cross-references for \CEE/ identifiers */
+ eight_bits spec_ctrl@t\2\2@>)
+{
+ name_pointer p; /* a referenced name */
+ while (next_control<format_code || next_control==spec_ctrl) {
+ if (next_control>=identifier && next_control<=xref_typewriter) {
+ if (next_control>identifier) @<Replace |"@@@@"| by |"@@"| @>@;
+ p=id_lookup(id_first, id_loc,next_control-identifier); new_xref(p);
+ }
+ if (next_control==section_name) {
+ section_xref_switch=cite_flag;
+ new_section_xref(cur_section);
+ }
+ next_control=get_next();
+ if (next_control=='|' || next_control==begin_comment ||
+ next_control==begin_short_comment) return;
+ }
+}
+
+@ The |outer_xref| subroutine is like |C_xref| except that it begins
+with |next_control!='|'| and ends with |next_control>=format_code|. Thus, it
+handles \CEE/ text with embedded comments.
+
+@c
+static void
+outer_xref(void) /* extension of |C_xref| */
+{
+ int bal; /* brace level in comment */
+ while (next_control<format_code)
+ if (next_control!=begin_comment && next_control!=begin_short_comment)
+ C_xref(ignore);
+ else {
+ boolean is_long_comment=(next_control==begin_comment);
+ bal=copy_comment(is_long_comment,1); next_control='|';
+ while (bal>0) {
+ C_xref(section_name); /* do not reference section names in comments */
+ if (next_control=='|') bal=copy_comment(is_long_comment,bal);
+ else bal=0; /* an error message will occur in phase two */
+ }
+ }
+}
+
+@ 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\,$\.{@@>}.
+
+@<Store cross-references in the \T...@>=
+while (true) {
+ switch (next_control=skip_TeX()) {
+ case translit_code: err_print("! Use @@l in limbo only"); continue;
+@.Use @@l in limbo...@>
+ case underline: xref_switch=def_flag; continue;
+ case trace: tracing=*(loc-1)-'0'; continue;
+ case '|': C_xref(section_name); break;
+ case xref_roman: case xref_wildcard: case xref_typewriter:
+ case noop: case section_name:
+ loc-=2; next_control=get_next(); /* scan to \.{@@>} */
+ if (next_control>=xref_roman && next_control<=xref_typewriter) {
+ @<Replace |"@@@@"| by |"@@"| @>@;
+ new_xref(id_lookup(id_first, id_loc,next_control-identifier));
+ }
+ break;
+ }
+ if (next_control>=format_code) break;
+}
+
+@ @<Replace |"@@@@"| by |"@@"| @>=
+{
+ char *src=id_first,*dst=id_first;
+ while(src<id_loc){
+ if(*src=='@@') src++;
+ *dst++=*src++;
+ }
+ id_loc=dst;
+ while (dst<src) *dst++=' '; /* clean up in case of error message display */
+}
+
+@ 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 |lhs| and |rhs| point to the respective identifiers involved
+in a format definition.
+
+@<Private...@>=
+static name_pointer lhs, rhs; /* pointers to |byte_start| for format identifiers */
+static name_pointer res_wd_end; /* pointer to the first nonreserved identifier */
+
+@ When we get to the following code we have |next_control>=format_code|.
+
+@<Store cross-references in the d...@>=
+while (next_control<=definition) { /* |format_code| or |definition| */
+ if (next_control==definition) {
+ xref_switch=def_flag; /* implied \.{@@!} */
+ next_control=get_next();
+ } else @<Process a format definition@>@;
+ outer_xref();
+}
+
+@ Error messages for improper format definitions will be issued in phase
+two. Our job in phase one is to define the |ilk| of a properly formatted
+identifier, and to remove cross-references to identifiers that we now
+discover should be unindexed.
+
+@<Process a form...@>= {
+ next_control=get_next();
+ if (next_control==identifier) {
+ lhs=id_lookup(id_first, id_loc,normal); lhs->ilk=normal;
+ if (xref_switch) new_xref(lhs);
+ next_control=get_next();
+ if (next_control==identifier) {
+ rhs=id_lookup(id_first, id_loc,normal);
+ lhs->ilk=rhs->ilk;
+ if (unindexed(lhs)) { /* retain only underlined entries */
+ xref_pointer q,r=NULL;
+ for (q=(xref_pointer)lhs->xref;q>xmem;q=q->xlink)
+ if (q->num<def_flag)
+ if (r) r->xlink=q->xlink;
+ else lhs->xref=(void *)q->xlink;
+ else r=q;
+ }
+ next_control=get_next();
+ }
+ }
+}
+
+@ A much simpler processing of format definitions occurs when the
+definition is found in limbo.
+
+@<Process simple format in limbo@>=
+{
+ if (get_next()!=identifier)
+ err_print("! Missing left identifier of @@s");
+@.Missing left identifier...@>
+ else {
+ lhs=id_lookup(id_first,id_loc,normal);
+ if (get_next()!=identifier)
+ err_print("! Missing right identifier of @@s");
+@.Missing right identifier...@>
+ else {
+ rhs=id_lookup(id_first,id_loc,normal);
+ lhs->ilk=rhs->ilk;
+ }
+ }
+}
+
+@ Finally, when the \TEX/ and definition parts have been treated, we have
+|next_control>=begin_C|.
+
+@<Store cross-references in the \CEE/...@>=
+if (next_control<=section_name) { /* |begin_C| or |section_name| */
+ if (next_control==begin_C) section_xref_switch=0;
+ else {
+ section_xref_switch=def_flag;
+ if(cur_section_char=='(' && cur_section!=name_dir)
+ set_file_flag(cur_section);
+ }
+ do {
+ if (next_control==section_name && cur_section!=name_dir)
+ new_section_xref(cur_section);
+ next_control=get_next(); outer_xref();
+ } while ( next_control<=section_name);
+}
+
+@ After phase one has looked at everything, we want to check that each
+section name was both defined and used. The variable |cur_xref| will point
+to cross-references for the current section name of interest.
+
+@<Private...@>=
+static xref_pointer cur_xref; /* temporary cross-reference pointer */
+static boolean an_output; /* did |file_flag| precede |cur_xref|? */
+
+@ The following recursive procedure
+walks through the tree of section names and prints out anomalies.
+@^recursion@>
+
+@c
+static void
+section_check(
+name_pointer p) /* print anomalies in subtree |p| */
+{
+ if (p) {
+ section_check(p->llink);
+ cur_xref=(xref_pointer)p->xref;
+ if (cur_xref->num==file_flag) {an_output=true; cur_xref=cur_xref->xlink;}
+ else an_output=false;
+ if (cur_xref->num <def_flag) {
+ fputs("\n! Never defined: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@.Never defined: <section name>@>
+ }
+ while (cur_xref->num >=cite_flag) cur_xref=cur_xref->xlink;
+ if (cur_xref==xmem && !an_output) {
+ fputs("\n! Never used: <",stdout);
+ print_section_name(p); putchar('>'); mark_harmless;
+@.Never used: <section name>@>
+ }
+ section_check(p->rlink);
+ }
+}
+
+@ @<Predecl...@>=@+static void section_check(name_pointer);
+
+@ @<Print error messages about un...@>=section_check(root);
+
+@* Low-level output routines.
+The \TEX/ output is supposed to appear in lines at most |line_length|
+characters long, so we place it into an output buffer. During the output
+process, |out_line| will hold the current line number of the line about to
+be output.
+
+@<Private...@>=
+static char out_buf[line_length+1]; /* assembled characters */
+static char *out_buf_end = out_buf+line_length; /* end of |out_buf| */
+static char *out_ptr; /* last character in |out_buf| */
+static int out_line; /* number of next line to be output */
+
+@ The |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 |per_cent| parameter is |true|, a |'%'| is appended to the line
+that is being output; in this case the breakpoint |b| should be strictly
+less than |out_buf_end|. If the |per_cent| parameter is |false|,
+trailing blanks are suppressed.
+The characters emptied from the buffer form a new line of output;
+if the |carryover| parameter is true, a |"%"| in that line will be
+carried over to the next line (so that \TEX/ will ignore the completion
+of commented-out text).
+
+@d c_line_write(c) fflush(active_file),fwrite(out_buf+1,sizeof(char),c,active_file)
+@d tex_putc(c) putc(c,active_file)
+@d tex_new_line putc('\n',active_file)
+@d tex_printf(c) fprintf(active_file,"%s",c)
+@d tex_puts(c) fputs(c,active_file)
+
+@<Predecl...@>=
+static void flush_buffer(char *,boolean,boolean);@/
+static void finish_line(void);
+
+@ @c
+static void
+flush_buffer(@t\1\1@>
+char *b, /* outputs from |out_buf+1| to |b|, where |b<=out_ptr| */
+boolean per_cent,boolean carryover@t\2\2@>)
+{
+ char *j; j=b; /* pointer into |out_buf| */
+ if (! per_cent) /* remove trailing blanks */
+ while (j>out_buf && *j==' ') j--;
+ c_line_write(j-out_buf);
+ if (per_cent) tex_putc('%');
+ tex_new_line; out_line++;
+ if (carryover)
+ while (j>out_buf)
+ if (*j--=='%' && (j==out_buf || *j!='\\')) {
+ *b--='%'; break;
+ }
+ if (b<out_ptr) memcpy(out_buf+1,b+1,(size_t)(out_ptr-b));
+ out_ptr-=b-out_buf;
+}
+
+@ 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 |finish_line| routine is called just before
+|get_line| inputs a new line, and just after a line break token has
+been emitted during the output of translated \CEE/ text.
+
+@c
+static void
+finish_line(void) /* do this at the end of a line */
+{
+ char *k; /* pointer into |buffer| */
+ if (out_ptr>out_buf) flush_buffer(out_ptr,false,false);
+ else {
+ for (k=buffer; k<=limit; k++)
+ if (!(xisspace(*k))) return;
+ flush_buffer(out_buf,false,false);
+ }
+}
+
+@ In particular, the |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
+`\.{\\input cwebmac}'.
+
+@<Start \TEX/...@>=
+out_ptr=out_buf+1; out_line=1; active_file=tex_file;
+*out_ptr='c'; tex_printf("\\input cwebma");
+
+@ When we wish to append one character |c| to the output buffer, we write
+`|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
+|out_str(s)|, where |s| is a string containing the characters.
+
+A line break will occur at a space or after a single-nonletter
+\TEX/ control sequence.
+
+@d out(c) {if (out_ptr>=out_buf_end) break_out(); *(++out_ptr)=c;}
+
+@<Predecl...@>=
+static void out_str(const char *);@/
+static void break_out(void);
+
+@ @c
+static void
+out_str(@t\1\1@> /* output characters from |s| to end of string */
+const char*s@t\2\2@>)
+{
+ while (*s) out(*s++);
+}
+
+@ The |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.
+
+@<Set init...@>=
+out_buf[0]='\\';
+
+@ 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 |'%'| is output at
+the break.
+
+@c
+static void
+break_out(void) /* finds a way to break the output line */
+{
+ char *k=out_ptr; /* pointer into |out_buf| */
+ while (true) {
+ if (k==out_buf) @<Print warning message, break the line, |return|@>@;
+ if (*k==' ') {
+ flush_buffer(k,false,true); return;
+ }
+ if (*(k--)=='\\' && *k!='\\') { /* we've decreased |k| */
+ flush_buffer(k,true,true); return;
+ }
+ }
+}
+
+@ 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 |'%'| just before the last character.
+
+@<Print warning message...@>=
+{
+ printf("\n! Line had to be broken (output l. %d):\n",out_line);
+@.Line had to be broken@>
+ term_write(out_buf+1, out_ptr-out_buf-1);
+ new_line; mark_harmless;
+ flush_buffer(out_ptr-1,true,true); return;
+}
+
+@ Here is a macro that outputs a section number in decimal notation.
+The number to be converted by |out_section| is known to be less than
+|def_flag|, so it cannot have more than five decimal digits. If
+the section is changed, we output `\.{\\*}' just after the number.
+
+@<Predecl...@>=
+static void out_section(sixteen_bits);@/
+static void out_name(name_pointer,boolean);
+
+@ @c
+static void
+out_section(
+sixteen_bits n)
+{
+ char s[6];
+ sprintf(s,"%d",n); out_str(s);
+ if(changed_section[n]) out_str ("\\*");
+@.\\*@>
+}
+
+@ The |out_name| procedure is used to output an identifier or index
+entry, enclosing it in braces.
+
+@c
+static void
+out_name(
+name_pointer p,
+boolean quote_xalpha)
+{
+ char *k, *k_end=(p+1)->byte_start; /* pointers into |byte_mem| */
+ out('{');
+ for (k=p->byte_start; k<k_end; k++) {
+ if (isxalpha(*k) && quote_xalpha) out('\\');
+@.\\\$@>
+@.\\\_@>
+ out(*k);
+ }
+ out('}');
+}
+
+@* Routines that copy \TEX/ material.
+During phase two, we use the subroutines |copy_limbo| and |copy_TeX| (and
+|copy_comment|) in place of the analogous |skip_limbo| and |skip_TeX|
+that were used in phase one.
+
+The |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.
+
+@<Predecl...@>=
+static void copy_limbo(void);@/
+static eight_bits copy_TeX(void);@/
+static int copy_comment(boolean,int);
+
+@ @c
+static void
+copy_limbo(void)
+{
+ char c;
+ while (true) {
+ if (loc>limit && (finish_line(), get_line()==false)) return;
+ *(limit+1)='@@';
+ while (*loc!='@@') out(*(loc++));
+ if (loc++<=limit) {
+ c=*loc++;
+ if (ccode[(eight_bits)c]==new_section) break;
+ switch (ccode[(eight_bits)c]) {
+ case translit_code: out_str("\\ATL"); break;
+@.\\ATL@>
+ case '@@': out('@@'); break;
+ case noop: skip_restricted(); break;
+ case format_code: if (get_next()==identifier) get_next();
+ if (loc>=limit) get_line(); /* avoid blank lines in output */
+ break; /* the operands of \.{@@s} are ignored on this pass */
+ default: err_print("! Double @@ should be used in limbo");
+@.Double @@ should be used...@>
+ out('@@');
+ }
+ }
+ }
+}
+
+@ The |copy_TeX| 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 |finish_line| work.
+
+@f copy_TeX TeX
+@c
+static eight_bits
+copy_TeX(void)
+{
+ char c; /* current character being copied */
+ while (true) {
+ if (loc>limit && (finish_line(), get_line()==false)) return new_section;
+ *(limit+1)='@@';
+ while ((c=*(loc++))!='|' && c!='@@') {
+ out(c);
+ if (out_ptr==out_buf+1 && (xisspace(c))) out_ptr--;
+ }
+ if (c=='|') return '|';
+ if (loc<=limit) return ccode[(eight_bits)*(loc++)];
+ }
+}
+
+@ The |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 |app_tok(t)| is used to append token |t| to the current
+token list, and it also makes sure that it is possible to append at least
+one further token without overflow.
+
+@d app_tok(c) {if (tok_ptr+2>tok_mem_end) overflow("token"); *(tok_ptr++)=c;}
+
+@c
+static int copy_comment(@t\1\1@> /* copies \TeX\ code in comments */
+boolean is_long_comment, /* is this a traditional \CEE/ comment? */
+int bal@t\2\2@>) /* brace balance */
+{
+ char c; /* current character being copied */
+ while (true) {
+ if (loc>limit) {
+ if (is_long_comment) {
+ if (get_line()==false) {
+ err_print("! Input ended in mid-comment");
+@.Input ended in mid-comment@>
+ loc=buffer+1; goto done;
+ }
+ }
+ else {
+ if (bal>1) err_print("! Missing } in comment");
+@.Missing \} in comment@>
+ goto done;
+ }
+ }
+ c=*(loc++);
+ if (c=='|') return bal;
+ if (is_long_comment) @<Check for end of comment@>@;
+ if (phase==2) {
+ if (ishigh(c)) app_tok(quoted_char);
+ app_tok(c);
+ }
+ @<Copy special things when |c=='@@', '\\'|@>@;
+ if (c=='{') bal++;
+ else if (c=='}') {
+ if(bal>1) bal--;
+ else {err_print("! Extra } in comment");
+@.Extra \} in comment@>
+ if (phase==2) tok_ptr--;
+ }
+ }
+ }
+done:@<Clear |bal| and |return|@>@;
+}
+
+@ @<Check for end of comment@>=
+if (c=='*' && *loc=='/') {
+ loc++;
+ if (bal>1) err_print("! Missing } in comment");
+@.Missing \} in comment@>
+ goto done;
+}
+
+@ @<Copy special things when |c=='@@'...@>=
+if (c=='@@') {
+ if (*(loc++)!='@@') {
+ err_print("! Illegal use of @@ in comment");
+@.Illegal use of @@...@>
+ loc-=2; if (phase==2) *(tok_ptr-1)=' '; goto done;
+ }
+}
+else { if (c=='\\' && *loc!='@@') {
+ if (phase==2) app_tok(*(loc++))@; else loc++; } }
+
+@ We output
+enough right braces to keep \TEX/ happy.
+
+@<Clear |bal|...@>=
+if (phase==2) while (bal-- >0) app_tok('}');
+return 0;
+
+@** 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{|exp| }\left\{\matrix{\hbox{|binop|}\cr\hbox{|ubinop|}}\right\}
+\hbox{ |exp| }\RA\hbox{ |exp|}$$
+and it means that three consecutive scraps whose respective categories are
+|exp|, |binop| (or |ubinop|),
+and |exp| are converted to one scrap whose category
+is |exp|. The translations of the original
+scraps are simply concatenated. The case of
+$$\hbox{|exp| |comma| |exp| $\RA$ |exp|} \hskip4emE_1C\,\\{opt}9\,E_2$$
+(rule 4) is only slightly more complicated:
+Here the resulting |exp| translation
+consists not only of the three original translations, but also of the
+tokens |opt| and 9 between the translations of the
+|comma| and the following |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 |if_clause| |stmt|
+|else_like| |if_like|, rule 63 is applied; but if the sequence is
+|if_clause| |stmt| |else_like| followed by anything other than
+|if_like|, rule 64 takes effect; and if the sequence is |if_clause|
+|stmt| followed by anything other than |else_like|, rule 65 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.
+
+@ Here is a list of the category codes that scraps can have.
+(A few others, like |int_like|, have already been defined; the
+|cat_name| array contains a complete list.)
+
+@d exp 1 /* denotes an expression, including perhaps a single identifier */
+@d unop 2 /* denotes a unary operator */
+@d binop 3 /* denotes a binary operator */
+@d ubinop 4
+ /* denotes an operator that can be unary or binary, depending on context */
+@d cast 5 /* denotes a cast */
+@d question 6 /* denotes a question mark and possibly the expressions flanking it */
+@d lbrace 7 /* denotes a left brace */
+@d rbrace 8 /* denotes a right brace */
+@d decl_head 9 /* denotes an incomplete declaration */
+@d comma 10 /* denotes a comma */
+@d lpar 11 /* denotes a left parenthesis or left bracket */
+@d rpar 12 /* denotes a right parenthesis or right bracket */
+@d prelangle 13 /* denotes `$<$' before we know what it is */
+@d prerangle 14 /* denotes `$>$' before we know what it is */
+@d langle 15 /* denotes `$<$' when it's used as angle bracket in a template */
+@d colcol 18 /* denotes `::' */
+@d base 19 /* denotes a colon that introduces a base specifier */
+@d decl 20 /* denotes a complete declaration */
+@d struct_head 21 /* denotes the beginning of a structure specifier */
+@d stmt 23 /* denotes a complete statement */
+@d function 24 /* denotes a complete function */
+@d fn_decl 25 /* denotes a function declarator */
+@d semi 27 /* denotes a semicolon */
+@d colon 28 /* denotes a colon */
+@d tag 29 /* denotes a statement label */
+@d if_head 30 /* denotes the beginning of a compound conditional */
+@d else_head 31 /* denotes a prefix for a compound statement */
+@d if_clause 32 /* pending \.{if} together with a condition */
+@d lproc 35 /* begins a preprocessor command */
+@d rproc 36 /* ends a preprocessor command */
+@d insert 37 /* a scrap that gets combined with its neighbor */
+@d section_scrap 38 /* section name */
+@d dead 39 /* scrap that won't combine */
+@d ftemplate 59 /* \\{make\_pair} */
+@d new_exp 60 /* \&{new} and a following type identifier */
+@d begin_arg 61 /* \.{@@[} */
+@d end_arg 62 /* \.{@@]} */
+
+@<Private...@>=
+static char cat_name[256][12];
+
+@ @<Set in...@>=
+{int c; for (c=0;c<256;c++) strcpy(cat_name[c],"UNKNOWN");}
+@.UNKNOWN@>
+ strcpy(cat_name[exp],"exp");
+ strcpy(cat_name[unop],"unop");
+ strcpy(cat_name[binop],"binop");
+ strcpy(cat_name[ubinop],"ubinop");
+ strcpy(cat_name[cast],"cast");
+ strcpy(cat_name[question],"?");
+ strcpy(cat_name[lbrace],"{"@q}@>);
+ strcpy(cat_name[rbrace],@q{@>"}");
+ strcpy(cat_name[decl_head],"decl_head");
+ strcpy(cat_name[comma],",");
+ strcpy(cat_name[lpar],"(");
+ strcpy(cat_name[rpar],")");
+ strcpy(cat_name[prelangle],"<");
+ strcpy(cat_name[prerangle],">");
+ strcpy(cat_name[langle],"\\<");
+ strcpy(cat_name[colcol],"::");
+ strcpy(cat_name[base],"\\:");
+ strcpy(cat_name[decl],"decl");
+ strcpy(cat_name[struct_head],"struct_head");
+ strcpy(cat_name[alfop],"alfop");
+ strcpy(cat_name[stmt],"stmt");
+ strcpy(cat_name[function],"function");
+ strcpy(cat_name[fn_decl],"fn_decl");
+ strcpy(cat_name[else_like],"else_like");
+ strcpy(cat_name[semi],";");
+ strcpy(cat_name[colon],":");
+ strcpy(cat_name[tag],"tag");
+ strcpy(cat_name[if_head],"if_head");
+ strcpy(cat_name[else_head],"else_head");
+ strcpy(cat_name[if_clause],"if()");
+ strcpy(cat_name[lproc],"#{"@q}@>);
+ strcpy(cat_name[rproc],@q{@>"#}");
+ strcpy(cat_name[insert],"insert");
+ strcpy(cat_name[section_scrap],"section");
+ strcpy(cat_name[dead],"@@d");
+ strcpy(cat_name[public_like],"public");
+ strcpy(cat_name[operator_like],"operator");
+ strcpy(cat_name[new_like],"new");
+ strcpy(cat_name[catch_like],"catch");
+ strcpy(cat_name[for_like],"for");
+ strcpy(cat_name[do_like],"do");
+ strcpy(cat_name[if_like],"if");
+ strcpy(cat_name[delete_like],"delete");
+ strcpy(cat_name[raw_ubin],"ubinop?");
+ strcpy(cat_name[const_like],"const");
+ strcpy(cat_name[raw_int],"raw");
+ strcpy(cat_name[int_like],"int");
+ strcpy(cat_name[case_like],"case");
+ strcpy(cat_name[sizeof_like],"sizeof");
+ strcpy(cat_name[struct_like],"struct");
+ strcpy(cat_name[typedef_like],"typedef");
+ strcpy(cat_name[define_like],"define");
+ strcpy(cat_name[template_like],"template");
+ strcpy(cat_name[ftemplate],"ftemplate");
+ strcpy(cat_name[new_exp],"new_exp");
+ strcpy(cat_name[begin_arg],"@@["@q]@>);
+ strcpy(cat_name[end_arg],@q[@>"@@]");
+ strcpy(cat_name[0],"zero");
+
+@ This code allows \.{CWEAVE} to display its parsing steps.
+
+@c
+static void
+print_cat(@t\1\1@> /* symbolic printout of a category */
+eight_bits c@t\2\2@>)
+{
+ fputs(cat_name[c],stdout);
+}
+
+@ @<Predecl...@>=@+static void print_cat(eight_bits);
+
+@ 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 |break_space| denotes an optional line break or an en space;
+
+\yskip\hang |force| denotes a line break;
+
+\yskip\hang |big_force| denotes a line break with additional vertical space;
+
+\yskip\hang |preproc_line| denotes that the line will be printed flush left;
+
+\yskip\hang |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 |n|, and the break will occur with penalty
+$10n$;
+
+\yskip\hang |backup| denotes a backspace of one em;
+
+\yskip\hang |cancel| obliterates any |break_space|, |opt|, |force|, or
+|big_force| tokens that immediately precede or follow it and also cancels any
+|backup| tokens that follow it;
+
+\yskip\hang |indent| causes future lines to be indented one more em;
+
+\yskip\hang |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; |break_space| and |force| and
+|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
+|indent|, |outdent|, |opt|, |backup|, |break_space|, |force|,
+|big_force| and |preproc_line|.
+However, a sequence of consecutive `\.\ ', |break_space|,
+|force|, and/or |big_force| tokens is first replaced by a single token
+(the maximum of the given ones).
+
+The token |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\,$\.\}$\,$|force|' surrounding comments, and
+`\.{\\X$n$:}$\,\ldots\,$\.{\\X}' surrounding section names, where
+|n| is the section number.
+
+@d math_rel 0206
+@d big_cancel 0210 /* like |cancel|, also overrides spaces */
+@d cancel 0211 /* overrides |backup|, |break_space|, |force|, |big_force| */
+@d indent 0212 /* one more tab (\.{\\1}) */
+@d outdent 0213 /* one less tab (\.{\\2}) */
+@d opt 0214 /* optional break in mid-statement (\.{\\3}) */
+@d backup 0215 /* stick out one unit to the left (\.{\\4}) */
+@d break_space 0216 /* optional break between statements (\.{\\5}) */
+@d force 0217 /* forced break between statements (\.{\\6}) */
+@d big_force 0220 /* forced break with additional space (\.{\\7}) */
+@d preproc_line 0221 /* begin line without indentation (\.{\\8}) */
+@^high-bit character handling@>
+@d quoted_char 0222
+ /* introduces a character token in the range |0200|--|0377| */
+@d end_translation 0223 /* special sentinel token at end of list */
+@d inserted 0224 /* sentinel to mark translations of inserts */
+@d qualifier 0225 /* introduces an explicit namespace qualifier */
+
+@ 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 |mathness|, which is explained
+further below.
+
+An identifier |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 |typedef| is translated with \.{\\\&} replacing
+\.{\\\\} and |raw_int| replacing |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
+\.{!=}&|binop|: \.{\\I}&yes\cr
+\.{<=}&|binop|: \.{\\Z}&yes\cr
+\.{>=}&|binop|: \.{\\G}&yes\cr
+\.{==}&|binop|: \.{\\E}&yes\cr
+\.{\&\&}&|binop|: \.{\\W}&yes\cr
+\.{\v\v}&|binop|: \.{\\V}&yes\cr
+\.{++}&|unop|: \.{\\PP}&yes\cr
+\.{--}&|unop|: \.{\\MM}&yes\cr
+\.{->}&|binop|: \.{\\MG}&yes\cr
+\.{>>}&|binop|: \.{\\GG}&yes\cr
+\.{<<}&|binop|: \.{\\LL}&yes\cr
+\.{::}&|colcol|: \.{\\DC}&maybe\cr
+\.{.*}&|binop|: \.{\\PA}&yes\cr
+\.{->*}&|binop|: \.{\\MGA}&yes\cr
+\.{...}&|raw_int|: \.{\\,\\ldots\\,}&yes\cr
+\."string\."&|exp|: \.{\\.\{}string with special characters quoted\.\}&maybe\cr
+\.{@@=}string\.{@@>}&|exp|: \.{\\vb\{}string with special characters
+ quoted\.\}&maybe\cr
+\.{@@'7'}&|exp|: \.{\\.\{@@'7'\}}&maybe\cr
+\.{077} or \.{\\77}&|exp|: \.{\\T\{\\\~77\}}&maybe\cr
+\.{0x7f}&|exp|: \.{\\T\{\\\^7f\}}&maybe\cr
+\.{77}&|exp|: \.{\\T\{77\}}&maybe\cr
+\.{77L}&|exp|: \.{\\T\{77\\\$L\}}&maybe\cr
+\.{0.1E5}&|exp|: \.{\\T\{0.1\\\_5\}}&maybe\cr
+\.+&|ubinop|: \.+&yes\cr
+\.-&|ubinop|: \.-&yes\cr
+\.*&|raw_ubin|: \.*&yes\cr
+\./&|binop|: \./&yes\cr
+\.<&|prelangle|: \.{\\langle}&yes\cr
+\.=&|binop|: \.{\\K}&yes\cr
+\.>&|prerangle|: \.{\\rangle}&yes\cr
+\..&|binop|: \..&yes\cr
+\.{\v}&|binop|: \.{\\OR}&yes\cr
+\.\^&|binop|: \.{\\XOR}&yes\cr
+\.\%&|binop|: \.{\\MOD}&yes\cr
+\.?&|question|: \.{\\?}&yes\cr
+\.!&|unop|: \.{\\R}&yes\cr
+\.\~&|unop|: \.{\\CM}&yes\cr
+\.\&&|raw_ubin|: \.{\\AND}&yes\cr
+\.(&|lpar|: \.(&maybe\cr
+\.[&|lpar|: \.[&maybe\cr
+\.)&|rpar|: \.)&maybe\cr
+\.]&|rpar|: \.]&maybe\cr
+\.\{&|lbrace|: \.\{&yes\cr
+\.\}&|lbrace|: \.\}&yes\cr
+\.,&|comma|: \.,&yes\cr
+\.;&|semi|: \.;&maybe\cr
+\.:&|colon|: \.:&no\cr
+\.\# (within line)&|ubinop|: \.{\\\#}&yes\cr
+\.\# (at beginning)&|lproc|: |force| |preproc_line| \.{\\\#}&no\cr
+end of \.\# line&|rproc|: |force|&no\cr
+identifier&|exp|: \.{\\\\\{}identifier with underlines and
+ dollar signs quoted\.\}&maybe\cr
+\.{and}&|alfop|: \stars&yes\cr
+\.{and\_eq}&|alfop|: \stars&yes\cr
+\.{asm}&|sizeof_like|: \stars&maybe\cr
+\.{auto}&|int_like|: \stars&maybe\cr
+\.{bitand}&|alfop|: \stars&yes\cr
+\.{bitor}&|alfop|: \stars&yes\cr
+\.{bool}&|raw_int|: \stars&maybe\cr
+\.{break}&|case_like|: \stars&maybe\cr
+\.{case}&|case_like|: \stars&maybe\cr
+\.{catch}&|catch_like|: \stars&maybe\cr
+\.{char}&|raw_int|: \stars&maybe\cr
+\.{class}&|struct_like|: \stars&maybe\cr
+\.{clock\_t}&|raw_int|: \stars&maybe\cr
+\.{compl}&|alfop|: \stars&yes\cr
+\.{const}&|const_like|: \stars&maybe\cr
+\.{const\_cast}&|raw_int|: \stars&maybe\cr
+\.{continue}&|case_like|: \stars&maybe\cr
+\.{default}&|case_like|: \stars&maybe\cr
+\.{define}&|define_like|: \stars&maybe\cr
+\.{defined}&|sizeof_like|: \stars&maybe\cr
+\.{delete}&|delete_like|: \stars&maybe\cr
+\.{div\_t}&|raw_int|: \stars&maybe\cr
+\.{do}&|do_like|: \stars&maybe\cr
+\.{double}&|raw_int|: \stars&maybe\cr
+\.{dynamic\_cast}&|raw_int|: \stars&maybe\cr
+\.{elif}&|if_like|: \stars&maybe\cr
+\.{else}&|else_like|: \stars&maybe\cr
+\.{endif}&|if_like|: \stars&maybe\cr
+\.{enum}&|struct_like|: \stars&maybe\cr
+\.{error}&|if_like|: \stars&maybe\cr
+\.{explicit}&|int_like|: \stars&maybe\cr
+\.{export}&|int_like|: \stars&maybe\cr
+\.{extern}&|int_like|: \stars&maybe\cr
+\.{FILE}&|raw_int|: \stars&maybe\cr
+\.{float}&|raw_int|: \stars&maybe\cr
+\.{for}&|for_like|: \stars&maybe\cr
+\.{fpos\_t}&|raw_int|: \stars&maybe\cr
+\.{friend}&|int_like|: \stars&maybe\cr
+\.{goto}&|case_like|: \stars&maybe\cr
+\.{if}&|if_like|: \stars&maybe\cr
+\.{ifdef}&|if_like|: \stars&maybe\cr
+\.{ifndef}&|if_like|: \stars&maybe\cr
+\.{include}&|if_like|: \stars&maybe\cr
+\.{inline}&|int_like|: \stars&maybe\cr
+\.{int}&|raw_int|: \stars&maybe\cr
+\.{jmp\_buf}&|raw_int|: \stars&maybe\cr
+\.{ldiv\_t}&|raw_int|: \stars&maybe\cr
+\.{line}&|if_like|: \stars&maybe\cr
+\.{long}&|raw_int|: \stars&maybe\cr
+\.{make\_pair}&|ftemplate|: \.{\\\\\{make\\\_pair\}}&maybe\cr
+\.{mutable}&|int_like|: \stars&maybe\cr
+\.{namespace}&|struct_like|: \stars&maybe\cr
+\.{new}&|new_like|: \stars&maybe\cr
+\.{not}&|alfop|: \stars&yes\cr
+\.{not\_eq}&|alfop|: \stars&yes\cr
+\.{NULL}&|exp|: \.{\\NULL}&yes\cr
+\.{offsetof}&|raw_int|: \stars&maybe\cr
+\.{operator}&|operator_like|: \stars&maybe\cr
+\.{or}&|alfop|: \stars&yes\cr
+\.{or\_eq}&|alfop|: \stars&yes\cr
+\.{pragma}&|if_like|: \stars&maybe\cr
+\.{private}&|public_like|: \stars&maybe\cr
+\.{protected}&|public_like|: \stars&maybe\cr
+\.{ptrdiff\_t}&|raw_int|: \stars&maybe\cr
+\.{public}&|public_like|: \stars&maybe\cr
+\.{register}&|int_like|: \stars&maybe\cr
+\.{reinterpret\_cast}&|raw_int|: \stars&maybe\cr
+\.{return}&|case_like|: \stars&maybe\cr
+\.{short}&|raw_int|: \stars&maybe\cr
+\.{sig\_atomic\_t}&|raw_int|: \stars&maybe\cr
+\.{signed}&|raw_int|: \stars&maybe\cr
+\.{size\_t}&|raw_int|: \stars&maybe\cr
+\.{sizeof}&|sizeof_like|: \stars&maybe\cr
+\.{static}&|int_like|: \stars&maybe\cr
+\.{static\_cast}&|raw_int|: \stars&maybe\cr
+\.{struct}&|struct_like|: \stars&maybe\cr
+\.{switch}&|for_like|: \stars&maybe\cr
+\.{template}&|template_like|: \stars&maybe\cr
+\.{TeX}&|exp|: \.{\\TeX}&yes\cr
+\.{this}&|exp|: \.{\\this}&yes\cr
+\.{throw}&|case_like|: \stars&maybe\cr
+\.{time\_t}&|raw_int|: \stars&maybe\cr
+\.{try}&|else_like|: \stars&maybe\cr
+\.{typedef}&|typedef_like|: \stars&maybe\cr
+\.{typeid}&|raw_int|: \stars&maybe\cr
+\.{typename}&|struct_like|: \stars&maybe\cr
+\.{undef}&|if_like|: \stars&maybe\cr
+\.{union}&|struct_like|: \stars&maybe\cr
+\.{unsigned}&|raw_int|: \stars&maybe\cr
+\.{using}&|int_like|: \stars&maybe\cr
+\.{va\_dcl}&|decl|: \stars&maybe\cr
+\.{va\_list}&|raw_int|: \stars&maybe\cr
+\.{virtual}&|int_like|: \stars&maybe\cr
+\.{void}&|raw_int|: \stars&maybe\cr
+\.{volatile}&|const_like|: \stars&maybe\cr
+\.{wchar\_t}&|raw_int|: \stars&maybe\cr
+\.{while}&|for_like|: \stars&maybe\cr
+\.{xor}&|alfop|: \stars&yes\cr
+\.{xor\_eq}&|alfop|: \stars&yes\cr
+\.{@@,}&|insert|: \.{\\,}&maybe\cr
+\.{@@\v}&|insert|: |opt| \.0&maybe\cr
+\.{@@/}&|insert|: |force|&no\cr
+\.{@@\#}&|insert|: |big_force|&no\cr
+\.{@@+}&|insert|: |big_cancel| \.{\{\}} |break_space|
+ \.{\{\}} |big_cancel|&no\cr
+\.{@@;}&|semi|: &maybe\cr
+\.{@@[@q]@>}&|begin_arg|: &maybe\cr
+\.{@q[@>@@]}&|end_arg|: &maybe\cr
+\.{@@\&}&|insert|: \.{\\J}&maybe\cr
+\.{@@h}&|insert|: |force| \.{\\ATH} |force|&no\cr
+\.{@@<}\thinspace section name\thinspace\.{@@>}&|section_scrap|:
+ \.{\\X}$n$\.:translated section name\.{\\X}&maybe\cr
+\.{@@(@q)@>}\thinspace section name\thinspace\.{@@>}&|section_scrap|:
+ \.{\\X}$n$\.{:\\.\{}section name with special characters
+ quoted\.{\ \}\\X}&maybe\cr
+\.{/*}comment\.{*/}&|insert|: |cancel|
+ \.{\\C\{}translated comment\.\} |force|&no\cr
+\.{//}comment&|insert|: |cancel|
+ \.{\\SHC\{}translated comment\.\} |force|&no\cr
+}
+
+\smallskip
+The construction \.{@@t}\thinspace stuff\/\thinspace\.{@@>} contributes
+\.{\\hbox\{}\thinspace stuff\/\thinspace\.\} to the following scrap.
+
+@i prod.w
+
+@* Implementing the productions.
+More specifically, a scrap is a structure consisting of a category
+|cat| and a |text_pointer| |trans|, which points to the translation in
+|tok_start|. When \CEE/ text is to be processed with the grammar above,
+we form an array |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 |pp| is a pointer into |scrap_info|. We will try to match
+the category codes |pp->cat,@,@,(pp+1)->cat|$,\,\,\ldots\,$
+to the left-hand sides of productions.
+
+\yskip\hang |scrap_base|, |lo_ptr|, |hi_ptr|, and |scrap_ptr| are such that
+the current sequence of scraps appears in positions |scrap_base| through
+|lo_ptr| and |hi_ptr| through |scrap_ptr|, inclusive, in the |cat| and
+|trans| arrays. Scraps located between |scrap_base| and |lo_ptr| have
+been examined, while those in positions |>=hi_ptr| have not yet been
+looked at by the parsing process.
+
+\yskip\noindent Initially |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 |lo_ptr>=pp+3|, since productions have as many as four terms,
+by moving scraps from |hi_ptr| to |lo_ptr|. If there are
+fewer than |pp+3| scraps left, the positions up to |pp+3| are filled with
+blanks that will not match in any productions. Parsing stops when
+|pp==lo_ptr+1| and |hi_ptr==scrap_ptr+1|.
+
+Since the |scrap| structure will later be used for other purposes, we
+declare its second element as a union.
+
+@<Type...@>=
+typedef struct {
+ eight_bits cat;
+ eight_bits mathness;
+ union {
+ text_pointer Trans;
+ @<Rest of |trans_plus| union@>@;
+ } trans_plus;
+} scrap;
+typedef scrap *scrap_pointer;
+
+@ @d trans trans_plus.Trans /* translation texts of scraps */
+
+@<Private...@>=
+static scrap scrap_info[max_scraps]; /* memory array for scraps */
+static scrap_pointer scrap_info_end=scrap_info+max_scraps-1; /* end of |scrap_info| */
+static scrap_pointer scrap_base; /* beginning of the current scrap sequence */
+static scrap_pointer scrap_ptr; /* ending of the current scrap sequence */
+static scrap_pointer max_scr_ptr; /* largest value assumed by |scrap_ptr| */
+static scrap_pointer pp; /* current position for reducing productions */
+static scrap_pointer lo_ptr; /* last scrap that has been examined */
+static scrap_pointer hi_ptr; /* first scrap that has not been examined */
+
+@ @<Set init...@>=
+scrap_base=scrap_info+1;
+max_scr_ptr=scrap_ptr=scrap_info;
+
+@ Token lists in |@!tok_mem| are composed of the following kinds of
+items for \TEX/ output.
+
+\yskip\item{$\bullet$}Character codes and special codes like |force| and
+|math_rel| represent themselves;
+
+\item{$\bullet$}|id_flag+p| represents \.{\\\\\{{\rm identifier $p$}\}};
+
+\item{$\bullet$}|res_flag+p| represents \.{\\\&\{{\rm identifier $p$}\}};
+
+\item{$\bullet$}|section_flag+p| represents section name |p|;
+
+\item{$\bullet$}|tok_flag+p| represents token list number |p|;
+
+\item{$\bullet$}|inner_tok_flag+p| represents token list number |p|, to be
+translated without line-break controls.
+
+@d id_flag 10240 /* signifies an identifier */
+@d res_flag 2*id_flag /* signifies a reserved word */
+@d section_flag 3*id_flag /* signifies a section name */
+@d tok_flag 4*id_flag /* signifies a token list */
+@d inner_tok_flag 5*id_flag /* signifies a token list in `\pb' */
+
+@c
+static void
+print_text(@t\1\1@> /* prints a token list for debugging; not used in |main| */
+text_pointer p@t\2\2@>)
+{
+ token_pointer j; /* index into |tok_mem| */
+ sixteen_bits r; /* remainder of token after the flag has been stripped off */
+ if (p>=text_ptr) printf("BAD");
+ else for (j=*p; j<*(p+1); j++) {
+ r=*j%id_flag;
+ switch (*j/id_flag) {
+ case 1: printf("\\\\{"@q}@>); print_id((name_dir+r)); printf(@q{@>"}");
+ break; /* |id_flag| */
+ case 2: printf("\\&{"@q}@>); print_id((name_dir+r)); printf(@q{@>"}");
+ break; /* |res_flag| */
+ case 3: printf("<"); print_section_name((name_dir+r)); printf(">");
+ break; /* |section_flag| */
+ case 4: printf("[[%d]]",r); break; /* |tok_flag| */
+ case 5: printf("|[[%d]]|",r); break; /* |inner_tok_flag| */
+ default: @<Print token |r| in symbolic form@>@;
+ }
+ }
+ update_terminal;
+}
+
+@ @<Predecl...@>=@+static void print_text(text_pointer p);
+
+@ @<Print token |r|...@>=
+switch (r) {
+ case math_rel: printf("\\mathrel{"@q}@>); break;
+ case big_cancel: printf("[ccancel]"); break;
+ case cancel: printf("[cancel]"); break;
+ case indent: printf("[indent]"); break;
+ case outdent: printf("[outdent]"); break;
+ case backup: printf("[backup]"); break;
+ case opt: printf("[opt]"); break;
+ case break_space: printf("[break]"); break;
+ case force: printf("[force]"); break;
+ case big_force: printf("[fforce]"); break;
+ case preproc_line: printf("[preproc]"); break;
+ case quoted_char: j++; printf("[%o]",(unsigned int)*j); break;
+ case end_translation: printf("[quit]"); break;
+ case inserted: printf("[inserted]"); break;
+ default: putxchar(r);
+}
+
+@ 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 |k|
+consecutive scraps starting at some position |j| are to be replaced by a
+single scrap of some category |c| whose translation is composed from the
+translations of the disappearing scraps. After this production has been
+applied, the production pointer |pp| should change by an amount |d|. Such
+a production can be represented by the quadruple |(j,k,c,d)|. For example,
+the production `|exp@,comma@,exp| $\RA$ |exp|' would be represented by
+`|(pp,3,exp,-2)|'; in this case the pointer |pp| should decrease by 2
+after the production has been applied, because some productions with
+|exp| in their second or third positions might now match,
+but no productions have
+|exp| in the fourth position of their left-hand sides. Note that
+the value of |d| is determined by the whole collection of productions, not
+by an individual one.
+The determination of |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 `|reduce(pp,3,exp,-2,4)|' when it implements
+the production just mentioned.
+
+Before calling |reduce|, the program should have appended the tokens of
+the new translation to the |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}|(pp)| will append the
+translations of two consecutive scraps, |pp->trans| and |(pp+1)->trans|, to
+the current token list. If the entire new translation is formed in this
+way, we write `|squash(j,k,c,d,n)|' instead of `|reduce(j,k,c,d,n)|'. For
+example, `|squash(pp,3,exp,-2,3)|' is an abbreviation for `\\{app3}|(pp);
+reduce(pp,3,exp,-2,3)|'.
+
+A couple more words of explanation:
+Both |big_app| and |app| append a token (while |big_app1| to |big_app3|
+append the specified number of scrap translations) to the current token list.
+The difference between |big_app| and |app| is simply that |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 |big_app|.
+
+The |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 |cat|) because to make each |cat| have
+a fixed |mathness| (as in the original \.{WEAVE}) would multiply the
+number of necessary production rules.
+
+The low two bits (i.e. |mathness % 4|) control the left boundary.
+(We need two bits because we allow cases |yes_math|, |no_math| and
+|maybe_math|, which can go either way.)
+The next two bits (i.e. |mathness / 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 |yes_math| boundary the scrap gets preceded
+or followed by a \.{\$}. The left boundary is |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.
+
+@d no_math 2 /* should be in horizontal mode */
+@d yes_math 1 /* should be in math mode */
+@d maybe_math 0 /* works in either horizontal or math mode */
+@d big_app2(a) big_app1(a);big_app1(a+1)
+@d big_app3(a) big_app2(a);big_app1(a+2)
+@d app(a) *(tok_ptr++)=(token)(a)
+@d app1(a) *(tok_ptr++)=(token)(tok_flag+(int)((a)->trans-tok_start))
+
+@<Private...@>=
+static int cur_mathness, init_mathness;
+
+@ @<Predecl...@>=
+static void app_str(const char *);@/
+static void big_app(token);@/
+static void big_app1(scrap_pointer);
+
+@ @c
+static void
+app_str(
+const char *s)
+{
+ while (*s) app_tok(*(s++));
+}
+
+static void
+big_app(
+token a)
+{
+ if (a==' ' || (a>=big_cancel && a<=big_force)) /* non-math token */ {
+ if (cur_mathness==maybe_math) init_mathness=no_math;
+ else if (cur_mathness==yes_math) app_str("{}$");
+ cur_mathness=no_math;
+ }
+ else {
+ if (cur_mathness==maybe_math) init_mathness=yes_math;
+ else if (cur_mathness==no_math) app_str("${}");
+ cur_mathness=yes_math;
+ }
+ app(a);
+}
+
+static void
+big_app1(
+scrap_pointer a)
+{
+ switch (a->mathness % 4) { /* left boundary */
+ case (no_math):
+ if (cur_mathness==maybe_math) init_mathness=no_math;
+ else if (cur_mathness==yes_math) app_str("{}$");
+ cur_mathness=a->mathness / 4; /* right boundary */
+ break;
+ case (yes_math):
+ if (cur_mathness==maybe_math) init_mathness=yes_math;
+ else if (cur_mathness==no_math) app_str("${}");
+ cur_mathness=a->mathness / 4; /* right boundary */
+ break;
+ case (maybe_math): /* no changes */ break;
+ }
+ app(tok_flag+(int)((a)->trans-tok_start));
+}
+
+@ 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.
+
+@d cat1 (pp+1)->cat
+@d cat2 (pp+2)->cat
+@d cat3 (pp+3)->cat
+@d lhs_not_simple (pp->cat!=public_like
+ && pp->cat!=semi
+ && pp->cat!=prelangle
+ && pp->cat!=prerangle @|
+ && pp->cat!=template_like
+ && pp->cat!=new_like
+ && pp->cat!=new_exp
+ && pp->cat!=ftemplate @|
+ && pp->cat!=raw_ubin
+ && pp->cat!=const_like
+ && pp->cat!=raw_int
+ && pp->cat!=operator_like)
+ /* not a production with left side length 1 */
+
+@<Match a production at |pp|, or increase |pp| if there is no match@>= {
+ if (cat1==end_arg && lhs_not_simple)
+ if (pp->cat==begin_arg) squash(pp,2,exp,-2,124);
+ else squash(pp,2,end_arg,-1,125);
+ else if (cat1==insert) squash(pp,2,pp->cat,-2,0);
+ else if (cat2==insert) squash(pp+1,2,(pp+1)->cat,-1,0);
+ else if (cat3==insert) squash(pp+2,2,(pp+2)->cat,0,0);
+ else
+ switch (pp->cat) {
+ case exp: @<Cases for |exp|@>@; @+break;
+ case lpar: @<Cases for |lpar|@>@; @+break;
+ case unop: @<Cases for |unop|@>@; @+break;
+ case ubinop: @<Cases for |ubinop|@>@; @+break;
+ case binop: @<Cases for |binop|@>@; @+break;
+ case cast: @<Cases for |cast|@>@; @+break;
+ case sizeof_like: @<Cases for |sizeof_like|@>@; @+break;
+ case int_like: @<Cases for |int_like|@>@; @+break;
+ case public_like: @<Cases for |public_like|@>@; @+break;
+ case colcol: @<Cases for |colcol|@>@; @+break;
+ case decl_head: @<Cases for |decl_head|@>@; @+break;
+ case decl: @<Cases for |decl|@>@; @+break;
+ case base: @<Cases for |base|@>@; @+break;
+ case struct_like: @<Cases for |struct_like|@>@; @+break;
+ case struct_head: @<Cases for |struct_head|@>@; @+break;
+ case fn_decl: @<Cases for |fn_decl|@>@; @+break;
+ case function: @<Cases for |function|@>@; @+break;
+ case lbrace: @<Cases for |lbrace|@>@; @+break;
+ case if_like: @<Cases for |if_like|@>@; @+break;
+ case else_like: @<Cases for |else_like|@>@; @+break;
+ case else_head: @<Cases for |else_head|@>@; @+break;
+ case if_clause: @<Cases for |if_clause|@>@; @+break;
+ case if_head: @<Cases for |if_head|@>@; @+break;
+ case do_like: @<Cases for |do_like|@>@; @+break;
+ case case_like: @<Cases for |case_like|@>@; @+break;
+ case catch_like: @<Cases for |catch_like|@>@; @+break;
+ case tag: @<Cases for |tag|@>@; @+break;
+ case stmt: @<Cases for |stmt|@>@; @+break;
+ case semi: @<Cases for |semi|@>@; @+break;
+ case lproc: @<Cases for |lproc|@>@; @+break;
+ case section_scrap: @<Cases for |section_scrap|@>@; @+break;
+ case insert: @<Cases for |insert|@>@; @+break;
+ case prelangle: @<Cases for |prelangle|@>@; @+break;
+ case prerangle: @<Cases for |prerangle|@>@; @+break;
+ case langle: @<Cases for |langle|@>@; @+break;
+ case template_like: @<Cases for |template_like|@>@; @+break;
+ case new_like: @<Cases for |new_like|@>@; @+break;
+ case new_exp: @<Cases for |new_exp|@>@; @+break;
+ case ftemplate: @<Cases for |ftemplate|@>@; @+break;
+ case for_like: @<Cases for |for_like|@>@; @+break;
+ case raw_ubin: @<Cases for |raw_ubin|@>@; @+break;
+ case const_like: @<Cases for |const_like|@>@; @+break;
+ case raw_int: @<Cases for |raw_int|@>@; @+break;
+ case operator_like: @<Cases for |operator_like|@>@; @+break;
+ case typedef_like: @<Cases for |typedef_like|@>@; @+break;
+ case delete_like: @<Cases for |delete_like|@>@; @+break;
+ case question: @<Cases for |question|@>@; @+break;
+ }
+ pp++; /* if no match was found, we move to the right */
+}
+
+@ In \CEE/, new specifier names can be defined via |typedef|, and we want
+to make the parser recognize future occurrences of the identifier thus
+defined as specifiers. This is done by the procedure |make_reserved|,
+which changes the |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.
+
+If the first identifier found is a keyword like `\&{case}', we
+return the special value |case_found|; this prevents underlining
+of identifiers in case labels.
+
+If the first identifier is the keyword `\&{operator}', we give up;
+users who want to index definitions of overloaded \CPLUSPLUS/ operators
+should say, for example, `\.{@@!@@\^\\\&\{operator\} \$+\{=\}\$@@>}' (or,
+more properly alpha\-betized,
+`\.{@@!@@:operator+=\}\{\\\&\{operator\} \$+\{=\}\$@@>}').
+
+@d no_ident_found (token_pointer)0 /* distinct from any identifier token */
+@d case_found (token_pointer)1 /* likewise */
+@d operator_found (token_pointer)2 /* likewise */
+
+@<Predecl...@>=
+static token_pointer find_first_ident(text_pointer);@/
+static void make_reserved(scrap_pointer);@/
+static void make_underlined(scrap_pointer);@/
+static void underline_xref(name_pointer);
+
+@ @c
+static token_pointer
+find_first_ident(
+text_pointer p)
+{
+ token_pointer q; /* token to be returned */
+ token_pointer j; /* token being looked at */
+ sixteen_bits r; /* remainder of token after the flag has been stripped off */
+ if (p>=text_ptr) confusion("find_first_ident");
+ for (j=*p; j<*(p+1); j++) {
+ r=*j%id_flag;
+ switch (*j/id_flag) {
+ case 2: /* |res_flag| */
+ if (name_dir[r].ilk==case_like) return case_found;
+ if (name_dir[r].ilk==operator_like) return operator_found;
+ if (name_dir[r].ilk!=raw_int) break;
+ case 1: return j;
+ case 4: case 5: /* |tok_flag| or |inner_tok_flag| */
+ if ((q=find_first_ident(tok_start+r))!=no_ident_found)
+ return q;
+ default: ; /* char, |section_flag|, fall thru: move on to next token */
+ if (*j==inserted) return no_ident_found; /* ignore inserts */
+ else if (*j==qualifier) j++; /* bypass namespace qualifier */
+ }
+ }
+ return no_ident_found;
+}
+
+@ The scraps currently being parsed must be inspected for any
+occurrence of the identifier that we're making reserved; hence
+the |for| loop below.
+
+@c
+static void
+make_reserved(@t\1\1@> /* make the first identifier in |p->trans| like |int| */
+scrap_pointer p@t\2\2@>)
+{
+ sixteen_bits tok_value; /* the name of this identifier, plus its flag */
+ token_pointer tok_loc; /* pointer to |tok_value| */
+ if ((tok_loc=find_first_ident(p->trans))<=operator_found)
+ return; /* this should not happen */
+ tok_value=*tok_loc;
+ for (;p<=scrap_ptr; p==lo_ptr? p=hi_ptr: p++) {
+ if (p->cat==exp) {
+ if (**(p->trans)==tok_value) {
+ p->cat=raw_int;
+ **(p->trans)=tok_value%id_flag+res_flag;
+ }
+ }
+ }
+ (name_dir+(sixteen_bits)(tok_value%id_flag))->ilk=raw_int;
+ *tok_loc=tok_value%id_flag+res_flag;
+}
+
+@ In the following situations we want to mark the occurrence of
+an identifier as a definition: when |make_reserved| is just about to be
+used; after a specifier, as in |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 |make_underlined| at appropriate times. Notice that, in the declaration
+of a function, we find out that the identifier is being defined only after
+it has been swallowed up by an |exp|.
+
+@c
+static void
+make_underlined(@t\1\1@>
+/* underline the entry for the first identifier in |p->trans| */
+scrap_pointer p@t\2\2@>)
+{
+ token_pointer tok_loc; /* where the first identifier appears */
+ if ((tok_loc=find_first_ident(p->trans))<=operator_found)
+ return; /* this happens, for example, in |case found:| */
+ xref_switch=def_flag;
+ underline_xref(*tok_loc%id_flag+name_dir);
+}
+
+@ We cannot use |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.
+
+@c
+static void
+underline_xref(
+name_pointer p)
+{
+ xref_pointer q=(xref_pointer)p->xref; /* pointer to cross-reference being examined */
+ xref_pointer r; /* temporary pointer for permuting cross-references */
+ sixteen_bits m; /* cross-reference value to be installed */
+ sixteen_bits n; /* cross-reference value being examined */
+ if (no_xref) return;
+ m=section_count+xref_switch;
+ while (q != xmem) {
+ n=q->num;
+ if (n==m) return;
+ else if (m==n+def_flag) {
+ q->num=m; return;
+ }
+ else if (n>=def_flag && n<m) break;
+ q=q->xlink;
+ }
+ @<Insert new cross-reference at |q|, not at beginning of list@>@;
+}
+
+@ 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 |p->xref|), but rather right before |q|.
+
+@<Insert new cross-reference at |q|...@>=
+ append_xref(0); /* this number doesn't matter */
+ xref_ptr->xlink=(xref_pointer)p->xref; r=xref_ptr;
+ update_node(p);
+ while (r->xlink!=q) {r->num=r->xlink->num; r=r->xlink;}
+ r->num=m; /* everything from |q| on is left undisturbed */
+
+@ Now comes the code that tries to match each production starting
+with a particular type of scrap. Whenever a match is discovered,
+the |squash| or |reduce| macro will cause the appropriate action
+to be performed, followed by |goto found|.
+
+@<Cases for |exp|@>=
+if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ make_underlined(pp); big_app1(pp); big_app(indent); app(indent);
+ reduce(pp,1,fn_decl,0,1);
+}
+else if (cat1==unop) squash(pp,2,exp,-2,2);
+else if ((cat1==binop || cat1==ubinop) && cat2==exp)
+ squash(pp,3,exp,-2,3);
+else if (cat1==comma && cat2==exp) {
+ big_app2(pp);
+ app(opt); app('9'); big_app1(pp+2); reduce(pp,3,exp,-2,4);
+}
+else if (cat1==lpar && cat2==rpar && cat3==colon) squash(pp+3,1,base,0,5);
+else if (cat1==cast && cat2==colon) squash(pp+2,1,base,0,5);
+else if (cat1==semi) squash(pp,2,stmt,-1,6);
+else if (cat1==colon) {
+ make_underlined (pp); squash(pp,2,tag,-1,7);
+}
+else if (cat1==rbrace) squash(pp,1,stmt,-1,8);
+else if (cat1==lpar && cat2==rpar && (cat3==const_like || cat3==case_like)) {
+ big_app1(pp+2); big_app(' '); big_app1(pp+3); reduce(pp+2,2,rpar,0,9);
+}
+else if (cat1==cast && (cat2==const_like || cat2==case_like)) {
+ big_app1(pp+1); big_app(' '); big_app1(pp+2); reduce(pp+1,2,cast,0,9);
+}
+else if (cat1==exp || cat1==cast) squash(pp,2,exp,-2,10);
+
+@ @<Cases for |lpar|@>=
+if ((cat1==exp||cat1==ubinop) && cat2==rpar) squash(pp,3,exp,-2,11);
+else if (cat1==rpar) {
+ big_app1(pp); app('\\'); app(','); big_app1(pp+1);
+@.\\,@>
+ reduce(pp,2,exp,-2,12);
+}
+else if ((cat1==decl_head || cat1==int_like || cat1==cast) && cat2==rpar)
+ squash(pp,3,cast,-2,13);
+else if ((cat1==decl_head || cat1==int_like || cat1==exp) && cat2==comma) {
+ big_app3(pp); app(opt); app('9'); reduce(pp,3,lpar,-1,14);
+}
+else if (cat1==stmt || cat1==decl) {
+ big_app2(pp); big_app(' '); reduce(pp,2,lpar,-1,15);
+}
+
+@ @<Cases for |unop|@>=
+if (cat1==exp || cat1==int_like) squash(pp,2,exp,-2,16);
+
+@ @<Cases for |ubinop|@>=
+if (cat1==cast && cat2==rpar) {
+ big_app('{'); big_app1(pp); big_app('}'); big_app1(pp+1);
+ reduce(pp,2,cast,-2,17);
+}
+else if (cat1==exp || cat1==int_like) {
+ big_app('{'); big_app1(pp); big_app('}'); big_app1(pp+1);
+ reduce(pp,2,cat1,-2,18);
+}
+else if (cat1==binop) {
+ big_app(math_rel); big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ big_app('}'); reduce(pp,2,binop,-1,19);
+}
+
+@ @<Cases for |binop|@>=
+if (cat1==binop) {
+ big_app(math_rel); big_app('{'); big_app1(pp); big_app('}');
+ big_app('{'); big_app1(pp+1); big_app('}');
+ big_app('}'); reduce(pp,2,binop,-1,20);
+}
+
+@ @<Cases for |cast|@>=
+if (cat1==lpar) squash(pp,2,lpar,-1,21);
+else if (cat1==exp) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,21);
+}
+else if (cat1==semi) squash(pp,1,exp,-2,22);
+
+@ @<Cases for |sizeof_like|@>=
+if (cat1==cast) squash(pp,2,exp,-2,23);
+else if (cat1==exp) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,24);
+}
+
+@ @<Cases for |int_like|@>=
+if (cat1==int_like|| cat1==struct_like) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,cat1,-2,25);
+}
+else if (cat1==exp && (cat2==raw_int||cat2==struct_like))
+ squash(pp,2,int_like,-2,26);
+else if (cat1==exp || cat1==ubinop || cat1==colon) {
+ big_app1(pp); big_app(' '); reduce(pp,1,decl_head,-1,27);
+}
+else if (cat1==semi || cat1==binop) squash(pp,1,decl_head,0,28);
+
+@ @<Cases for |public_like|@>=
+if (cat1==colon) squash(pp,2,tag,-1,29);
+else squash(pp,1,int_like,-2,30);
+
+@ @<Cases for |colcol|@>=
+if (cat1==exp||cat1==int_like) {
+ app(qualifier); squash(pp,2,cat1,-2,31);
+}@+else if (cat1==colcol) squash(pp,2,colcol,-1,32);
+
+@ @<Cases for |decl_head|@>=
+if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,decl_head,-1,33);
+}
+else if (cat1==ubinop) {
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,decl_head,-1,34);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1); squash(pp,2,decl_head,-1,35);
+}
+else if ((cat1==binop||cat1==colon) && cat2==exp && (cat3==comma ||
+ cat3==semi || cat3==rpar))
+ squash(pp,3,decl_head,-1,36);
+else if (cat1==cast) squash(pp,2,decl_head,-1,37);
+else if (cat1==lbrace || cat1==int_like || cat1==decl) {
+ big_app1(pp); big_app(indent); app(indent); reduce(pp,1,fn_decl,0,38);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,39);
+
+@ @<Cases for |decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1);
+ reduce(pp,2,decl,-1,40);
+}
+else if (cat1==stmt || cat1==function) {
+ big_app1(pp); big_app(big_force);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,41);
+}
+
+@ @<Cases for |base|@>=
+if (cat1==int_like || cat1==exp) {
+ if (cat2==comma) {
+ big_app1(pp); big_app(' '); big_app2(pp+1);
+ app(opt); app('9'); reduce(pp,3,base,0,42);
+ }
+ else if (cat2==lbrace) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); big_app(' '); big_app1(pp+2);
+ reduce(pp,3,lbrace,-2,43);
+ }
+}
+
+@ @<Cases for |struct_like|@>=
+if (cat1==lbrace) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,struct_head,0,44);
+}
+else if (cat1==exp||cat1==int_like) {
+ if (cat2==lbrace || cat2==semi) {
+ make_underlined(pp+1); make_reserved(pp+1);
+ big_app1(pp); big_app(' '); big_app1(pp+1);
+ if (cat2==semi) reduce(pp,2,decl_head,0,45);
+ else {
+ big_app(' '); big_app1(pp+2);reduce(pp,3,struct_head,0,46);
+ }
+ }
+ else if (cat2==colon) squash(pp+2,1,base,2,47);
+ else if (cat2!=base) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,int_like,-2,48);
+ }
+}
+
+@ @<Cases for |struct_head|@>=
+if ((cat1==decl || cat1==stmt || cat1==function) && cat2==rbrace) {
+ big_app1(pp); big_app(indent); big_app(force); big_app1(pp+1);
+ big_app(outdent); big_app(force); big_app1(pp+2);
+ reduce(pp,3,int_like,-2,49);
+}
+else if (cat1==rbrace) {
+ big_app1(pp); app_str("\\,"); big_app1(pp+1);
+@.\\,@>
+ reduce(pp,2,int_like,-2,50);
+}
+
+@ @<Cases for |fn_decl|@>=
+if (cat1==decl) {
+ big_app1(pp); big_app(force); big_app1(pp+1); reduce(pp,2,fn_decl,0,51);
+}
+else if (cat1==stmt) {
+ big_app1(pp); app(outdent); app(outdent); big_app(force);
+ big_app1(pp+1); reduce(pp,2,function,-1,52);
+}
+
+@ @<Cases for |function|@>=
+if (cat1==function || cat1==decl || cat1==stmt) {
+ big_app1(pp); big_app(big_force); big_app1(pp+1); reduce(pp,2,cat1,-1,53);
+}
+
+@ @<Cases for |lbrace|@>=
+if (cat1==rbrace) {
+ big_app1(pp); app('\\'); app(','); big_app1(pp+1);
+@.\\,@>
+ reduce(pp,2,stmt,-1,54);
+}
+else if ((cat1==stmt||cat1==decl||cat1==function) && cat2==rbrace) {
+ big_app(force); big_app1(pp); big_app(indent); big_app(force);
+ big_app1(pp+1); big_app(force); big_app(backup); big_app1(pp+2);
+ big_app(outdent); big_app(force); reduce(pp,3,stmt,-1,55);
+}
+else if (cat1==exp) {
+ if (cat2==rbrace) squash(pp,3,exp,-2,56);
+ else if (cat2==comma && cat3==rbrace) squash(pp,4,exp,-2,56);
+}
+
+@ @<Cases for |if_like|@>=
+if (cat1==exp) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,if_clause,0,57);
+}
+
+@ @<Cases for |else_like|@>=
+if (cat1==colon) squash(pp+1,1,base,1,58);
+else if (cat1==lbrace) squash(pp,1,else_head,0,59);
+else if (cat1==stmt) {
+ big_app(force); big_app1(pp); big_app(indent); big_app(break_space);
+ big_app1(pp+1); big_app(outdent); big_app(force);
+ reduce(pp,2,stmt,-1,60);
+}
+
+@ @<Cases for |else_head|@>=
+if (cat1==stmt || cat1==exp) {
+ big_app(force); big_app1(pp); big_app(break_space); app(noop);
+ big_app(cancel); big_app1(pp+1); big_app(force);
+ reduce(pp,2,stmt,-1,61);
+}
+
+@ @<Cases for |if_clause|@>=
+if (cat1==lbrace) squash(pp,1,if_head,0,62);
+else if (cat1==stmt) {
+ if (cat2==else_like) {
+ big_app(force); big_app1(pp); big_app(indent); big_app(break_space);
+ big_app1(pp+1); big_app(outdent); big_app(force); big_app1(pp+2);
+ if (cat3==if_like) {
+ big_app(' '); big_app1(pp+3); reduce(pp,4,if_like,0,63);
+ }@+else reduce(pp,3,else_like,0,64);
+ }
+ else squash(pp,1,else_like,0,65);
+}
+
+@ @<Cases for |if_head|@>=
+if (cat1==stmt || cat1==exp) {
+ if (cat2==else_like) {
+ big_app(force); big_app1(pp); big_app(break_space); app(noop);
+ big_app(cancel); big_app1(pp+1); big_app(force); big_app1(pp+2);
+ if (cat3==if_like) {
+ big_app(' '); big_app1(pp+3); reduce(pp,4,if_like,0,66);
+ }@+else reduce(pp,3,else_like,0,67);
+ }
+ else squash(pp,1,else_head,0,68);
+}
+
+@ @<Cases for |do_like|@>=
+if (cat1==stmt && cat2==else_like && cat3==semi) {
+ big_app1(pp); big_app(break_space); app(noop); big_app(cancel);
+ big_app1(pp+1); big_app(cancel); app(noop); big_app(break_space);
+ big_app2(pp+2); reduce(pp,4,stmt,-1,69);
+}
+
+@ @<Cases for |case_like|@>=
+if (cat1==semi) squash(pp,2,stmt,-1,70);
+else if (cat1==colon) squash(pp,2,tag,-1,71);
+else if (cat1==exp) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,72);
+}
+
+@ @<Cases for |catch_like|@>=
+if (cat1==cast || cat1==exp) {
+ big_app2(pp); big_app(indent); big_app(indent); reduce(pp,2,fn_decl,0,73);
+}
+
+@ @<Cases for |tag|@>=
+if (cat1==tag) {
+ big_app1(pp); big_app(break_space); big_app1(pp+1); reduce(pp,2,tag,-1,74);
+}
+else if (cat1==stmt||cat1==decl||cat1==function) {
+ big_app(force); big_app(backup); big_app1(pp); big_app(break_space);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,75);
+}
+
+@ The user can decide at run-time whether short statements should be
+grouped together on the same line.
+
+@d force_lines flags['f'] /* should each statement be on its own line? */
+
+@<Set init...@>=
+force_lines=true;
+
+@ @<Cases for |stmt|@>=
+if (cat1==stmt||cat1==decl||cat1==function) {
+ big_app1(pp);
+ if (cat1==function) big_app(big_force);
+ else if (cat1==decl) big_app(big_force);
+ else if (force_lines) big_app(force);
+ else big_app(break_space);
+ big_app1(pp+1); reduce(pp,2,cat1,-1,76);
+}
+
+@ @<Cases for |semi|@>=
+big_app(' '); big_app1(pp); reduce(pp,1,stmt,-1,77);
+
+@ @<Cases for |lproc|@>=
+if (cat1==define_like) make_underlined(pp+2);
+if (cat1==else_like || cat1==if_like ||cat1==define_like)
+ squash(pp,2,lproc,0,78);
+else if (cat1==rproc) {
+ app(inserted); big_app2(pp); reduce(pp,2,insert,-1,79);
+} else if (cat1==exp || cat1==function) {
+ if (cat2==rproc) {
+ app(inserted); big_app1(pp); big_app(' '); big_app2(pp+1);
+ reduce(pp,3,insert,-1,80);
+ }
+ else if (cat2==exp && cat3==rproc && cat1==exp) {
+ app(inserted); big_app1(pp); big_app(' '); big_app1(pp+1); app_str(" \\5");
+@.\\5@>
+ big_app2(pp+2); reduce(pp,4,insert,-1,80);
+ }
+}
+
+@ @<Cases for |section_scrap|@>=
+if (cat1==semi) {
+ big_app2(pp); big_app(force); reduce(pp,2,stmt,-2,81);
+}
+else squash(pp,1,exp,-2,82);
+
+@ @<Cases for |insert|@>=
+if (cat1)
+ squash(pp,2,cat1,0,83);
+
+@ @<Cases for |prelangle|@>=
+init_mathness=cur_mathness=yes_math;
+app('<'); reduce(pp,1,binop,-2,84);
+
+@ @<Cases for |prerangle|@>=
+init_mathness=cur_mathness=yes_math;
+app('>'); reduce(pp,1,binop,-2,85);
+
+@ @<Cases for |langle|@>=
+if (cat1==prerangle) {
+ big_app1(pp); app('\\'); app(','); big_app1(pp+1);
+@.\\,@>
+ reduce(pp,2,cast,-1,86);
+}
+else if (cat1==decl_head || cat1==int_like || cat1==exp) {
+ if (cat2==prerangle) squash(pp,3,cast,-1,87);
+ else if (cat2==comma) {
+ big_app3(pp); app(opt); app('9'); reduce(pp,3,langle,0,88);
+ }
+}
+
+@ @<Cases for |template_like|@>=
+if (cat1==exp && cat2==prelangle) squash(pp+2,1,langle,2,89);
+else if (cat1==exp || cat1==raw_int) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,cat1,-2,90);
+}@+ else squash(pp,1,raw_int,0,91);
+
+@ @<Cases for |new_like|@>=
+if (cat1==lpar && cat2==exp && cat3==rpar) squash(pp,4,new_like,0,92);
+else if (cat1==cast) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,93);
+}
+else if (cat1!=lpar) squash(pp,1,new_exp,0,94);
+
+@ @<Cases for |new_exp|@>=
+if (cat1==int_like || cat1==const_like) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,new_exp,0,95);
+}
+else if (cat1==struct_like && (cat2==exp || cat2==int_like)) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); big_app(' ');
+ big_app1(pp+2); reduce(pp,3,new_exp,0,96);
+}
+else if (cat1==raw_ubin) {
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,new_exp,0,97);
+}
+else if (cat1==lpar) squash(pp,1,exp,-2,98);
+else if (cat1==exp) {
+ big_app1(pp); big_app(' '); reduce(pp,1,exp,-2,98);
+}
+else if (cat1!=raw_int && cat1!=struct_like && cat1!=colcol)
+ squash(pp,1,exp,-2,99);
+
+@ @<Cases for |ftemplate|@>=
+if (cat1==prelangle) squash(pp+1,1,langle,1,100);
+else squash(pp,1,exp,-2,101);
+
+@ @<Cases for |for_like|@>=
+if (cat1==exp) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,else_like,-2,102);
+}
+
+@ @<Cases for |raw_ubin|@>=
+if (cat1==const_like) {
+ big_app2(pp); app_str("\\ "); reduce(pp,2,raw_ubin,0,103);
+@.\\\ @>
+} else squash(pp,1,ubinop,-2,104);
+
+@ @<Cases for |const_like|@>=
+squash(pp,1,int_like,-2,105);
+
+@ @<Cases for |raw_int|@>=
+if (cat1==prelangle) squash(pp+1,1,langle,1,106);
+else if (cat1==colcol) squash(pp,2,colcol,-1,107);
+else if (cat1==cast) squash(pp,2,raw_int,0,108);
+else if (cat1==lpar) squash(pp,1,exp,-2,109);
+else if (cat1!=langle) squash(pp,1,int_like,-3,110);
+
+@ @<Cases for |operator_like|@>=
+if (cat1==binop || cat1==unop || cat1==ubinop) {
+ if (cat2==binop) break;
+ big_app1(pp); big_app('{'); big_app1(pp+1); big_app('}');
+ reduce(pp,2,exp,-2,111);
+}
+else if (cat1==new_like || cat1==delete_like) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,112);
+}
+else if (cat1==comma) squash(pp,2,exp,-2,113);
+else if (cat1!=raw_ubin) squash(pp,1,new_exp,0,114);
+
+@ @<Cases for |typedef_like|@>=
+if ((cat1==int_like || cat1==cast) && (cat2==comma || cat2==semi))
+ squash(pp+1,1,exp,-1,115);
+else if (cat1==int_like) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,typedef_like,0,116);
+}
+else if (cat1==exp && cat2!=lpar && cat2!=exp && cat2!=cast) {
+ make_underlined(pp+1); make_reserved(pp+1);
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,typedef_like,0,117);
+}
+else if (cat1==comma) {
+ big_app2(pp); big_app(' '); reduce(pp,2,typedef_like,0,118);
+}
+else if (cat1==semi) squash(pp,2,decl,-1,119);
+else if (cat1==ubinop && (cat2==ubinop || cat2==cast)) {
+ big_app('{'); big_app1(pp+1); big_app('}'); big_app1(pp+2);
+ reduce(pp+1,2,cat2,0,120);
+}
+
+@ @<Cases for |delete_like|@>=
+if (cat1==lpar && cat2==rpar) {
+ big_app2(pp); app('\\'); app(','); big_app1(pp+2);
+@.\\,@>
+ reduce(pp,3,delete_like,0,121);
+}
+else if (cat1==exp) {
+ big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,exp,-2,122);
+}
+
+@ @<Cases for |question|@>=
+if (cat1==exp && (cat2==colon || cat2==base)) {
+ (pp+2)->mathness=5*yes_math; /* this colon should be in math mode */
+ squash(pp,3,binop,-2,123);
+}
+
+@ Now here's the |reduce| procedure used in our code for productions.
+
+The `|freeze_text|' macro is used to give official status to a token list.
+Before saying |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 |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 |tok_start| array. After saying |freeze_text|, the
+old current token list becomes legitimate, and its number is the current
+value of |text_ptr-1| since |text_ptr| has been increased. The new
+current token list is empty and ready to be appended to.
+Note that |freeze_text| does not check to see that |text_ptr| hasn't gotten
+too large, since it is assumed that this test was done beforehand.
+
+@d freeze_text *(++text_ptr)=tok_ptr
+
+@<Predecl...@>=
+static void reduce(scrap_pointer,short,eight_bits,short,short);@/
+static void squash(scrap_pointer,short,eight_bits,short,short);
+
+@ @c
+static void
+reduce(
+scrap_pointer j, short k,
+eight_bits c,
+short d, short n)
+{
+ scrap_pointer i, i1; /* pointers into scrap memory */
+ j->cat=c; j->trans=text_ptr;
+ j->mathness=4*cur_mathness+init_mathness;
+ freeze_text;
+ if (k>1) {
+ for (i=j+k, i1=j+1; i<=lo_ptr; i++, i1++) {
+ i1->cat=i->cat; i1->trans=i->trans;
+ i1->mathness=i->mathness;
+ }
+ lo_ptr=lo_ptr-k+1;
+ }
+ pp=(pp+d<scrap_base? scrap_base: pp+d);
+ @<Print a snapshot of the scrap list if debugging @>@;
+ pp--; /* we next say |pp++| */
+}
+
+@ Here's the |squash| procedure, which
+takes advantage of the simplification that occurs when |k==1|.
+
+@c
+static void
+squash(
+scrap_pointer j, short k,
+eight_bits c,
+short d, short n)
+{
+ scrap_pointer i; /* pointers into scrap memory */
+ if (k==1) {
+ j->cat=c; pp=(pp+d<scrap_base? scrap_base: pp+d);
+ @<Print a snapshot...@>@;
+ pp--; /* we next say |pp++| */
+ return;
+ }
+ for (i=j; i<j+k; i++) big_app1(i);
+ reduce(j,k,c,d,n);
+}
+
+@ And 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.
+
+@d safe_tok_incr 20
+@d safe_text_incr 10
+@d safe_scrap_incr 10
+
+@<Reduce the scraps using the productions until no more rules apply@>=
+while (true) {
+ @<Make sure the entries |pp| through |pp+3| of |cat| are defined@>@;
+ if (tok_ptr+safe_tok_incr>tok_mem_end) {
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ overflow("token");
+ }
+ if (text_ptr+safe_text_incr>tok_start_end) {
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+ overflow("text");
+ }
+ if (pp>lo_ptr) break;
+ init_mathness=cur_mathness=maybe_math;
+ @<Match a production...@>@;
+}
+
+@ 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.
+
+@<Make sure the entries...@>=
+if (lo_ptr<pp+3) {
+ while (hi_ptr<=scrap_ptr && lo_ptr!=pp+3) {
+ (++lo_ptr)->cat=hi_ptr->cat; lo_ptr->mathness=(hi_ptr)->mathness;
+ lo_ptr->trans=(hi_ptr++)->trans;
+ }
+ for (i=lo_ptr+1;i<=pp+3;i++) i->cat=0;
+}
+
+@ If \.{CWEAVE} is being run in debugging mode, the production numbers and
+current stack categories will be printed out when |tracing| is set to 2;
+a sequence of two or more irreducible scraps will be printed out when
+|tracing| is set to 1.
+
+@<Private...@>=
+static int tracing; /* can be used to show parsing details */
+
+@ @<Print a snapsh...@>=
+{ scrap_pointer k_l; /* pointer into |scrap_info| */
+ if (tracing==2) {
+ printf("\n%d:",n);
+ for (k_l=scrap_base; k_l<=lo_ptr; k_l++) {
+ if (k_l==pp) putxchar('*'); else putxchar(' ');
+ if (k_l->mathness %4 == yes_math) putchar('+');
+ else if (k_l->mathness %4 == no_math) putchar('-');
+ print_cat(k_l->cat);
+ if (k_l->mathness /4 == yes_math) putchar('+');
+ else if (k_l->mathness /4 == no_math) putchar('-');
+ }
+ if (hi_ptr<=scrap_ptr) fputs("...",stdout); /* indicate that more is coming */
+ }
+}
+
+@ The |translate| function assumes that scraps have been stored in
+positions |scrap_base| through |scrap_ptr| of |cat| and |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 |translate|, we will have |text_ptr+3<=max_texts| and
+|tok_ptr+6<=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
+|translate|, we should have |text_ptr<max_texts| and |scrap_ptr<max_scraps|,
+since |translate| might add a new text and a new scrap before it checks
+for overflow.
+
+@c
+static text_pointer
+translate(void) /* converts a sequence of scraps */
+{
+ scrap_pointer i, /* index into |cat| */
+ j; /* runs through final scraps */
+ pp=scrap_base; lo_ptr=pp-1; hi_ptr=pp;
+ @<If tracing, print an indication of where we are@>@;
+ @<Reduce the scraps...@>@;
+ @<Combine the irreducible scraps that remain@>@;
+}
+
+@ @<Predecl...@>=@+static text_pointer translate(void);
+
+@ 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.
+
+@<Combine the irreducible...@>= {
+ @<If semi-tracing, show the irreducible scraps@>@;
+ for (j=scrap_base; j<=lo_ptr; j++) {
+ if (j!=scrap_base) app(' ');
+ if (j->mathness % 4 == yes_math) app('$');
+ app1(j);
+ if (j->mathness / 4 == yes_math) app('$');
+ if (tok_ptr+6>tok_mem_end) overflow("token");
+ }
+ freeze_text; return text_ptr-1;
+}
+
+@ @<If semi-tracing, show the irreducible scraps@>=
+if (lo_ptr>scrap_base && tracing==1) {
+ printf("\nIrreducible scrap sequence in section %d:",section_count);
+@.Irreducible scrap sequence...@>
+ mark_harmless;
+ for (j=scrap_base; j<=lo_ptr; j++) {
+ printf(" "); print_cat(j->cat);
+ }
+}
+
+@ @<If tracing,...@>=
+if (tracing==2) {
+ printf("\nTracing after l. %d:\n",cur_line); mark_harmless;
+@.Tracing after...@>
+ if (loc>buffer+50) {
+ printf("...");
+ term_write(loc-51,51);
+ }
+ else term_write(buffer,loc-buffer);
+}
+
+@* 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 |C_parse| that is analogous to the
+|C_xref| routine used during phase one.
+
+Like |C_xref|, the |C_parse| procedure starts with the current
+value of |next_control| and it uses the operation |next_control=get_next()|
+repeatedly to read \CEE/ text until encountering the next `\.{\v}' or
+`\.{/*}', or until |next_control>=format_code|. The scraps corresponding to
+what it reads are appended into the |cat| and |trans| arrays, and |scrap_ptr|
+is advanced.
+
+@c
+static void
+C_parse(@t\1\1@> /* creates scraps from \CEE/ tokens */
+ eight_bits spec_ctrl@t\2\2@>)
+{
+ int count; /* characters remaining before string break */
+ while (next_control<format_code || next_control==spec_ctrl) {
+ @<Append the scrap appropriate to |next_control|@>@;
+ next_control=get_next();
+ if (next_control=='|' || next_control==begin_comment ||
+ next_control==begin_short_comment) return;
+ }
+}
+
+@ @<Predecl...@>=@+static void C_parse(eight_bits);
+
+@ The following macro is used to append a scrap whose tokens have just
+been appended:
+
+@d app_scrap(c,b) {
+ (++scrap_ptr)->cat=(c); scrap_ptr->trans=text_ptr;
+ scrap_ptr->mathness=5*(b); /* no no, yes yes, or maybe maybe */
+ freeze_text;
+}
+
+@ @<Append the scr...@>=
+@<Make sure that there is room for the new scraps, tokens, and texts@>@;
+switch (next_control) {
+ case section_name:
+ app(section_flag+(int)(cur_section-name_dir));
+ app_scrap(section_scrap,maybe_math);
+ app_scrap(exp,yes_math);@+break;
+ case string: case constant: case verbatim:
+ @<Append a string or constant@>@;@+break;
+ case identifier: app_cur_id(true);@+break;
+ case TeX_string:
+ @<Append a \TEX/ string, without forming a scrap@>@;@+break;
+ case '/': case '.':
+ app(next_control);@+app_scrap(binop,yes_math);@+break;
+ case '<': app_str("\\langle");@+app_scrap(prelangle,yes_math);@+break;
+@.\\langle@>
+ case '>': app_str("\\rangle");@+app_scrap(prerangle,yes_math);@+break;
+@.\\rangle@>
+ case '=': app_str("\\K");@+app_scrap(binop,yes_math);@+break;
+@.\\K@>
+ case '|': app_str("\\OR");@+app_scrap(binop,yes_math);@+break;
+@.\\OR@>
+ case '^': app_str("\\XOR");@+app_scrap(binop,yes_math);@+break;
+@.\\XOR@>
+ case '%': app_str("\\MOD");@+app_scrap(binop,yes_math);@+break;
+@.\\MOD@>
+ case '!': app_str("\\R");@+app_scrap(unop,yes_math);@+break;
+@.\\R@>
+ case '~': app_str("\\CM");@+app_scrap(unop,yes_math);@+break;
+@.\\CM@>
+ case '+': case '-': app(next_control);@+app_scrap(ubinop,yes_math);@+break;
+ case '*': app(next_control);@+app_scrap(raw_ubin,yes_math);@+break;
+ case '&': app_str("\\AND");@+app_scrap(raw_ubin,yes_math);@+break;
+@.\\AND@>
+ case '?': app_str("\\?");@+app_scrap(question,yes_math);@+break;
+@.\\?@>
+ case '#': app_str("\\#");@+app_scrap(ubinop,yes_math);@+break;
+@.\\\#@>
+ case ignore: case xref_roman: case xref_wildcard:
+ case xref_typewriter: case noop:@+break;
+ case '(': case '[': app(next_control);@+app_scrap(lpar,maybe_math);@+break;
+ case ')': case ']': app(next_control);@+app_scrap(rpar,maybe_math);@+break;
+ case '{': app_str("\\{"@q}@>);@+app_scrap(lbrace,yes_math);@+break;
+@.\\\{@>@q}@>
+ case '}': app_str(@q{@>"\\}");@+app_scrap(rbrace,yes_math);@+break;
+@q{@>@.\\\}@>
+ case ',': app(',');@+app_scrap(comma,yes_math);@+break;
+ case ';': app(';');@+app_scrap(semi,maybe_math);@+break;
+ case ':': app(':');@+app_scrap(colon,no_math);@+break;@/
+ @t\4@> @<Cases involving nonstandard characters@>@;
+ case thin_space: app_str("\\,");@+app_scrap(insert,maybe_math);@+break;
+@.\\,@>
+ case math_break: app(opt);@+app_str("0");@+
+ app_scrap(insert,maybe_math);@+break;
+ case line_break: app(force);@+app_scrap(insert,no_math);@+break;
+ case left_preproc: app(force);@+app(preproc_line);@+app_str("\\#");
+ app_scrap(lproc,no_math);@+break;
+@.\\\#@>
+ case right_preproc: app(force);@+app_scrap(rproc,no_math);@+break;
+ case big_line_break: app(big_force);@+app_scrap(insert,no_math);@+break;
+ case no_line_break: app(big_cancel);@+app(noop);@+app(break_space);@+
+ app(noop);@+app(big_cancel);
+ app_scrap(insert,no_math);@+break;
+ case pseudo_semi: app_scrap(semi,maybe_math);@+break;
+ case macro_arg_open: app_scrap(begin_arg,maybe_math);@+break;
+ case macro_arg_close: app_scrap(end_arg,maybe_math);@+break;
+ case join: app_str("\\J");@+app_scrap(insert,no_math);@+break;
+@.\\J@>
+ case output_defs_code: app(force);@+app_str("\\ATH");@+app(force);
+ app_scrap(insert,no_math);@+break;
+@.\\ATH@>
+ default: app(inserted);@+app(next_control);
+ app_scrap(insert,maybe_math);@+break;
+}
+
+@ @<Make sure that there is room for the new...@>=
+if (scrap_ptr+safe_scrap_incr>scrap_info_end ||
+ tok_ptr+safe_tok_incr>tok_mem_end @| ||
+ text_ptr+safe_text_incr>tok_start_end) {
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+ overflow("scrap/token/text");
+}
+
+@ 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 |char| codes.
+
+@<Cases involving nonstandard...@>=
+case non_eq: app_str("\\I");@+app_scrap(binop,yes_math);@+break;
+@.\\I@>
+case lt_eq: app_str("\\Z");@+app_scrap(binop,yes_math);@+break;
+@.\\Z@>
+case gt_eq: app_str("\\G");@+app_scrap(binop,yes_math);@+break;
+@.\\G@>
+case eq_eq: app_str("\\E");@+app_scrap(binop,yes_math);@+break;
+@.\\E@>
+case and_and: app_str("\\W");@+app_scrap(binop,yes_math);@+break;
+@.\\W@>
+case or_or: app_str("\\V");@+app_scrap(binop,yes_math);@+break;
+@.\\V@>
+case plus_plus: app_str("\\PP");@+app_scrap(unop,yes_math);@+break;
+@.\\PP@>
+case minus_minus: app_str("\\MM");@+app_scrap(unop,yes_math);@+break;
+@.\\MM@>
+case minus_gt: app_str("\\MG");@+app_scrap(binop,yes_math);@+break;
+@.\\MG@>
+case gt_gt: app_str("\\GG");@+app_scrap(binop,yes_math);@+break;
+@.\\GG@>
+case lt_lt: app_str("\\LL");@+app_scrap(binop,yes_math);@+break;
+@.\\LL@>
+case dot_dot_dot: app_str("\\,\\ldots\\,");@+app_scrap(raw_int,yes_math);
+ @+break;
+@.\\,@>
+@.\\ldots@>
+case colon_colon: app_str("\\DC");@+app_scrap(colcol,maybe_math);@+break;
+@.\\DC@>
+case period_ast: app_str("\\PA");@+app_scrap(binop,yes_math);@+break;
+@.\\PA@>
+case minus_gt_ast: app_str("\\MGA");@+app_scrap(binop,yes_math);@+break;
+@.\\MGA@>
+
+@ The following code must use |app_tok| instead of |app| in order to
+protect against overflow. Note that |tok_ptr+1<=max_toks| after |app_tok|
+has been used, so another |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.
+@^special string characters@>
+
+@<Append a string or...@>=
+count= -1;
+if (next_control==constant) app_str("\\T{"@q}@>);
+@.\\T@>
+else if (next_control==string) {
+ count=20; app_str("\\.{"@q}@>);
+}
+@.\\.@>
+else app_str("\\vb{"@q}@>);
+@.\\vb@>
+while (id_first<id_loc) {
+ if (count==0) { /* insert a discretionary break in a long string */
+ app_str(@q(@>@q{@>"}\\)\\.{"@q}@>); count=20;
+@q(@>@.\\)@>
+ }
+@^high-bit character handling@>
+ if((eight_bits)(*id_first)>0177) {
+ app_tok(quoted_char);
+ app_tok((eight_bits)(*id_first++));
+ }
+ else {
+ switch (*id_first) {
+ case ' ':case '\\':case '#':case '%':case '$':case '^':
+ case '{': case '}': case '~': case '&': case '_': app('\\'); break;
+@.\\\ @>
+@.\\\\@>
+@.\\\#@>
+@.\\\%@>
+@.\\\$@>
+@.\\\^@>
+@.\\\{@>@q}@>
+@q{@>@.\\\}@>
+@.\\\~@>
+@.\\\&@>
+@.\\\_@>
+ case '@@': if (*(id_first+1)=='@@') id_first++;
+ else err_print("! Double @@ should be used in strings");
+@.Double @@ should be used...@>
+ }
+ app_tok(*id_first++);
+ }
+ count--;
+}
+app(@q{@>'}');
+app_scrap(exp,maybe_math);
+
+@ 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 |finish_C| is called.
+
+There's a known bug here, in cases where an adjacent scrap is
+|prelangle| or |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 |insert| scrap, which is combined
+with a |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.
+@^bug, known@>
+
+@<Append a \TEX/ string, without forming a scrap@>=
+app_str("\\hbox{"@q}@>);
+@^high-bit character handling@>
+while (id_first<id_loc)
+ if((eight_bits)(*id_first)>0177) {
+ app_tok(quoted_char);
+ app_tok((eight_bits)(*id_first++));
+ }
+ else {
+ if (*id_first=='@@') id_first++;
+ app_tok(*id_first++);
+ }
+app(@q{@>'}');
+
+@ The function |app_cur_id| appends the current identifier to the
+token list; it also builds a new scrap if |scrapping==true|.
+
+@<Predec...@>=
+static void app_cur_id(boolean);@/
+static text_pointer C_translate(void);@/
+static void outer_parse(void);
+
+@ @c
+static void
+app_cur_id(@t\1\1@>
+boolean scrapping@t\2\2@>) /* are we making this into a scrap? */
+{
+ name_pointer p=id_lookup(id_first,id_loc,normal);
+ if (p->ilk<=custom) { /* not a reserved word */
+ app(id_flag+(int)(p-name_dir));
+ if (scrapping) app_scrap(p->ilk==func_template? ftemplate: exp,
+ p->ilk==custom? yes_math: maybe_math);
+@.\\NULL@>
+ } else {
+ app(res_flag+(int)(p-name_dir));
+ if (scrapping) {
+ if (p->ilk==alfop) app_scrap(ubinop,yes_math)@;
+ else app_scrap(p->ilk,maybe_math);
+ }
+ }
+}
+
+@ When the `\.{\v}' that introduces \CEE/ text is sensed, a call on
+|C_translate| will return a pointer to the \TEX/ translation of
+that text. If scraps exist in |scrap_info|, they are
+unaffected by this translation process.
+
+@c
+static text_pointer
+C_translate(void)
+{
+ text_pointer p; /* points to the translation */
+ scrap_pointer save_base; /* holds original value of |scrap_base| */
+ save_base=scrap_base; scrap_base=scrap_ptr+1;
+ C_parse(section_name); /* get the scraps together */
+ if (next_control!='|') err_print("! Missing '|' after C text");
+@.Missing '|'...@>
+ app_tok(cancel); app_scrap(insert,maybe_math);
+ /* place a |cancel| token as a final ``comment'' */
+ p=translate(); /* make the translation */
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+ scrap_ptr=scrap_base-1; scrap_base=save_base; /* scrap the scraps */
+ return p;
+}
+
+@ The |outer_parse| routine is to |C_parse| as |outer_xref|
+is to |C_xref|: It constructs a sequence of scraps for \CEE/ text
+until |next_control>=format_code|. Thus, it takes care of embedded comments.
+
+The token list created from within `\pb' brackets is output as an argument
+to \.{\\PB}, if the user has invoked \.{CWEAVE} with the \.{+e} flag.
+Although \.{cwebmac} ignores \.{\\PB}, other macro packages
+might use it to localize the special meaning of the macros that mark up
+program text.
+
+@d make_pb flags['e']
+
+@<Set init...@>=
+make_pb=true;
+
+@ @c
+static void
+outer_parse(void) /* makes scraps from \CEE/ tokens and comments */
+{
+ int bal; /* brace level in comment */
+ text_pointer p, q; /* partial comments */
+ while (next_control<format_code)
+ if (next_control!=begin_comment && next_control!=begin_short_comment)
+ C_parse(ignore);
+ else {
+ boolean is_long_comment=(next_control==begin_comment);
+ @<Make sure that there is room for the new...@>@;
+ app(cancel); app(inserted);
+ if (is_long_comment) app_str("\\C{"@q}@>);
+@.\\C@>
+ else app_str("\\SHC{"@q}@>);
+@.\\SHC@>
+ bal=copy_comment(is_long_comment,1); next_control=ignore;
+ while (bal>0) {
+ p=text_ptr; freeze_text; q=C_translate();
+ /* at this point we have |tok_ptr+6<=max_toks| */
+ app(tok_flag+(int)(p-tok_start));
+ if (make_pb) app_str("\\PB{");
+@.\\PB@>
+ app(inner_tok_flag+(int)(q-tok_start));
+ if (make_pb) app_tok('}');
+ if (next_control=='|') {
+ bal=copy_comment(is_long_comment,bal);
+ next_control=ignore;
+ }
+ else bal=0; /* an error has been reported */
+ }
+ app(force); app_scrap(insert,no_math);
+ /* the full comment becomes a scrap */
+ }
+}
+
+@* 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:
+|outer| mode, which translates tokens like |force| into line-breaking
+control sequences, and |inner| mode, which ignores them except that blank
+spaces take the place of line breaks. (b) The |cancel| instruction applies
+to adjacent token or tokens that are output, and this cuts across levels
+of recursion since `|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 |break_space| and
+|force|. (d) The final line break should be suppressed, and there should
+be no |force| token output immediately after `\.{\\Y\\B}'.
+
+@ 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 |end_field| is the |tok_mem| location where the token list of a
+particular level will end;
+
+\yskip\hang |tok_field| is the |tok_mem| location from which the next token
+on a particular level will be read;
+
+\yskip\hang |mode_field| is the current mode, either |inner| or |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
+|stack| array. We call the current values |cur_end|, |cur_tok|, and
+|cur_mode|.
+
+The global variable |stack_ptr| tells how many levels of output are
+currently in progress. The end of output occurs when an |end_translation|
+token is found, so the stack is never empty except when we first begin the
+output process.
+
+@d inner 0 /* value of |mode| for \CEE/ texts within \TEX/ texts */
+@d outer 1 /* value of |mode| for \CEE/ texts in sections */
+
+@<Typed...@>= typedef int mode;
+typedef struct {
+ token_pointer end_field; /* ending location of token list */
+ token_pointer tok_field; /* present location within token list */
+ boolean mode_field; /* interpretation of control tokens */
+} output_state;
+typedef output_state *stack_pointer;
+
+@ @d cur_end cur_state.end_field /* current ending location in |tok_mem| */
+@d cur_tok cur_state.tok_field /* location of next output token in |tok_mem| */
+@d cur_mode cur_state.mode_field /* current mode of interpretation */
+@d init_stack stack_ptr=stack;cur_mode=outer /* initialize the stack */
+
+@<Private...@>=
+static output_state cur_state; /* |cur_end|, |cur_tok|, |cur_mode| */
+static output_state stack[stack_size]; /* info for non-current levels */
+static stack_pointer stack_end=stack+stack_size-1; /* end of |stack| */
+static stack_pointer stack_ptr; /* first unused location in the output state stack */
+static stack_pointer max_stack_ptr; /* largest value assumed by |stack_ptr| */
+
+@ @<Set init...@>=
+max_stack_ptr=stack;
+
+@ To insert token-list |p| into the output, the |push_level| subroutine
+is called; it saves the old level of output and gets a new one going.
+The value of |cur_mode| is not changed.
+
+@<Predecl...@>=
+static void push_level(text_pointer);@/
+static void pop_level(void);
+
+@ @c
+static void
+push_level(@t\1\1@> /* suspends the current level */
+text_pointer p@t\2\2@>)
+{
+ if (stack_ptr==stack_end) overflow("stack");
+ if (stack_ptr>stack) { /* save current state */
+ stack_ptr->end_field=cur_end;
+ stack_ptr->tok_field=cur_tok;
+ stack_ptr->mode_field=cur_mode;
+ }
+ stack_ptr++;
+ if (stack_ptr>max_stack_ptr) max_stack_ptr=stack_ptr;
+ cur_tok=*p; cur_end=*(p+1);
+}
+
+@ Conversely, the |pop_level| routine restores the conditions that were in
+force when the current level was begun. This subroutine will never be
+called when |stack_ptr==1|.
+
+@c
+static void
+pop_level(void)
+{
+ cur_end=(--stack_ptr)->end_field;
+ cur_tok=stack_ptr->tok_field; cur_mode=stack_ptr->mode_field;
+}
+
+@ The |get_output| function returns the next byte of output that is not a
+reference to a token list. It returns the values |identifier| or |res_word|
+or |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 |cur_name| points to the identifier or section name in
+question.
+
+@<Private...@>=
+static name_pointer cur_name;
+
+@ @d res_word 0201 /* returned by |get_output| for reserved words */
+@d section_code 0200 /* returned by |get_output| for section names */
+
+@<Predecl...@>=
+static eight_bits get_output(void);@/
+static void output_C(void);@/
+static void make_output(void);
+
+@ @c
+static eight_bits
+get_output(void) /* returns the next token of output */
+{
+ sixteen_bits a; /* current item read from |tok_mem| */
+ restart: while (cur_tok==cur_end) pop_level();
+ a=*(cur_tok++);
+ if (a>=0400) {
+ cur_name=a % id_flag + name_dir;
+ switch (a / id_flag) {
+ case 2: return res_word ; /* |a==res_flag+cur_name| */
+ case 3: return section_code ; /* |a==section_flag+cur_name| */
+ case 4: push_level(a % id_flag + tok_start); goto restart;
+ /* |a==tok_flag+cur_name| */
+ case 5: push_level(a % id_flag + tok_start); cur_mode=inner; goto restart;
+ /* |a==inner_tok_flag+cur_name| */
+ default: return identifier; /* |a==id_flag+cur_name| */
+ }
+ }
+ return (eight_bits)a;
+}
+
+@ The real work associated with token output is done by |make_output|.
+This procedure appends an |end_translation| token to the current token list,
+and then it repeatedly calls |get_output| and feeds characters to the output
+buffer until reaching the |end_translation| sentinel. It is possible for
+|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 |output_C| does the scanning, translation, and
+output of \CEE/ text within `\pb' brackets, and this procedure uses
+|make_output| to output the current token list. Thus, the recursive call
+of |make_output| actually occurs when |make_output| calls |output_C|
+while outputting the name of a section.
+@^recursion@>
+
+@c
+static void
+output_C(void) /* outputs the current token list */
+{
+ token_pointer save_tok_ptr;
+ text_pointer save_text_ptr;
+ sixteen_bits save_next_control; /* values to be restored */
+ text_pointer p; /* translation of the \CEE/ text */
+ save_tok_ptr=tok_ptr; save_text_ptr=text_ptr;
+ save_next_control=next_control; next_control=ignore; p=C_translate();
+ app(inner_tok_flag+(int)(p-tok_start));
+ if (make_pb) {
+ out_str("\\PB{"); make_output(); out('}');
+@.\\PB@>
+ }@+else make_output(); /* output the list */
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ text_ptr=save_text_ptr; tok_ptr=save_tok_ptr; /* forget the tokens */
+ next_control=save_next_control; /* restore |next_control| to original state */
+}
+
+@ Here is \.{CWEAVE}'s major output handler.
+
+@c
+static void
+make_output(void) /* outputs the equivalents of tokens */
+{
+ eight_bits a=0, /* current output byte */
+ b; /* next output byte */
+ int c; /* count of |indent| and |outdent| tokens */
+ char scratch[longest_name+1]; /* scratch area for section names */
+ char *k, *k_limit; /* indices into |scratch| */
+ char *j; /* index into |buffer| */
+ char *p; /* index into |byte_mem| */
+ char delim; /* first and last character of string being copied */
+ char *save_loc, *save_limit; /* |loc| and |limit| to be restored */
+ name_pointer cur_section_name; /* name of section being output */
+ boolean save_mode; /* value of |cur_mode| before a sequence of breaks */
+ app(end_translation); /* append a sentinel */
+ freeze_text; push_level(text_ptr-1);
+ while (true) {
+ a=get_output();
+ reswitch: switch(a) {
+ case end_translation: return;
+ case identifier: case res_word: @<Output an identifier@>@; break;
+ case section_code: @<Output a section name@>@; break;
+ case math_rel: out_str("\\MRL{"@q}@>);
+@.\\MRL@>
+ case noop: case inserted: break;
+ case cancel: case big_cancel: c=0; b=a;
+ while (true) {
+ a=get_output();
+ if (a==inserted) continue;
+ if ((a<indent && !(b==big_cancel&&a==' ')) || a>big_force) break;
+ if (a==indent) c++; else if (a==outdent) c--;
+ else if (a==opt) a=get_output();
+ }
+ @<Output saved |indent| or |outdent| tokens@>@;
+ goto reswitch;
+ case indent: case outdent: case opt: case backup: case break_space:
+ case force: case big_force: case preproc_line: @<Output a control,
+ look ahead in case of line breaks, possibly |goto reswitch|@>@; break;
+ case quoted_char: out(*(cur_tok++));
+ case qualifier: break;
+ default: out(a); /* otherwise |a| is an ordinary character */
+ }
+ }
+}
+
+@ 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\}}'.
+
+@<Output an identifier@>=
+out('\\');
+if (a==identifier) {
+ if (cur_name->ilk==custom && !doing_format) {
+ custom_out:
+ for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++)
+ out(*p=='_'? 'x': *p=='$'? 'X': *p);
+ break;
+ } else if (is_tiny(cur_name)) out('|')@;
+@.\\|@>
+ else { delim='.';
+ for (p=cur_name->byte_start;p<(cur_name+1)->byte_start;p++)
+ if (xislower(*p)) { /* not entirely uppercase */
+ delim='\\'; break;
+ }
+ out(delim);
+ }
+@.\\\\@>
+@.\\.@>
+}@+else if (cur_name->ilk==alfop) {
+ out('X');
+ goto custom_out;
+}@+else out('&'); /* |a==res_word| */
+@.\\\&@>
+if (is_tiny(cur_name)) {
+ if (isxalpha((cur_name->byte_start)[0]))
+ out('\\');
+ out((cur_name->byte_start)[0]);
+}
+else out_name(cur_name,true);
+
+@ The current mode does not affect the behavior of \.{CWEAVE}'s output routine
+except when we are outputting control tokens.
+
+@<Output a control...@>=
+if (a<break_space || a==preproc_line) {
+ if (cur_mode==outer) {
+ out('\\'); out(a-cancel+'0');
+@.\\1@>
+@.\\2@>
+@.\\3@>
+@.\\4@>
+@.\\8@>
+ if (a==opt) {
+ b=get_output(); /* |opt| is followed by a digit */
+ if (b!='0' || force_lines==false) out(b)@;
+ else out_str("{-1}"); /* |force_lines| encourages more \.{@@\v} breaks */
+ }
+ } else if (a==opt) b=get_output(); /* ignore digit following |opt| */
+ }
+else @<Look ahead for strongest line break, |goto reswitch|@>
+
+@ If several of the tokens |break_space|, |force|, |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}').
+
+@<Look ahead for st...@>= {
+ b=a; save_mode=cur_mode; c=0;
+ while (true) {
+ a=get_output();
+ if (a==inserted) continue;
+ if (a==cancel || a==big_cancel) {
+ @<Output saved |indent| or |outdent| tokens@>@;
+ goto reswitch; /* |cancel| overrides everything */
+ }
+ if ((a!=' ' && a<indent) || a==backup || a>big_force) {
+ if (save_mode==outer) {
+ if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\B",4)==0)
+ goto reswitch;
+ @<Output saved |indent| or |outdent| tokens@>@;
+ out('\\'); out(b-cancel+'0');
+@.\\5@>
+@.\\6@>
+@.\\7@>
+ if (a!=end_translation) finish_line();
+ }
+ else if (a!=end_translation && cur_mode==inner) out(' ');
+ goto reswitch;
+ }
+ if (a==indent) c++;
+ else if (a==outdent) c--;
+ else if (a==opt) a=get_output();
+ else if (a>b) b=a; /* if |a==' '| we have |a<b| */
+ }
+}
+
+@ @<Output saved...@>=
+ for (;c>0;c--) out_str("\\1");
+@.\\1@>
+ for (;c<0;c++) out_str("\\2");
+@.\\2@>
+
+@ The remaining part of |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
+|tok_mem| area.
+
+@<Output a section name@>= {
+ out_str("\\X");
+@.\\X@>
+ cur_xref=(xref_pointer)cur_name->xref;
+ if (cur_xref->num==file_flag) {an_output=true; cur_xref=cur_xref->xlink;}
+ else an_output=false;
+ if (cur_xref->num>=def_flag) {
+ out_section(cur_xref->num-def_flag);
+ if (phase==3) {
+ cur_xref=cur_xref->xlink;
+ while (cur_xref->num>=def_flag) {
+ out_str(", ");
+ out_section(cur_xref->num-def_flag);
+ cur_xref=cur_xref->xlink;
+ }
+ }
+ }
+ else out('0'); /* output the section number, or zero if it was undefined */
+ out(':');
+ if (an_output) out_str("\\.{"@q}@>);
+@.\\.@>
+ @<Output the text of the section name@>@;
+ if (an_output) out_str(@q{@>" }");
+ out_str("\\X");
+}
+
+@ @<Output the text...@>=
+sprint_section_name(scratch,cur_name);
+k=scratch;
+k_limit=scratch+strlen(scratch);
+cur_section_name=cur_name;
+while (k<k_limit) {
+ b=*(k++);
+ if (b=='@@') @<Skip next character, give error if not `\.{@@}'@>@;
+ if (an_output)
+ switch (b) {
+ case ' ':case '\\':case '#':case '%':case '$':case '^':
+ case '{': case '}': case '~': case '&': case '_':
+ out('\\'); /* falls through */
+@.\\\ @>
+@.\\\\@>
+@.\\\#@>
+@.\\\%@>
+@.\\\$@>
+@.\\\^@>
+@.\\\{@>@q}@>
+@q{@>@.\\\}@>
+@.\\\~@>
+@.\\\&@>
+@.\\\_@>
+ default: out(b);
+ }
+ else { if (b!='|') out(b)@;
+ else {
+ @<Copy the \CEE/ text into the |buffer| array@>@;
+ save_loc=loc; save_limit=limit; loc=limit+2; limit=j+1;
+ *limit='|'; output_C();
+ loc=save_loc; limit=save_limit;
+ } }
+}
+
+@ @<Skip next char...@>=
+if (*k++!='@@') {
+ fputs("\n! Illegal control code in section name: <",stdout);
+@.Illegal control code...@>
+ print_section_name(cur_section_name); printf("> "); mark_error;
+}
+
+@ 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 |delim| is zero outside of strings, otherwise it
+equals the delimiter that began the string being copied.
+
+@<Copy the \CEE/ text into...@>=
+j=limit+1; *j='|'; delim=0;
+while (true) {
+ if (k>=k_limit) {
+ fputs("\n! C text in section name didn't end: <",stdout);
+@.C text...didn't end@>
+ print_section_name(cur_section_name); printf("> "); mark_error; break;
+ }
+ b=*(k++);
+ if (b=='@@' || (b=='\\' && delim!=0))
+ @<Copy a quoted character into the buffer@>@;
+ else {
+ if (b=='\'' || b=='"') {
+ if (delim==0) delim=b;
+ else if (delim==b) delim=0; }
+ if (b!='|' || delim!=0) {
+ if (j>buffer+long_buf_size-3) overflow("buffer");
+ *(++j)=b;
+ }
+ else break;
+ }
+}
+
+@ @<Copy a quoted char...@>= {
+ if (j>buffer+long_buf_size-4) overflow("buffer");
+ *(++j)=b; *(++j)=*(k++);
+}
+
+@** 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.
+
+@c
+static void
+phase_two(void) {
+reset_input(); if (show_progress) fputs("\nWriting the output file...",stdout);
+@.Writing the output file...@>
+section_count=0; format_visible=true; copy_limbo();
+finish_line(); flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */
+while (!input_has_ended) @<Translate the current section@>@;
+}
+
+@ @<Predecl...@>=@+static void phase_two(void);
+
+@ 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 |out_line| or |out_ptr| will
+change if a section is non-null, so the following macros `|save_position|'
+and `|emit_space_if_needed|' are able to handle the situation:
+
+@d save_position save_line=out_line; save_place=out_ptr
+@d emit_space_if_needed if (save_line!=out_line || save_place!=out_ptr)
+ out_str("\\Y");
+ space_checked=true;
+@.\\Y@>
+
+@<Private...@>=
+static int save_line; /* former value of |out_line| */
+static char *save_place; /* former value of |out_ptr| */
+static int sec_depth; /* the integer, if any, following \.{@@*} */
+static boolean space_checked; /* have we done |emit_space_if_needed|? */
+static boolean format_visible; /* should the next format declaration be output? */
+static boolean doing_format=false; /* are we outputting a format declaration? */
+static boolean group_found=false; /* has a starred section occurred? */
+
+@ @<Translate the current section@>= {
+ section_count++;
+ @<Output the code for the beginning of a new section@>@;
+ save_position;
+ @<Translate the \TEX/ part of the current section@>@;
+ @<Translate the definition part of the current section@>@;
+ @<Translate the \CEE/ part of the current section@>@;
+ @<Show cross-references to this section@>@;
+ @<Output the code for the end of a section@>@;
+}
+
+@ 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.
+
+@<Output the code for the beginning...@>=
+if (*(loc-1)!='*') out_str("\\M");
+@.\\M@>
+else {
+ while (*loc == ' ') loc++;
+ if (*loc=='*') { /* ``top'' level */
+ sec_depth = -1;
+ loc++;
+ }
+ else {
+ for (sec_depth=0; xisdigit(*loc);loc++)
+ sec_depth = sec_depth*10 + (*loc) -'0';
+ }
+ while (*loc == ' ') loc++; /* remove spaces before group title */
+ group_found=true;
+ out_str("\\N");
+@.\\N@>
+ {@+ char s[32];@+sprintf(s,"{%d}",sec_depth+1);@+out_str(s);@+}
+ if (show_progress)
+ printf("*%d",section_count); update_terminal; /* print a progress report */
+}
+out_str("{");out_section(section_count); out_str("}");
+
+@ 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.
+
+@<Translate the \T...@>= do {
+ next_control=copy_TeX();
+ switch (next_control) {
+ case '|': init_stack; output_C(); break;
+ case '@@': out('@@'); break;
+ case TeX_string: case noop:
+ case xref_roman: case xref_wildcard: case xref_typewriter:
+ case section_name: loc-=2; next_control=get_next(); /* skip to \.{@@>} */
+ if (next_control==TeX_string)
+ err_print("! TeX string should be in C text only"); break;
+@.TeX string should be...@>
+ case thin_space: case math_break: case ord:
+ case line_break: case big_line_break: case no_line_break: case join:
+ case pseudo_semi: case macro_arg_open: case macro_arg_close:
+ case output_defs_code:
+ err_print("! You can't do that in TeX text"); break;
+@.You can't do that...@>
+ }
+} while (next_control<format_code);
+
+@ When we get to the following code we have |next_control>=format_code|, and
+the token memory is in its initial empty state.
+
+@<Translate the d...@>=
+space_checked=false;
+while (next_control<=definition) { /* |format_code| or |definition| */
+ init_stack;
+ if (next_control==definition) @<Start a macro definition@>@;
+ else @<Start a format definition@>@;
+ outer_parse(); finish_C(format_visible); format_visible=true;
+ doing_format=false;
+}
+
+@ The |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 |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 |force| and |big_force|). This \.{\\6} or
+\.{\\7} is replaced by the concluding \.{\\par} or by \.{\\Y\\par}.
+
+@c
+static void
+finish_C(@t\1\1@> /* finishes a definition or a \CEE/ part */
+ boolean visible@t\2\2@>) /* nonzero if we should produce \TeX\ output */
+{
+ text_pointer p; /* translation of the scraps */
+ if (visible) {
+ out_str("\\B"); app_tok(force); app_scrap(insert,no_math);
+ p=translate();
+@.\\B@>
+ app(tok_flag+(int)(p-tok_start)); make_output(); /* output the list */
+ if (out_ptr>out_buf+1) {
+ if (*(out_ptr-1)=='\\') {
+@.\\6@>
+@.\\7@>
+@.\\Y@>
+ if (*out_ptr=='6') out_ptr-=2;
+ else if (*out_ptr=='7') *out_ptr='Y';
+ }
+ }
+ out_str("\\par"); finish_line();
+ }
+ if (text_ptr>max_text_ptr) max_text_ptr=text_ptr;
+ if (tok_ptr>max_tok_ptr) max_tok_ptr=tok_ptr;
+ if (scrap_ptr>max_scr_ptr) max_scr_ptr=scrap_ptr;
+ tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info;
+ /* forget the tokens and the scraps */
+}
+
+@ @<Predecl...@>=@+static void finish_C(boolean);
+
+@ 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 `\.)'.
+
+@<Start a macro...@>= {
+ if (save_line!=out_line || save_place!=out_ptr || space_checked) app(backup);
+ if(!space_checked){emit_space_if_needed;save_position;}
+ app_str("\\D"); /* this will produce `\&{define }' */
+@.\\D@>
+ if ((next_control=get_next())!=identifier)
+ err_print("! Improper macro definition");
+@.Improper macro definition@>
+ else {
+ app('$'); app_cur_id(false);
+ if (*loc=='(')
+ reswitch: switch (next_control=get_next()) {
+ case '(': case ',': app(next_control); goto reswitch;
+ case identifier: app_cur_id(false); goto reswitch;
+ case ')': app(next_control); next_control=get_next(); break;
+ default: err_print("! Improper macro definition"); break;
+ }
+ else next_control=get_next();
+ app_str("$ "); app(break_space);
+ app_scrap(dead,no_math); /* scrap won't take part in the parsing */
+ }
+}
+
+@ @<Start a format...@>= {
+ doing_format=true;
+ if(*(loc-1)=='s' || *(loc-1)=='S') format_visible=false;
+ if(!space_checked){emit_space_if_needed;save_position;}
+ app_str("\\F"); /* this will produce `\&{format }' */
+@.\\F@>
+ next_control=get_next();
+ if (next_control==identifier) {
+ app(id_flag+(int)(id_lookup(id_first, id_loc,normal)-name_dir));
+ app(' ');
+ app(break_space); /* this is syntactically separate from what follows */
+ next_control=get_next();
+ if (next_control==identifier) {
+ app(id_flag+(int)(id_lookup(id_first, id_loc,normal)-name_dir));
+ app_scrap(exp,maybe_math); app_scrap(semi,maybe_math);
+ next_control=get_next();
+ }
+ }
+ if (scrap_ptr!=scrap_info+2) err_print("! Improper format definition");
+@.Improper format definition@>
+}
+
+@ Finally, when the \TEX/ and definition parts have been treated, we have
+|next_control>=begin_C|. We will make the global variable |this_section|
+point to the current section name, if it has a name.
+
+@<Private...@>=
+static name_pointer this_section; /* the current section name, or zero */
+
+@ @<Translate the \CEE/...@>=
+this_section=name_dir;
+if (next_control<=section_name) {
+ emit_space_if_needed; init_stack;
+ if (next_control==begin_C) next_control=get_next();
+ else {
+ this_section=cur_section;
+ @<Check that '=' or '==' follows this section name, and
+ emit the scraps to start the section definition@>@;
+ }
+ while (next_control<=section_name) {
+ outer_parse();
+ @<Emit the scrap for a section name if present@>@;
+ }
+ finish_C(true);
+}
+
+@ The title of the section and an $\E$ or $\mathrel+\E$ are made
+into a scrap that should not take part in the parsing.
+
+@<Check that '='...@>=
+do next_control=get_next();
+ while (next_control=='+'); /* allow optional `\.{+=}' */
+if (next_control!='=' && next_control!=eq_eq)
+ err_print("! You need an = sign after the section name");
+@.You need an = sign...@>
+ else next_control=get_next();
+if (out_ptr>out_buf+1 && *out_ptr=='Y' && *(out_ptr-1)=='\\') app(backup);
+ /* the section name will be flush left */
+@.\\Y@>
+app(section_flag+(int)(this_section-name_dir));
+cur_xref=(xref_pointer)this_section->xref;
+if(cur_xref->num==file_flag) cur_xref=cur_xref->xlink;
+app_str("${}");
+if (cur_xref->num!=section_count+def_flag) {
+ app_str("\\mathrel+"); /* section name is multiply defined */
+ this_section=name_dir; /* so we won't give cross-reference info here */
+}
+app_str("\\E"); /* output an equivalence sign */
+@.\\E@>
+app_str("{}$");
+app(force); app_scrap(dead,no_math);
+ /* this forces a line break unless `\.{@@+}' follows */
+
+@ @<Emit the scrap...@>=
+if (next_control<section_name) {
+ err_print("! You can't do that in C text");
+@.You can't do that...@>
+ next_control=get_next();
+}
+else if (next_control==section_name) {
+ app(section_flag+(int)(cur_section-name_dir));
+ app_scrap(section_scrap,maybe_math);
+ next_control=get_next();
+}
+
+@ Cross references relating to a named section are given
+after the section ends.
+
+@<Show cross...@>=
+if (this_section>name_dir) {
+ cur_xref=(xref_pointer)this_section->xref;
+ if (cur_xref->num==file_flag){an_output=true;cur_xref=cur_xref->xlink;}
+ else an_output=false;
+ if (cur_xref->num>def_flag)
+ cur_xref=cur_xref->xlink; /* bypass current section number */
+ footnote(def_flag); footnote(cite_flag); footnote(0);
+}
+
+@ The |footnote| procedure gives cross-reference information about
+multiply defined section names (if the |flag| parameter is
+|def_flag|), or about references to a section name
+(if |flag==cite_flag|), or to its uses (if |flag==0|). It assumes that
+|cur_xref| points to the first cross-reference entry of interest, and it
+leaves |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.
+
+@c
+static void
+footnote(@t\1\1@> /* outputs section cross-references */
+sixteen_bits flag@t\2\2@>)
+{
+ xref_pointer q; /* cross-reference pointer variable */
+ if (cur_xref->num<=flag) return;
+ finish_line(); out('\\');
+@.\\A@>
+@.\\Q@>
+@.\\U@>
+ out(flag==0? 'U': flag==cite_flag? 'Q': 'A');
+ @<Output all the section numbers on the reference list |cur_xref|@>@;
+ out('.');
+}
+
+@ @<Predecl...@>=@+static void footnote(sixteen_bits);
+
+@ The following code distinguishes three cases, according as the number
+of cross-references is one, two, or more than two. Variable |q| points
+to the first cross-reference, and the last link is a zero.
+
+@<Output all the section numbers...@>=
+q=cur_xref; if (q->xlink->num>flag) out('s'); /* plural */
+while (true) {
+ out_section(cur_xref->num-flag);
+ cur_xref=cur_xref->xlink; /* point to the next cross-reference to output */
+ if (cur_xref->num<=flag) break;
+ if (cur_xref->xlink->num>flag) out_str(", "); /* not the last */
+ else {out_str("\\ET"); /* the last */
+@.\\ET@>
+ if (cur_xref != q->xlink) out('s'); /* the last of more than two */
+ }
+}
+
+@ @<Output the code for the end of a section@>=
+out_str("\\fi"); finish_line();
+@.\\fi@>
+flush_buffer(out_buf,false,false); /* insert a blank line, it looks nice */
+
+@** 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 |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.
+
+@c
+static void
+phase_three(void) {
+if (no_xref) {
+ finish_line();
+ out_str("\\end");
+@.\\end@>
+ finish_line();
+}
+else {
+ phase=3; if (show_progress) fputs("\nWriting the index...",stdout);
+@.Writing the index...@>
+ finish_line();
+ if ((idx_file=fopen(idx_file_name,"wb"))==NULL)
+ fatal("! Cannot open index file ",idx_file_name);
+@.Cannot open index file@>
+ if (change_exists) {
+ @<Tell about changed sections@>@; finish_line(); finish_line();
+ }
+ out_str("\\inx"); finish_line();
+@.\\inx@>
+ active_file=idx_file; /* change active file to the index file */
+ @<Do the first pass of sorting@>@;
+ @<Sort and output the index@>@;
+ finish_line(); fclose(active_file); /* finished with |idx_file| */
+ active_file=tex_file; /* switch back to |tex_file| for a tic */
+ out_str("\\fin"); finish_line();
+@.\\fin@>
+ if ((scn_file=fopen(scn_file_name,"wb"))==NULL)
+ fatal("! Cannot open section file ",scn_file_name);
+@.Cannot open section file@>
+ active_file=scn_file; /* change active file to section listing file */
+ @<Output all the section names@>@;
+ finish_line(); fclose(active_file); /* finished with |scn_file| */
+ active_file=tex_file;
+ if (group_found) out_str("\\con");@+else out_str("\\end");
+@.\\con@>
+@.\\end@>
+ finish_line();
+ fclose(active_file);
+}
+if (show_happiness) {
+ if (show_progress) new_line;
+ fputs("Done.",stdout);
+}
+check_complete(); /* was all of the change file used? */
+}
+
+@ @<Predecl...@>=@+static void phase_three(void);
+
+@ Just before the index comes a list of all the changed sections, including
+the index section itself.
+
+@<Private...@>=
+static sixteen_bits k_section; /* runs through the sections */
+
+@ @<Tell about changed sections@>= {
+ /* remember that the index is already marked as changed */
+ k_section=0;
+ while (!changed_section[++k_section]);
+ out_str("\\ch ");
+@.\\ch@>
+ out_section(k_section);
+ while (k_section<section_count) {
+ while (!changed_section[++k_section]);
+ out_str(", "); out_section(k_section);
+ }
+ out('.');
+}
+
+@ 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 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 |c| begins at location |bucket[c]| and continues through
+the |blink| array.
+
+@<Private...@>=
+static name_pointer bucket[256];
+static name_pointer next_name; /* successor of |cur_name| when sorting */
+static name_pointer blink[max_names]; /* links in the buckets */
+
+@ 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.
+
+@<Do the first pass...@>= {
+int c;
+for (c=0; c<256; c++) bucket[c]=NULL;
+for (h=hash; h<=hash_end; h++) {
+ next_name=*h;
+ while (next_name) {
+ cur_name=next_name; next_name=cur_name->link;
+ if (cur_name->xref!=(void *)xmem) {
+ c=(eight_bits)((cur_name->byte_start)[0]);
+ if (xisupper(c)) c=tolower(c);
+ blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
+ }
+ }
+}
+}
+
+@ During the sorting phase we shall use the |cat| and |trans| arrays from
+\.{CWEAVE}'s parsing algorithm and rename them |depth| and |head|. They now
+represent a stack of identifier lists for all the index entries that have
+not yet been output. The variable |sort_ptr| tells how many such lists are
+present; the lists are output in reverse order (first |sort_ptr|, then
+|sort_ptr-1|, etc.). The |j|th list starts at |head[j]|, and if the first
+|k| characters of all entries on this list are known to be equal we have
+|depth[j]==k|.
+
+@<Rest of |trans_plus| union@>=
+name_pointer Head;
+
+@ @d depth cat /* reclaims memory that is no longer needed for parsing */
+@d head trans_plus.Head /* ditto */
+@f sort_pointer int
+@d sort_pointer scrap_pointer /* ditto */
+@d sort_ptr scrap_ptr /* ditto */
+@d max_sorts max_scraps /* ditto */
+
+@<Private...@>=
+static eight_bits cur_depth; /* depth of current buckets */
+static char *cur_byte; /* index into |byte_mem| */
+static sixteen_bits cur_val; /* current cross-reference number */
+static sort_pointer max_sort_ptr; /* largest value of |sort_ptr| */
+
+@ @<Set init...@>=
+max_sort_ptr=scrap_info;
+
+@ The desired alphabetic order is specified by the |collate| array; namely,
+$|collate|[0]<|collate|[1]<\cdots<|collate|[100]$.
+
+@<Private...@>=
+static eight_bits collate[101+128]; /* collation order */
+@^high-bit character handling@>
+
+@ 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.
+@^ASCII code dependencies@>
+@^high-bit character handling@>
+
+We initialize |collate| by copying a few characters at a time, because
+some \CEE/ compilers choke on long strings.
+
+@<Set init...@>=
+collate[0]=0;
+memcpy((char *)collate+1,
+ " \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17",16);
+/* 16 characters + 1 = 17 */
+memcpy((char *)collate+17,
+ "\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37",16);
+/* 16 characters + 17 = 33 */
+memcpy((char *)collate+33,
+ "!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|}~_",32);
+/* 32 characters + 33 = 65 */
+memcpy((char *)collate+65,
+ "abcdefghijklmnopqrstuvwxyz0123456789",36);
+/* (26 + 10) characters + 65 = 101 */
+memcpy((char *)collate+101,
+ "\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217",16);
+/* 16 characters + 101 = 117 */
+memcpy((char *)collate+117,
+ "\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237",16);
+/* 16 characters + 117 = 133 */
+memcpy((char *)collate+133,
+ "\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257",16);
+/* 16 characters + 133 = 149 */
+memcpy((char *)collate+149,
+ "\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277",16);
+/* 16 characters + 149 = 165 */
+memcpy((char *)collate+165,
+ "\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317",16);
+/* 16 characters + 165 = 181 */
+memcpy((char *)collate+181,
+ "\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337",16);
+/* 16 characters + 181 = 197 */
+memcpy((char *)collate+197,
+ "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357",16);
+/* 16 characters + 197 = 213 */
+memcpy((char *)collate+213,
+ "\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377",16);
+/* 16 characters + 213 = 229 */
+
+@ Procedure |unbucket| goes through the buckets and adds nonempty lists
+to the stack, using the collating sequence specified in the |collate| array.
+The parameter to |unbucket| tells the current depth in the buckets.
+Any two sequences that agree in their first 255 character positions are
+regarded as identical.
+
+@d infinity 255 /* $\infty$ (approximately) */
+
+@c
+static void
+unbucket(@t\1\1@> /* empties buckets having depth |d| */
+eight_bits d@t\2\2@>)
+{
+ int c; /* index into |bucket|; cannot be a simple |char| because of sign
+ comparison below */
+ for (c=100+128; c>= 0; c--) if (bucket[collate[c]]) {
+@^high-bit character handling@>
+ if (sort_ptr>=scrap_info_end) overflow("sorting");
+ sort_ptr++;
+ if (sort_ptr>max_sort_ptr) max_sort_ptr=sort_ptr;
+ if (c==0) sort_ptr->depth=infinity;
+ else sort_ptr->depth=d;
+ sort_ptr->head=bucket[collate[c]]; bucket[collate[c]]=NULL;
+ }
+}
+
+@ @<Predecl...@>=@+static void unbucket(eight_bits);
+
+@ @<Sort and output...@>=
+sort_ptr=scrap_info; unbucket(1);
+while (sort_ptr>scrap_info) {
+ cur_depth=sort_ptr->depth;
+ if (blink[sort_ptr->head-name_dir]==0 || cur_depth==infinity)
+ @<Output index entries for the list at |sort_ptr|@>@;
+ else @<Split the list at |sort_ptr| into further lists@>@;
+}
+
+@ @<Split the list...@>= {
+ eight_bits c;
+ next_name=sort_ptr->head;
+ do {
+ cur_name=next_name; next_name=blink[cur_name-name_dir];
+ cur_byte=cur_name->byte_start+cur_depth;
+ if (cur_byte==(cur_name+1)->byte_start) c=0; /* hit end of the name */
+ else {
+ c=(eight_bits) *cur_byte;
+ if (xisupper(c)) c=tolower(c);
+ }
+ blink[cur_name-name_dir]=bucket[c]; bucket[c]=cur_name;
+ } while (next_name);
+ --sort_ptr; unbucket(cur_depth+1);
+}
+
+@ @<Output index...@>= {
+ cur_name=sort_ptr->head;
+ do {
+ out_str("\\I");
+@.\\I@>
+ @<Output the name at |cur_name|@>@;
+ @<Output the cross-references at |cur_name|@>@;
+ cur_name=blink[cur_name-name_dir];
+ } while (cur_name);
+ --sort_ptr;
+}
+
+@ @<Output the name...@>=
+switch (cur_name->ilk) {
+ case normal: case func_template: if (is_tiny(cur_name)) out_str("\\|");
+ else {char *j;
+ for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
+ if (xislower(*j)) goto lowcase;
+ out_str("\\."); break;
+lowcase: out_str("\\\\");
+ }
+ break;
+@.\\|@>
+@.\\.@>
+@.\\\\@>
+ case wildcard: out_str("\\9");@+ goto not_an_identifier;
+@.\\9@>
+ case typewriter: out_str("\\.");
+@.\\.@>
+ case roman: not_an_identifier: out_name(cur_name,false); goto name_done;
+ case custom: {char *j; out_str("$\\");
+ for (j=cur_name->byte_start;j<(cur_name+1)->byte_start;j++)
+ out(*j=='_'? 'x': *j=='$'? 'X': *j);
+ out('$');
+ goto name_done;
+ }
+ default: out_str("\\&");
+@.\\\&@>
+}
+out_name(cur_name,true);
+name_done:@;
+
+@ Section numbers that are to be underlined are enclosed in
+`\.{\\[}$\,\ldots\,$\.]'.
+
+@<Output the cross-references...@>=
+@<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>@;
+do {
+ out_str(", "); cur_val=cur_xref->num;
+ if (cur_val<def_flag) out_section(cur_val);
+ else {out_str("\\["); out_section(cur_val-def_flag); out(']');}
+@.\\[@>
+ cur_xref=cur_xref->xlink;
+} while (cur_xref!=xmem);
+out('.'); finish_line();
+
+@ List inversion is best thought of as popping elements off one stack and
+pushing them onto another. In this case |cur_xref| will be the head of
+the stack that we push things onto.
+@<Private...@>=
+static xref_pointer next_xref, this_xref;
+ /* pointer variables for rearranging a list */
+
+@ @<Invert the cross-reference list at |cur_name|, making |cur_xref| the head@>=
+this_xref=(xref_pointer)cur_name->xref; cur_xref=xmem;
+do {
+ next_xref=this_xref->xlink; this_xref->xlink=cur_xref;
+ cur_xref=this_xref; this_xref=next_xref;
+} while (this_xref!=xmem);
+
+@ The following recursive procedure walks through the tree of section names and
+prints them.
+@^recursion@>
+
+@c
+static void
+section_print(@t\1\1@> /* print all section names in subtree |p| */
+name_pointer p@t\2\2@>)
+{
+ if (p) {
+ section_print(p->llink); out_str("\\I");
+@.\\I@>
+ tok_ptr=tok_mem+1; text_ptr=tok_start+1; scrap_ptr=scrap_info; init_stack;
+ app(p-name_dir+section_flag); make_output();
+ footnote(cite_flag);
+ footnote(0); /* |cur_xref| was set by |make_output| */
+ finish_line();@/
+ section_print(p->rlink);
+ }
+}
+
+@ @<Predecl...@>=@+static void section_print(name_pointer);
+
+@ @<Output all the section names@>=section_print(root);
+
+@ Because on some systems the difference between two pointers is a |ptrdiff_t|
+rather than an |int|, we use \.{\%ld} to print these quantities.
+
+@c
+void
+print_stats(void) {
+ puts("\nMemory usage statistics:");
+@.Memory usage statistics:@>
+ printf("%ld names (out of %ld)\n",
+ (ptrdiff_t)(name_ptr-name_dir),(long)max_names);
+ printf("%ld cross-references (out of %ld)\n",
+ (ptrdiff_t)(xref_ptr-xmem),(long)max_refs);
+ printf("%ld bytes (out of %ld)\n",
+ (ptrdiff_t)(byte_ptr-byte_mem),(long)max_bytes);
+ puts("Parsing:");
+ printf("%ld scraps (out of %ld)\n",
+ (ptrdiff_t)(max_scr_ptr-scrap_info),(long)max_scraps);
+ printf("%ld texts (out of %ld)\n",
+ (ptrdiff_t)(max_text_ptr-tok_start),(long)max_texts);
+ printf("%ld tokens (out of %ld)\n",
+ (ptrdiff_t)(max_tok_ptr-tok_mem),(long)max_toks);
+ printf("%ld levels (out of %ld)\n",
+ (ptrdiff_t)(max_stack_ptr-stack),(long)stack_size);
+ puts("Sorting:");
+ printf("%ld levels (out of %ld)\n",
+ (ptrdiff_t)(max_sort_ptr-scrap_info),(long)max_scraps);
+}
+
+@** 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.
diff --git a/Build/source/texk/web2c/cwebdir/cweb.1 b/Build/source/texk/web2c/cwebdir/cweb.1
new file mode 100644
index 00000000000..a9aa69bf433
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweb.1
@@ -0,0 +1,132 @@
+.TH CWEB 1 2018-Dec-16
+.
+.SH NAME
+ctangle, cweave \- translate CWEB to C and/or TeX
+.
+.SH SYNOPSIS
+.na
+.B ctangle
+[
+.B \-bhp
+] [
+.B +s
+] webfile[.w] [{changefile[.ch]|-} [outputfile[.c]]]
+.br
+.B cweave
+[
+.B \-befhpx
+] [
+.B +s
+] webfile[.w] [{changefile[.ch]|-} [outputfile[.tex]]]
+.ad
+.
+.SH DESCRIPTION
+The
+.I ctangle
+program converts a CWEB
+source document into a C\ program that may be compiled in the usual way.
+The output file includes #line specifications so that debugging can be
+done in terms of the CWEB source file.
+.PP
+The
+.I cweave
+program converts the same CWEB file into a TeX file that may be
+formatted and printed in the usual way.
+It takes appropriate care of typographic details like page
+layout and the use of indentation, italics, boldface, etc., and it supplies
+extensive cross-index information that it gathers automatically.
+.PP
+CWEB allows you to prepare a single
+document containing all the information that is needed both to produce
+a compilable C\ program and to produce a well-formatted document
+describing the program in as much detail as the writer may desire.
+The user of CWEB ought to be familiar with TeX as well as\ C.
+.PP
+The command line should have one, two, or three names on it.
+The first is taken as the CWEB file (and .w is added if there is no
+extension).
+If that file cannot be opened, the extension .web is tried instead.
+(But .w is recommended, since .web usually implies Pascal.)
+If there is a second name, it is a change file (and .ch is added if there is
+no extension).
+The change file overrides parts of the WEB file,
+as described in the documentation.
+If there is a third name, it overrides
+the default name of the output file, which is ordinarily the same as
+the name of the input file (but on the current directory) with the
+extension .c or .tex.
+.PP
+Options in the command line may be either turned off with\ \-
+(if they are on by default) or turned on with\ + (if they are off by
+default).
+In fact, the options are processed from left to right,
+so a sequence like -f\ +f corresponds to +f (which is the default).
+.PP
+The
+.B \-b
+option suppresses the banner line that normally appears on your terminal
+when ctangle or cweave begins.
+The
+.B \-h
+option suppresses the happy message that normally appears if the processing
+was successful.
+The
+.B \-p
+option suppresses progress reports (starred module numbers) as the processing
+takes place.
+If you say -bhp, you get nothing but error messages.
+.PP
+The
+.B +s
+option prints statistics about memory usage at the end of a run.
+.PP
+There are three other options applicable to
+.I cweave
+only:
+.B \-f
+means do not force a newline after every statement in the formatted output.
+.B \-e
+inhibits the enclosure of C\ material formatted by
+.I cweave
+in brackets
+\ePB{...}.
+Such brackets are normally inserted so that special hooks
+can be used by
+.I cweb-latex
+and similar programs.
+.B \-x
+means omit the index and table of contents.
+.
+.SH FILES
+The location of the files mentioned below varies from system to system.
+.TP
+cwebmac.tex
+TeX macros used by cweave output.
+.TP
+cwebman.tex
+The user manual.
+.TP
+/usr/lib/cweb
+Directory for cweb "include" files.
+.
+.SH "SEE ALSO"
+.TP
+.I Literate Programming
+by D. E. Knuth
+.TP
+.I Weaving a Program
+by Wayne Sewell
+.TP
+.I The CWEB System of Structured Documentation
+by Donald E. Knuth and Silvio Levy (hardcopy version of cwebman.tex
+and the source code listings)
+.TP
+tex(1), cc(1)
+.
+.SH AUTHORS
+Don Knuth wrote WEB for TeX and Pascal.
+Silvio Levy designed and developed CWEB
+by adapting the WEB conventions to\ C and by recoding everything in CWEB.
+Knuth began using CWEB and made further refinements.
+Many other helpers are acknowledged in the CWEB manual.
+
diff --git a/Build/source/texk/web2c/cwebdir/cweb.el b/Build/source/texk/web2c/cwebdir/cweb.el
new file mode 100644
index 00000000000..c243f35b2e4
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cweb.el
@@ -0,0 +1,218 @@
+;; This file contains extensions to GNU-Emacs, to wit:
+; (1) some WEB-oriented functions that are also of general use
+; (2) changes to the GNU-distributed TeX mode
+; (3) definitions of simple WEB and CWEB modes
+
+; To use: Put this in your EMACS-lisp library and say (load-library "cweb")
+; in your .emacs init file.
+
+; Contributed by Don Knuth, July 1990
+
+;; OK, here's part (1): some WEB-oriented functions whose main purpose is
+; to maintain a stack of module names that are "pending" as you are writing
+; a program. When you first think of a module that needs to be written later,
+; put it into the pending list (by typing CTL-Z instead of @> after the
+; name). Later you can say CTL-\ to retrieve a pending name (and if
+; you want to cycle through the pending names, ESC-y after CTL-\ will
+; do it, just as ESC-y works after a yank).
+; After you've said CTL-\, the current region is the name just removed from
+; the pending list. If you change your mind, you can put it back again by
+; saying ESC-\. If you had put it into the pending list by mistake, you
+; can get rid of it by using the normal CTL-W operation (kill-region).
+; The following code binds the new commands to CTL-Z, CTL-\, and ESC-\
+; in all modes. You may prefer other bindings, of course.
+; CTL-Z is normally "suspend emacs", but it is best not used when emacs
+; has its own window as it usually does nowadays; if you need the
+; old CTL-Z, you might rather bind it to CTL-X CTL-Z.
+; CTL-\ is normally undefined.
+; ESC-\ is normally "delete space", but ESC-space DEL does that easily too.
+
+(defvar pending-list nil
+ "List of strings (usually WEB module names) still pending.")
+
+(defun into-pending-list (beg end)
+ "Copy region into pending-list."
+ (interactive "r")
+ (indicate-region)
+ (setq pending-list (cons (buffer-substring beg end) pending-list)))
+
+(defun new-module-name-pending ()
+ "Insert @> to complete a module name, then put it into pending-list."
+ (interactive)
+ (insert "@>")
+ (push-mark)
+ (if (search-backward "@<" nil t)
+ (progn
+ (exchange-point-and-mark)
+ (into-pending-list (point) (mark))
+ )
+ (message "There's no @< to begin the module name!")))
+(global-set-key "\C-z" 'new-module-name-pending)
+
+(defun pop-pending-list (arg)
+ "Remove first element of pending-list and insert it as current region.
+With argument, put point at left; otherwise point will follow the insertion.
+Say \\[new-yank-pop] to replace this by another element of the list.
+Say \\[into-pending-list] to put it back in the list."
+ (interactive "*P")
+ (if (consp pending-list)
+ (progn
+ (push-mark (point))
+ (insert (car pending-list))
+ (setq pending-list (cdr pending-list))
+ (if arg
+ (exchange-point-and-mark)))
+ (message "Nothing is pending.")
+ (setq this-command nil)))
+(global-set-key "\C-\\" 'pop-pending-list)
+(global-set-key "\M-\\" 'into-pending-list)
+
+(defun new-yank-pop (arg)
+ "If previous command was \\[pop-pending-list], pop a different string;
+otherwise do an ordinary Meta-y."
+ (interactive "*p")
+ (if (eq last-command 'pop-pending-list)
+ (let (xch)
+ (setq xch (< (point) (mark)))
+ (setq pending-list (append pending-list
+ (list (buffer-substring (point) (mark)))))
+ (delete-region (point) (mark))
+ (setq this-command 'pop-pending-list)
+ (pop-pending-list xch))
+ (yank-pop arg)))
+(global-set-key "\M-y" 'new-yank-pop)
+
+(defun indicate-region ()
+ "Bounce cursor to mark and back again"
+ (let ((point-save (point)))
+ (unwind-protect
+ (progn (goto-char (mark))
+ (sit-for 0 300)) ;; wait 300 milliseconds
+ (goto-char point-save))))
+
+; I prefer to change the standard copy-region command to the following,
+; which gives me visual feedback about what I've copied to the kill ring:
+(defun indicate-and-copy-region (beg end)
+ "Indicate current region, then copy it to the kill ring."
+ (interactive "r")(indicate-region)(copy-region-as-kill beg end))
+(global-set-key "\M-w" 'indicate-and-copy-region)
+
+; Here's another convenient command, bound to the usually unused ESC-".
+(defun ditto (arg)
+ "Copy ARG characters from the line above."
+ (interactive "*p")
+ (let (ch)
+ (while (> arg 0)
+ (setq temporary-goal-column (current-column))
+ (save-excursion
+ (previous-line 1)
+ (setq ch (following-char)))
+ (insert ch)
+ (setq arg (1- arg)))))
+(global-set-key "\M-\"" 'ditto)
+; If "ditto" suddenly fails to work, you have probably set goal-column
+; inadvertently. To unset it, say C-u C-x C-n.
+
+;; OK, here's part (2): Changes to TeX mode.
+; The WEB modes below are very much like TeX mode, but some improvements were
+; desirable in TeX mode:
+; I made newline act as it does in indented-text mode, since this
+; works nicely for both TeX and WEB (Pascal or C code).
+; I made RET check for unmatched delimiters if it ends a paragraph.
+; Otherwise TeX mode remains as it was before.
+
+(setq TeX-mode-map (make-sparse-keymap))
+(define-key TeX-mode-map "\C-c\C-k" 'TeX-kill-job)
+(define-key TeX-mode-map "\C-c\C-l" 'TeX-recenter-output-buffer)
+(define-key TeX-mode-map "\C-c\C-q" 'TeX-show-print-queue)
+(define-key TeX-mode-map "\C-c\C-p" 'TeX-print)
+(define-key TeX-mode-map "\"" 'TeX-insert-quote)
+(define-key TeX-mode-map "\e}" 'up-list)
+(define-key TeX-mode-map "\e{" 'TeX-insert-braces)
+(define-key TeX-mode-map "\C-c\C-r" 'TeX-region)
+(define-key TeX-mode-map "\C-c\C-b" 'TeX-buffer)
+(define-key TeX-mode-map "\C-c\C-f" 'TeX-close-LaTeX-block)
+(define-key TeX-mode-map "\r" 'TeX-newline)
+(define-key TeX-mode-map "\t" 'indent-relative)
+(setq TeX-mode-hook '(lambda ()
+ (make-local-variable 'indent-line-function)
+ (setq indent-line-function 'indent-relative-maybe)))
+
+(defun TeX-newline (arg)
+"If previous character is newline and no ARG, check for unbalanced braces
+and/or dollar signs in previous paragraph. If ARG is \\[universal-argument],
+do a single newline; otherwise do ordinary newline."
+ (interactive "*P")
+ (if (and (eq (preceding-char) ?\n) (not arg))
+ (TeX-check-paragraph)
+ (if (listp arg)
+ (newline)
+ (newline arg))))
+
+(defun TeX-check-paragraph ()
+"Insert a newline following a newline, breaking a paragraph for TeX.
+Check for mismatched delimiters in paragraph being terminated."
+ (interactive)
+ (if (TeX-validate-paragraph
+ (save-excursion
+ (search-backward "\n\n" nil 'move)
+ (point))
+ (point))
+ (insert ?\n)
+ (insert ?\n)
+ (error "Mismatched delimiters in that paragraph?")))
+
+;; and now, part (3): WEB and CWEB modes.
+; These are like plain TeX mode except that the automatic conversion of
+; " to `` or '' is disabled. (Personally I never liked that feature anyway,
+; since it's easy to get used to typing `` and ''. In WEB modes, the
+; feature soon becomes intolerable, unless you never use string constants!)
+; Another thing distinguishing WEB mode from TeX is ESC-p and ESC-n, to
+; move to previous or next module. These keys are usually unbound, except
+; when processing email.
+
+(defun forward-module (arg)
+"Advance past next WEB module beginning; with ARG, repeat ARG times."
+ (interactive "p")
+ (move-to-module arg))
+(defun backward-module (arg)
+"Advance to previous WEB module beginning; with ARG, repeat ARG times."
+ (interactive "p")
+ (move-to-module (- arg)))
+(defun move-to-module (arg)
+ (while (> arg 0)
+ (re-search-forward "@ \\|@\\*\\|@\n")
+ (setq arg (1- arg)))
+ (while (< arg 0)
+ (re-search-backward "@ \\|@\\*\\|@\n")
+ (setq arg (1+ arg))))
+
+(defun web-mode ()
+ "Major mode like TeX mode plus \\[forward-module] and \\[backward-module]
+for relative module movement. The automatic \" feature is disabled."
+ (interactive)
+ (plain-tex-mode)
+ (local-set-key "\M-n" 'forward-module)
+ (local-set-key "\M-p" 'backward-module)
+ (local-set-key "\"" 'self-insert-command)
+ (setq mode-name "WEB")
+ (setq major-mode 'web-mode)
+ (run-hooks 'web-mode-hook))
+(setq auto-mode-alist (cons '("\\.web$" . web-mode) auto-mode-alist))
+
+(defun cweb-mode ()
+ "Major mode like TeX mode plus \\[forward-module] and \\[backward-module]
+for relative module movement. The automatic \" feature is disabled."
+ (interactive)
+ (plain-tex-mode)
+ (local-set-key "\M-n" 'forward-module)
+ (local-set-key "\M-p" 'backward-module)
+ (local-set-key "\"" 'self-insert-command)
+ (setq comment-start nil)
+ (modify-syntax-entry ?% "@")
+ (setq mode-name "CWEB")
+ (setq major-mode 'cweb-mode)
+ (setq tex-fontify-script nil) ;; needed in GNU Emacs version 22?
+ (run-hooks 'cweb-mode-hook))
+(setq auto-mode-alist (cons '("\\.w$" . cweb-mode) auto-mode-alist))
+(setq auto-mode-alist (cons '("\\.ch$" . cweb-mode) auto-mode-alist))
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/amiga_types.w b/Build/source/texk/web2c/cwebdir/cwebinputs/amiga_types.w
new file mode 100644
index 00000000000..dc5d4afe003
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/amiga_types.w
@@ -0,0 +1,109 @@
+%
+% CWEB/INCLUDE $VER: AMIGA_TYPES.W 1.3 (13.8.1998)
+%
+% SYNOPSIS:
+% This file tells CWEAVE to treat AMIGA specific keywords as
+% reserved words. Some of these are introduced by Commodore's
+% operating system, others by the SAS/C compiler.
+%
+% CREATION DATE: unknown
+%
+% AUTHOR: Andreas Scherer
+%
+% COPYRIGHT: There is no restriction to the usage of this file.
+
+@q Keywords specific to SAS/C@>
+
+@s __aligned int
+@s __asm int
+@s __chip int
+@s __far int
+@s __inline int
+@s __interrupt int
+@s __near int
+@s __regargs int
+@s __saveds int
+@s __stackext int
+@s __stdargs int
+
+@q Registers of the AMIGA@>
+
+@s __d0 int
+@s __d1 int
+@s __d2 int
+@s __d3 int
+@s __d4 int
+@s __d5 int
+@s __d6 int
+@s __d7 int
+@s __a0 int
+@s __a1 int
+@s __a2 int
+@s __a3 int
+@s __a4 int
+@s __a5 int
+@s __a6 int
+@s __a7 int
+@s __fp0 int
+@s __fp1 int
+@s __fp2 int
+@s __fp3 int
+@s __fp4 int
+@s __fp5 int
+@s __fp6 int
+@s __fp7 int
+
+@q Keywords by Commodore@>
+
+@s GLOBAL int
+@s IMPORT int
+@s STATIC int
+@s REGISTER int
+@s VOID int
+@s APTR int
+@s LONG int
+@s ULONG int
+@s LONGBITS int
+@s WORD int
+@s UWORD int
+@s WORDBITS int
+@s BYTE int
+@s UBYTE int
+@s BYTEBITS int
+@s RPTR int
+@s STRPTR int
+@s SHORT int
+@s USHORT int
+@s COUNT int
+@s UCOUNT int
+@s CPTR int
+@s FLOAT int
+@s DOUBLE int
+@s BOOL int
+@s TEXT int
+@s BPTR int
+@s BSTR int
+
+@s byte int
+@s Class int
+@s ClassID int
+@s CxMsg int
+@s CxObj int
+@s dev_t int
+@s DIR int
+@s DisplayInfoHandle int
+@s ino_t int
+@s IX int
+@s Msg int
+@s Object int
+@s off_t int
+@s PFL int
+@s PLANEPTR int
+@s Tag int
+@s tPoint int
+@s ushort int
+@s u_char int
+@s u_int int
+@s u_long int
+@s u_short int
+@s WINDOW int
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/c++1xlib.w b/Build/source/texk/web2c/cwebdir/cwebinputs/c++1xlib.w
new file mode 100644
index 00000000000..249d70544da
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/c++1xlib.w
@@ -0,0 +1,37 @@
+@q This file defines type names introduced in modern dialects of C++ as @>
+@q special items for formatting; see http://en.cppreference.com/w/cpp/header @>
+@q only the std::class names listed there are included here. @>
+
+@q @@i'nclude this file in addition to the file 'c++lib.w' @>
+
+@s type_index int
+@s initializer_list int
+@s tuple int
+@s any int
+@s optional int
+@s variant int
+@s error_code int
+@s basic_string_view int
+@s array int
+@s forward_list int
+@s unordered_set int
+@s unordered_multiset int
+@s unordered_map int
+@s unordered_multimap int
+@s thread int
+@s path int
+
+@q add more std::classes from (some) C++1x headers @>
+
+@s integral_constant int
+@s bool_constant int
+@s function int
+@s mem_fn int
+@s bad_function_call int
+@s is_bind_expression int
+@s is_placeholder int
+@s reference_wrapper int
+@s hash int
+@s unique_ptr int
+@s shared_ptr int
+@s weak_ptr int
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_ecma94.w b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_ecma94.w
new file mode 100644
index 00000000000..f36bdaf4d0a
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_ecma94.w
@@ -0,0 +1,44 @@
+%
+% CWEB/INCLUDE $VER: CWEB_ECMA94.W 1.6 (13.01.2019)
+%
+% SYNOPSIS:
+% Transliteration table for umlauts and special characters
+% according to the ISO 8859-1/ECMA-94/Latin-1 codepage.
+% @@include this file in limbo.
+% Note that not all equivalents to the TeX macros are present.
+%
+% DATE: 28.03.94: Derived from ECMA94.TEX (V1.0)
+%
+% AUTHOR:
+% Andreas Scherer <https://ascherer.github.io/>
+%
+% Please send suggestions (pull requests) and bug reports (issues)
+% to https://github.com/ascherer/cwebbin
+%
+% COPYRIGHT: There is no restriction to the usage of this file.
+%
+% CHANGES:
+% March 25, 1996: New postal address. (V1.2)
+% August 13, 1998: New e-mail address. (V1.3)
+% June 11, 2000: Include matching TeX macros. (V1.4)
+% July 10, 2017: Complete overhaul. (V1.5)
+% January 13, 2019: Non-generic names. (V1.6)
+
+\input cweb_ecma94.sty
+\noatl
+
+@q b0 @> @q b1 @> @q b2 @> @q b3 @> @q b4 @> @l b5 mu
+@q b6 @> @q b7 @> @q b8 @> @q b9 @> @q ba @> @q bb @>
+@q bc @> @q bd @> @q be @> @q bf @>
+@l c0 A @l c1 A @l c2 A @l c3 A @l c4 Ae @l c5 AA
+@l c6 AE @l c7 C @l c8 E @l c9 E @l ca E @l cb Ee
+@l cc I @l cd I @l ce I @l cf Ie
+@q d0 @> @l d1 N @l d2 O @l d3 O @l d4 O @l d5 O
+@l d6 Oe @q d7 @> @l d8 O @l d9 U @l da U @l db U
+@l dc Ue @l dd Y @q de @> @l df ss
+@l e0 a @l e1 a @l e2 a @l e3 a @l e4 ae @l e5 aa
+@l e6 ae @l e7 c @l e8 e @l e9 e @l ea e @l eb ee
+@l ec i @l ed i @l ee i @l ef ie
+@q f0 @> @l f1 n @l f2 o @l f3 o @l f4 o @l f5 o
+@l f6 oe @q f7 @> @l f8 o @l f9 u @l fa u @l fb u
+@l fc ue @l fd y @q fe @> @l ff ye
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_hp8.w b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_hp8.w
new file mode 100644
index 00000000000..c5644a31973
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_hp8.w
@@ -0,0 +1,47 @@
+%
+% CWEB/INCLUDE $VER: CWEB_HP8.W 1.6 (13.01.2019)
+%
+% SYNOPSIS:
+% Transliteration table for umlauts and special characters
+% according to the Hewlett-Packard Roman 8 codepage.
+% @@include this file in limbo.
+% Note that not all equivalents to the TeX macros are present.
+%
+% DATE: 28.03.94: Derived from HP8.TEX (V1.0)
+%
+% AUTHOR:
+% Andreas Scherer <https://ascherer.github.io/>
+%
+% Please send suggestions (pull requests) and bug reports (issues)
+% to https://github.com/ascherer/cwebbin
+%
+% COPYRIGHT: There is no restriction to the usage of this file.
+%
+% CHANGES:
+% March 25, 1996: New postal address. (V1.2)
+% August 13, 1998: New e-mail address. (V1.3)
+% June 11, 2000: Include matching TeX macros. (V1.4)
+% July 10, 2017: Complete overhaul. (V1.5)
+% January 13, 2019: Non-generic names. (V1.6)
+
+\input cweb_hp8.sty
+\noatl
+
+@q a0 @> @l a1 A @l a2 A @l a3 E @l a4 E @l a5 Ee
+@l a6 I @l a7 Ie @q a8 @> @q a9 @> @q aa @> @q ab @>
+@q ac @> @l ad U @l ae U @q af @>
+@q b0 @> @l b1 Y @l b2 y @q b3 @> @l b4 C @l b5 c
+@l b6 N @l b7 n @q b8 @> @q b9 @> @q ba @> @q bb @>
+@q bc @> @q bd @> @q be @> @q bf @>
+@l c0 a @l c1 e @l c2 o @l c3 u @l c4 a @l c5 e
+@l c6 o @l c7 u @l c8 a @l c9 e @l ca o @l cb u
+@l cc ae @l cd ee @l ce oe @l cf ue
+@l d0 AA @l d1 i @l d2 O @l d3 AE @l d4 aa @l d5 i
+@l d6 o @l d7 ae @l d8 Ae @l d9 i @l da Oe @l db Ue
+@l dc E @l dd ie @l de ss @l df O
+@l e0 A @l e1 A @l e2 a @q e3 @> @q e4 @> @l e5 I
+@l e6 I @l e7 O @l e8 O @l e9 O @l ea o @q eb @>
+@q ec @> @l ed U @l ee Ye @l ef ye
+@q f0 @> @q f1 @> @q f2 @> @l f3 mu @q f4 @> @q f5 @>
+@q f6 @> @q f7 @> @q f8 @> @q f9 @> @q fa @> @q fb @>
+@q fc @> @q fd @> @q fe @> @q ff @>
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_mac8.w b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_mac8.w
new file mode 100644
index 00000000000..874f2558039
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_mac8.w
@@ -0,0 +1,53 @@
+%
+% CWEB/INCLUDE $VER: CWEB_MAC8.W 1.6 (13.01.2019)
+%
+% SYNOPSIS:
+% Transliteration table for umlauts and special characters
+% according to the Macintosh 8-bit codepage.
+% @@include this file in limbo.
+% Note that not all equivalents to the TeX macros are present.
+%
+% DATE: 23.06.94: Derived from MAC8.TEX (V1.0)
+%
+% AUTHOR:
+% Andreas Scherer <https://ascherer.github.io/>
+%
+% Please send suggestions (pull requests) and bug reports (issues)
+% to https://github.com/ascherer/cwebbin
+%
+% COPYRIGHT: There is no restriction to the usage of this file.
+%
+% CHANGES:
+% March 25, 1996: New postal address. (V1.2)
+% August 13, 1998: New e-mail address. (V1.3)
+% June 11, 2000: Include matching TeX macros. (V1.4)
+% July 10, 2017: Complete overhaul. (V1.5)
+% January 13, 2019: Non-generic names. (V1.6)
+
+\input cweb_mac8.sty
+\noatl
+
+@l 80 Ae @l 81 A @l 82 C @l 83 E @l 84 N @l 85 Oe
+@l 86 Ue @l 87 a @l 88 a @l 89 a @l 8a ae @l 8b a
+@l 8c a @l 8d c @l 8e e @l 8f e
+@l 90 e @l 91 ee @l 92 i @l 93 i @l 94 i @l 95 ie
+@l 96 n @l 97 o @l 98 o @l 99 o @l 9a oe @l 9b o
+@l 9c u @l 9d u @l 9e u @l 9f ue
+@q a0 @> @q a1 @> @q a2 @> @q a3 @> @q a4 @> @q a5 @>
+@q a6 @> @l a7 ss @q a8 @> @q a9 @> @q aa @> @q ab @>
+@q ac @> @q ad @> @l ae AE @l af O
+@q b0 @> @q b1 @> @q b2 @> @q b3 @> @q b4 @> @l b5 mu
+@q b6 @> @q b7 @> @q b8 @> @q b9 @> @q ba @> @q bb @>
+@q bc @> @q bd @> @l be ae @l bf o
+@q c0 @> @q c1 @> @q c2 @> @q c3 @> @q c4 @> @q c5 @>
+@q c6 @> @q c7 @> @q c8 @> @q c9 @> @q ca @> @l cb A
+@l cc A @l cd O @q ce @> @q cf @>
+@q d0 @> @q d1 @> @q d2 @> @q d3 @> @q d4 @> @q d5 @>
+@q d6 @> @q d7 @> @l d8 ye @l d9 Ye @q da @> @q db @>
+@q dc @> @q dd @> @q de @> @q df @>
+@q e0 @> @q e1 @> @q e2 @> @q e3 @> @q e4 @> @l e5 A
+@l e6 E @l e7 A @l e8 Ee @l e9 E @l ea I @l eb I
+@l ec Ie @l ed I @l ee O @l ef O
+@q f0 @> @l f1 O @l f2 U @l f3 U @l f4 U @q f5 @>
+@q f6 @> @q f7 @> @q f8 @> @q f9 @> @q fa @> @q fb @>
+@q fc @> @q fd @> @q fe @> @q ff @>
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_pc850.w b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_pc850.w
new file mode 100644
index 00000000000..0c3af38e04e
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/cweb_pc850.w
@@ -0,0 +1,50 @@
+%
+% CWEB/INCLUDE $VER: CWEB_PC850.W 1.6 (13.01.2019)
+%
+% SYNOPSIS:
+% Transliteration table for umlauts and special characters
+% according to the IBM PC International Codepage 850.
+% @@include this file in limbo.
+% Note that not all equivalents to the TeX macros are present.
+%
+% DATE: 28.03.94: Derived from PC850.TEX (V1.0)
+%
+% AUTHOR:
+% Andreas Scherer <https://ascherer.github.io/>
+%
+% Please send suggestions (pull requests) and bug reports (issues)
+% to https://github.com/ascherer/cwebbin
+%
+% COPYRIGHT: There is no restriction to the usage of this file.
+%
+% CHANGES:
+% March 25, 1996: New postal address. (V1.2)
+% August 13, 1998: New e-mail address. (V1.3)
+% June 11, 2000: Include matching TeX macros. (V1.4)
+% July 10, 2017: Complete overhaul. (V1.5)
+% January 13, 2019: Non-generic names. (V1.6)
+
+\input cweb_pc850.sty
+\noatl
+
+@l 80 C @l 81 ue @l 82 e @l 83 a @l 84 ae @l 85 a
+@l 86 aa @l 87 c @l 88 e @l 89 ee @l 8a e @l 8b ie
+@l 8c i @l 8d i @l 8e Ae @l 8f AA
+@l 90 E @l 91 ae @l 92 AE @l 93 o @l 94 oe @l 95 o
+@l 96 u @l 97 u @l 98 ye @l 99 Oe @l 9a Ue @l 9b o
+@q 9c @> @l 9d O @q 9e @> @q 9f @>
+@l a0 a @l a1 i @l a2 o @l a3 u @l a4 n @l a5 N
+@q a6 @> @q a7 @> @q a8 @> @q a9 @> @q aa @> @q ab @>
+@q ac @> @q ad @> @q ae @> @q af @>
+@q b0 @> @q b1 @> @q b2 @> @q b3 @> @q b4 @> @l b5 A
+@l b6 A @l b7 A @q b8 @> @q b9 @> @q ba @> @q bb @>
+@q bc @> @q bd @> @q be @> @q bf @>
+@q c0 @> @q c1 @> @q c2 @> @q c3 @> @q c4 @> @q c5 @>
+@l c6 a @l c7 A @q c8 @> @q c9 @> @q ca @> @q cb @>
+@q cc @> @q cd @> @q ce @> @q cf @>
+@q d0 @> @q d1 @> @l d2 E @l d3 Ee @l d4 E @q d5 @>
+@l d6 I @l d7 I @l d8 Ie @q d9 @> @q da @> @q db @>
+@q dc @> @q dd @> @l de I @q df @>
+@l e0 O @l e1 ss @l e2 O @l e3 O @l e4 o @l e5 O
+@l e6 mu @q e7 @> @q e8 @> @l e9 U @l ea U @l eb U
+@l ec y @l ed Y @q ee @> @q ef @>
diff --git a/Build/source/texk/web2c/cwebdir/cwebinputs/iso_types.w b/Build/source/texk/web2c/cwebdir/cwebinputs/iso_types.w
new file mode 100644
index 00000000000..3bb244b1c64
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebinputs/iso_types.w
@@ -0,0 +1,119 @@
+@q This file defines syntax keywords and type names introduced in @>
+@q modern dialects of C and C++ as special entities for formatting @>
+
+@q C99 and C11 keywords, see http://en.cppreference.com/w/c/keyword @>
+
+@s restrict int
+
+@q C99 and C11 types @>
+
+@s _Alignas int
+@s _Alignof int
+@s _Atomic int
+@s _Bool int
+@s _Complex int
+@s _Generic int
+@s _Imaginary int
+@s _Noreturn int
+@s _Static_assert int
+@s _Thread_local int
+
+@s alignas int
+@s alignof int
+@s atomic_bool int
+@s atomic_char int
+@s atomic_schar int
+@s atomic_uchar int
+@s atomic_short int
+@s atomic_ushort int
+@s atomic_int int
+@s atomic_uint int
+@s atomic_long int
+@s atomic_ulong int
+@s atomic_llong int
+@s atomic_ullong int
+@s atomic_char16_t int
+@s atomic_char32_t int
+@s atomic_wchar_t int
+@s atomic_int_least8_t int
+@s atomic_uint_least8_t int
+@s atomic_int_least16_t int
+@s atomic_uint_least16_t int
+@s atomic_int_least32_t int
+@s atomic_uint_least32_t int
+@s atomic_int_least64_t int
+@s atomic_uint_least64_t int
+@s atomic_int_fast8_t int
+@s atomic_uint_fast8_t int
+@s atomic_int_fast16_t int
+@s atomic_uint_fast16_t int
+@s atomic_int_fast32_t int
+@s atomic_uint_fast32_t int
+@s atomic_int_fast64_t int
+@s atomic_uint_fast64_t int
+@s atomic_intptr_t int
+@s atomic_uintptr_t int
+@s atomic_size_t int
+@s atomic_ptrdiff_t int
+@s atomic_intmax_t int
+@s atomic_uintmax_t int
+@s bool int
+@s complex int
+@s imaginary int
+@s noreturn int
+@s static_assert int
+@s thread_local int
+
+@q C99 preprocessor @>
+
+@s _Pragma int
+
+@q C++99 and C++11 keywords, see http://en.cppreference.com/w/cpp/keyword @>
+
+@s constexpr int
+@s decltype int
+@s false int
+@s final int
+@s noexcept int
+@s override int
+@s true int
+
+@q Fundamental types of C++99 and C++11, see @>
+@q http://en.cppreference.com/w/cpp/language/types @>
+
+@s nullptr_t int
+@s char16_t int
+@s char32_t int
+
+@q Integral types of C99 and C++, see @>
+@q http://en.cppreference.com/w/c/types/integer and @>
+@q http://en.cppreference.com/w/cpp/types/integer @>
+
+@s int8_t int
+@s int16_t int
+@s int32_t int
+@s int64_t int
+@s int_fast8_t int
+@s int_fast16_t int
+@s int_fast32_t int
+@s int_fast64_t int
+@s int_least8_t int
+@s int_least16_t int
+@s int_least32_t int
+@s int_least64_t int
+@s intmax_t int
+@s intptr_t int
+@s uint8_t int
+@s uint16_t int
+@s uint32_t int
+@s uint64_t int
+@s uint_fast8_t int
+@s uint_fast16_t int
+@s uint_fast32_t int
+@s uint_fast64_t int
+@s uint_least8_t int
+@s uint_least16_t int
+@s uint_least32_t int
+@s uint_least64_t int
+@s uintmax_t int
+@s uintptr_t int
diff --git a/Build/source/texk/web2c/cwebdir/cwebmac.tex b/Build/source/texk/web2c/cwebdir/cwebmac.tex
new file mode 100644
index 00000000000..385dc474e71
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebmac.tex
@@ -0,0 +1,552 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 4.2 --- February 2021
+\ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros
+\xdef\fmtversion{\fmtversion+CWEB4.2}
+\chardef\cwebversion=4 \chardef\cwebrevision=1
+\newif\ifpdf
+\ifx\pdf+\pdftrue\fi
+% Uncomment the following line if you want PDF goodies to be the default
+%\ifx\pdf-\else\pdftrue\fi
+\def\pdflinkcolor{0 0 1} % the RGB values for hyperlink color
+\ifx\undefined\XeTeXrevision\else\pdftrue\fi % XeTeX produces PDF output
+\newif\ifpdftex
+\ifx\pdfoutput\undefined \pdftexfalse \else\ifnum\pdfoutput=0 \pdftexfalse
+%\else \pdftextrue \pdfoutput=1 \input pdfcolor \let\setcolor\pdfsetcolor \fi\fi
+\else \pdftextrue \pdfoutput=1 % changed in 3.69
+ \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too
+ \def\Blue{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
+\fi\fi
+\newif\ifacro \ifpdf\acrotrue\fi \ifpdftex\acrotrue\fi
+
+\let\:=\. % preserve a way to get the dot accent
+ % (all other accents will still work as usual)
+
+\parskip 0pt % no stretch between paragraphs
+\parindent 1em % for paragraphs and for the first line of C text
+
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\CEE/{{\mc C\spacefactor1000}}
+\def\UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\def\TEX/{\TeX}
+\def\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\def\Cee{\CEE/} % for backward compatibility
+\def\9#1{}
+ % with this definition of \9 you can say @:sort key}{TeX code@>
+ % to alphabetize an index entry by the sort key but format with the TeX code
+\font\eightrm=cmr8
+\let\sc=\eightrm % for smallish caps (NOT a caps-and-small-caps font)
+\let\mainfont=\tenrm
+\let\cmntfont\tenrm
+%\font\tenss=cmss10 \let\cmntfont\tenss % alternative comment font
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+\font\tentex=cmtex10 % TeX extended character set (used in strings)
+\fontdimen7\tentex=0pt % no double space after sentences
+
+\def\\#1{\leavevmode\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\leavevmode\hbox{$#1$}} % one-letter identifiers look better this way
+\def\&#1{\leavevmode\hbox{\bf
+ \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+ #1\/\kern.05em}} % boldface type for reserved words
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+\def\){{\tentex\kern-.05em}\discretionary{\hbox{\tentex\BS}}{}{}}
+\def\AT{@} % at sign for control text (not needed in versions >= 2.9)
+\def\ATL{\par\noindent\bgroup\catcode`\_=12 \postATL} % print @l in limbo
+\def\postATL#1 #2 {\bf letter \\{\uppercase{\char"#1}}
+ tangles as \tentex "#2"\egroup\par}
+\def\noATL#1 #2 {}
+\def\noatl{\let\ATL=\noATL} % suppress output from @l
+\def\ATH{{\acrofalse\X\kern-.5em:Preprocessor definitions\X}}
+\let\PB=\relax % hook for program brackets |...| in TeX part or section name
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\chardef\RB=`\} % right brace in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+\chardef\CF=`\^ % circumflex character in a string
+
+\newbox\PPbox % symbol for ++
+\setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+\def\PP{\copy\PPbox}
+\newbox\MMbox \setbox\MMbox=\hbox{\kern.5pt\raise1pt\hbox{\sevensy\char0
+ \kern-1pt\char0}\kern.5pt}
+\def\MM{\copy\MMbox}
+\newbox\MGbox % symbol for ->
+\setbox\MGbox=\hbox{\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+\def\MG{\copy\MGbox}
+\def\MRL#1{\mathrel{\let\K==#1}}
+%\def\MRL#1{\KK#1}\def\KK#1#2{\buildrel\;#1\over{#2}}
+\let\GG=\gg
+\let\LL=\ll
+\let\NULL=\Lambda
+\mathchardef\AND="2026 % bitwise and; also \& (unary operator)
+\let\OR=\mid % bitwise or
+\let\XOR=\oplus % bitwise exclusive or
+\def\CM{{\sim}} % bitwise complement
+\newbox\MODbox \setbox\MODbox=\hbox{\eightrm\%}
+\def\MOD{\mathbin{\copy\MODbox}}
+\def\DC{\kern.1em{::}\kern.1em} % symbol for ::
+\def\PA{\mathbin{.*}} % symbol for .*
+\def\MGA{\mathbin{\MG*}} % symbol for ->*
+\def\this{\&{this}}
+
+\newbox\bak \setbox\bak=\hbox to -1em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind em\noindent\kern\ind em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+\def\8{\hskip-\ind em\hskip 2em} % no indentation
+
+\newcount\gdepth % depth of current major group, plus one
+\newcount\secpagedepth
+\secpagedepth=3 % page breaks will occur for depths -1, 0, and 1
+\newtoks\gtitle % title of current major group
+\newskip\intersecskip \intersecskip=12pt minus 3pt % space between sections
+\let\yskip=\smallskip
+\def\?{\mathrel?}
+\def\note#1#2.{\Y\noindent{\hangindent2em%
+ \baselineskip10pt\eightrm#1~\ifacro{\pdfnote#2.}\else#2\fi.\par}}
+
+\newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD
+\newtoks\toksE \newtoks\toksF \newtoks\usersanitizer
+\newcount\countA \countA=0 \newcount\countB \countB=0
+\newcount\countC \countC=0
+\newif\iftokprocessed \newif\ifTnum \newif\ifinstr
+{\def\\{\global\let\spacechar= }\\ }
+
+\ifacro % The following are pdf macros
+\def\thewidth{\the\wd0 \space}
+\def\theheight{\the\ht\strutbox\space}
+\def\thedepth{\the\dp\strutbox\space}
+\ifpdftex
+ \ifx\pdfannotlink\undefined\let\pdfannotlink\pdfstartlink\fi% for pdfTeX 0.14
+ \def\pdflink#1#2{\hbox{\pdfannotlink height\ht\strutbox depth\dp\strutbox
+ attr{/Border [0 0 0]} goto num #1 \Blue #1\Black\pdfendlink}} % changed 3.69
+\else\def\pdflink#1#2{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
+ depth \thedepth << /Type /Annot /Subtype /Link
+ /Border [0 0 0] /A << /S /GoTo /D (#2) >> >>}\box0\relax}\fi
+\def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA}
+\def\firstsecno#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}%
+ \def\makenote{\addtokens\toksB{\the\toksC}\def\makenote{\toksD={}
+ \toksC={}\let\space\empty}\makenote}\maketoks}}
+\def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+\def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}%
+ \ifcat\noexpand\first0\countB=`#1\else\countB=0\fi\toksA={#2}}
+\def\maketoks{\expandafter\poptoks\the\toksA|ENDTOKS|%
+ \ifnum\countB>`9 \countB=0 \fi
+ \ifnum\countB<`0
+ \ifnum0=\countC\else\makenote\fi
+ \ifx\first.\let\next=\maketoksdone\else
+ \let\next=\maketoks
+ \addtokens\toksB{\the\toksD}
+ \ifx\first,\addtokens\toksB{\space}\fi
+ \fi
+ \else \addtokens\toksC{\the\toksD}\global\countC=1\let\next=\maketoks
+ \fi
+ \next
+}
+\def\makenote{\addtokens\toksB
+ {\noexpand\pdflink{\the\toksC}{\romannumeral\the\toksC}}\toksC={}\global\countC=0}
+\def\maketoksdone{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\def\pdfURL#1#2{\ifpdftex\pdfannotlink height\ht\strutbox depth\dp\strutbox
+ attr {/Border [0 0 0]} user { /Type /Action /Subtype /Link /A
+ << /S /URI /URI (#2) >>}\Blue #1\Black \pdfendlink % changed in 3.69
+ \else \ifpdf{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth\space height \theheight
+ \space depth \thedepth\space << /Border [0 0 0]
+ /Type /Action /Subtype /Link /A << /S /URI /URI (#2) >> >>}\box0\relax}%
+ \else #1 ({\tt#2})\fi\fi}
+{\catcode`\~=12 \gdef\TILDE/{~}} % ~ in a URL
+{\catcode`\_=12 \gdef\UNDER/{_}} % _ in a URL
+\def\sanitizecommand#1#2{\addtokens\usersanitizer
+ {\noexpand\dosanitizecommand\noexpand#1{#2}}}
+\def\dosanitizecommand#1#2{\ifx\nxt#1\addF{#2}\fi}
+
+\catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12
+ \def\lbchar[{] \def\rbchar[}]
+\catcode`\[=12 \catcode`\]=12 \catcode`\{=1 \catcode`\}=2
+\catcode`\~=12 \def\tildechar{~} \catcode`\~=13
+\catcode`\|=0 |catcode`|\=12 |def|bschar{\} |catcode`|\=0 \catcode`\|=12
+\def\makeoutlinetoks{\Tnumfalse\afterassignment\makeolproctok\let\nxt= }
+\def\makeolnexttok{\afterassignment\makeolproctok\let\nxt= }
+\def\makeolgobbletok{\afterassignment\makeolnexttok\let\nxt= }
+\def\addF#1{\addtokens\toksF{#1}\tokprocessedtrue}
+% now comes a routine to "sanitize" section names, for pdf outlines
+\def\makeolproctok{\tokprocessedfalse
+ \let\next\makeolnexttok % default
+ \ifx\nxt\outlinedone\let\next\outlinedone
+ \else\ifx{\nxt \else\ifx}\nxt \Tnumfalse \instrfalse % skip braces
+ \else\ifx$\nxt % or a $ sign
+ \else\ifx^\nxt \addF^\else\ifx_\nxt \addF_% sanitize ^ and _
+ \else\ifx\nxt\spacechar \addF\space
+ \else\if\noexpand\nxt\relax % we have a control sequence; is it one we know?
+ \ifx\nxt~\addF\space
+ \else\ifx\nxt\onespace\addF\space
+ \else\the\usersanitizer
+ \iftokprocessed\else\makeolproctokctli
+ \iftokprocessed\else\makeolproctokctlii
+ \iftokprocessed\else\makeolproctokctliii % if not recognised, skip it
+ \fi\fi\fi\fi\fi
+ \else % we don't have a control sequence, it's an ordinary char
+ \ifx/\nxt \addF{\string\/}% quote chars special to PDF with backslash
+ \else\ifx(\nxt \addF{\string\(}\else\ifx)\nxt \addF{\string\)}%
+ \else\ifx[\nxt \addF{\string\[}\else\ifx]\nxt \addF{\string\]}%
+ \else\expandafter\makeolproctokchar\meaning\nxt
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next
+}
+\def\makeolproctokchar#1 #2 #3{\addF{#3}}
+\def\makeolproctokctli{%
+ \ifx\nxt\CEE\addF{C}\let\next\makeolgobbletok % \CEE/
+ \else\ifx\nxt\UNIX\addF{UNIX}\let\next\makeolgobbletok % \UNIX/
+ \else\ifx\nxt\TEX\addF{TeX}\let\next\makeolgobbletok % \TEX/
+ \else\ifx\nxt\TeX\addF{TeX}\else\ifx\nxt\LaTeX\addF{LaTeX}%
+ \else\ifx\nxt\CPLUSPLUS\addF{C++}\let\next\makeolgobbletok % \CPLUSPLUS/
+ \else\ifx\nxt\Cee\addF{C}%
+ \else\ifx\nxt\PB \let\next\makeolgobbletok \tokprocessedtrue % \PB{...}
+ \else\ifx\nxt\.\tokprocessedtrue\instrtrue % \.{...}
+ % skip \|
+ \else\ifx\nxt\\\ifinstr\addF{\bschar\bschar}\else\tokprocessedtrue\fi
+ \else\ifx\nxt\&\ifinstr\addF&\else\tokprocessedtrue\fi
+ \else\ifx\nxt\~\ifTnum\addF{0}\else\addF\tildechar\fi % 077->\T{\~77}
+ \else\ifx\nxt\_\ifTnum\addF{E}\else\addF_\fi % 0.1E5->\T{0.1\_5}
+ \else\ifx\nxt\^\ifTnum\addF{0x}\else\addF^\fi % 0x77 -> \T{\^77}
+ \else\ifx\nxt\$\ifTnum\tokprocessedtrue\else\addF$\fi % \T{77\$L}
+ \else\ifx\nxt\{\addF\lbchar \else\ifx\nxt\}\addF\rbchar
+ \else\ifx\nxt\ \addF\space \else\ifx\nxt\#\addF{\string\#}%
+ \else\ifx\nxt\PP\addF{++}\else\ifx\nxt\MM\addF{--}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+}
+\def\makeolproctokctlii{%
+ \ifx\nxt\MG\addF{->}\else\ifx\nxt\GG\addF{>>}%
+ \else\ifx\nxt\LL\addF{<<}\else\ifx\nxt\NULL\addF{NULL}%
+ \else\ifx\nxt\AND\addF&\else\ifx\nxt\OR\addF|%
+ \else\ifx\nxt\XOR\addF^\else\ifx\nxt\CM\addF\tildechar
+ \else\ifx\nxt\MOD\addF{\string\%}\else\ifx\nxt\DC\addF{::}%
+ \else\ifx\nxt\PA\addF{.*}\else\ifx\nxt\MGA\addF{->*}%
+ \else\ifx\nxt\this\addF{this}\else\ifx\nxt\?\addF?%
+ \else\ifx\nxt\E\addF{==}\else\ifx\nxt\G\addF{>=}%
+ \else\ifx\nxt\I\addF{!=}\else\ifx\nxt\K\addF{=}%
+ \else\ifx\nxt\l\addF{l}\else\ifx\nxt\L\addF{L}%
+ \else\ifx\nxt\o\addF{o}\else\ifx\nxt\O\addF{O}%
+ \else\ifx\nxt\R\addF!%
+ \else\ifx\nxt\T \Tnumtrue \let\next\makeolgobbletok
+ \tokprocessedtrue % \T{number}
+ \else\ifx\nxt\AM\addF&\else\ifx\nxt\%\addF{\string\%}%
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi
+}
+\def\makeolproctokctliii{%
+ \ifx\nxt\V\addF{||}\else\ifx\nxt\W\addF{&&}\else\ifx\nxt\Z\addF{<=}%
+ \else\ifx\nxt\*\addF*\else\ifx\nxt\Xand\addF{\space and\space}%
+ \else\ifx\nxt\Xandxeq\addF{\space and_eq\space}%
+ \else\ifx\nxt\Xbitand\addF{\space bitand\space}%
+ \else\ifx\nxt\Xbitor\addF{\space bitor\space}%
+ \else\ifx\nxt\Xcompl\addF{\space compl\space}%
+ \else\ifx\nxt\Xnot\addF{\space not\space}%
+ \else\ifx\nxt\Xnotxeq\addF{\space not_eq\space}%
+ \else\ifx\nxt\Xor\addF{\space or\space}%
+ \else\ifx\nxt\Xorxeq\addF{\space or_eq\space}%
+ \else\ifx\nxt\Xxor\addF{\space xor\space}%
+ \else\ifx\nxt\Xxorxeq\addF{\space xor_eq\space}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi
+}
+\def\outlinedone{\edef\outlinest{\global\noexpand\toksE={\the\toksF}}%
+ \outlinest\let\outlinedone=\relax}
+\fi % End of pdf macros
+
+\def\lapstar{\rlap{*}}
+\def\stsec{\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent{\let\*=\lapstar\bf\secstar.\quad}%
+ \ifacro \smash{\raise\baselineskip\hbox to0pt{\let\*=\empty
+ \ifpdftex \pdfdest num \secstar fith%
+ \else \special{pdf: dest (\romannumeral\secstar)
+ [ @thispage /FitH @ypos ]}\fi}}\fi}
+\let\startsection=\stsec
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 } } % begin `define' or `format'
+\def\A{\note{See also section}} % xref for doubly defined section name
+\def\As{\note{See also sections}} % xref for multiply defined section name
+\def\B{\rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 1000 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+\def\C#1{\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$}
+\let\SHC\C % "// short comments" treated like "/* ordinary comments */"
+%\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+%\def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+\def\D{\defin{\#define}} % macro definition
+\let\E=\equiv % equivalence sign
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+% \H is long Hungarian umlaut accent
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+\let\K== % assignment operator
+%\let\K=\leftarrow % "honest" alternative to standard assignment operator
+% \L is Polish letter suppressed-L
+\outer\def\M#1{\MN{#1}\ifon\vfil\penalty-100\vfilneg % beginning of section
+ \vskip\intersecskip\startsection\ignorespaces}
+\outer\def\N#1#2#3.{% beginning of starred section
+ \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
+ \gdepth=#1\gtitle={#3}\MN{#2}%
+ \ifon\ifnum#1<\secpagedepth \vfil\eject % force page break if depth is small
+ \else\vfil\penalty-100\vfilneg\vskip\intersecskip\fi\fi
+ \message{*\secno} % progress report
+ \def\stripprefix##1>{}\def\gtitletoks{#3}%
+ \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
+ \edef\next{\write\cont{\ZZ{\gtitletoks}{#1}{\secno}% write to contents file
+ {\noexpand\the\pageno}{\the\toksE}}}\next % \ZZ{title}{depth}{sec}{page}{ss}
+ \ifpdftex\expandafter\xdef\csname curr#1\endcsname{\secno}
+ \ifnum#1>0\countB=#1 \advance\countB by-1
+ \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi\fi
+ \ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
+ [ @thispage /FitH @ypos ] >>}\fi
+ \ifon\startsection{\bf#3.\quad}\ignorespaces}
+\def\MN#1{\par % common code for \M, \N
+ {\xdef\secstar{#1}\let\*=\empty\xdef\secno{#1}}% remove \* from section name
+ \ifx\secno\secstar \onmaybe \else\ontrue \fi
+ \mark{{{\tensy x}\secno}{\the\gdepth}{\the\gtitle}}}
+% each \mark is {section reference or null}{depth plus 1}{group title}
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+\def\Q{\note{This code is cited in section}} % xref for mention of a section
+\def\Qs{\note{This code is cited in sections}} % xref for mentions of a section
+\let\R=\lnot % logical not
+% \S is section sign
+\def\T#1{\leavevmode % octal, hex or decimal constant
+ \hbox{$\def\?{\kern.2em}%
+% \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant % versions < 3.67
+ \def\$##1{\egroup_{\rm##1}\bgroup}% suffix to constant % in version 3.67
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct \let\^=\hex {#1}$}}
+\def\U{\note{This code is used in section}} % xref for use of a section
+\def\Us{\note{This code is used in sections}} % xref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi %$% section name
+ \XX$\langle\,${\let\I=\ne#2\eightrm\kern.5em
+ \ifacro{\pdfnote#1.}\else#1\fi}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\le
+\let\ZZ=\let % now you can \write the control sequence \ZZ
+\let\*=*
+
+\def\Xand{\W} \def\Xandxeq{\MRL{{\AND}{\K}}} \def\Xbitand{\AND}
+\def\Xbitor{\OR} \def\Xcompl{\CM} \def\Xnot{\R} \def\Xnotxeq{\I} \def\Xor{\V}
+\def\Xorxeq{\MRL{{\OR}{\K}}} \def\Xxor{\XOR} \def\Xxorxeq{\MRL{{\XOR}{\K}}}
+
+%\def\oct{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}} % WEB style
+%\def\hex{\hbox{\rm\char"7D\tt\aftergroup}} % WEB style
+\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}% CWEB style
+\def\hex{\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} % CWEB style
+\def\vb#1{\leavevmode\hbox{\kern2pt\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule\kern2pt}} % verbatim string
+
+\def\onmaybe{\let\ifon=\maybe} \let\maybe=\iftrue
+\newif\ifon \newif\iftitle \newif\ifpagesaved
+
+\newif\ifheader
+\def\lheader{\headertrue\mainfont\the\pageno\eightrm\qquad\grouptitle
+ \hfill\title\qquad\mainfont\topsecno} % top line on left-hand pages
+\def\rheader{\headertrue\mainfont\topsecno\eightrm\qquad\title\hfill
+ \grouptitle\qquad\mainfont\the\pageno} % top line on right-hand pages
+\def\grouptitle{\let\i=I\let\j=J\uppercase\expandafter{\expandafter
+ \takethree\topmark}}
+\def\topsecno{\expandafter\takeone\topmark}
+\def\takeone#1#2#3{#1}
+\def\taketwo#1#2#3{#2}
+\def\takethree#1#2#3{#3}
+\def\nullsec{\eightrm\kern-2em} % the \kern-2em cancels \qquad in headers
+
+\let\page=\pagebody \raggedbottom
+% \def\page{\box255 }\normalbottom % faster, but loses plain TeX footnotes
+\def\normaloutput#1#2#3{\ifodd\pageno\hoffset=\pageshift\fi
+ \shipout\vbox{
+ \vbox to\fullpageheight{
+ \iftitle\global\titlefalse
+ \else\hbox to\pagewidth{\vbox to10pt{}\ifodd\pageno #3\else#2\fi}\fi
+ \vfill#1}} % parameter #1 is the page itself
+ \global\advance\pageno by1}
+
+\gtitle={\.{CWEB} output} % this running head is reset by starred sections
+\mark{\noexpand\nullsec0{\the\gtitle}}
+\def\title{\expandafter\uppercase\expandafter{\jobname}}
+\def\topofcontents{\centerline{\titlefont\title}\vskip.7in
+ \vfill} % this material will start the table of contents page
+\def\startpdf{\ifpdftex\pdfcatalog{/PageMode /UseOutlines}\else
+ \ifpdf{\special{pdf: docview << /PageMode /UseOutlines >>}}\fi\fi}
+\def\botofcontents{\vfill
+ \centerline{\covernote}} % this material will end the table of contents page
+\def\covernote{}
+\def\contentspagenumber{0} % default page number for table of contents
+\newdimen\pagewidth \pagewidth=6.5in % the width of each page
+\newdimen\pageheight \pageheight=8.7in % the height of each page
+\newdimen\fullpageheight \fullpageheight=9in % page height including headlines
+\newdimen\pageshift \pageshift=\hoffset
+ % shift righthand pages wrt lefthand ones (changed in version 3.70)
+\def\magnify#1{\mag=#1\pagewidth=6.5truein\pageheight=8.7truein
+ \fullpageheight=9truein\setpage}
+\def\setpage{\hsize\pagewidth\vsize\pageheight} % use after changing page size
+\def\contentsfile{\jobname.toc} % file that gets table of contents info
+\def\readcontents{\input \contentsfile}
+\def\readindex{\input \jobname.idx}
+\def\readsections{\input \jobname.scn}
+
+\newwrite\cont
+\output{\setbox0=\page % the first page is garbage
+ \openout\cont=\contentsfile
+ \write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
+ \global\output{\normaloutput\page\lheader\rheader}}
+\setpage
+\vbox to \vsize{} % the first \topmark won't be null
+
+\def\ch{\note{The following sections were changed by the change file:}
+ \let\*=\relax}
+\newbox\sbox % saved box preceding the index
+\newbox\lbox % lefthand column in the index
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \def\page{\box255 } \normalbottom
+ \write\cont{} % ensure that the contents file isn't empty
+ \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Index:}
+ \parskip 0pt plus .5pt
+ \outer\def\I##1, ##2.{\par\hangindent2em\noindent##1:\kern1em
+ \ifacro\pdfnote##2.\else##2\fi.} % index entry
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt
+ \readindex}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \ifpdftex \makebookmarks \fi % added in Version 3.68
+ \parfillskip 0pt plus 1fil
+ \def\grouptitle{NAMES OF THE SECTIONS}
+ \let\topsecno=\nullsec
+ \message{Section names:}
+ \output={\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1~\ifacro{\pdfnote##2.}\else{##2}\fi.}}
+ \def\Q{\note{Cited in section}} % crossref for mention of a section
+ \def\Qs{\note{Cited in sections}} % crossref for mentions of a section
+ \def\U{\note{Used in section}} % crossref for use of a section
+ \def\Us{\note{Used in sections}} % crossref for uses of a section
+ \def\I{\par\hangindent 2em}\let\*=*
+ \ifacro \def\outsecname{Names of the sections} \let\Xpdf\X
+% \ifpdftex \makebookmarks \pdfdest name {NOS} fitb % in versions < 3.68
+ \ifpdftex \pdfdest name {NOS} fith % changed in version 3.69
+ \pdfoutline goto name {NOS} count -\secno {\outsecname}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
+ \else\ifpdf
+ \special{pdf: outline -1 << /Title (\outsecname)
+ /Dest [ @thispage /FitH @ypos ] >>}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \special{pdf: outline 0 << /Title (\the\toksE)
+ /A << /S /GoTo /D (\romannumeral\the\toksA) >> >>}}
+ \fi\fi\fi
+ \readsections}
+\def\makebookmarks{\let\ZZ=\writebookmarkline \readcontents\relax}
+\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi} % Petr Olsak's macros from texinfo.tex
+\def\advancenumber#1{\countA=\expnumber{#1}\relax \advance\countA by1
+ \expandafter\xdef\csname#1\endcsname{\the\countA}}
+\def\writebookmarkline#1#2#3#4#5{{%
+ \let\(=\let \let\)=\let \let\[=\let \let\]=\let \let\/=\let
+ \pdfoutline goto num #3 count -\expnumber{chunk#2.#3} {#5}}}
+\def\con{\par\vfill\eject % finish the section names
+% \ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage \output={\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber
+ \def\grouptitle{TABLE OF CONTENTS}
+ \message{Table of contents:}
+ \topofcontents \startpdf
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \let\ZZ=\contentsline
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+\def\contentsline#1#2#3#4#5{\ifnum#2=0 \smallbreak\fi
+ \line{\consetup{#2}#1
+ \rm\leaders\hbox to .5em{.\hfil}\hfil
+ \ \ifacro\pdflink{#3}{\romannumeral#3}\else#3\fi\hbox to3em{\hss#4}}}
+\def\consetup#1{\ifcase#1 \bf % depth -1 (@**)
+ \or % depth 0 (@*)
+ \or \hskip2em % depth 1 (@*1)
+ \or \hskip4em \or \hskip6em \or \hskip8em \or \hskip10em % depth 2,3,4,5
+ \else \hskip12em \fi} % depth 6 or more
+\def\noinx{\let\inx=\end} % no indexes or table of contents
+\def\nosecs{\let\FIN=\fin \def\fin{\let\parfillskip=\end \FIN}}
+ % no index of section names or table of contents
+\def\nocon{\let\con=\end} % no table of contents
+\def\today{\ifcase\month\or
+ January\or February\or March\or April\or May\or June\or
+ July\or August\or September\or October\or November\or December\fi
+ \space\number\day, \number\year}
+\newcount\twodigits
+\def\hours{\twodigits=\time \divide\twodigits by 60 \printtwodigits
+ \multiply\twodigits by-60 \advance\twodigits by\time :\printtwodigits}
+\def\gobbleone1{}
+\def\printtwodigits{\advance\twodigits100
+ \expandafter\gobbleone\number\twodigits
+ \advance\twodigits-100 }
+\def\TeX{{\ifmmode\it\fi
+ \leavevmode\hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
+\def\datethis{\def\startsection{\leftline{\sc\today\ at \hours}\bigskip
+ \let\startsection=\stsec\stsec}}
+ % say `\datethis' in limbo, to get your listing timestamped before section 1
+%\def\datecontentspage{% versions up to 3.65
+% \def\topofcontents{\leftline{\sc\today\ at \hours}\bigskip
+% \centerline{\titlefont\title}\vfill}} % timestamps the contents page
+\def\datecontentspage{% changed in version 3.66
+ \def\botofcontents{\vfill
+ \centerline{\covernote}
+ \bigskip
+ \leftline{\sc\today\ at \hours}}} % timestamps the contents page
diff --git a/Build/source/texk/web2c/cwebdir/cwebman-w2c.ch b/Build/source/texk/web2c/cwebdir/cwebman-w2c.ch
new file mode 100644
index 00000000000..929896ee31c
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebman-w2c.ch
@@ -0,0 +1,333 @@
+@q Changes for CWEB in TeX Live from numerous contributors. @>
+@q This file is in the Public Domain. @>
+
+@q Most of the original Kpathsea changes by Wlodek Bzyl and Olaf Weber @>
+@q were merged with the set of change files of the CWEBbin project; @>
+@q see https://github.com/ascherer/cwebbin for the original parts. @>
+
+@q This stripped change file {comm,ctang,cweav,ctwill,cwebman}-w2c.ch @>
+@q has been created from the elaborate set of change files @>
+@q {comm,ctang,cweav,cwebman}-patch.ch, @>
+@q {comm,cweav,cwebman}-extensions.ch, {comm,ctang,cweav}-output.ch, @>
+@q {comm,ctang,cweav}-i18n.ch, and cweav-twill.ch for CTWILL, and @>
+@q {comm,ctang,cweav,ctwill,cwebman}-texlive.ch with the 'tie' processor @>
+@q and is used as a monolithic changefile for {common,ctangle,cweave}.w @>
+@q and cwebman.tex in TeX Live. @>
+
+@q Please send comments, suggestions, etc. to tex-k@@tug.org. @>
+
+@x
+\input cwebmac
+\acrofalse\pdffalse\pdftexfalse
+@y
+\input cwebmac
+@z
+
+@x
+\def\page{\box255 } \normalbottom
+@y
+\let\page=\pagebody \raggedbottom
+\newcount\footnotecount \footnotecount 1\relax
+\def\cwebfootnote#1{\footnote{${}^{\the\footnotecount}$}{#1}%
+ \advance\footnotecount by 1\relax}
+@z
+
+@x
+\outer\def\section #1.{\penalty-500\bigskip
+ \centerline{\sectionfont\def\.##1{{\twelvett##1}} #1}\nobreak\vskip 6pt
+ \everypar{\hskip-\parindent\everypar{}}}
+@y
+\ifacro
+ \pdfpagewidth=\pagewidth \advance\pdfpagewidth by 2cm
+ \pdfpageheight=\pageheight \advance\pdfpageheight by 3cm
+ \ifpdftex \pdfhorigin=1cm \pdfvorigin=1cm
+ \else \advance\pdfpageheight by 1cm \global\pageshift=-1.54cm
+ \global\hoffset=-1.54cm \global\voffset=-1.54cm \fi
+\fi
+
+\newcount\destcount \destcount=1\relax
+
+\def\subsections{0}
+\outer\def\section #1.{\penalty-500\bigskip
+ \centerline{\sectionfont\def\.##1{{\twelvett##1}}
+ \ifacro\vbox to 0pt{\kern-2.5ex\relax
+ \ifpdftex\pdfdest num \destcount fitbh\relax
+ \else\special{pdf: dest (\the\destcount) [ @thispage /FitBH @ypos ]}\fi
+ \def\.##1{##1}\def\TeX{TeX}%
+ \ifpdftex\pdfoutline goto num \destcount
+ \ifnum\subsections>0 count -\subsections\fi {#1}\relax
+ \else\special{pdf: outline 0 << /Title (#1)
+ /A << /S /GoTo /D (\the\destcount) >> >>}\fi
+ \gdef\subsections{0}%
+ \global\advance\destcount by 1\relax
+ \kern2.5ex\relax
+ }\fi #1}\nobreak\vskip 6pt
+ \everypar{\hskip-\parindent\everypar{}}}
+
+\def\appA{15}
+\def\appB{16}
+\def\appC{17}
+
+\def\Appendix#1{\leavevmode
+ \ifacro\ifpdftex
+ \pdfstartlink attr{/Border[0 0 0]} goto num\csname app#1\endcsname\relax
+ \Blue\hbox{Appendix}~#1\Black
+ \pdfendlink
+ \else
+ \setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{\hbox{Appendix}~#1}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
+ depth \thedepth << /Type /Annot /Subtype /Link /Border [0 0 0]
+ /A << /S /GoTo /D (\csname app#1\endcsname) >> >>}\box0\relax
+ \fi\else Appendix~#1\fi}
+
+\newcount\subdestcount \subdestcount=151\relax
+
+\outer\def\subsection #1.{\ifacro
+ \ifpdftex\pdfdest num \subdestcount fitbh\relax
+ \pdfoutline goto num \subdestcount {#1}\relax
+ \else\special{pdf: dest (\the\subdestcount) [ @thispage /FitBH @ypos ]}%
+ \special{pdf: outline 1 << /Title (#1)
+ /A << /S /GoTo /D (\the\subdestcount) >> >>}\fi
+ \global\advance\subdestcount by 1\relax
+ \fi}
+@z
+
+@x
+\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.2)}
+@y
+\def\Kpathsea/{{\mc KPATHSEA\spacefactor1000}}
+\def\runninghead{{\tentt CWEB} USER MANUAL (Version 4.2 [\TeX~Live])}
+@z
+
+@x
+\vskip 18pt\centerline{(Version 4.2 --- February 2021)}
+@y
+\vskip 18pt\centerline{(Version 4.2 --- February 2021)%
+\footnote*{This document describes the extended \.{CWEB} (Version 4.2 [\TeX~Live]).}}
+@z
+
+@x
+Internet page \.{http://www-cs-faculty.stanford.edu/\char`\~knuth/cweb.html}
+@y
+Internet page
+\pdfURL{\.{http://www-cs-faculty.stanford.edu/\char`\~knuth/cweb.html}}%
+ {http://www-cs-faculty.stanford.edu/\TILDE/knuth/cweb.html}
+@z
+
+@x
+\.{https://github.com/ascherer/cweb} with the really current news.
+@y
+\pdfURL{\.{https://github.com/ascherer/cweb}}%
+ {https://github.com/ascherer/cweb}
+with the really current news.
+@z
+
+@x
+should be sent to the \TeX-related mailing list \.{tex-k@tug.org}.
+@y
+should be sent to the \TeX-related mailing list
+\pdfURL{\.{tex-k@tug.org}}%
+ {mailto:tex-k@tug.org}.
+@z
+
+@x
+email address in a \.{CWEB} file (e.g., \.{tex-k@@tug.org}).
+@y
+email address in a \.{CWEB} file (e.g.,
+\pdfURL{\.{tex-k@@tug.org}}%
+ {mailto:tex-k@tug.org}).
+@z
+
+@x
+it cannot find them in the current directory.
+@y
+it cannot find them in the current directory.%
+\cwebfootnote{\acrofalse In this extended implementation, if an \.{@i}nclude
+file can not be found in the current directory, \.{CWEB} will use the
+conventions of the \Kpathsea/ library as outlined in section~\X91:File lookup
+with \Kpathsea/\X~of \pdfURL{appendix~D}{common-changes.pdf} to look for it.
+% FIXME
+(This is true for any other input or change file lookup.)}
+@z
+
+@x
+except for error messages.
+@y
+except for error messages.%
+\cwebfootnote{\.{CWEB} in \TeX~Live runs `\.{--quiet}ly', i.\,e.,
+options `\.{b}', `\.{h}', and `\.{p}' are `off' by default.}
+@z
+
+@x
+output by \.{CWEAVE}. (On by default.) (Has no effect on \.{CTANGLE}.)
+@y
+output by \.{CWEAVE}. (On by default.) (Has no effect on \.{CTANGLE}.)%
+\cwebfootnote{This extended version of \.{CWEB} adds the following options
+to the list:
+\hfil\smallskip
+\option d Set the debugging variable \\{kpathsea\_debug} to the numeric
+value $N\in[0,127]$ of this option. See section~93 % FIXME
+of \pdfURL{appendix~D}{common-changes.pdf} for details.
+\hfil\vskip\normallineskip
+\option i Indent parameters in function declarations. This causes the
+formal parameter declarations in function heads to be indented. (On by
+default; \.{-i} typesets declarations flush left; some people think this
+to be more logical than indenting them) (Has no effect on \.{CTANGLE}.)
+\hfil\vskip\normallineskip
+\option l This option takes the string of characters to its right as its
+argument to switch between different user languages and macro packages.
+For example, if you call \.{CWEAVE} with the `\.{+ld}' (or `\.{-ld}') option,
+the German \.{CWEB} macros \.{dcwebmac.tex} will be loaded in the first line
+of output instead of the English ones. To avoid conflicts, the Danish
+macros could be called \.{dkcwebmac.tex} and would be included by `\.{+ldk}'.
+(Off by default) (Has no effect on \.{CTANGLE}.)
+\hfil\vskip\normallineskip
+\option o Separate declarations and the first statement in a function block.
+\.{CWEAVE} automatically inserts a bit of extra space. (On by default.)
+(Has no effect on \.{CTANGLE}.)
+\hfil\vskip\normallineskip
+\option t Overwrite output files with temporary output only if changes occur.
+(On by default.)}
+@z
+
+@x
+Sometimes things don't work as smoothly, and you get a bunch of
+@y
+\acrofalse\pdftexfalse\pdffalse
+Sometimes things don't work as smoothly, and you get a bunch of
+@z
+
+@x
+`$\\{main}(\\{argc},\39\\{argv}{}$)'.
+@y
+`$\\{main}(\\{argc},\39\\{argv}{}$)'.
+\ifx\pdf+\pdftrue\fi
+\ifx\pdfoutput\undefined \pdftexfalse \else\ifnum\pdfoutput=0 \pdftexfalse
+\else \pdftextrue \pdfoutput=1\fi\fi
+\ifpdf\acrotrue\fi \ifpdftex\acrotrue\fi
+@z
+
+@x
+\section Hypertext and hyperdocumentation.
+@y
+\vfill\eject
+\section Hypertext and hyperdocumentation.
+@z
+
+@x
+the program sources at \.{ftp://ftp.cs.stanford.edu/pub/ctwill}.
+@y
+the program sources at
+\pdfURL{\.{ftp://ftp.cs.stanford.edu/pub/ctwill}}%
+ {ftp://ftp.cs.stanford.edu/pub/ctwill}.%
+\cwebfootnote{\TeX~Live comes with an up-to-date \.{ctwill} executable -- and
+its associated helpers -- out of the box.}
+@z
+
+@x
+As an example of a real program written in \.{CWEB}, Appendix~A
+@y
+As an example of a real program written in \.{CWEB}, \Appendix A
+@z
+
+@x
+Appendix B is the file that sets \TEX/ up to accept
+the output of \.{CWEAVE}, and Appendix~C discusses how to use some of those
+@y
+\Appendix B is the file that sets \TEX/ up to accept
+the output of \.{CWEAVE}, and \Appendix C discusses how to use some of those
+@z
+
+@x
+appendices D, E, and~F, which exhibit the complete source code for
+\.{CTANGLE} and \.{CWEAVE}.
+
+\vfil\eject\titletrue
+@y
+appendices \pdfURL{D}{common.pdf}, \pdfURL{E}{ctangle.pdf},
+and~\pdfURL{F}{cweave.pdf}, which exhibit the complete source code for
+\.{CTANGLE} and \.{CWEAVE}.%
+\cwebfootnote{Actually, \pdfURL{Appendix~D}{common.pdf} contains the source
+code for \.{COMMON}, and the additional \pdfURL{Appendix~G}{ctwill.pdf}
+exhibits the source code for \.{CTWILL}, which is based on \.{CWEAVE}.}
+
+\eject\titletrue
+@z
+
+@x
+\section Appendix A: Excerpts from a \.{CWEB} Program.
+@y
+\def\subsections{4}
+\section Appendix A: Excerpts from a \.{CWEB} Program.
+\subsection CWEB file format.
+@z
+
+@x
+generated sections 27--31 of the file \.{common.w}, which contains
+@y
+generated sections 27--31 of the file
+\pdfURL{\.{common.w}}{common.pdf}, which contains
+@z
+
+@x
+\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CTANGLE}}
+@y
+\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CTANGLE}}
+\subsection Translation by CTANGLE.
+@z
+
+@x
+\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CWEAVE}}
+@y
+\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CWEAVE}}
+\subsection Translation by CWEAVE.
+@z
+
+@x
+\def\runninghead{APPENDIX A --- FINAL DOCUMENT}
+
+And here's what the same excerpt looks like when typeset.
+(Can you spot the typographical nicety used in the \.{CWEB} code?)
+\let\K=\leftarrow
+@y
+\def\runninghead{APPENDIX A --- FINAL DOCUMENT}
+\subsection Final document.
+
+\acrofalse\pdftexfalse\pdffalse
+And here's what the same excerpt looks like when typeset.
+(Can you spot the typographical niceties used in the \.{CWEB} code?)
+\let\K=\leftarrow
+\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+@z
+
+@x
+\vfil\eject\titletrue
+@y
+\vfil\eject\titletrue
+\ifx\pdf+\pdftrue\fi
+\ifx\pdfoutput\undefined \pdftexfalse \else\ifnum\pdfoutput=0 \pdftexfalse
+\else \pdftextrue \pdfoutput=1\fi\fi
+\ifpdf\acrotrue\fi \ifpdftex\acrotrue\fi
+@z
+
+@x
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4.2)\}{ }\\vfill\}}\cr}$$
+@y
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4.2)\}{ }\\vfill\}}\cr}$$
+@z
+
+@x
+if you have a duplex printer. Appendices D, E, and F of the complete
+@y
+if you have a duplex printer. Appendices \pdfURL{D}{common.pdf},
+\pdfURL{E}{ctangle.pdf}, and \pdfURL{F}{cweave.pdf}\cwebfootnote{And
+\pdfURL{Appendix~G}{ctwill.pdf}.} of the complete
+@z
+
+@x
+\point 20. Furthermore, group titles can be converted to an arbitrary
+@y
+\vfill\eject
+\point 20. Furthermore, group titles can be converted to an arbitrary
+@z
+
diff --git a/Build/source/texk/web2c/cwebdir/cwebman.tex b/Build/source/texk/web2c/cwebdir/cwebman.tex
new file mode 100644
index 00000000000..df652232b72
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/cwebman.tex
@@ -0,0 +1,1774 @@
+% This file generates the user manual; TeX it, don't read it!
+% update 14 Nov 2016 by DEK: corrected obsolete remarks re debugging info
+
+\def\tangref{3} % where the main explanation of CTANGLing is given
+\input cwebmac
+\acrofalse\pdffalse\pdftexfalse
+\def\page{\box255 } \normalbottom
+\parskip 0pt plus 1pt
+\def\RA{\char'31 } % right arrow
+\def\hang{\hangindent 4em\ignorespaces}
+\font\eightrm=cmr8
+\font\ninerm=cmr9
+\font\ninett=cmtt9
+\font\eighttt=cmtt8
+\font\twelvett=cmtt12
+\font\quoterm=cmssq8
+\font\quoteit=cmssqi8
+\font\authorfont=cmr12
+\font\sectionfont=cmbx12
+
+\def\pb{\.{|...|}}
+\def\v{\.{\char'174}} % vertical (|) in typewriter font
+\def\lpile{\def\cr{\hfill\endline}\matrix} % I only use \lpile by itself
+\abovedisplayskip=.5\abovedisplayskip
+\belowdisplayskip=.5\belowdisplayskip
+\abovedisplayshortskip=.5\abovedisplayshortskip
+\belowdisplayshortskip=.5\belowdisplayshortskip
+\advance\baselineskip by -.5pt
+\advance\pageheight by \baselineskip % the manual just got a bit longer
+\advance\fullpageheight by \baselineskip
+\setpage
+
+\outer\def\section #1.{\penalty-500\bigskip
+ \centerline{\sectionfont\def\.##1{{\twelvett##1}} #1}\nobreak\vskip 6pt
+ \everypar{\hskip-\parindent\everypar{}}}
+
+\def\lheader{\mainfont\the\pageno\hfill\sc\runninghead\hfill}
+\def\rheader{\hfill\sc\runninghead\hfill\mainfont\the\pageno}
+\def\runninghead{{\tentt CWEB} USER MANUAL (VERSION 4.2)}
+
+% This verbatim mode assumes that ! marks are !! in the text being copied.
+\def\verbatim{\begingroup
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt \let\!=!
+ \catcode`\ =13 \catcode`\^^M=13
+ \tt \catcode`\!=0 \verbatimdefs \verbatimgobble}
+{\catcode`\^^M=13{\catcode`\ =13\gdef\verbatimdefs{\def^^M{\ \par}\let =\ }} %
+ \gdef\verbatimgobble#1^^M{}}
+
+\null\vfill
+\centerline{\titlefont The {\ttitlefont CWEB} System of
+ Structured Documentation}
+\vskip 18pt\centerline{(Version 4.2 --- February 2021)}
+\vskip 24pt
+\centerline{\authorfont Donald E. Knuth and Silvio Levy}
+\vfill
+
+\noindent
+\TeX\ is a trademark of the American Mathematical Society.
+
+\noindent
+Acrobat Reader is a trademark of Adobe Systems Incorporated.
+
+\bigskip\noindent
+The printed form of this manual is copyright \copyright\ 1994
+ by Addison-Wesley Publishing Company, Inc. All rights reserved.
+\smallskip\noindent
+The electronic form is copyright \copyright\ 1987, 1990, 1993, 2000
+ by Silvio Levy and Donald E. Knuth.
+
+\bigskip\noindent
+Permission is granted to make and distribute verbatim copies of the
+electronic form of this document provided that the electronic copyright
+notice and this permission notice are preserved on all copies.
+
+\smallskip\noindent
+Permission is granted to copy and distribute modified versions of the
+electronic form 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.
+
+\smallskip\noindent
+Individuals may make copies of the documentation from the electronic files
+for their own personal use.
+
+\smallskip\noindent
+Internet page \.{http://www-cs-faculty.stanford.edu/\char`\~knuth/cweb.html}
+contains current info about \.{CWEB} and related topics.
+
+\smallskip\noindent
+From there you can also reach the \.{CWEB} development page
+\.{https://github.com/ascherer/cweb} with the really current news.
+
+\pageno=0 \titletrue\eject
+
+\titletrue
+\centerline{\titlefont The {\ttitlefont CWEB} System of
+ Structured Documentation}
+
+\vskip 15pt plus 3pt minus 3pt
+\centerline{\authorfont Donald E. Knuth and Silvio Levy}
+
+\vskip 24pt plus 3pt minus 3pt
+\noindent
+This document describes a version of Don Knuth's \.{WEB} system,
+adapted to \CEE/ by Silvio Levy. Since its creation in 1987, \.{CWEB}
+has been revised and enhanced in various ways, by both Knuth and Levy.
+We now believe that its evolution is near an end; however, bug
+reports, suggestions and comments are still welcome, and
+should be sent to the \TeX-related mailing list \.{tex-k@tug.org}.
+
+Readers who are familiar with Knuth's memo ``The \.{WEB} System of Structured
+Documentation'' will be able
+to skim this material rapidly, because \.{CWEB} and \.{WEB} share
+the same philosophy and (essentially) the same syntax. In some respects
+\.{CWEB} is a simplification
+of \.{WEB}: for example, \.{CWEB} does not need \.{WEB}'s features
+for macro definition and string handling, because \CEE/ and its
+preprocessor already take care of macros and strings. Similarly, the \.{WEB}
+conventions of denoting octal and hexadecimal constants by \.{@'77}
+and \.{@"3f} are replaced by \CEE/'s conventions \.{077} and
+\.{0x3f}. All other features of \.{WEB} have been
+retained, and new features have been added.
+
+We thank all who contributed suggestions and criticism to
+the development of \.{CWEB}. We are especially grateful to Steve
+Avery, Nelson Beebe, Hans-Hermann Bode, Klaus Guntermann, Norman Ramsey,
+Joachim Schnitter, and Saroj Mahapatra,
+who contributed code, and to Cameron Smith, who
+made many suggestions improving the manual. Ramsey has made
+literate programming accessible to users of yet other languages by means of
+his \.{SPIDER} system [see {\sl Communications of the ACM\/ \bf32} (1989),
+1051--1055]. The book {\sl Literate Programming\/} by Knuth (1992) contains
+a comprehensive bibliography of related early work.
+Bode, Schnitter, and Mahapatra adapted \.{CWEB} so that it works
+for \CPLUSPLUS/ as well; therefore in the text below you can read \CPLUSPLUS/
+for \CEE/ if you so desire.
+
+\section Introduction.
+The philosophy behind \.{CWEB} is
+that programmers who want to provide the best
+possible documentation for their programs need two things
+simultaneously: a language like \TEX/ for formatting, and a language like
+\CEE/ for programming. Neither type of language can provide the
+best documentation by itself. But when both are appropriately combined, we
+obtain a system that is much more useful than either language separately.
+
+The structure of a software program may be thought of as a ``web'' that is
+made up of many interconnected pieces. To document such a program, we want
+to explain each individual part of the web and how it relates to its
+neighbors. The typographic tools provided by \TEX/ give us an opportunity
+to explain the local structure of each part by making that structure
+visible, and the programming tools provided by \CEE/ make it possible
+for us to specify the algorithms formally and unambiguously. By combining
+the two, we can develop a style of programming that maximizes our ability
+to perceive the structure of a complex piece of software, and at the same
+time the documented programs can be mechanically translated into a working
+software system that matches the documentation.
+
+The \.{CWEB} system consists of two programs named \.{CWEAVE} and \.{CTANGLE}.
+When writing a \.{CWEB} program the user keeps the
+\CEE/ code and the documentation in the same file, called the \.{CWEB}
+file and generally named \.{something.w}. The command
+`\.{cweave} \.{something}' creates an output file \.{something.tex}, which
+can then be fed to \TEX/, yielding a ``pretty printed'' version of
+\.{something.w} that correctly handles
+typographic details like page layout and the use of indentation,
+italics, boldface, and mathematical symbols. The typeset output also
+includes extensive cross-index
+information that is gathered automatically. Similarly, if you run the
+command `\.{ctangle} \.{something}' you will get a \CEE/ file \.{something.c},
+which can then be compiled to yield executable code.
+
+Besides providing a documentation tool, \.{CWEB} enhances the \CEE/
+language by providing the
+ability to permute pieces of the program text, so that a large system can
+be understood entirely in terms of small sections and their local
+interrelationships. The \.{CTANGLE} program is so named because it takes a
+given web and moves the sections from their web structure into the order
+required by \CEE/; the advantage of programming in \.{CWEB} is that the
+algorithms can be expressed in ``untangled'' form, with each section
+explained separately. The \.{CWEAVE} program is so named because it takes
+a given web and intertwines the \TEX/ and \CEE/ portions contained in
+each section, then it knits the whole fabric into a structured document.
+(Get it? Wow.) Perhaps there is some deep connection here with the fact
+that the German word for ``weave'' is ``{\it webe\/}'', and the
+corresponding Latin imperative is ``{\it texe\/}''!
+
+A user of \.{CWEB} should be fairly familiar with the \CEE/
+programming language. A minimal amount of acquaintance with \TEX/ is also
+desirable, but in fact it can be acquired as one uses \.{CWEB}, since
+straight text can be typeset in \TEX/ with virtually no knowledge of
+that language. To someone familiar with both \CEE/ and \TEX/ the amount of
+effort necessary to learn the commands of \.{CWEB} is small.
+
+\section Overview.
+Two kinds of material go into \.{CWEB} files: \TEX/ text and \CEE/ text.
+A programmer writing in \.{CWEB} should be thinking both of the
+documentation and of the \CEE/ program being created;
+i.e., the programmer should be instinctively aware of the different
+actions that \.{CWEAVE} and \.{CTANGLE} will perform on the \.{CWEB} file.
+\TEX/ text is essentially copied without change by \.{CWEAVE}, and it is
+entirely deleted by \.{CTANGLE}; the \TEX/ text is ``pure
+documentation.'' \CEE/ text, on the other hand, is formatted by
+\.{CWEAVE} and it is shuffled around by \.{CTANGLE}, according to rules that
+will become clear later. For now the important point to keep in mind is
+that there are two kinds of text. Writing \.{CWEB} programs is something
+like writing \TEX/ documents, but with an additional ``\CEE/ mode''
+that is added to \TEX/'s horizontal mode, vertical mode, and math mode.
+
+A \.{CWEB} file is built up from units called {\sl sections\/} that are more
+or less self-contained. Each section has three parts:
+
+\yskip\item{$\bullet$} A \TEX/ part, containing explanatory material about what
+is going on in the section.
+
+\item{$\bullet$} A middle part, containing macro definitions that serve as
+abbreviations for \CEE/ constructions that would be less comprehensible
+if written out in full each time. They are turned by \.{CTANGLE} into
+preprocessor macro definitions.
+
+\item{$\bullet$} A \CEE/ part, containing a piece of the program that
+\.{CTANGLE} will produce. This \CEE/ code should ideally be about a
+dozen lines long, so that it is easily comprehensible as a unit and so
+that its structure is readily perceived.
+
+\yskip\noindent The three parts of each section must appear in this order;
+i.e., the \TEX/ commentary must come first, then the middle part, and
+finally the \CEE/ code. Any of the parts may be empty.
+
+A section begins with either of the symbols `\.{@\ }' or `\.{@*}', where
+`\.{\ }' denotes a blank space. A section ends
+at the beginning of the next section (i.e., at the next
+`\.{@\ }' or `\.{@*}'), or at the end of the file, whichever comes first.
+The \.{CWEB} file may also contain material that is not part of any section
+at all, namely the text (if any) that occurs before the first section.
+Such text is said to be ``in limbo''; it is ignored by \.{CTANGLE}
+and copied essentially verbatim by \.{CWEAVE}, so its function is to
+provide any additional formatting instructions that may be desired in the
+\TEX/ output. Indeed, it is customary to begin a \.{CWEB} file with
+\TEX/ code in limbo that loads special fonts, defines special macros,
+changes the page sizes, and/or produces a title page.
+
+Sections are numbered consecutively, starting with 1. These numbers appear
+at the beginning of each section of the \TEX/ documentation output by
+\.{CWEAVE}, and they appear
+as bracketed comments at the beginning and end of the code generated by that
+section in the \CEE/ program output by \.{CTANGLE}.
+
+\section Section Names.
+Fortunately, you never mention these numbers yourself when you are writing
+in \.{CWEB}. You just say `\.{@\ }' or `\.{@*}' at the beginning of each
+new section, and the numbers are supplied automatically by \.{CWEAVE} and
+\.{CTANGLE}. As far as you are concerned, a section has a
+{\sl name\/} instead of a number; its name is specified by writing
+`\.{@<}' followed by \TEX/ text followed by `\.{@>}'. When \.{CWEAVE}
+outputs a section name, it replaces the `\.{@<}' and `\.{@>}' by
+angle brackets and inserts the section number in small type. Thus, when you
+read the output of \.{CWEAVE} it is easy to locate any section that is
+referred to in another section.
+
+For expository purposes, a section name should be a good description of the
+contents of that section; i.e., it should stand for the abstraction
+represented by the section. Then the section can be ``plugged into'' one or
+more other sections in such a way
+that unimportant details of its inner workings
+are suppressed. A section name therefore ought to be long enough to convey
+the necessary meaning.
+
+Unfortunately, it is laborious to type
+such long names over and over again, and it is also difficult to specify a
+long name twice in exactly the same way so that \.{CWEAVE} and \.{CTANGLE}
+will be able to match the names to the sections. To ameliorate this situation,
+\.{CWEAVE} and \.{CTANGLE} let you abbreviate a section name, so long as
+the full name appears somewhere in the \.{CWEB} file; you can type simply
+`\.{@<$\alpha$...@>}', where $\alpha$ is any string that is a prefix of
+exactly one section name appearing in the file. For example, `\.{@<Clear
+the arrays@>}' can be abbreviated to `\.{@<Clear...@>}' if no other section
+name begins with the five letters `\.{Clear}'. Elsewhere
+you might use the abbreviation `\.{@<Clear t...@>}', and so on.
+
+Section names must otherwise match character for character, except
+that consecutive characters of white space (spaces, tab marks, newlines, and/or
+form feeds) are treated as equivalent to a single space, and such spaces are
+deleted at the beginning and end of the name. Thus, `\.{@< Clear { }the
+arrays @>}' will also match the name in the previous example.
+Spaces following the ellipsis in abbreviations are ignored as well, but
+not those before, so that `\.{@<Clear t ...@>}' would not match
+`\.{@<Clear the arrays@>}'.
+
+\section What \.{CTANGLE} Does.
+We have said that a section begins with `\.{@\ }' or `\.{@*}', but we
+didn't say how it gets divided up into a \TEX/ part, a middle part,
+and a \CEE/ part. The middle part begins with the first appearance of
+`\.{@d}' or `\.{@f}' in the section, and the \CEE/ part begins with
+the first appearance of `\.{@c}' or `\.{@<section name@>=}'. In the
+latter case you are saying, in effect, that the section name stands
+for the \CEE/ text that follows. Alternatively, if the \CEE/ part
+begins with `\.{@c}' instead of a section name, the current section is
+said to be {\sl unnamed}.
+
+The construct `\.{@<section name@>}' can appear
+any number of times in the \CEE/ part of a section:
+Subsequent appearances indicate that a named section is being
+``used'' rather than ``defined.'' In other words, the
+\CEE/ code for the named section, presumably defined elsewhere, should be
+spliced in at this point in the \CEE/ program. Indeed,
+the main idea of \.{CTANGLE} is to make a \CEE/ program out of
+individual sections, named and unnamed. The exact way in which this is done
+is this: First all the macro definitions
+indicated by `\.{@d}' are turned into \CEE/ preprocessor macro definitions
+and copied at the beginning.
+Then the \CEE/ parts of unnamed sections are copied down,
+in order; this constitutes the first-order
+approximation to the text of the program. (There should be at least
+one unnamed section, otherwise there will be no program.) Then all section
+names that appear in the first-order approximation are replaced by the \CEE/
+parts of the corresponding sections, and this substitution process
+continues until no section names remain. All comments are removed, because
+the \CEE/ program is intended only for the eyes of the \CEE/ compiler.
+
+If the same name has been given to more than one section, the \CEE/ text
+for that name is obtained by putting together all of the \CEE/ parts in
+the corresponding sections. This feature is useful, for example, in a
+section named `Global variables', since one can then
+declare global variables in whatever sections those variables are
+introduced. When several sections have the same name, \.{CWEAVE} assigns the
+first section number as the number corresponding to that name, and it
+inserts a note at the bottom of that section telling the reader to `See
+also sections so-and-so'; this footnote gives the numbers of all the other
+sections having the same name as the present one. The \CEE/ text
+corresponding to a section is usually formatted by \.{CWEAVE} so that the
+output has an equivalence sign in place of the equals sign in the \.{CWEB}
+file; i.e., the output says `$\langle\,$section
+name$\,\rangle\equiv\null$\CEE/ text'. However, in the case of the second
+and subsequent appearances of a section with the same name, this `$\equiv$'
+sign is replaced by `$\mathrel+\equiv$', as an indication that the
+following \CEE/ text is being appended to the \CEE/ text of another section.
+
+As \.{CTANGLE} enters and leaves sections, it inserts preprocessor
+\.{\#line} commands into the \CEE/ output file. This means that
+when the compiler gives you error messages, or when you debug your program,
+the messages refer to line numbers in the \.{CWEB} file, and not in the
+\CEE/ file. In most cases you can therefore
+forget about the \CEE/ file altogether.
+
+\section What \.{CWEAVE} Does.
+The general idea of \.{CWEAVE} is to make a \.{.tex} file from the \.{CWEB}
+file in the following way: The first line of the \.{.tex} file
+tells \TEX/ to input a file with macros that
+define \.{CWEB}'s documentation conventions. The next lines of the file
+will be copied from whatever \TEX/ text is in limbo before the first
+section. Then comes the output for each section in turn, possibly
+interspersed with end-of-page marks. Finally, \.{CWEAVE} will generate a
+cross-reference index that lists each section number in which each \CEE/
+identifier appears, and it will also generate an alphabetized list
+of the section names, as well as a table of contents that
+shows the page and section numbers for each ``starred'' section.
+
+What is a ``starred'' section, you ask? A section that begins with `\.{@*}'
+instead of `\.{@\ }' is slightly special in that it denotes a new major
+group of sections. The `\.{@*}' should be followed by the title of this
+group, followed by a period. Such sections will always start on a new page
+in the \TEX/ output, and the group title will appear as a running headline
+on all subsequent pages until the next starred section. The title will also
+appear in the table of contents, and in boldface type at the beginning of
+its section. Caution: Do not use \TEX/ control sequences in such titles,
+unless you know that the \.{cwebmac} macros will do the right thing with
+them. The reason is that these titles are converted to uppercase when
+they appear as running heads, and they are converted to boldface when they
+appear at the beginning of their sections, and they are also written out to
+a table-of-contents file used for temporary storage while \TEX/ is
+working; whatever control sequences you use must be meaningful in all
+three of these modes.
+
+The \TEX/ output produced by \.{CWEAVE} for each section consists of
+the following: First comes the section number (e.g., `\.{\\M123.}'
+at the beginning of section 123, except that `\.{\\N}' appears in place of
+`\.{\\M}' at the beginning of a starred section). Then comes the
+\TEX/ part of the section, copied almost verbatim except as noted
+below. Then comes the middle part and the \CEE/ part, formatted
+so that there will be a little extra space between them if both are
+nonempty. The middle and \CEE/ parts are obtained by inserting
+a bunch of funny-looking \TEX/ macros into the \CEE/ program; these
+macros handle typographic details about fonts and proper math spacing,
+as well as line breaks and indentation.
+
+\section C Code in \TEX/ Text and Vice Versa.
+When you are typing \TEX/ text, you will probably want to make frequent
+reference to variables and other quantities in your \CEE/ code, and you
+will want those variables to have the same typographic treatment
+when they appear in your text as when they appear in your
+program. Therefore the \.{CWEB} language allows you to get the effect of
+\CEE/ editing within \TEX/ text, if you place `\.|' marks before and
+after the \CEE/ material. For example, suppose you want to say something
+like this:
+$$\hbox{ If \\{pa} is declared as `\&{int} ${}{*}\\{pa}$',
+the assignment $\\{pa}\K{\AND}\|a[\T{0}]$ makes \\{pa}
+point to the zeroth element of \|a.}$$
+The \TEX/ text would look like this in your \.{CWEB} file:
+$$\lpile{\.{If |pa| is declared as `|int *pa|', the assignment}\cr
+\.{|pa=\&a[0]| makes |pa| point to the zeroth element of |a|.}\cr}$$
+And \.{CWEAVE} translates this into something
+you are glad you didn't have to type:
+$$\lpile{\.{If \\PB\{\\\\\{pa\}\} is declared as `\\PB\{\\\&\{int\}
+ \$\{\}\{*\}\\\\\{pa\}\$\}', the}\cr
+\.{assignment \\PB\{\$\\\\\{pa\}\\K\{\\AND\}\\|a[\\T\{0\}]\$\}
+ makes \\PB\{\\\\\{pa\}\} point}\cr
+\.{to the zeroth element of \\PB\{\\|a\}.}\cr}$$
+Incidentally, the cross-reference index that \.{CWEAVE} would make, in
+the presence of a comment like this, would include
+the current section number as one of the index entries for \\{pa},
+even though \\{pa} might not appear in the \CEE/ part of
+this section. Thus, the index covers references to identifiers in
+the explanatory comments as well as in the program itself; you will
+soon learn to appreciate this feature. However, the identifiers
+\&{int} and \|a\ would not be indexed,
+because \.{CWEAVE} does not make index entries for reserved words or
+single-letter identifiers. Such identifiers are felt to be so ubiquitous
+that it would be pointless to mention every place where they occur.
+
+Although a section begins with \TEX/ text and ends with \CEE/ text, we
+have noted that the dividing line isn't sharp, since \CEE/ text can be
+included in \TEX/ text if it is enclosed in `\pb'. Conversely, \TEX/ text
+appears frequently within \CEE/ text, because everything in
+comments (i.e., between \.{/*} and \.{*/}, or following \.{//})
+is treated as \TEX/ text.
+Likewise, the text of a section name consists of \TEX/ text, but
+the construct \.{@<section name@>} as a whole is expected to be found
+in \CEE/ text; thus, one typically goes back and forth
+between the \CEE/ and \TEX/ environments in a natural way, as in these
+examples:
+$$
+\displaylines{
+\hbox{\.{if} \.{(x==0)} \.{@<Empty} \.{the} \.{|buffer|} \.{array@>}} \cr
+\hbox{\.{...} \.{using} \.{the} \.{algorithm}
+\.{in} \.{|@<Empty} \.{the} \.{|buffer|} \.{array@>|.}} }
+$$
+The first of these excerpts
+would be found in the \CEE/ part of a section, into which the code
+from the section
+named ``Empty the \\{buffer} array'' is being spliced. The second excerpt
+would be found in the \TEX/ part of the section, and the named section
+is being ``cited'', rather than defined or used.
+(Note the `\pb' surrounding the section name in this case.)
+
+\section Macros.
+The control code \.{@d} followed by
+$$\\{identifier}\.{ }\hbox{\CEE/ text}\qquad\hbox{or by}\qquad
+\\{identifier}\.(\\{par}_1,\ldots,\\{par}_n\.{) }\hbox{\CEE/ text}$$
+(where there is no blank between the
+\\{identifier} and the parentheses in the second case) is
+transformed by \.{CTANGLE} into a preprocessor command, starting with
+\.{\#define}, which is printed at the top of the \CEE/ output file
+as explained earlier.
+
+A `\.{@d}' macro definition can go on for several lines, and the
+newlines don't have to be protected by backslashes, since \.{CTANGLE}
+itself inserts the backslashes. If
+for any reason you need a \.{\#define} command at a specific spot in
+your \CEE/ file, you can treat it as \CEE/ code, instead of as a
+\.{CWEB} macro; but then you do have to protect newlines yourself.
+
+\section Strings and constants.
+If you want a string to appear in the \CEE/ file, delimited by pairs of
+\.' or \." marks as usual, you can type it exactly so in the \.{CWEB} file,
+except that the character `\.@' should be typed `\.{@@}' (it becomes a
+control code, the only one that can appear in strings; see below).
+Strings should end on the same line as they begin, unless there's a
+backslash at the end of lines within them.
+
+\TEX/ and \CEE/ have different ways to refer to octal and hex constants,
+because \TEX/ is oriented to technical writing while \CEE/ is oriented to
+computer processing. In \TEX/ you
+make a constant octal or hexadecimal by prepending \.' or \.",
+respectively, to it; in \CEE/ the constant should be preceded by \.0
+or \.{0x}. In \.{CWEB} it seems reasonable to let each convention hold
+in its respective realm; so in \CEE/ text you get $40_8$ by typing
+`\.{040}', which \.{CTANGLE} faithfully copies into the \CEE/ file (for
+the compiler's benefit) and which \.{CWEAVE} prints as $\T{\~40}$.
+Similarly, \.{CWEAVE} prints the hexadecimal \CEE/ constant `\.{0x20}'
+as \T{\^20}. The use of italic font for octal digits and typewriter font
+for hexadecimal digits makes the meaning of such constants clearer in
+a document. For consistency, then, you
+should type `\.{|040|}' or `\.{|0x20|}'
+in the \TEX/ part of the section.
+
+\section Control codes.
+A \.{CWEB} {\sl control code\/}
+is a two-character combination of which the first is `\.@'.
+We've already seen the meaning of several control codes; it's time to
+list them more methodically.
+
+In the following list,
+the letters in brackets after a control code indicate in what contexts that
+code is allowed. $L$ indicates that the code is allowed in limbo; $T$
+(for \TEX/), $M$ (for middle), and $C$ (for \CEE/) mean that the code is
+allowed in each of the three parts of a section, at top level---that
+is, outside such constructs as `\pb' and section names. An arrow $\to$
+means that the control code terminates the present part of the \.{CWEB}
+file, and inaugurates the part indicated by the letter following the
+arrow. Thus $[LTMC\to T]$ next to \.{@\ } indicates that this control
+code can occur in limbo, or in any of the three parts of a section, and
+that it starts the (possibly empty) \TEX/ part of the following section.
+
+Two other abbreviations can occur in these brackets: The letter $r$ stands for
+{\it restricted context}, that is, material inside \CEE/ comments, section
+names, \CEE/ strings and control texts (defined below); the letter
+$c$ stands for {\it inner \CEE/ context}, that is, \CEE/ material
+inside `\pb' (including `\pb's inside comments, but not those
+occurring in other restricted contexts). An asterisk $*$ following
+the brackets means
+that the context from this control code to the matching \.{@>} is
+restricted.
+
+Control codes involving letters are case-insensitive; thus \.{@d} and
+\.{@D} are equivalent. Only the lowercase versions are mentioned
+specifically below.
+
+\gdef\@#1[#2] {\penalty-50\yskip\hangindent 2em\noindent\.{@#1\unskip
+ \spacefactor1000{ }}$[#2]$\quad}
+\def\more{\hangindent 2em \hangafter0}
+\def\subsec{\penalty-300\medskip\noindent}
+
+\@@ [LTMCrc] A double \.@ denotes the single character `\.@'. This is
+the only control code that is legal everywhere.
+Note that you must use this convention if you are giving an internet
+email address in a \.{CWEB} file (e.g., \.{tex-k@@tug.org}).
+
+\subsec
+Here are the codes that introduce the \TEX/ part of a section.
+
+\@\ [LTMC\to T] This denotes the beginning of a new (unstarred)
+section. A tab mark or form feed or
+end-of-line character is equivalent to a space when it follows an \.@
+sign (and in most other cases).
+
+\@* [LTMC\to T] This denotes the beginning of a new starred
+section, i.e., a section that begins a new major group. The title of the new
+group should appear after the \.{@*}, followed by a period. As explained
+above, \TEX/ control sequences should be avoided in such titles unless
+they are quite simple. When \.{CWEAVE} and \.{CTANGLE} read a \.{@*}, they
+print an asterisk on the terminal
+followed by the current section number, so that the user
+can see some indication of progress. The very first section should be starred.
+
+\more You can specify the ``depth'' of a starred section by typing \.* or a
+decimal number after the \.{@*}; this indicates the relative ranking
+of the current group of sections in the program hierarchy. Top-level
+portions of the program, introduced by \.{@**}, get their names typeset
+in boldface type in the table of contents; they are said to have
+depth~$-1$. Otherwise the depth is a nonnegative number, which governs
+the amount of indentation on the contents page. Such indentation helps
+clarify the structure of a long program. The depth is assumed to be 0
+if it is not specified explicitly; when your program is short, you
+might as well leave all depths zero. A starred section always begins
+a new page in the output, unless the depth is greater than~1.
+
+\subsec
+The middle part of each section consists of any number of
+macro definitions (beginning with \.{@d}) and format definitions (beginning
+with \.{@f} or \.{@s}), intermixed in any order.
+
+\@d [TM\to M] Macro definitions begin with \.{@d}, followed by
+an identifier and optional parameters and \CEE/ text as explained earlier.
+
+\@f [TM\to M] Format definitions begin with \.{@f}; they cause
+\.{CWEAVE} to treat identifiers in a special way when they appear in
+\CEE/ text. The general form of a format definition is `\.{@f} \|l
+\|r', followed by an optional comment enclosed between
+\.{/*} and \.{*/}, where \|l and \|r
+are identifiers; \.{CWEAVE} will subsequently treat identifier \|l as it
+currently treats \|r. This feature allows a \.{CWEB} programmer to invent
+new reserved words and/or to unreserve some of \CEE/'s reserved
+identifiers. For example, the common words `error' and `line'
+have been given a special meaning in the \CEE/ preprocessor,
+so \.{CWEAVE} is set up to format them specially; if you want a variable
+named \\{error} or \\{line}, you should say
+$$\.{@f error normal}\qquad\qquad\.{@f line normal}$$
+somewhere in your program.
+
+\more If \|r is the special identifier `\\{TeX}', identifier \|l
+will be formatted as a \TEX/ control sequence; for example,
+`\.{@f foo TeX}' in the \.{CWEB} file will cause identifier \\{foo} to
+be output as \.{\\foo} by \.{CWEAVE}. The programmer should define
+\.{\\foo} to have whatever custom format is desired, assuming \TEX/
+math mode. (Each underline
+character is converted to \.{x} when making the \TEX/ control sequence,
+and each dollar sign is converted to~\.X;
+thus \\{foo\_bar} becomes \.{\\fooxbar}. Other characters, including digits,
+are left untranslated, so \TEX/ will consider them as macro parameters,
+not as part of the control sequence itself. For example,
+$$\.{\\def\\x\#1\{x\_\{\#1\}\} @f x1 TeX @f x2 TeX}$$
+will format \.{x1} and \.{x2} not as \\{x1} and \\{x2} but as $x_1$ and $x_2$.)
+
+\more If \|r is the special identifier `\\{make\_pair}', identifier \|l will
+be treated as a \CPLUSPLUS/ function template. For example, after
+\.{@f}~\.{convert}~\.{make\_pair} one can say `\.{convert<int>(2.5)}' without
+having \.< and \.> misunderstood as less-than and greater-than signs.
+
+\more \.{CWEAVE} knows that identifiers being
+defined with a \&{typedef} should become reserved words; thus you
+don't need format definitions very often.
+
+\@s [TM\to M;\;L] Same as \.{@f}, but \.{CWEAVE} does not show the format
+definition in the output, and the optional \CEE/ comment is not
+allowed. This is used mostly in \.{@i} files.
+
+\subsec
+Next come the codes that govern the \CEE/ part of a section.
+
+\@{c @p} [TM\to C] The \CEE/ part of an unnamed section begins with \.{@c}
+(or with \.{@p} for ``program''; both control codes do the same thing).
+This causes \.{CTANGLE} to append the following \CEE/ code
+to the first-order program text, as explained on page~\tangref.
+Note that \.{CWEAVE} does not print a `\.{@c}' in the \TEX/
+output, so if you are creating a \.{CWEB} file based on a \TEX/-printed
+\.{CWEB} documentation you have to remember to insert \.{@c} in the
+appropriate places of the unnamed sections.
+
+\@< [TM\to C;\; C;\; c] $*$ This control code introduces a
+section name (or unambiguous prefix, as discussed above), which
+consists of \TEX/ text and extends to the matching \.{@>}.
+The whole construct \.{@<...@>} is conceptually a \CEE/ element.
+The behavior is different depending on the context:
+
+\more A \.{@<} appearing in contexts $T$ and $M$ attaches the
+following section name to the current section, and inaugurates the
+\CEE/ part of the section. The closing \.{@>} should be followed by
+\.{=} or \.{+=}.
+
+\more
+In context $C$, \.{@<} indicates that the named
+section is being used---its \CEE/ definition is spliced in by
+\.{CTANGLE}, as explained on page~\tangref.
+As an error-detection measure,
+\.{CTANGLE} and \.{CWEAVE} complain if such a section name is followed
+by \.=, because most likely this is meant as the definition of a new
+section, and so should be preceded by \.{@\ }. If you really want to
+say $\langle\,$foo$\,\rangle=\\{bar}$, where $\langle\,$foo$\,\rangle$
+is being used and not defined, put a newline before the \.=.
+
+\more
+Finally, in inner \CEE/ context (that is, within `\pb' in the \TEX/ part
+of a section or in a comment), \.{@<...@>}
+means that the named section is being
+cited. Such an occurrence is ignored by \.{CTANGLE}. Note that
+even here we think of the section name as being a \CEE/ element, hence the \pb.
+
+\@( [TM\to C;\;C;\;c] $*$ A section name can begin with \.{@(}.
+Everything works just as for \.{@<}, except that the \CEE/ code
+of the section named \.{@(foo@>} is written by \.{CTANGLE}
+to file \.{foo}. In this way you can get multiple-file output from
+a single \.{CWEB} file. (The \.{@d} definitions are not output
+to such files, only to the master \.{.c} file.) One use of this feature
+is to produce header files for other program modules that will be loaded
+with the present one. Another use is to produce a test routine that
+goes with your program. By keeping the sources for a program and its
+header and test routine together, you are more likely to keep
+all three consistent with each other. Notice that the output of a named
+section can be incorporated in several different output files, because
+you can mention \.{@<foo@>} in both \.{@(bar1@>} and \.{@(bar2@>}.
+
+\@h [Cc] Causes \.{CTANGLE}
+to insert at the current spot the \.{\#define} statements
+from the middle parts of all sections,
+and {\it not\/} to write them at the beginning of the \CEE/ file.
+Useful when you want the macro definitions to come after the include files,
+say. (Ignored by \.{CTANGLE} inside `\pb'.)
+
+\subsec
+The next several control codes introduce ``control
+texts,'' which end with the next `\.{@>}'. The closing `\.{@>}' must be on
+the same line of the \.{CWEB} file as the line where the control text began.
+The context from each of these control codes to the matching \.{@>} is
+restricted.
+
+\@\^ [TMCc] $*$ The control text that follows, up to the next
+`\.{@>}', will be entered into the index together with the identifiers of
+the \CEE/ program; this text will appear in roman type. For example, to
+put the phrase ``system dependencies'' into the index that is output by
+\.{CWEAVE}, type
+`\.{@\^system dependencies@>}' in each section
+that you want to index as system dependent.
+
+\@. [TMCc] $*$ The control text that follows will be entered into the index
+in \.{typewriter} \.{type}.
+
+\@: [TMCc] $*$ The control text that follows will be entered into the index
+in a format controlled by the \TEX/ macro `\.{\\9}', which you
+should define as desired.
+
+\@t [MCc] $*$ The control text that follows will
+be put into a \TEX/ \.{\\hbox} and formatted along with the neighboring
+\CEE/ program. This text is ignored by \.{CTANGLE}, but it can be used
+for various purposes within \.{CWEAVE}. For example, you can make comments
+that mix \CEE/ and classical mathematics, as in `$\\{size}<2^{15}$', by
+typing `\.{|size < 2@t\$\^\{15\}\$@>|}'.
+
+\@= [MCc] $*$ The control text that follows will
+be passed verbatim to the \CEE/ program.
+
+\@q [LTMCc] $*$ The control text that follows will
+be totally ignored---it's a comment for readers of the \.{CWEB} file only.
+A file intended to be included in
+limbo, with \.{@i}, can identify itself with \.{@q} comments.
+Another use is to balance unbalanced parentheses in \CEE/ strings,
+so that your text editor's parenthesis matcher doesn't go into a tailspin.
+
+\@! [TMCc] $*$
+The section number in an index entry will be underlined if `\.{@!}'
+immediately precedes the identifier or control text being indexed. This
+convention is used to distinguish the sections where an identifier is
+defined, or where it is explained in some special way, from the sections
+where it is used. A~reserved word or an identifier of length one will not
+be indexed except for underlined entries. An `\.{@!}' is implicitly inserted
+by \.{CWEAVE} when an identifier is being defined or declared in \CEE/
+code; for example, the definition
+$$\hbox{\&{int} \\{array}[\\{max\_dim}], \\{count}${}=\\{old\_count};$}$$
+makes the names \\{array} and \\{count} get an underlined entry in the
+index. Statement labels, function definitions like
+\\{main}(\&{int}~\\{argc},\,\&{char}~$*$\\{argv}[\,]),
+and \&{typedef} definitions also
+imply underlining. An old-style
+function definition (without prototyping) doesn't define its arguments;
+the arguments will, however, be considered to be defined
+(i.e., their index entries will be underlined) if their types are
+declared before the body of the function in the usual way
+(e.g., `\&{int}~\\{argc}; \&{char}~${*}\\{argv}[\,]$; $\{\,\ldots\,\}$').
+Thus \.{@!} is not needed very often, except in unusual constructions
+or in cases like
+$$\.{enum boolean \{@!false, @!true\};}$$
+here \.{@!} gives the best results because individual constants enumerated
+by \.{enum} are not automatically underlined in the index at their
+point of definition.
+
+\subsec
+We now turn to control codes that affect only the operation of
+\.{CTANGLE}.
+
+\@' [MCc] This control code is dangerous because it has quite different
+meanings in \.{CWEB} and the original \.{WEB}. In \.{CWEB} it produces the
+decimal constant corresponding to the ASCII code for a string of length~1
+(e.g., \.{@'a'} is \.{CTANGLE}d into \.{97} and \.{@'\\t'} into
+\.9). You might want to use this if you need to work in ASCII on a
+non-ASCII machine; but in most cases the \CEE/ conventions of
+\.{<ctype.h>} are adequate for character-set-independent programming.
+
+\@\& [MCc] The \.{@\&} operation causes whatever is on its left to be
+adjacent to whatever is on its right, in the \CEE/ output. No spaces or
+line breaks will separate these two items.
+
+\@l [L] \.{CWEB} programmers have the option of using any 8-bit character
+code from the often-forbidden range 128--255 within \TEX/ text; such
+characters are also permitted in strings and even in identifiers of the
+\CEE/ program.
+Under various extensions of the basic
+ASCII standard, the higher 8-bit codes correspond
+to accented letters, letters from non-Latin alphabets,
+and so on. When such characters occur in identifiers, \.{CTANGLE} must replace
+them by standard ASCII alphanumeric characters or
+\.{\_}, in order to generate legal \CEE/ code. It does this by means
+of a transliteration table, which by default associates the string
+\.{Xab} to the character with ASCII code \T{\^}$ab$ (where $a$ and $b$ are
+hexadecimal digits, and $a\ge8$). By placing the
+construction \.{@l\ ab\ newstring} in limbo, you are telling
+\.{CTANGLE} to replace this character by \.{newstring} instead.
+For example, the ISO Latin-1 code for the letter `\"u' is \T{\^FC}
+(or \.{'\char`\\374'}),
+and \.{CTANGLE} will normally change this code to the
+three-character sequence \.{XFC} if it
+appears in an identifier. If you say \.{@l} \.{fc} \.{ue}, the code will
+be transliterated into \.{ue} instead.
+
+\more
+\.{CWEAVE} passes 8-bit characters straight through to \TEX/ without
+transliteration; therefore \TEX/ must be prepared to receive them.
+If you are formatting all your nonstandard identifiers as ``custom''
+control sequences, you should
+make \TEX/ treat all their characters as letters. Otherwise you should either
+make your 8-bit codes ``active'' in \TEX/, or load fonts that
+contain the special characters you need in the correct positions.
+(The font selected by \TEX/ control sequence \.{\\it} is used for
+identifiers.)
+Look for special macro packages designed for \.{CWEB} users in your language;
+or, if you are brave, write one yourself.
+
+\subsec
+The next eight control codes (namely `\.{@,}', `\.{@/}', `\.{@|}', `\.{@\#}',
+`\.{@+}', `\.{@;}', `\.{@[}', and `\.{@]}') have no effect on the \CEE/
+program output by \.{CTANGLE}; they merely help to improve the readability
+of the \TEX/-formatted \CEE/ that is output by \.{CWEAVE}, in unusual
+circumstances. \.{CWEAVE}'s built-in formatting method is fairly good
+when dealing with syntactically correct \CEE/ text, but
+it is incapable of handling all possible cases, because it must deal with
+fragments of text involving macros and section names; these fragments do
+not necessarily obey \CEE/'s syntax. Although \.{CWEB} allows you to
+override the automatic formatting, your best strategy is not to worry
+about such things until you have seen what \.{CWEAVE} produces automatically,
+since you will probably need to make only a few corrections when you are
+touching up your documentation.
+
+\@, [MCc] This control code inserts a thin space in \.{CWEAVE}'s output.
+Sometimes you need this extra space if you are using
+macros in an unusual way, e.g., if two identifiers are adjacent.
+
+\@/ [MC] This control code causes a line break to occur within a \CEE/
+program formatted by \.{CWEAVE}. Line breaks
+are chosen automatically by \TEX/ according to a scheme that works 99\%\
+of the time, but sometimes you will prefer to force a line break so that
+the program is segmented according to logical rather than visual
+criteria. If a comment follows, say `\.{@/@,}' to break the line
+before the comment.
+
+\@| [MC] This control code specifies an optional line break in the midst of
+an expression. For example, if you have
+a long expression on the right-hand side of an assignment
+statement, you can use `\.{@|}' to specify breakpoints more logical than
+the ones that \TEX/ might choose on visual grounds.
+
+\@\# [MC] This control code forces a line break, like \.{@/} does,
+and it also causes a little extra white space to appear between the lines at
+this break. You might use it, for example,
+between groups of macro definitions that are logically separate but within
+the same section. \.{CWEB} automatically inserts this extra space
+between functions, between external declarations and functions, and
+between declarations and statements within a function.
+
+\@+ [MC] This control code cancels a line break that might otherwise be
+inserted by \.{CWEAVE}, e.g., before the word `\&{else}', if you want to
+put a short if--else construction on a single line.
+If you say `\.{\{@+}' at the beginning of a compound statement
+that is the body of a function, the first declaration or
+statement of the function will appear on the same line as the
+left brace, and it will be indented by the same amount as the
+second declaration or statement on the next line.
+
+\@; [MC] This control code is treated like a semicolon, for formatting
+purposes, except that it is invisible. You can use it, for example, after
+a section name or macro when the \CEE/ text represented by that section or macro
+is a compound statement or ends
+with a semicolon. Consider constructions like
+$$\lpile{\.{if (condition) macro @;}\cr
+\.{else break;}\cr}$$
+where \\{macro} is defined to be a compound statement (enclosed in braces).
+This is a well-known infelicity of \CEE/ syntax.
+
+\@{[} [MC] See \.{@]}.
+
+\@] [MC] Place \.{@[...@]} brackets around program text that \.{CWEAVE} is
+supposed to format as an expression, if it doesn't already do so. (This
+occasionally applies to unusual macro arguments.) Also
+insert `\.{@[@]}' between a simple type name and a left parenthesis
+when declaring a pointer to a function, as in
+$$\.{int @[@] (*f)();}$$
+otherwise \.{CWEAVE} will confuse the first part of that declaration with
+the \CPLUSPLUS/ expression `\&{int}($*f$)'. Another example, for people
+who want to use low-level \.{\#define} commands in the midst of \CEE/ code
+and the definition begins with a cast:
+$$\.{\#define foo @[(int)(bar)@]}$$
+
+\subsec
+The remaining control codes govern the input that \.{CWEB} sees.
+
+\@{x @y @z}[\\{change\_file}]
+\.{CWEAVE} and \.{CTANGLE} are designed to work with two input files,
+called \\{web\_file} and \\{change\_file}, where \\{change\_file} contains
+data that overrides selected portions of \\{web\_file}. The resulting merged
+text is actually what has been called the \.{CWEB} file elsewhere in this
+report.
+
+\more Here's how it works: The change file consists of zero or more ``changes,''
+where a change has the form `\.{@x}$\langle$old lines$\rangle$\.{@y}$\langle$%
+new lines$\rangle$\.{@z}'. The special control codes \.{@x}, \.{@y}, \.{@z},
+which are allowed only in change files, must appear at the beginning of a line;
+the remainder of such a line is ignored.
+The $\langle$old lines$\rangle$ represent material that exactly matches
+consecutive lines of the \\{web\_file}; the $\langle$new lines$\rangle$
+represent zero or more lines that are supposed to replace the old. Whenever
+the first ``old line'' of a change is found to match a line in the
+\\{web\_file}, all the other lines in that change must match too.
+
+\more Between changes, before the first change, and after the last change,
+the change file can have any number of lines that do not begin with
+`\.{@x}', `\.{@y}', or~`\.{@z}'. Such lines are bypassed and not used for
+matching purposes.
+
+\more This dual-input feature is useful when working with a master \.{CWEB}
+file that has been received from elsewhere (e.g., \.{tangle.w} or
+\.{weave.w} or \.{tex.web}), when changes are desirable to customize the
+program for your local computer system. You will be able to debug your
+system-dependent changes without clobbering the master web file; and once
+your changes are working, you will be able to incorporate them readily
+into new releases of the master web file that you might receive from time
+to time.
+
+\@i [\\{web\_file}]
+Furthermore the \\{web\_file} itself can be a combination of
+several files. When either \.{CWEAVE} or \.{CTANGLE} is reading a file and
+encounters the control code \.{@i} at the beginning of a line, it
+interrupts normal reading and starts looking at the file named after the
+\.{@i}, much as the \CEE/ preprocessor does when it encounters an \.{\#include}
+line. After the included file has been entirely read, the program
+goes back to the next line
+of the original file. The file name following \.{@i} can be
+surrounded by \." characters, but such delimiters are
+optional. Include files can nest.
+
+\more
+Change files can have lines starting with \.{@i}. In this way
+you can replace one included file with another. Conceptually, the
+replacement mechanism described above does its work first, and
+its output is then checked for \.{@i} lines. If \.{@i} \.{foo}
+occurs between \.{@y} and \.{@z} in a change file, individual lines
+of file \.{foo} and files it includes are not changeable; but changes
+can be made to lines from files that were included by unchanged input.
+
+\more On \UNIX/ systems (and others that support environment variables),
+if the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
+of the same name was defined at compile time,
+\.{CWEB} will look for include files in the directory thus named, if
+it cannot find them in the current directory.
+
+\section Additional features and caveats.
+
+1. In certain installations of \.{CWEB} that
+{\def\\#1#2{`{\tentex\char'#1#2}'}%
+have an extended character set, the characters
+\\13, \\01, \\31, \\32, \\34, \\35,
+\\36, \\37, \\04, \\20, and \\21}
+can be typed as abbreviations for `\.{++}', `\.{--}', `\.{->}',
+`\.{!=}', `\.{<=}', `\.{>=}', `\.{==}', `\.{\v\v}', `\.{\&\&}',
+`\.{<<}', and `\.{>>}',
+respectively.
+
+2. If you have an extended character set, you can use it with only minimal
+restrictions, as discussed under the rules for \.{@l} above. But you should
+stick to standard ASCII characters if you want to write programs that will
+be useful to all the poor souls out there who don't have extended
+character sets.
+
+3. The \TEX/ file output by \.{CWEAVE} is broken into lines having at most
+80 characters each. When
+\TEX/ text is being copied, the existing line breaks are copied as well.
+If you aren't doing anything too tricky, \.{CWEAVE} will recognize when
+a \TEX/ comment is being split across two or more lines, and it will
+append `\.\%' to the beginning of such continued comments.
+
+4. \CEE/ text is translated by a ``bottom up'' procedure that
+identifies each token as a ``part of speech'' and combines parts of speech
+into larger and larger phrases as much as possible according to a special
+grammar that is explained in the documentation of \.{CWEAVE}. It is easy to
+learn the translation scheme for simple constructions like single
+identifiers and short expressions, just by looking at a few examples of
+what \.{CWEAVE} does, but the general mechanism is somewhat complex because
+it must handle much more than \CEE/ itself. Furthermore the output
+contains embedded codes that cause \TEX/ to indent and break lines as
+necessary, depending on the fonts used and the desired page width. For
+best results it is wise to avoid enclosing long \CEE/ texts in \pb, since the
+indentation and line breaking codes are omitted when the \pb\ text is
+translated from \CEE/ to \TEX/. Stick to simple expressions or
+statements. If a \CEE/ preprocessor command is enclosed in \pb,
+the \.\# that introduces it must be at the beginning of a line,
+or \.{CWEAVE} won't print it correctly.
+
+5. Comments are not permitted in \pb\ text. After a `\.|'
+signals the change from \TEX/ text to \CEE/ text, the next `\.|' that is
+not part of a string or control text or section name ends the \CEE/ text.
+
+6. A comment must have properly nested occurrences of left and right
+braces, otherwise \.{CWEAVE} will complain. But it
+does try to balance the braces, so that \TEX/ won't foul up too much.
+
+7. When you're debugging a program and decide to omit some of your
+\CEE/ code, do NOT simply ``comment it out.'' Such comments are not
+in the spirit of \.{CWEB} documentation; they will appear to readers
+as if they were explanations of the uncommented-out instructions.
+Furthermore, comments of a program must be valid \TEX/ text; hence
+\.{CWEAVE} will get confused if you enclose \CEE/ statements in
+\.{/*...*/} instead of in \.{/*|...|*/}. If you must comment out
+\CEE/ code, you can surround it with preprocessor commands
+like \.{\#if 0==1} and \.{\#endif}.
+
+8. The \.{@f} feature allows you to define one identifier to act like
+another, and these format definitions are carried out sequentially.
+In general, a given identifier has only one printed format
+throughout the entire document, and this format is used even before
+the \.{@f} that defines it. The reason is that \.{CWEAVE} operates in two
+passes; it processes \.{@f}'s and cross-references on the first pass and
+it does the output on the second. (However, identifiers that
+implicitly get a boldface format, thanks to a \.{typedef} declaration,
+don't obey this rule; they are printed differently before and after
+the relevant \.{typedef}. This is unfortunate, but hard to fix. You can
+get around the restriction by saying, say, `\.{@s} \.{foo} \.{int}',
+before or after the \.{typedef}.)
+
+9. Sometimes it is desirable to insert spacing into formatted \CEE/ code that
+is more general than the thin space provided by `\.{@,}'. The \.{@t} feature
+can be used for this purpose; e.g., `\.{@t\\hskip 1in@>}' will
+leave one inch of blank space. Furthermore, `\.{@t\\4@>}' can be
+used to backspace by one unit of indentation, since the control sequence
+\.{\\4} is defined in \.{cwebmac} to be such a backspace. (This
+control sequence is used, for example, at the beginning of lines that
+contain labeled statements, so that the label will stick out a little at
+the left.) You can also use `\.{@t\}\\3\{-5@>}' to force a break
+in the middle of an expression.
+
+10. Each identifier in \.{CWEB} has a single formatting convention. Therefore
+you shouldn't use the same identifier to denote, say, both a type name and
+part of a \.{struct}, even though \CEE/ does allow this.
+
+\section Running the programs.
+The \UNIX/ command line for \.{CTANGLE} is
+$$\.{ctangle [options] webfile[.w] [\{changefile[.ch]|-\} [outfile[.c]]]}$$
+and the same conventions apply to \.{CWEAVE}. If `\.-' or no change file is
+specified, the change file is null. The extensions \.{.w} and \.{.ch}
+are appended only if the given file names contain no dot. If the
+web file defined in this way cannot be found, the extension \.{.web}
+will be tried. For example, `\.{cweave} \.{cob}' will try to read
+\.{cob.w}; failing that, it will try \.{cob.web} before giving up.
+If no output file name is specified, the name of the \CEE/ file output by
+\.{CTANGLE} is obtained by appending the extension \.{.c};
+the name of the \TEX/ file output by \.{CWEAVE} gets the extension \.{.tex}.
+Index files output by \.{CWEAVE} replace \.{.tex} by \.{.idx} and \.{.scn}.
+
+Programmers who like terseness might choose to set up their
+ operating shell so that `\.{wv}' expands to
+`\.{cweave -bhp}'; this will suppress most terminal output from \.{CWEAVE}
+except for error messages.
+
+Options are introduced either by a \.- sign, to turn an option off,
+or by a \.+ sign to turn one on. For example, `\.{-fb}' turns off
+options \.f and \.b; `\.{+s}' turns on option \.s. Options can be
+specified before the file names, after the file names, or both. The following
+options are currently implemented:
+
+\yskip
+\def\option#1 {\textindent{\.#1}\hangindent2\parindent}
+
+\option b Print a banner line at the beginning of execution. (On
+by default.)
+
+\option e Enclose \CEE/ material formatted by \.{CWEAVE} in
+brackets \.{\\PB\{...\}}, so that special hooks can be used.
+(On by default; has no effect on \.{CTANGLE}.)
+
+\option f Force line breaks after each \CEE/ statement formatted
+by \.{CWEAVE}. (On by default; \.{-f} saves paper but looks less \CEE/-like
+to some people.) (Has no effect on \.{CTANGLE}.)
+
+\option h Print a happy message at the conclusion of a successful
+run. (On by default.)
+
+\option p Give progress reports as the program runs. (On by default.)
+
+\option s Show statistics about memory usage after the program
+runs to completion. (Off by default.)
+If you
+have large \.{CWEB} files or sections, you may need to see
+how close you come to exceeding the capacity of \.{CTANGLE} and/or \.{CWEAVE}.
+
+\option x Include indexes and a table of contents in the \TEX/ file
+output by \.{CWEAVE}. (On by default.) (Has no effect on \.{CTANGLE}.)
+
+\section Further details about formatting.
+You may not like the way \.{CWEAVE} handles certain
+situations. If you're desperate, you can customize \.{CWEAVE}
+by changing its grammar. This means changing the source code,
+a task that you might find amusing. A table of grammar rules
+appears in the \.{CWEAVE} source listing, and you can make a separate
+copy of that table by copying the file \.{prod.w} found in the \.{CWEB}
+sources and saying `\.{cweave}~\.{-x}~\.{prod}', followed by
+`\.{tex}~\.{prod}'.
+
+You can see exactly
+how \.{CWEAVE} is parsing your \CEE/ code by preceding
+it with the line `\.{@ @c @2}'. (The control code `\.{@2}'
+turns on a ``peeping'' mode, and `\.{@0}' turns it off.)
+For example, if you run \.{CWEAVE} on the file
+\medskip
+\begingroup
+\verbatim
+@ @c @2
+main (argc,argv)
+char **argv;
+{ for (;argc>0;argc--) printf("%s\n",argv[argc-1]); }
+!endgroup
+\endgroup
+\medskip\noindent
+you get the following gibberish on your screen:
+\medskip
+\begingroup
+\verbatim
+[...]
+14:*exp +(+ exp...
+11:*exp +exp+ raw...
+10:*+exp+ raw +ubinop?+...
+[...]
+60: +fn_decl+*+{+ -stmt- +}-
+55:*+fn_decl+ -stmt-
+52:*+function-
+[...]
+!endgroup
+\endgroup
+\medskip
+The first line says that grammar rule 14 has just been applied, and \.{CWEAVE}
+currently has in its memory a sequence of chunks of \TEX/ code (called
+``scraps'') that are respectively
+of type \\{exp} (for expression), open-parenthesis,
+\\{exp} again, close-parenthesis, and further scraps that haven't yet
+been considered by the parser. (The \.+ and \.- signs stipulate that
+\TEX/ should be in or out of math mode at the scrap boundaries. The \.* shows
+the parser's current position.)
+Then rule 11 is applied, and
+the sequence $(\,exp\,)$ becomes an \\{exp} and so on. In the
+end the whole \CEE/ text has become one big scrap of type \\{function}.
+
+Sometimes things don't work as smoothly, and you get a bunch of
+lines lumped together. This means that \.{CWEAVE} could not
+digest something in your \CEE/ code. For instance, suppose
+`\.{@<Argument definitions@>}' had appeared instead of
+`\.{char **argv;}' in the program above. Then \.{CWEAVE} would have
+been somewhat mystified, since it thinks that section names
+are just \\{exp}s. Thus it would tell \TEX/ to format
+`\X2:Argument declarations\X' on the same line as
+`$\\{main}(\\{argc},\39\\{argv}{}$)'.
+In this case you should help \.{CWEAVE} by putting `\.{@/}' after
+`\.{main(argc,argv)}'.
+
+\.{CWEAVE} automatically inserts a bit of extra space between declarations
+and the first apparent statement of a block. One way to defeat this
+spacing locally is
+$$\vbox{\halign{#\hfil\cr
+\.{int x;@+@t\}\\6\{@>}\cr
+\.{@<Other locals@>@;@\#}\cr}}$$
+the `\.{@\#}' will put extra space after `$\langle\,$Other locals$\,\rangle$'.
+
+\section Hypertext and hyperdocumentation.
+
+Many people have of course noticed analogies between \.{CWEB} and the
+World Wide Web. The \.{CWEB} macros are in fact set up so that the output of
+\.{CWEAVE} can be converted easily into Portable Document Format,
+with clickable hyperlinks that can be read with Adobe's Acrobat Reader,
+using a widely available open-source program called \.{dvipdfm} developed
+by Mark~A. Wicks. After using \.{CWEAVE} to convert \.{cob.w} into
+\.{cob.tex}, you can prepare and view a hypertext version of the program
+by giving the commands
+$$\vbox{\halign{\.{#}\hfil\cr
+tex "\\let\\pdf+ \\input cob"\cr
+dvipdfm cob\cr
+acroread cob.pdf\cr}}$$
+instead of invoking \TeX\ in the normal way. (Thanks to Hans Hagen,
+C\'esar Augusto Rorato Crusius, and Julian Gilbey
+for the macros that make this work.)
+Alternatively, thanks to H\`an Th\^e\kern-.3em\raise.3ex\hbox{\'{}} Th\`anh
+and Andreas Scherer, you can generate \.{cob.pdf} in one step by simply
+saying `\.{pdftex}~\.{cob}'.
+A third way to create PDF output from \.{CWEB} input is to say
+`\.{xetex}~\.{cob}'.
+
+A more elaborate system called \.{CTWILL}, which extends the usual cross
+references of \.{CWEAVE} by preparing links from the uses of identifiers
+to their definitions, is also available---provided that you are willing
+to work a bit harder in cases where an identifier is multiply defined.
+\.{CTWILL} is intended primarily for hardcopy output, but its principles
+could be used for hypertext as well.
+See Chapter 11 of {\sl Digital Typography\/} by D.~E. Knuth (1999), and
+the program sources at \.{ftp://ftp.cs.stanford.edu/pub/ctwill}.
+
+\section Appendices.
+
+As an example of a real program written in \.{CWEB}, Appendix~A
+contains an excerpt from the \.{CWEB} program itself. The reader who
+examines the listings in this appendix carefully will get a good
+feeling for the basic ideas of \.{CWEB}.
+
+Appendix B is the file that sets \TEX/ up to accept
+the output of \.{CWEAVE}, and Appendix~C discusses how to use some of those
+macros to vary the output formats.
+
+A ``long'' version of this manual, which can be produced from the \.{CWEB}
+sources via the \UNIX/ command \.{make} \.{fullmanual}, also contains
+appendices D, E, and~F, which exhibit the complete source code for
+\.{CTANGLE} and \.{CWEAVE}.
+
+\vfil\eject\titletrue
+
+\def\runninghead{APPENDIX A --- {\tentt CWEB} FILE FORMAT}
+\section Appendix A: Excerpts from a \.{CWEB} Program.
+
+This appendix consists
+of four listings. The first shows the \.{CWEB} input that
+generated sections 27--31 of the file \.{common.w}, which contains
+routines common to \.{CWEAVE} and \.{CTANGLE}.
+Note that some of the lines are indented to show the program structure;
+the indentation is ignored by \.{CWEAVE} and \.{CTANGLE}, but users find
+that \.{CWEB} files are quite readable if they have some such indentation.
+
+The second and third listings show corresponding parts of
+the \CEE/ code output by \.{CTANGLE} and of
+the \TEX/ code output by \.{CWEAVE}, when run on \.{common.w}.
+The fourth listing shows how that output looks in print.
+
+\vskip 6pt
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+\verbatim
+@ Procedure |prime_the_change_buffer|
+sets |change_buffer| in preparation for the next matching operation.
+Since blank lines in the change file are not used for matching, we have
+|(change_limit==change_buffer && !!changing)| if and only if
+the change file is exhausted. This procedure is called only when
+|changing| is |true|; hence error messages will be reported correctly.
+
+@<Predecl...@>=
+static void prime_the_change_buffer(void);@/
+
+@ @c
+static void
+prime_the_change_buffer(void)
+{
+ change_limit=change_buffer; /* this value is used if the change file ends */
+ @<Skip over comment lines in the change file; |return| if end of file@>@;
+ @<Skip to the next nonblank line; |return| if end of file@>@;
+ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>@;
+}
+
+@ While looking for a line that begins with \.{@@x} in the change file, we
+allow lines that begin with \.{@@}, as long as they don't begin with \.{@@y},
+\.{@@z}, or \.{@@i} (which would probably mean that the change file is fouled up).
+
+@<Skip over comment lines in the change file...@>=
+while(true) {
+ change_line++;
+ if (!!input_ln(change_file)) return;
+ if (limit<buffer+2) continue;
+ if (buffer[0]!!='@@') continue;
+ if (xisupper(buffer[1])) buffer[1]=tolower((eight_bits)buffer[1]);
+ if (buffer[1]=='x') break;
+ if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
+ loc=buffer+2;
+ err_print("!! Missing @@x in change file");
+@.Missing @@x...@>
+ }
+}
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do {
+ change_line++;
+ if (!!input_ln(change_file)) {
+ err_print("!! Change file ended after @@x");
+@.Change file ended...@>
+ return;
+ }
+} while (limit==buffer);
+
+@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
+{
+ change_limit=change_buffer+(ptrdiff_t)(limit-buffer);
+ strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+}
+!endgroup
+\endgroup
+\vfill\eject
+
+\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CTANGLE}}
+
+Here's the portion of the \CEE/ code generated by \.{CTANGLE} that corresponds
+to the source on the preceding page. Notice that sections~29, 30 and~31
+have been tangled into section~28.
+
+\vskip6pt
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+\verbatim
+/*:24*//*28:*/
+#line 234 "common.w"
+
+static void
+prime_the_change_buffer(void)
+{
+change_limit= change_buffer;
+/*29:*/
+#line 248 "common.w"
+
+while(true){
+change_line++;
+if(!!input_ln(change_file))return;
+if(limit<buffer+2)continue;
+if(buffer[0]!!='@')continue;
+if(xisupper(buffer[1]))buffer[1]= tolower((eight_bits)buffer[1]);
+if(buffer[1]=='x')break;
+if(buffer[1]=='y'||buffer[1]=='z'||buffer[1]=='i'){
+loc= buffer+2;
+err_print("!! Missing @x in change file");
+
+}
+}
+
+/*:29*/
+#line 239 "common.w"
+
+/*30:*/
+#line 265 "common.w"
+
+do{
+change_line++;
+if(!!input_ln(change_file)){
+err_print("!! Change file ended after @x");
+
+return;
+}
+}while(limit==buffer);
+
+/*:30*/
+#line 240 "common.w"
+
+/*31:*/
+#line 275 "common.w"
+
+{
+change_limit= change_buffer+(ptrdiff_t)(limit-buffer);
+strncpy(change_buffer,buffer,(size_t)(limit-buffer+1));
+}
+
+/*:31*/
+#line 241 "common.w"
+
+}
+
+/*:28*//*33:*/
+!endgroup
+\endgroup
+\vfill\eject
+
+\def\runninghead{APPENDIX A --- TRANSLATION BY {\tentt CWEAVE}}
+
+Here is the corresponding excerpt from \.{common.tex}.
+(Code for section 31 is omitted for space reasons.)
+
+\vskip6pt
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+\verbatim
+\M{27}Procedure \PB{\\{prime\_the\_change\_buffer}}
+sets \PB{\\{change\_buffer}} in preparation for the next matching operation.
+Since blank lines in the change file are not used for matching, we have
+\PB{$(\\{change\_limit}\E\\{change\_buffer}\W\R\\{changing})$} if and only if
+the change file is exhausted. This procedure is called only when
+\PB{\\{changing}} is \PB{\\{true}}; hence error messages will be reported
+correctly.
+
+\Y\B\4\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\6
+\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par
+\fi
+
+\M{28}\B\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void})\1\1\2\2\6
+${}\{{}$\1\6
+${}\\{change\_limit}\K\\{change\_buffer}{}$;\C{ this value is used if the
+change file ends }\6
+\X29:Skip over comment lines in the change file; \PB{\&{return}} if end of file%
+\X\6
+\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X\6
+\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} and %
+\PB{\\{change\_limit}}\X\6
+\4${}\}{}$\2\par
+\fi
+
+\M{29}While looking for a line that begins with \.{@x} in the change file, we
+allow lines that begin with \.{@}, as long as they don't begin with \.{@y},
+\.{@z}, or \.{@i} (which would probably mean that the change file is fouled
+up).
+
+\Y\B\4\X29:Skip over comment lines in the change file; \PB{\&{return}} if end
+of file\X${}\E{}$\6
+\&{while} (\\{true})\5
+${}\{{}$\1\6
+${}\\{change\_line}\PP;{}$\6
+\&{if} ${}(\R\\{input\_ln}(\\{change\_file})){}$\1\5
+\&{return};\2\6
+\&{if} ${}(\\{limit}<\\{buffer}+\T{2}){}$\1\5
+\&{continue};\2\6
+\&{if} ${}(\\{buffer}[\T{0}]\I\.{'@'}){}$\1\5
+\&{continue};\2\6
+\&{if} (\\{xisupper}(\\{buffer}[\T{1}]))\1\5
+${}\\{buffer}[\T{1}]\K\\{tolower}{}$((\&{eight\_bits}) \\{buffer}[\T{1}]);\2\6
+\&{if} ${}(\\{buffer}[\T{1}]\E\.{'x'}){}$\1\5
+\&{break};\2\6
+\&{if} ${}(\\{buffer}[\T{1}]\E\.{'y'}\V\\{buffer}[\T{1}]\E\.{'z'}\V\\{buffer}[%
+\T{1}]\E\.{'i'}){}$\5
+${}\{{}$\1\6
+${}\\{loc}\K\\{buffer}+\T{2};{}$\6
+\\{err\_print}(\.{"!!\ Missing\ @x\ in\ cha}\)\.{nge\ file"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U28.\fi
+
+\M{30}Here we are looking at lines following the \.{@x}.
+
+\Y\B\4\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X${}%
+\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{change\_line}\PP;{}$\6
+\&{if} ${}(\R\\{input\_ln}(\\{change\_file})){}$\5
+${}\{{}$\1\6
+\\{err\_print}(\.{"!!\ Change\ file\ ended}\)\.{\ after\ @x"});\6
+\&{return};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\5
+\&{while} ${}(\\{limit}\E\\{buffer}){}$;\par
+\U28.\fi
+!endgroup
+\endgroup
+\vfil\eject
+
+\def\runninghead{APPENDIX A --- FINAL DOCUMENT}
+
+And here's what the same excerpt looks like when typeset.
+(Can you spot the typographical nicety used in the \.{CWEB} code?)
+\let\K=\leftarrow
+
+\M{27}Procedure \PB{\\{prime\_the\_change\_buffer}}
+sets \PB{\\{change\_buffer}} in preparation for the next matching operation.
+Since blank lines in the change file are not used for matching, we have
+\PB{$(\\{change\_limit}\E\\{change\_buffer}\W\R\\{changing})$} if and only if
+the change file is exhausted. This procedure is called only when
+\PB{\\{changing}} is \PB{\\{true}}; hence error messages will be reported
+correctly.
+
+\Y\B\4\X7:Predeclaration of procedures\X${}\mathrel+\E{}$\6
+\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void});\par
+\fi
+
+\M{28}\B\&{static} \&{void} \\{prime\_the\_change\_buffer}(\&{void})\1\1\2\2\6
+${}\{{}$\1\6
+${}\\{change\_limit}\K\\{change\_buffer}{}$;\C{ this value is used if the
+change file ends }\6
+\X29:Skip over comment lines in the change file; \PB{\&{return}} if end of file%
+\X\6
+\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X\6
+\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}} and %
+\PB{\\{change\_limit}}\X\6
+\4${}\}{}$\2\par
+\fi
+
+\M{29}While looking for a line that begins with \.{@x} in the change file, we
+allow lines that begin with \.{@}, as long as they don't begin with \.{@y},
+\.{@z}, or \.{@i} (which would probably mean that the change file is fouled
+up).
+
+\Y\B\4\X29:Skip over comment lines in the change file; \PB{\&{return}} if end
+of file\X${}\E{}$\6
+\&{while} (\\{true})\5
+${}\{{}$\1\6
+${}\\{change\_line}\PP;{}$\6
+\&{if} ${}(\R\\{input\_ln}(\\{change\_file})){}$\1\5
+\&{return};\2\6
+\&{if} ${}(\\{limit}<\\{buffer}+\T{2}){}$\1\5
+\&{continue};\2\6
+\&{if} ${}(\\{buffer}[\T{0}]\I\.{'@'}){}$\1\5
+\&{continue};\2\6
+\&{if} (\\{xisupper}(\\{buffer}[\T{1}]))\1\5
+${}\\{buffer}[\T{1}]\K\\{tolower}{}$((\&{eight\_bits}) \\{buffer}[\T{1}]);\2\6
+\&{if} ${}(\\{buffer}[\T{1}]\E\.{'x'}){}$\1\5
+\&{break};\2\6
+\&{if} ${}(\\{buffer}[\T{1}]\E\.{'y'}\V\\{buffer}[\T{1}]\E\.{'z'}\V\\{buffer}[%
+\T{1}]\E\.{'i'}){}$\5
+${}\{{}$\1\6
+${}\\{loc}\K\\{buffer}+\T{2};{}$\6
+\\{err\_print}(\.{"!\ Missing\ @x\ in\ cha}\)\.{nge\ file"});\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\par
+\U28.\fi
+
+\M{30}Here we are looking at lines following the \.{@x}.
+
+\Y\B\4\X30:Skip to the next nonblank line; \PB{\&{return}} if end of file\X${}%
+\E{}$\6
+\&{do}\5
+${}\{{}$\1\6
+${}\\{change\_line}\PP;{}$\6
+\&{if} ${}(\R\\{input\_ln}(\\{change\_file})){}$\5
+${}\{{}$\1\6
+\\{err\_print}(\.{"!\ Change\ file\ ended}\)\.{\ after\ @x"});\6
+\&{return};\6
+\4${}\}{}$\2\6
+\4${}\}{}$\2\5
+\&{while} ${}(\\{limit}\E\\{buffer}){}$;\par
+\U28.\fi
+
+\M{31}\B\X31:Move \PB{\\{buffer}} and \PB{\\{limit}} to \PB{\\{change\_buffer}}
+and \PB{\\{change\_limit}}\X${}\E{}$\6
+${}\{{}$\1\6
+${}\\{change\_limit}\K\\{change\_buffer}+(\&{ptrdiff\_t})(\\{limit}-%
+\\{buffer});{}$\6
+${}\\{strncpy}(\\{change\_buffer},\39\\{buffer},\39(\&{size\_t})(\\{limit}-%
+\\{buffer}+\T{1}));{}$\6
+\4${}\}{}$\2\par
+\Us28\ET33.\fi
+\vfil\eject\titletrue
+\rightskip=0pt % get out of C mode (cf. \B)
+\sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+
+\def\runninghead{APPENDIX B --- MACROS FOR FORMATTING}
+\section Appendix B: The \.{cwebmac.tex} file.
+This is the file that extends ``plain \TEX/'' format in order to support the
+features needed by the output of \.{CWEAVE}.
+
+\vskip6pt
+\begingroup \def\tt{\eighttt} \baselineskip9pt
+\def\printmacs{\begingroup
+ \def\do##1{\catcode`##1=12 } \dospecials
+ \parskip 0pt \parindent 0pt
+ \catcode`\ =13 \catcode`\^^M=13
+ \tt \verbatimdefs \input cwebmac \endgroup}
+\printmacs
+\endgroup
+\vfill\eject
+
+\def\runninghead{APPENDIX C --- NOTES ON FORMATTING}
+\section Appendix C: How to use \.{CWEB} macros.
+The macros in \.{cwebmac} make it possible to produce a variety of formats
+without editing the output of \.{CWEAVE}, and the purpose of this appendix
+is to explain some of the possibilities.
+
+\def\point#1.{\yskip\indent#1.\quad\ignorespaces}
+
+\point 1. Four fonts have been declared in addition to the standard fonts of
+\.{PLAIN} format: You can say `\.{\{\\mc UNIX\}}' to get {\mc UNIX} in
+medium-size caps; you can say `\.{\{\\sc STUFF\}}' to get {\sc STUFF}
+in small caps; and you can select the largish fonts \.{\\titlefont}
+and \.{\\ttitlefont} in the title of your document, where \.{\\ttitlefont}
+is a typewriter style of type. There are macros \.{\\UNIX/} and \.{\\CEE/}
+to refer to \UNIX/ and \CEE/ with medium-size caps.
+
+\point 2. When you mention an identifier in \TEX/ text, you normally call
+it `\.{|identifier|}'. But you can also say `\.{\\\\\{identifier\}}'. The
+output will look the same in both cases, but the second alternative
+doesn't put \\{identifier} into the index, since
+it bypasses \.{CWEAVE}'s translation from \CEE/ mode. In the second
+case you must put a backslash before each underline character
+in the identifier.
+
+\point 3. To get typewriter-like type, as when referring to `\.{CWEB}', you
+can use the `\.{\\.}' macro (e.g., `\.{\\.\{CWEB\}}'). In the argument to
+this macro you should insert an additional backslash before the symbols
+listed as `special string characters' in the index to \.{CWEAVE}, i.e.,
+before backslashes and dollar signs and the like.
+A `\.{\\\ }' here will result in the visible space symbol; to get an
+invisible space following a control sequence you can say `\.{\{\ \}}'.
+If the string is long, you can break it up into substrings that
+are separated by `\.{\\)}'\,; the latter gives a discretionary backslash
+if \TEX/ has to break a line here.
+
+\point 4. The three control sequences \.{\\pagewidth}, \.{\\pageheight},
+and \.{\\fullpageheight} can be redefined in the limbo section at the
+beginning of your \.{CWEB} file, to change the dimensions of each page.
+The default settings
+$$\lpile{\.{\\pagewidth=6.5in}\cr
+ \.{\\pageheight=8.7in}\cr
+ \.{\\fullpageheight=9in}\cr}$$
+were used to prepare this manual; \.{\\fullpageheight} is
+\.{\\pageheight} plus room for the additional heading and page numbers at
+the top of each page. If you change any of these quantities, you should
+call the macro \.{\\setpage} immediately after making the change.
+
+\point 5. The \.{\\pageshift} macro defines an amount by which right-hand
+pages (i.e., odd-numbered pages) are shifted right with respect to
+left-hand (even-numbered) ones. By adjusting this amount you may be
+able to get two-sided output in which the page numbers line up on
+opposite sides of each sheet.
+
+\point 6. The \.{\\title} macro will appear at the top of each page
+in small caps; it is the job name unless redefined.
+
+\point 7. The first page usually is assigned page
+number 1. To start on page 16, with contents
+on page 15, say this: `\.{\\def\\contentspagenumber\{15\}}
+\.{\\pageno=\\contentspagenumber} \.{\\advance\\pageno by 1}'.
+
+\point 8. The macro \.{\\iftitle} will suppress the header line if it is
+defined by `\.{\\titletrue}'. The normal value is \.{\\titlefalse}
+except for the table of contents; thus, the contents
+page is usually unnumbered.
+
+Two macros are provided to give flexibility to the table of
+contents: \.{\\topofcontents} is invoked just before the contents
+info is read, and \.{\\botofcontents} is invoked just after.
+Here's a typical definition:
+$$\lpile{\.{\\def\\topofcontents\{\\null\\vfill}\cr
+ \.{ { }\\titlefalse \% include headline on the contents page}\cr
+ \.{ { }\\def\\rheader\{\\mainfont The \{\\tt CWEAVE\}{ }processor\\hfil\}}\cr
+ \.{ { }\\centerline\{\\titlefont The \{\\ttitlefont CWEAVE\}{ }processor\}}\cr
+ \.{ { }\\vskip 15pt \\centerline\{(Version 4.2)\}{ }\\vfill\}}\cr}$$
+Redefining \.{\\rheader}, which is the headline for right-hand pages,
+suffices in this case to put the desired information at the top of the
+contents page.
+
+\point 9. Data for the table of contents is written to a file that
+is read after the indexes have been \TEX/ed; there's one line of data
+for every starred section. The file \.{common.toc} might look like this:
+$$\lpile{\.{\\ZZ \{Introduction\}\{0\}\{1\}\{28\}\{\}}\cr
+ \.{\\ZZ \{The character set\}\{2\}\{5\}\{29\}\{\}}\cr}$$
+and so on. The \.{\\topofcontents} macro could
+redefine \.{\\ZZ} so that the information appears in any desired format.
+(See also point~19 below.)
+
+\point 10. Sometimes it is necessary or desirable to divide the output of
+\.{CWEAVE} into subfiles that can be processed separately. For example,
+the listing of \TEX/ runs to more than 500 pages, and that is enough to
+exceed the capacity of many printing devices and/or their software.
+When an extremely large job isn't cut into smaller pieces, the entire
+process might be spoiled by a single error of some sort, making it
+necessary to start everything over.
+
+Here's a safe way to break a woven file into three parts:
+Say the pieces are $\alpha$,
+$\beta$, and $\gamma$, where each piece begins with a starred section.
+All macros should be defined in the opening limbo section of $\alpha$,
+and copies of this \TEX/ code should be placed at the
+beginning of $\beta$ and of $\gamma$. In order to process the parts
+separately, we need to take care of two things: The starting page
+numbers of $\beta$ and $\gamma$ need to be set up properly, and
+the table of contents data from all three runs needs to be
+accumulated.
+
+The \.{cwebmac} macros include two control sequences \.{\\contentsfile} and
+\.{\\readcontents} that facilitate the necessary processing. We include
+`\.{\\def\\contentsfile\{cont1\}}' in the limbo section of $\alpha$, and
+we include `\.{\\def\\contentsfile\{cont2\}}' in the limbo section of
+$\beta$; this causes \TEX/ to write the contents data for $\alpha$ and $\beta$
+into \.{cont1.tex} and \.{cont2.tex}. Now in $\gamma$ we say
+$$\.{\\def\\readcontents\{\\input cont1 \\input cont2
+ \\input \\contentsfile\}}\,;$$
+this brings in the data from all three pieces, in the proper order.
+
+However, we still need to solve the page-numbering problem. One way to
+do it is to include the following in the limbo material for $\beta$:
+$$\lpile{\.{\\message\{Please type the last page number of part 1: \}}\cr
+ \.{\\read -1 to \\temp \\pageno=\\temp \\advance\\pageno by 1}\cr}$$
+Then you simply provide the necessary data when \TEX/ requests
+it; a similar construction is used at the beginning of $\gamma$.
+
+This method can, of course, be used to divide a woven file into
+any number of pieces.
+
+\point 11. Sometimes it is nice to include things in the index that are
+typeset in a special way. For example, we might want to have an
+index entry for `\TeX'. \.{CWEAVE} provides two simple ways to
+typeset an index entry (unless the entry is an identifier or a reserved word):
+`\.{@\^}' gives roman type, and `\.{@.}' gives typewriter type.
+But if we try to typeset `\TeX' in roman type by saying, e.g.,
+`\.{@\^\\TeX@>}', the backslash character gets in the way,
+and this entry wouldn't appear in the index with the T's.
+
+The solution is to use the `\.{@:}' feature, declaring a macro that
+simply removes a sort key as follows:
+$$\.{\\def\\9\#1\{\}}$$
+Now you can say, e.g., `\.{@:TeX\}\{\\TeX@>}' in your \.{CWEB} file; \.{CWEAVE}
+puts it into the index alphabetically, based on the sort key, and
+produces the macro call `\.{\\9\{TeX\}\{\\TeX\}}' which will ensure that
+the sort key isn't printed.
+
+A similar idea can be used to insert hidden material into section
+names so that they are alphabetized in whatever way you might wish.
+Some people call these tricks ``special refinements''; others call
+them ``kludges.''
+
+\point 12. The control sequence \.{\\secno} is set to the number of the
+section being typeset.
+
+\point 13. If you want to list only the sections that have changed,
+together with the index, put the command `\.{\\let\\maybe=\\iffalse}' in
+the limbo section before the first section of your \.{CWEB} file. It's
+customary to make this the first change in your change file.
+
+This feature has a \TeX nical limitation, however: You cannot use it
+together with control sequences like \.{\\proclaim} or \.{\\+} or
+\.{\\newcount} that plain \TeX\ has declared to be `\.{\\outer}',
+because \TeX\ refuses to skip silently over such control sequences.
+One way to work around this limitation is to say
+$$\.{\\fi \\let\\proclaim\\relax \\def\\proclaim\{...\} \\ifon}$$
+where \.{\\proclaim} is redefined to be the same as usual but without
+an \.{\\outer} qualification. (The \.{\\fi} here stops the conditional
+skipping, and the \.{\\ifon} turns it back on again.) Similarly,
+$$\.{\\fi \\newcount\\n \\ifon}$$
+is a safe way to use \.{\\newcount}. Plain \TeX\ already provides a
+non-outer macro \.{\\tabalign} that does the work of \.{\\+}; you can say
+$$\postdisplaypenalty=10000
+\.{\\fi \\let\\+\\tabalign \\ifon}$$
+if you prefer the shorter notation \.{\\+}.
+
+\point 14. To get output in languages other than English, redefine the
+macros \.{\\A}, \.{\\As}, \.{\\ATH},
+\.{\\ET}, \.{\\ETs}, \.{\\Q}, \.{\\Qs}, \.{\\U},
+\.{\\Us}, \.{\\ch}, \.{\\fin}, \.{\\con}, \.{\\today}, \.{\\datethis}, and
+\.{\\datecontentspage}. \.{CWEAVE} itself need not be changed.
+
+\point 15. Some output can be selectively suppressed with the macros
+\.{\\noatl}, \.{\\noinx}, \.{\\nosecs}, \.{\\nocon}.
+
+\point 16. All accents and special text symbols of plain \TEX/ format
+will work in \.{CWEB} documents just as they are described in
+Chapter~9 of {\sl The \TEX/book}, with one exception.
+The dot accent (normally \.{\\.}) must be typed \.{\\:} instead.
+
+\point 17. Several commented-out lines in \.{cwebmac.tex} are suggestions
+that users may wish to adopt. For example, one such line inserts a blank page
+if you have a duplex printer. Appendices D, E, and F of the complete
+version of this manual are printed using a commented-out option that
+substitutes `$\gets$' for `$=$' in the program listings. Looking at those
+appendices might help you decide which format you like better.
+
+\point 18. Andreas Scherer has contributed a macro called \.{\\pdfURL}
+with which one can say things like the following, anywhere in the \TeX\ parts
+or the \CEE/ comments of a \.{CWEB} file:
+$$\vbox{\halign{\.{#}\hfil\cr
+You can send email to
+ \\pdfURL\{the author\}\{mailto:andreas\\UNDER/github@@freenet.de\}\cr
+or visit \\pdfURL\{his home page\}\{https://github.com/ascherer\}\cr}}$$
+In a {\mc PDF} document, the first argument will appear in blue as
+clickable text; the Acrobat reader, if correctly configured, will then
+redirect those links to the user's browser and open either the
+email client or the HTML viewer. In a hardcopy document, both arguments
+will be printed ({\tt the second in parentheses and typewriter type}).
+Certain special characters in an Internet address need to be handled
+in a somewhat awkward way, so that \.{CWEAVE} and/or \TeX\
+will not confuse them with formatting controls: Use \.{@@} for \.@
+and \.{\\TILDE/} for \.\~ and \.{\\UNDER/} for \.\_.
+
+\point 19. {\mc PDF} documents contain bookmarks that list all the major group
+titles in the table of contents, some of which will be subsidiary to
+others if the depth feature of \.{@*} has been used.
+Such bookmark entries are also known as ``outlines.''
+Moreover, the final group title, `Names of the sections',
+can be opened up to list every section name; Acrobat users can therefore
+navigate easily to any desired section.
+
+The macros of \.{cwebmac.tex} are careful to ``sanitize'' all the names
+that appear as bookmarks, by removing special characters and
+formatting codes that are inappropriate for the limited typographic
+capabilities of {\mc PDF} outlines. For example, one section of \.{CWEAVE}
+is named `Cases for \\{case\_like}', which is represented by the \TeX\ code
+`\.{Cases} \.{for} \.{\\PB\{\\\\\{case\\\_like\}\}}' in \.{cweave.tex}; its
+sanitized name is simply `\.{Cases} \.{for} \.{case\_like}'.
+(When \.{.pdf} files are produced, the fifth parameter of every \.{\\ZZ} in
+the \.{.toc} file is set to the sanitized form of the first parameter;
+see point~9 above and point~20 below.)
+
+In general, sanitization removes \TeX\ control sequences and braces,
+except for control sequences defined by \.{CWEB} itself. Such a translation
+works most of the time, but you can override the defaults and obtain any
+translation that you want by using \TeX nical tricks. For example, after
+$$\.{\\sanitizecommand\\foo\{bar\}}$$
+the control sequence \.{\\foo} will sanitize to `\.{bar}'. And after
+$$\.{\\def\\kluj\#1\\\\\{foo\}}$$
+the \TeX\ code `\.{\\kluj bar\\\\}' will print as `foo' but sanitize
+to `\.{bar}', because the control sequences \.{\\kluj} and
+\.{\\\\} are removed by sanitization.
+
+\point 20. Furthermore, group titles can be converted to an arbitrary
+sanitized text while also changing their form in running headlines, by
+using \.{\\ifheader}. Consider, for example, a \.{CWEB} source file that
+begins with the two lines
+$$\lpile{\.{\\def\\klujj\#1\\\\\{\\ifheader FOO\\else foo\\fi\}}\cr
+\.{@*Chinese \\klujj bar\\.}\cr}$$
+This coding introduces a major group entitled `{\bf Chinese foo}', with
+running headline `{\eightrm CHINESE FOO}' and table-of-contents entry
+`Chinese foo'. The corresponding bookmark is, however, `\.{Chinese} \.{bar}'.
+And the corresponding \.{.toc} file entry is
+`\.{\\ZZ \{Chinese \\klujj bar\\\\\}\{1\}\{1\}\{1\}\{Chinese bar\}}'.
+
+\vfill\end
+
diff --git a/Build/source/texk/web2c/cwebdir/examples/Makefile b/Build/source/texk/web2c/cwebdir/examples/Makefile
new file mode 100644
index 00000000000..c029d805c0f
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/Makefile
@@ -0,0 +1,57 @@
+#
+# generic Makefile to use when you've got CWEB
+# (add it to, or add to it, whatever you like)
+#
+#======================================================================
+
+CFLAGS = -g
+MLIB = -lm
+RM = /bin/rm -f
+WFILES = extex.w treeprint.w wc.w wmerge.w wordtest.w oemacs.w
+
+#======================================================================
+
+.SUFFIXES: .tex .dvi .w
+
+.w.tex:
+ cweave $*
+
+.tex.dvi:
+ tex $<
+
+.w.dvi:
+ make $*.tex
+ make $*.dvi
+
+.w.c:
+ ctangle $*
+
+.w.o:
+ make $*.c
+ make $*.o
+
+.c.o:
+ cc $(CFLAGS) -c $*.c
+
+.w:
+ make $*.c
+ cc $(CFLAGS) $*.c -o $*
+
+#======================================================================
+
+all: $(WFILES:.w=) excweb
+
+excweb: extex
+ ln extex excweb
+
+oemacs: oemacs.c
+ cc $(CFLAGS) -I/usr/openwin/include oemacs.c \
+ -o oemacs -lxview -lolgx -lX11
+
+doc: $(WFILES:.w=.dvi)
+
+clean:
+ $(RM) *~ \#~ .\#* *.o *.log *.dvi *.toc core a.out
+
+clobber: clean
+ $(RM) $(WFILES:.w=) $(WFILES:.w=.c) $(WFILES:.w=.tex)
diff --git a/Build/source/texk/web2c/cwebdir/examples/README b/Build/source/texk/web2c/cwebdir/examples/README
new file mode 100644
index 00000000000..ca21cf075c8
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/README
@@ -0,0 +1,55 @@
+This directory contains several files for programs that are tutorial
+and/or useful. If you are new to CWEB, read "wc.w" first; it's a
+typical example of CWEB applied to system programming.
+
+The Makefile on this directory is a generic way to build applications
+written in CWEB. Say, for example, "make wc" to get an executable
+program "wc" from wc.w. Say "make wc.dvi" to get a printable listing
+of its documentation. The program "wc" is a slight improvement over
+UNIX's standard word-count utility. (Try it, for example, with "wc *".)
+
+The treeprint program, by Norman Ramsey, generates tree-structured
+representations of file hierarchies. To use it, say "make treeprint.run"
+and then
+ find dir -type p -print | sort | treeprint
+(on a UNIX system), where dir is a directory with interesting subdirectories.
+
+The wmerge program, by Silvio Levy, produces a single CWEB file from a
+given CWEB file and a change file. It expands any "web include" (@i)
+specifications in the original CWEB file. To use it, say "make wmerge.run"
+and then, e.g., "wmerge foo.w bar.ch > foobar.w". Both CTANGLE and
+CWEAVE already accept change files, so you need not merge anything yourself
+in normal day-to-day operations; but wmerge can be useful in connection with
+the spelling checker described below.
+
+If you intend to read the source code of CTANGLE and CWEAVE, you may
+well wish to read wmerge.w first, or the hardcopy version obtained from
+"make wmerge.dvi"; it is similar but much simpler.
+
+The extex and wordtest programs, by Don Knuth, are useful spellcheckers.
+After "make extex.run" say also "ln extex excweb"; this gives
+you two filter programs, extex and excweb, that remove extraneous
+material from TeX and CWEB source files, respectively. To use them,
+you can say for example
+ cat foo.w | excweb | spell
+(or replace "cat foo.w" with "wmerge foo.w bar.ch"). A similar pipeline
+for TeX files would be
+ cat foo.tex | extex | spell
+Even better is to replace "spell" by "wordtest /usr/local/lib/dict/words",
+if you have a suitable dictionary. One such dictionary in the public domain
+can be found in directory ~ftp/pub/dict at ftp.cs.stanford.edu, available
+via anonymous ftp. To make your own dictionary from given ones,
+ cat dict1 dict2 dict3 dict4 | wordtest > words
+is quick and effective. See the documentation of wordtest for more info.
+
+A file kspell.el that provides an emacs user interface to extex+excweb+wordtest
+also appears in this directory. (Somebody should write ELWEB...)
+
+The files xview_types.w and xlib_types.w are examples of @i (include) files
+that can be used when writing XView programs. They are based on the header
+files in OpenWindows Version 3.0.
+
+An example XView application appears in Knuth's program oemacs.w, which
+he uses for heavy emacsing. It's not very portable, but if you have
+OpenWindows3 and a Sun Type-4 keyboard you may like it as much as he does.
+(It replaces "emacstool".) The file oemacs.el goes with it.
diff --git a/Build/source/texk/web2c/cwebdir/examples/extex.ch b/Build/source/texk/web2c/cwebdir/examples/extex.ch
new file mode 100644
index 00000000000..1b3f0cebd11
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/extex.ch
@@ -0,0 +1,23 @@
+@x In my work (mainly TAOCP) I use \: (not \.) for the dot accent
+'&`&\relax\^&"&\relax\~&=&.&u&v\cr
+@y
+'&`&\relax\^&"&\relax\~&=&:&u&v\cr
+@z
+@x
+ 1,1,1,1,1,0,0,1, /* \.{\\-} and \.{\\.} */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1, /* \.{\\=} */
+@y
+ 1,1,1,1,1,0,1,1, /* \.{\\-} */
+ 1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1, /* \.{:} and \.{\\=} */
+@z
+@x and I use |...xref-tag...| for cross-references
+case '|': if (web>1) {
+ save_skipping=skipping;
+ goto skip_C_prime;
+ }
+@y
+case '|': if (web>1) {
+ save_skipping=skipping;
+ goto skip_C_prime;
+ } else discard_to('|');
+@z
diff --git a/Build/source/texk/web2c/cwebdir/examples/extex.w b/Build/source/texk/web2c/cwebdir/examples/extex.w
new file mode 100644
index 00000000000..b060d7431a6
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/extex.w
@@ -0,0 +1,366 @@
+\datethis
+@* Introduction. This program is a simple filter that inputs \TEX/ or \.{CWEB}
+files and outputs its best guess at the ``words'' they contain. The word
+list can then be passed to a spelling check routine such as {\tt wordtest}.
+
+If this program is invoked with the name `{\tt excweb}', it will apply
+special rules based on the syntax of \.{CWEB} files. Otherwise it will
+use only the \TEX/ conventions. (Note that \UNIX/'s {\tt ln} command
+allows a program to be invoked with more than one name although it
+appears only once in the computer's memory.)
+
+The \TEX/ conventions adopted here say that words are what remain
+after you remove nonletters, control sequences,
+comments triggered by \.\% marks, and material enclosed
+within \.{\$...\$} or \.{\$\$...\$\$}. However, an apostrophe within
+a word will be retained. The plain \TEX/ control
+sequences for accented characters and special text characters, namely
+$$\vbox{\halign{&\.{\\#}\hfil\qquad\cr
+'&`&\relax\^&"&\relax\~&=&.&u&v\cr
+H&t&c&d&b&oe&OE&ae&AE\cr
+aa&AA&o&O&l&L&ss&i&j\cr}}$$
+will also be retained, so that users can treat them as parts of words.
+A blank space
+following any of the alphabetic control sequences in this list will be carried
+along too. If any of these control sequences is followed by \.\{, everything
+up to the next \.\} will also be retained. Thus, for example, the
+construction `\.{m\\=\{\\i\}n\\u\ us}' will be considered a single word,
+in spite of the control sequences and the space between the two u's.
+Discretionary hyphens `\.{\char`\\-}' are treated in the same way as accents.
+
+The \.{CWEB} conventions are essentially the same as the \TEX/ conventions,
+in the \TEX/ parts of a \.{CWEB} file. The \CEE/ parts of the file
+are blanked out.
+
+No attempt is made to reach a high level of artificial intelligence,
+which would be able to truly understand the input file. Tricky users can
+ confuse us. But we claim that devious tricks are their problem, not ours.
+
+@ So here goes. The main idea is to keep a one-character lookahead
+buffer, called |c|, which is set to zero when the character has been
+processed. A giant switch to various cases, depending on the value of~|c|,
+keeps everything moving.
+
+If you don't like |goto| statements, don't read this. (And don't read
+any other programs that simulate finite-state automata.)
+
+@c
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+extern void exit(); /* system routine that terminates execution */
+@#
+@<Global variables@>@;
+@<Procedures@>@;
+@#
+int main(argc,argv)
+ int argc; /* the number of arguments (should be 1, but this isn't checked) */
+ char *argv[]; /* the arguments (|*argv| is the program name) */
+{
+ @<Local variables@>;
+ if (strlen(*argv)>=6 && strcmp(*argv+strlen(*argv)-6,"excweb")==0) {
+ web=1;
+ @<Adjust tables for \.{CWEB} mode@>;
+ } else web=0;
+ comment=skipping=c=0;
+ main_cycle: if (c) goto big_switch;
+ restart: c=get();
+ big_switch: switch(c) {
+ @<Special cases of the giant switch where we don't just discard |c|@>@;
+ case EOF: exit(0);
+ default: goto restart;
+ }
+ @<Labeled code segments, which exit by explicit |goto|@>;
+}
+
+@ @<Global variables@>=
+int c; /* one-character look-see buffer */
+
+@ @<Local variables@>=
+int web; /* are we looking for \.{CWEB} constructs? */
+int comment; /* are we inside a \CEE/ comment in a \.{CWEB} document? */
+int skipping; /* are we skipping \CEE/ code in a \.{CWEB} document? */
+int save_skipping; /* value of |skipping| outside current \CEE/ mode */
+register int cc; /* temporary buffer */
+
+@* Simple cases.
+Let's do some of the easiest things first, in order to get the hang of
+this program. Several special characters will cause us to ignore everything
+until the first appearance of something else.
+
+@d discard_to(x) {@+while (get()!=x) ;@+}
+@d discard_to_dol {@+for (cc=c,c=get();c!='$' || cc=='\\';cc=c,c=get())
+ if (cc=='\\' && c==cc) c='\0';@+}
+
+@<Special cases...@>=
+case '%': discard_to('\n');@+goto restart;
+case '$': c=getchar();
+ if (c!='$') discard_to_dol@;
+ else { /* after \.{\$\$} we discard everything to the next \.{\$\$} */
+ do discard_to_dol@;
+ while (getchar()!='$');
+ }
+ goto restart;
+
+@ The `|get|' procedure in the code above is like \Cee's standard
+`|getchar|', except that it immediately terminates execution at the end of
+the input file. Otherwise malformed input files could lead to
+infinite loops.
+
+@<Procedures@>=
+int get()
+{@+register int x;
+ x=getchar();
+ if (x==EOF) exit(0);
+ return x;
+}
+
+@ More complex behavior is handled by jumping out of the |switch| statement
+to one of the routines following it. None of the cases say |break|, so
+the code following the switch statement is accessible only via |goto|.
+
+@<Special cases...@>=
+case 'a': case 'A':
+case 'b': case 'B':
+case 'c': case 'C':
+case 'd': case 'D':
+case 'e': case 'E':
+case 'f': case 'F':
+case 'g': case 'G':
+case 'h': case 'H':
+case 'i': case 'I':
+case 'j': case 'J':
+case 'k': case 'K':
+case 'l': case 'L':
+case 'm': case 'M':
+case 'n': case 'N':
+case 'o': case 'O':
+case 'p': case 'P':
+case 'q': case 'Q':
+case 'r': case 'R':
+case 's': case 'S':
+case 't': case 'T':
+case 'u': case 'U':
+case 'v': case 'V':
+case 'w': case 'W':
+case 'x': case 'X':
+case 'y': case 'Y':
+case 'z': case 'Z':
+goto out_word;
+
+@ When letters appear in |stdin|, we pass them immediately through to |stdout|
+with little further ado.
+An apostrophe is rejected unless it is immediately followed by a letter.
+
+@<Labeled code...@>=
+out_word: putchar(c);
+continue_word: c=getchar();
+checkout_word:
+if (isalpha(c)) goto out_word;
+if (c=='\'') {
+ c=getchar();
+ if (isalpha(c)) {
+ putchar('\'');@+goto out_word;
+ }
+ goto end_word;
+}
+if (c=='\\' && controlseq()) goto control_seq_in_word;
+end_word: putchar('\n');
+ goto main_cycle;
+
+@* Control sequences. The |controlseq()| function is the only
+delicate part of this program. After a backslash has been scanned,
+|controlseq| looks to see if the next characters define one of the
+special plain \TEX/ macros listed above. If so, the control sequence
+and its immediately following argument (if any) are output and
+|controlseq| returns a nonzero value. If not, nothing is output and
+|controlseq| returns zero. In both cases the value of |c| will be
+nonzero if and only if |controlseq| has had to look ahead at a
+character it decided not to process.
+
+@ @<Labeled code...@>=
+control_seq_in_word: if (!c) goto continue_word;
+goto checkout_word;
+
+@ @<Special cases...@>=
+case '\\': if (controlseq()) goto control_seq_in_word;
+goto main_cycle;
+
+@ @<Procedures@>=
+int controlseq()
+{
+ int l; /* number of letters in the control sequence */
+ char a,b; /* the first two characters after `\.\\' */
+ l=0;
+ a=c=getchar();
+ while (isalpha(c)) {
+ l++;
+ c=getchar();
+ if (l==1) b=c;
+ }
+ if (l==0) c=getchar();
+ @<Check for special plain \TEX/ control sequences;
+ output them and |return 1| if found@>;
+ return 0;
+}
+
+@ @d pair(x,y) (a==x && b==y)
+
+@<Check for special...@>=
+if ((a>='"' && a<='~' && ptab[a-'"']==l) ||
+ (l==2 && (pair('a','e') || pair('A','E')@|
+ || pair('o','e') || pair('O','E')@|
+ || pair('a','a') || pair('A','A') || pair('s','s')))) {
+ putchar('\\');
+ putchar(a);
+ if (l==2) putchar(b);
+ if (l && c==' ') {
+ putchar(' '); /* optional space after alphabetic control sequence */
+ c=getchar();
+ }
+ if (c=='{') {
+ do@+{putchar(c);
+ c=get();
+ }@+while (c!='}'); /* optional argument after special control sequence */
+ putchar(c);
+ c=0;
+ }
+ return 1;
+}
+
+@ The |ptab| entries for nonletters are 0 when the control sequence is
+special, otherwise~1; the conventions for letters are reversed.
+
+@<Global...@>=
+char ptab[]={0,1,1,1,1,0, /* \.{\\"} and \.{\\'} */
+ 1,1,1,1,1,0,0,1, /* \.{\\-} and \.{\\.} */
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1, /* \.{\\=} */
+ 1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1, /* \.{\\H}, \.{\\L}, \.{\\O} */
+ 0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1, /* \.{\\\^} */
+ 0,0,1,1,1,0,0,0, /* \.{\\`}, \.{\\b}, \.{\\c}, \.{\\d} */
+ 0,1,1,0,1,0,0,1, /* \.{\\i}, \.{\\j}, \.{\\l}, \.{\\o} */
+ 0,0,0,0,1,1,1,0, /* \.{\\t}, \.{\\u}, \.{\\v} */
+ 0,0,0,1,1,1,0}; /* \.{\\\~} */
+
+@ In \.{CWEB} the \TEX/ control sequence `\.{\\.}' denotes the typewriter
+font used for strings, not the dot-over accent. We must modify
+|ptab| to reflect this unfortunate (but too-late-too-change) design decision.
+
+@<Adjust tables for \.{CWEB} mode@>=
+ptab[12]=1;
+
+@* CWEB considerations.
+We're finished now with all that would be needed if we only wanted to
+handle \TEX/. For \.{CWEB} a bit more should be done.
+
+The \.{CWEB} escape character is \.{@@}, and the character following
+it tells us what mode we should enter. In \TEX/ mode we should not
+only do what we normally do for \TEX/ files, we should also ignore
+material delimited by \.{\char"7C...\char"7C}, being careful to recognize when
+|'|'| is part of a string (as it just was). And we should stop \TEX/
+mode if we scan \.{*/} while in a \CEE/ comment.
+
+@<Special cases...@>=
+case '@@': if (web) goto do_web;
+ goto restart;
+case '|': if (web>1) {
+ save_skipping=skipping;
+ goto skip_C_prime;
+ }
+ goto restart;
+case '*': if (!comment) goto restart;
+ c=getchar();
+ if (c=='/') {
+ comment=0;
+ goto skip_C;
+ }
+ goto big_switch;
+
+@ The characters that follow \.@@ in a \.{CWEB} file can be classified into
+a few types that have distinct implications for {\tt excweb}.
+
+@d nop 0 /* control code that doesn't matter to us */
+@d start_section 1 /* control code that begins a \.{CWEB} section */
+@d start_C 2 /* control code that begins \CEE/ code */
+@d start_name 3 /* control code that begins a section name */
+@d start_index 4 /* control code for \.{CWEB} index entry */
+@d start_insert 5 /* control code for \CEE/ material ended by `\.{@@>}' */
+@d end_item 6 /* `\.{@@>}' */
+@d ignore_line 7 /* `\.{@@i}' or `\.{@@l}' */
+
+@<Global...@>=
+char wtab[]={start_section,nop,nop,nop,nop,nop,nop,nop, /* \.{\ !"\#\$\%\&'} */
+ start_name,nop,start_section,nop,nop,nop,start_index,nop, /* \.{()*+,-./} */
+ nop,nop,nop,nop,nop,nop,nop,nop, /* \.{01234567} */
+ nop,nop,start_index,nop,start_name,start_insert,end_item,nop,
+ /* \.{89:;<=>?} */
+ nop,nop,nop,start_C,start_C,nop,start_C,nop, /* \.{@@ABCDEFG} */
+ nop,ignore_line,nop,nop,ignore_line,nop,nop,nop, /* \.{HIJKLMNO} */
+ start_C,start_insert,nop,start_C,start_insert,nop,nop,nop, /* \.{PQRSTUVW} */
+ nop,nop,nop,nop,nop,nop,start_index,nop, /* \.{XYZ[\\]\^\_} */
+ nop,nop,nop,start_C,start_C,nop,start_C,nop, /* \.{`abcdefg} */
+ nop,ignore_line,nop,nop,ignore_line,nop,nop,nop, /* \.{hijklmno} */
+ start_C,start_insert,nop,start_C,start_insert}; /* \.{pqrst} */
+
+@ We do not leave \TEX/ mode until the first \.{WEB} section has begun.
+
+@<Labeled code...@>=
+do_web: c=getchar();
+ if (c<' ' || c>'t') goto restart;
+ switch(wtab[c-' ']){
+ case nop: case start_index: goto restart;
+ case start_section: web++; /* out of ``limbo'' */
+ comment=skipping=0;@+goto restart;
+ case start_C: if (web>1) goto skip_C;
+ goto restart;
+ case start_name: case start_insert: if (web>1) skipping=1;
+ goto restart;
+ case end_item: if (skipping) goto skip_C;
+ goto restart;
+ case ignore_line: discard_to('\n');
+ goto restart;
+ }
+
+@ The final piece of program we need is a sub-automaton to pass over
+the \CEE/ parts of a \.{CWEB} document. The main subtlety here is that
+we don't want to get out of synch while scanning over a supposed
+string constant or verbatim insert.
+
+@<Labeled code...@>=
+skip_C: save_skipping=2;
+skip_C_prime: skipping=1;
+ while (1) {
+ c=get();
+ C_switch: switch(c) {
+ case '/': c=get();
+ if (c!='*') goto C_switch;
+ comment=1; /* fall through to the next case, returning to \TEX/ mode */
+ case '|': if (save_skipping==2) continue; /* |'|'| as \CEE/ operator */
+ skipping=save_skipping;@+goto restart; /* |'|'| as \.{CWEB} delimiter */
+ case '@@': c=getchar();
+ inner_switch: if (c<' ' || c>'t') continue;
+ switch(wtab[c-' ']) {
+ case nop: case start_C: case end_item: continue;
+ case start_section: web++;
+ comment=skipping=0;@+goto restart;
+ case start_name: case start_index: goto restart;
+ case start_insert: do@+discard_to('@@')@;@+while ((c=getchar())=='@@');
+ goto inner_switch; /* now |c| should equal |'>'| */
+ case ignore_line: discard_to('\n');
+ continue;
+ }
+ case '\'': case '"':
+ while ((cc=get())!=c && cc!='\n')
+ if (cc=='\\') getchar();
+ else if (cc=='@@') {
+ cc=getchar();
+ if (cc!='@@') { /* syntax error, we try to recover */
+ c=cc; goto inner_switch;
+ }
+ };
+ continue; /* \.{CWEB} strings do not extend past one line */
+ default: continue;
+ }
+ }
+
+@* Index.
diff --git a/Build/source/texk/web2c/cwebdir/examples/kspell.el b/Build/source/texk/web2c/cwebdir/examples/kspell.el
new file mode 100644
index 00000000000..1825021280b
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/kspell.el
@@ -0,0 +1,228 @@
+;; Alternative spelling enterface for Emacs, contributed by Don Knuth
+;; (Uses the wordtest and extex programs, which are
+;; supplied as examples with the CWEB distribution,
+;; available by anonymous ftp from ftp.cs.stanford.edu)
+
+;; Based in part on "spell.el" from GNU Emacs; redistributed under
+;; the terms of the GNU General Public License; NO WARRANTY implied.
+
+;; To install this, using the default directories defined below,
+;; install wordtest and extex in /usr/local/bin, then say
+;; "ln /usr/local/bin/extex /usr/local/bin/excweb", then install
+;; a suitable dictionary in /usr/local/lib/dict/words; one such
+;; dictionary can be found in ~ftp/pub/dict/words at ftp.cs.stanford.edu.
+;; Also create an empty file called .words in your home directory.
+;; Finally, add (load-library "kspell") to your .emacs file, or
+;; include such a line in site-init.el if kspell is to be used by everybody.
+;; If you get a message like "Checking spelling of buffer...not correct"
+;; and nothing else, the probable cause is that the wordtest program
+;; could not open /usr/local/lib/dict/words or ~/.words for reading.
+
+;; Note (10 Feb 1998): The spell-check logic failed to catch "obso1ete"
+;; as a scanner-typo for "obsolete". The reason is that, although "obso"
+;; and "ete" are non-words, they couldn't be found in query-replace
+;; for the regexps "\bobso\b" and "\bete\b".
+
+(provide 'kspell)
+
+(defvar wordtest-command "wordtest" ;; maybe "/usr/local/bin/wordtest" better?
+ "*Command to run the wordtest program; can include command-line options.")
+
+;; "wordtest [options] [dictionaries] <infile >outfile" outputs all
+;; lines of infile that don't appear in the dictionaries. The options
+;; can define arbitrary character code mappings of 8-bit characters.
+;; The default mapping takes a-z into A-Z, otherwise is ASCII.
+
+(defvar wordtest-filter "extex" ;; maybe "/usr/local/bin/extex" is better?
+ "*Command to run the filter needed by wordtest.")
+(make-variable-buffer-local 'wordtest-filter)
+
+;; The extex filter extracts words from its input and outputs them on
+;; separate lines as required by wordtest. It removes TeX control
+;; sequences except those used to make accents and special characters.
+;; There's a companion filter excweb that also removes C code from CWEBs.
+(setq cweb-mode-hook '(lambda () (setq wordtest-filter "excweb")))
+
+(defvar wordtest-system-dictionary "/usr/local/lib/dict/words"
+ "*Sorted dictionary containing all \"correct\" words,
+including all variant forms obtained by prefix and suffix transformations.")
+;; The standard UNIX dictionary /usr/dict/words is NOT satisfactory.
+
+(defvar wordtest-personal-dictionary "~/.words"
+ "*Default dictionary to supplement the words in the system dictionary.
+If nil, no supplementary dictionary will be used.
+This dictionary must be in alphabetic order as defined by wordtest.
+Inserting any word with the + option to kspell-region will sort the file.")
+(make-variable-buffer-local 'wordtest-personal-dictionary)
+
+(defun set-personal-dictionary (filename)
+ "Defines the supplementary personal dictionary for kspell to use in the
+current buffer, overriding the default value of wordtest-personal-dictionary."
+ (interactive "FPersonal dictionary file name: ")
+ (setq wordtest-personal-dictionary filename))
+
+(defun unset-personal-dictionary ()
+ "Tells kspell not to use personal spelling dictionary with current buffer."
+ (interactive)
+ (setq wordtest-personal-dictionary nil))
+
+(defun insert-into-personal-dictionary (word)
+ "Put WORD into user's dictionary and sort that dictionary."
+ (interactive "sword: ")
+ (let ((xword (concat word "\n")))
+ (if (null wordtest-personal-dictionary)
+ (setq wordtest-personal-dictionary
+ (read-string "Personal dictionary file name: " "~/.words")))
+ (set-buffer (find-file-noselect wordtest-personal-dictionary))
+ (goto-char (point-min))
+ (insert xword)
+ (call-process-region (point-min) (point-max) shell-file-name
+ t t nil "-c" wordtest-command)
+ (search-backward xword (point-min) 1) ;; in case the user is watching
+ (while (not (bolp)) (search-backward xword (point-min) 1))
+ (save-buffer)))
+
+(defun kspell-buffer ()
+ "Check spelling of every word in the buffer.
+For each incorrect word, you are asked for the correct spelling
+and then put into a query-replace to fix some or all occurrences.
+
+If you do not want to change a word, just give the same word
+as its \"incorrect\" spelling; then the query replace is skipped.
+Words are given in lowercase, but they will be Capitalized when
+replacing Capitalized words, ALL_CAPS when replacing ALL_CAPS words.
+If you type ? after a replacement, your correction will first be
+looked up in the dictionary, and the query-replace will occur
+only if the replacement is found. If you type + after a replacement,
+your replacement will be inserted into the current personal dictionary.
+
+You can leave the minibuffer to do some other editing and then come
+back again to the query-replace loop by typing \\[other-window]."
+ (interactive)
+ (save-excursion (kspell-region (point-min) (point-max) "buffer")))
+
+(defun kspell-word ()
+ "Check spelling of the word at or before point.
+If it is not correct, ask user for the correct spelling and
+query-replace the entire buffer to substitute it as with kspell-buffer."
+ (interactive)
+ (let (beg end wordtest-filter)
+ (save-excursion
+ (if (not (looking-at "\\<"))
+ (forward-word -1))
+ (setq beg (point))
+ (forward-word 1)
+ (setq end (point))
+ (kspell-region beg end (buffer-substring beg end)))))
+
+(defun kspell-region (start end &optional description)
+ "Like kspell-buffer but checks only words in the current region.
+Used in a program, applies from START to END.
+DESCRIPTION is an optional string naming the unit being checked:
+for example, \"buffer\"."
+ (interactive "r")
+ (let (correct
+ (filter wordtest-filter)
+ (buf (get-buffer-create " *kspell*")) ;; hidden by list-buffers
+ (dicts wordtest-system-dictionary))
+ (if wordtest-personal-dictionary
+ (setq dicts (concat dicts " " wordtest-personal-dictionary)))
+ (save-excursion
+ (save-excursion
+ (set-buffer buf)
+ (widen)
+ (erase-buffer))
+ (message "Checking spelling of %s..." (or description "region"))
+ (if (and (null filter)
+ (< end (point-max))
+ (= ?\n (char-after end)))
+ (call-process-region start (1+ end) shell-file-name
+ nil buf nil "-c"
+ (concat wordtest-command " " dicts))
+ (let ((oldbuf (current-buffer)))
+ (save-excursion
+ (set-buffer buf)
+ (insert-buffer-substring oldbuf start end)
+ (or (bolp) (insert ?\n))
+ (if filter
+ (call-process-region (point-min) (point-max) shell-file-name
+ t t nil "-c" filter))
+ (call-process-region (point-min) (point-max) shell-file-name
+ t t nil "-c"
+ (concat wordtest-command " " dicts)))))
+ (setq correct (save-excursion (set-buffer buf) (= (buffer-size) 0)))
+ (message "Checking spelling of %s...%scorrect"
+ (or description "region")
+ (if correct "" "not "))
+ (if correct t
+ (let (word newword qtext lastchar
+ (case-fold-search t)
+ (case-replace t))
+ (while (save-excursion
+ (set-buffer buf)
+ (> (buffer-size) 0))
+ (save-excursion
+ (set-buffer buf)
+ (goto-char (point-min))
+ (setq word (downcase
+ (buffer-substring (point)
+ (progn (end-of-line) (point)))))
+ (forward-char 1) ;; pass the newline
+ (delete-region (point-min) (point))
+ (setq qtext (concat "\\b" (regexp-quote word) "\\b")))
+ (goto-char (point-min))
+ (setq lastchar nil)
+ (if (re-search-forward qtext nil t)
+ (while (null lastchar)
+ (setq newword
+ (read-string
+ (concat "edit a replacement for `" word "': ")
+ word))
+ (if (null newword) (setq lastchar 0)
+ (setq lastchar (string-to-char (substring newword -1)))
+ (if (memq lastchar '(?? ?+))
+ (setq newword (substring newword 0 -1))))
+ (cond ((= lastchar ??)
+ (cond ((or (string= word newword) (string= "" newword))
+ (describe-function 'kspell-buffer)
+ (setq lastchar nil))
+ ((not (kspelt-right newword))
+ (setq lastchar nil))))
+ ((= lastchar ?+)
+ (save-excursion
+ (insert-into-personal-dictionary newword))))
+ (cond ((string= word newword))
+ ((null lastchar))
+ (t
+ (goto-char (point-min))
+ (if (or (equal word newword) (null lastchar)) t
+ (query-replace-regexp qtext newword))))))))))))
+
+(defun kspelt-right (word)
+ "T if WORD is in the system dictionary or user's personal dictionary."
+ (let ((buf (get-buffer-create " *temp*"))
+ (pdict wordtest-personal-dictionary))
+ (message "Checking spelling of %s..." word)
+ (save-excursion
+ (set-buffer buf)
+ (widen)
+ (erase-buffer)
+ (insert word "\n")
+ (if pdict
+ (call-process-region (point-min) (point-max) shell-file-name
+ t t nil "-c"
+ (concat wordtest-command " "
+ wordtest-system-dictionary " "
+ pdict))
+ (call-process-region (point-min) (point-max) shell-file-name
+ t t nil "-c"
+ (concat wordtest-command " "
+ wordtest-system-dictionary)))
+ (= 0 (buffer-size)))))
+
+(defun kspell-string (string)
+ "Check spelling of string supplied as argument."
+ (interactive "sSpell string: ")
+ (message "%s is %scorrect" string
+ (if (kspelt-right string) "" "in")))
+
diff --git a/Build/source/texk/web2c/cwebdir/examples/oemacs.el b/Build/source/texk/web2c/cwebdir/examples/oemacs.el
new file mode 100644
index 00000000000..1f16c51e786
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/oemacs.el
@@ -0,0 +1,176 @@
+;; macros to go with oemacs
+
+; suntool-map is the map for "\C-x*", the oemacs prefix for function keys
+; commented-out lines agree with the settings in $(EMACS)/lisp/term/sun.el
+
+(setq suntool-map-hooks '( ; not your usual hook list
+; (define-key suntool-map "al" 'keyboard-quit) ; Stop
+; (define-key suntool-map "bl" 'redraw-display) ; Again L2
+; (define-key suntool-map "b\M-l" 'repeat-complex-command); M-Again = C-X ESC
+; (define-key repeat-complex-command-map "\C-x*b\M-l"
+; 'previous-complex-command) ; M-Again M-Again...
+ (define-key suntool-map "bL" 'rerun-prev-command) ; AGAIN (no confirm)
+; (define-key suntool-map "b\M-L" 'rerun-prev-command) ; M-AGAIN
+; (define-key suntool-map "cl" 'buffer-menu) ; Props
+; (define-key suntool-map "dl" 'undo) ; Undo
+; (define-key suntool-map "el" 'ignore-key) ; Front
+; (define-key suntool-map "fl" 'sun-select-region) ; Copy
+; (define-key suntool-map "f," 'copy-region-as-kill) ; C-Copy
+; (define-key suntool-map "gl" 'ignore-key) ; Open
+; (define-key suntool-map "hl" 'sun-yank-selection) ; Paste
+; (define-key suntool-map "h," 'yank) ; C-Paste
+; (define-key suntool-map "il" 'research-forward) ; Find (with default)
+; (define-key suntool-map "i\M-l" 'research-backward) ; M-Find
+; (define-key suntool-map "iL" 'isearch-forward-regexp) ; FIND (incremental)
+; (define-key suntool-map "i\M-L" 'isearch-backward-regexp); M-FIND
+; (define-key suntool-map "i," 're-search-forward) ; C-Find (ordinary)
+; (define-key suntool-map "i\M-," 're-search-backward) ; C-M-Find
+ (define-key suntool-map "jl" 'sun-cut-region) ; Cut
+ (define-key suntool-map "j," 'kill-region-and-unmark) ; C-Cut
+ (define-key suntool-map "jL" 'pop-the-mark) ; CUT
+; (define-key suntool-map "j\M-l" 'exchange-point-and-mark); M-Cut
+
+ (define-key suntool-map "at" 'bury-buffer) ; F1
+; (define-key suntool-map "bt" 'toggle-selective-display) ; F2
+; (define-key suntool-map "ct" 'scroll-down-in-place) ; F3
+; (define-key suntool-map "cT" '(lambda(n) (interactive "p") (scroll-down n)))
+; (define-key suntool-map "dt" 'scroll-up-in-place) ; F4
+; (define-key suntool-map "dT" '(lambda(n) (interactive "p") (scroll-up n)))
+ (define-key suntool-map "et" 'jumpup) ; F5
+; (define-key suntool-map "ft" 'shrink-window) ; F6
+; (define-key suntool-map "fT" 'shrink-window-horizontally) ; Shift-F6
+; (define-key suntool-map "gt" 'enlarge-window) ; F7
+; (define-key suntool-map "gT" 'enlarge-window-horizontally) ; Shift-F7
+ (define-key suntool-map "ht" 'tags-search) ; F8
+ (define-key suntool-map "it" 'tags-query-replace) ; F9
+ (define-key suntool-map "jt" 'narrow-to-region) ; F10
+ (define-key suntool-map "j\M-t" 'narrow-to-page) ; M-F10
+ (define-key suntool-map "kt" 'revert-buffer) ; F11
+ (define-key suntool-map "k\M-t" 'quick-revert-other-buffer) ; M-F11
+ (define-key suntool-map "lt" 'goto-line) ; F12
+ (define-key suntool-map "l\M-t" 'goto-line) ; M-F12
+
+ (define-key suntool-map "ar" 'redraw-display) ; Pause, R1
+ (define-key suntool-map "br" 'call-secondlast-kbd-macro) ; PrSc, R2
+ (define-key suntool-map "cr" 'ignore-key) ; Scroll Lock Break, R3
+ (define-key suntool-map "dr" 'unbound-key) ; KP=, R4
+ (define-key suntool-map "d\M-r" 'bind-last-kbd-macro-to-KP=) ; M-KP=, M-R4
+ (define-key suntool-map "er" 'unbound-key) ; KP/, R5
+ (define-key suntool-map "e\M-r" 'bind-last-kbd-macro-to-KP/) ; M-KP/, M-R5
+ (define-key suntool-map "fr" 'unbound-key) ; KP*, R6
+ (define-key suntool-map "f\M-r" 'bind-last-kbd-macro-to-KP*) ; M-KP*, M-R6
+; (define-key suntool-map "gr" 'beginning-of-buffer) ; Home, R7
+
+; (define-key suntool-map "hr" 'previous-line) ; Up, R8
+; (define-key suntool-map "ir" 'scroll-down) ; PgUp, R9
+; (define-key suntool-map "iR" 'backward-page) ; Shift-PGUP
+; (define-key suntool-map "jr" 'backward-char) ; Lft, R10
+ (define-key suntool-map "kr" "\C-u\C-l") ; KP5, R11
+; (define-key suntool-map "lr" 'forward-char) ; Rt, R12
+; (define-key suntool-map "mr" 'end-of-buffer) ; End, R13
+; (define-key suntool-map "nr" 'next-line) ; Dn, R14
+; (define-key suntool-map "or" 'scroll-up) ; PgDn, R15
+; (define-key suntool-map "oR" 'forward-page) ; Shift-PGUP
+
+ (define-key suntool-map "ab" 'apropos) ; Help
+ (define-key suntool-map "a\M-b" 'mouse-help) ; M-Help
+ (define-key suntool-map "aB" 'describe-bindings) ; HELP
+ (define-key suntool-map "a\M-B" 'describe-mouse-bindings); M-HELP
+ (define-key suntool-map "a\"" 'command-apropos) ; C-Help
+ (define-key suntool-map "a\C-B" 'apropos) ; C-HELP
+ (define-key suntool-map "a\M-\C-B" 'help-for-dummies) ; M-C-HELP
+ (define-key suntool-map "bb" 'ignore-key) ; Alt
+ (define-key suntool-map "cb" 'ignore-key) ; AltGraph
+ (define-key suntool-map "db" 'auto-fill-mode) ; Keypad Ins
+ (define-key suntool-map "eb" 'overwrite-mode) ; Keypad Del
+ (define-key suntool-map "fb" 'call-last-kbd-macro) ; Keypad Enter
+ (define-key suntool-map "gb" 'forward-paragraph) ; Keypad +
+ (define-key suntool-map "hb" 'backward-paragraph) ; Keypad -
+ ))
+
+
+; redefinition of emacs functions
+(defun end-of-buffer ()
+ "Move point to the end of the buffer; leave a mark at previous position.
+Scroll so that point is at the bottom of the window, if possible."
+ (interactive)
+ (push-mark)
+ (goto-char (point-max))
+ (recenter -1))
+
+; new functions
+(defun jumpup ()
+ "Scroll so that point is at the top of the window."
+ (interactive)(recenter 0))
+
+(defun quick-revert-buffer ()
+ "Revert the buffer without asking for confirmation."
+ (interactive)
+ (revert-buffer t t))
+
+(defun quick-revert-other-buffer (n)
+ "Revert the Nth other buffer without asking for confirmation."
+ (interactive "p")
+ (other-window n)
+ (revert-buffer t t)
+ (other-window (- n)))
+
+(defun bind-last-kbd-macro-to-KP= ()
+ "Assign the last keyboard macro to the = key on the numeric keypad."
+ (interactive)
+ (define-key suntool-map "dr" last-kbd-macro))
+
+(defun bind-last-kbd-macro-to-KP/ ()
+ "Assign the last keyboard macro to the / key on the numeric keypad."
+ (interactive)
+ (define-key suntool-map "er" last-kbd-macro))
+
+(defun bind-last-kbd-macro-to-KP* ()
+ "Assign the last keyboard macro to the * key on the numeric keypad."
+ (interactive)
+ (define-key suntool-map "fr" last-kbd-macro))
+
+(defvar secondlast-kbd-macro nil)
+(defun pre-end-kbd-macro ()
+ "Preserve last-kbd-macro as secondlast-kbd-macro, then end-kbd-macro."
+ (interactive)
+ (setq secondlast-kbd-macro last-kbd-macro)
+ (end-kbd-macro))
+(substitute-key-definition 'end-kbd-macro 'pre-end-kbd-macro global-map)
+(substitute-key-definition 'end-kbd-macro 'pre-end-kbd-macro esc-map)
+(substitute-key-definition 'end-kbd-macro 'pre-end-kbd-macro ctl-x-map)
+
+(defun call-secondlast-kbd-macro (n)
+ "Like call-last-kbd-macro, but uses the macro defined before that."
+ (interactive "p")
+ (let ((last-kbd-macro secondlast-kbd-macro))
+ (call-last-kbd-macro n)))
+
+; The turn-numlock-on/off commands are created automatically by oemacs
+; when the NumLock light changes state.
+(defun turn-numlock-on () ; numlock is always off when oemacs starts
+ "Bind keys in keypad area to numeric interpretations."
+ (interactive)
+ (setq hb-binding (lookup-key suntool-map "hb"))
+ (setq gb-binding (lookup-key suntool-map "gb"))
+ (setq fb-binding (lookup-key suntool-map "fb"))
+ (setq eb-binding (lookup-key suntool-map "eb"))
+ (setq db-binding (lookup-key suntool-map "db"))
+ (define-key suntool-map "hb" "-")
+ (define-key suntool-map "gb" "+")
+ (define-key suntool-map "fb" "\C-j")
+ (define-key suntool-map "eb" ".")
+ (define-key suntool-map "db" "0"))
+(defun turn-numlock-off ()
+ "Rebind keys in keypad area to function-key interpretations."
+ (interactive)
+ (define-key suntool-map "hb" hb-binding)
+ (define-key suntool-map "gb" gb-binding)
+ (define-key suntool-map "fb" fb-binding)
+ (define-key suntool-map "eb" eb-binding)
+ (define-key suntool-map "db" db-binding))
+(defvar hb-binding nil)
+(defvar gb-binding nil)
+(defvar fb-binding nil)
+(defvar eb-binding nil)
+(defvar db-binding nil)
diff --git a/Build/source/texk/web2c/cwebdir/examples/oemacs.w b/Build/source/texk/web2c/cwebdir/examples/oemacs.w
new file mode 100644
index 00000000000..5810b0e7b26
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/oemacs.w
@@ -0,0 +1,896 @@
+\datethis
+@i xview_types.w
+
+@* Introduction.
+This program provides an interface between the GNU Emacs editor and the
+OpenWindows environment, using the XView toolkit for interactive graphics.
+It is based on \.{emacstool}, a SunView interface written by Jeff Peck
+of Sun Microsystems in 1986 and adapted by him in 1988 to \.{xvetool},
+an early XView interface. The present code, by Don Knuth, is designed to work
+with OpenWindows Version~3 as distributed in 1992, using a Sun Type~4
+keyboard.
+
+GNU Emacs is a highly portable and versatile program, which does most
+of the hard work involved in editing files. Our job is simply twofold:
+To get \.{emacs} started in an appropriate window, and to transmit
+keyboard and mouse events as sequences of characters that \.{emacs}
+can happily consume. These simple tasks do, however, require us to
+get a lot of fussy details right. In fact, this program could not have been
+written without a good deal more knowledge about XView than can be found
+in the manuals. Fortunately Jeff Peck works for Sun, and his
+inside knowledge has provided the necessary clues. (All complaints below
+about the XView documentation are based on the reference manuals and
+programming manuals available from Sun and from O'Reilly \AM\ Associates, in
+the summer of 1992. Let us hope that such problems will not persist;
+computer programming should be fun, but some of the code below was
+written only after a bitter struggle!)
+
+The command-line arguments to \.{oemacs} are either standard XView
+arguments, which specify the font and the size and position of the window,
+the icon, the colors, etc.; or they are standard arguments of \.{emacs},
+which typically specify the file to be edited and a position in that file.
+If I decide later to make certain things in \.{oemacs} less hardwired,
+I will look for options in the X resource database instead of on the
+command line.
+
+An important note about using \.{xmodmap} to change the behavior of
+certain keys appears below. It makes \.{emacs} more powerful, unless you
+have other good uses for those keys. (See the entry for \.{xmodmap}
+in the index.)
+
+Before using \.{oemacs}, you must compile \.{emacs} with the
+\.{sunfns} module (which the \.{Makefile} will do for you if you've
+configured it correctly), and you should include the lines
+$$\vbox{\halign{\.{#}\hfil\cr
+(load-library "sun-mouse")\cr
+(load-library "sun-fns")\cr}}$$
+in Emacs's file \.{lisp/site-init.el}.
+
+Caution: This program was developed and tested with Peck's improved
+versions of sun-mouse and sun-fns; these are available from
+\.{peck@@sun.com} if not yet part of the GNU distribution.
+
+@ We follow the traditional structure of XView applications. The |exit|
+statement at the end is important, because \.{oemacs} can be invoked by
+the \.{system} command in \TEX/ (when the user has typed \.e in response
+to an error message); without |exit(0)|, \TEX/ would complain of trouble
+executing this program, although we would simply be terminating the program
+without returning any particular value.
+
+@c
+@<Include header files@>@;
+@#
+Frame frame; /* the base frame where we will live */
+@<Global variables@>@; /* additional globals besides |frame| */
+@#
+@<Event-handling procedures@>@;
+@#
+main(argc,argv)
+ int argc;@+char *argv[]; /* typical \UNIX/ setup */
+{
+ @<Special initialization@>;
+ @<Install the components and controls of |frame|@>;
+ xv_main_loop(frame);
+ exit(0);
+}
+
+@ Including the header file \.{<xview/xview.h>} also causes other
+basic header files like \.{<xview/frame.h>}, \.{<xview/icon.h>}, etc.,
+to be loaded. We must call the \CEE/ compiler with the flag
+\.{-I\$(OPENWINHOME)/include} so that the \CEE/ preprocessor will
+find the OpenWindows header files.
+
+Some \UNIX/ systems define string functions in \.{<string.h>}, some in
+\.{<strings.h>}; the Sun documentation calls for \.{<string.h>}. My
+experiments indicate that Sun's compiler and loader work perfectly
+well with string functions even when no header files are given, so the
+programmer doesn't really have to remember the right name. Similarly,
+\.{<stdio.h>} isn't really needed with Sun's \CEE/, unless certain macros
+are used. I'll include \.{<string.h>} and \.{<stdio.h>} anyway, in the
+spirit of being obedient to the stated rules.
+
+@<Include...@>=
+#include <string.h>
+#include <stdio.h>
+#include <xview/xview.h>
+
+@* The icon and frame.
+First we attach an icon that will appear if the user closes the \.{oemacs}
+window later.
+
+There are two reasons for doing this first. One is that we might as well
+begin with an easy task, in order to get warmed up. The other is that
+if we specify the icon {\it after\/} creating the frame, we will unconditionally
+override an icon that the user may have specified with the \.{-WI}
+option on the command line. (This is one of the little things a
+programmer has to turn by trial and error, since the XView documentation
+leaves much unsaid.)
+
+The colors used in the icon will be inherited from the frame, so they will
+be reversed if the user asks for reverse video. I~prefer to have the icon
+always in black on a yellow background, so I'm making the color explicit.
+(I hope this will work on monochrome displays; it works fine on my
+grayscale monitor.)
+
+@<Create a frame with the gnu icon@>=
+{@+Server_image icon_image=(Server_image)xv_create(NULL,SERVER_IMAGE,@|
+ XV_WIDTH,64,XV_HEIGHT,64,SERVER_IMAGE_BITS,icon_bits,NULL);
+ Server_image mask_image=(Server_image)xv_create(NULL,SERVER_IMAGE,@|
+ XV_WIDTH,64,XV_HEIGHT,64,SERVER_IMAGE_BITS,mask_bits,NULL);
+ Cms cms=(Cms)xv_create(NULL,CMS,CMS_SIZE,2,@|
+ CMS_NAMED_COLORS,"yellow","black",NULL,NULL);
+ Icon icon=(Icon)xv_create(NULL,ICON,@|
+ ICON_IMAGE,icon_image,ICON_MASK_IMAGE,mask_image,@|
+ WIN_CMS,cms,NULL);
+ frame=xv_create(NULL,FRAME,FRAME_ICON,icon,NULL);
+}
+
+@ @<Include...@>=
+#include <xview/cms.h>
+
+@ If the user hasn't specified a label with the \.{-Wl} option, we turn off
+the header line at the top of the frame. That gives us a chance to see
+two more lines of the file \.{emacs} is editing. However, we add a
+label of our own; it will show up in the virtual window manager display.
+
+@<Remove the frame header, unless the user has specifically requested it@>=
+if (xv_get(frame,XV_LABEL)==NULL) /* no label specified */
+ xv_set(frame,FRAME_SHOW_HEADER,FALSE,XV_LABEL,"OEMACS",NULL);
+
+@ The following icon and mask are derived from the ``what's gnu'' image on the
+back cover of the GNU Emacs manual. (This accounts for my black-on-yellow
+preference.)
+
+@<Global...@>=
+unsigned short icon_bits[]={@|
+ 0x0000, 0x0000, 0x0000, 0x1E00,
+ 0x0000, 0x0000, 0x0000, 0x0900,@|
+ 0x001E, 0x0000, 0x0000, 0x0880,
+ 0x0064, 0x0000, 0x0000, 0x0440,@|
+ 0x0088, 0x0000, 0x0000, 0x0420,
+ 0x0110, 0x0000, 0x0000, 0x0210,@|
+ 0x0220, 0x0000, 0x0000, 0x0210,
+ 0x0420, 0x0FCF, 0x01C0, 0x0108,@|
+ 0x0840, 0x1030, 0x8620, 0x0088,
+ 0x1080, 0x00C0, 0x5810, 0x0084,@|
+ 0x1080, 0x1F00, 0x2008, 0x0044,
+ 0x2100, 0xE200, 0x1004, 0x0044,@|
+ 0x4103, 0x0400, 0x0002, 0x0042,
+ 0x4204, 0x080E, 0x0001, 0x0042,@|
+ 0x8200, 0x7830, 0x0020, 0x8082,
+ 0x8203, 0x9040, 0x0018, 0x4102,@|
+ 0x8204, 0x2080, 0x07C6, 0x3E04,
+ 0x8108, 0x410C, 0x0021, 0x8004,@|
+ 0x8080, 0x8210, 0x03D0, 0x6008,
+ 0x4041, 0x0420, 0x0008, 0x1810,@|
+ 0x403E, 0x0820, 0x0FFC, 0x0620,
+ 0x2000, 0x1040, 0x0002, 0x01C0,@|
+ 0x1000, 0x608C, 0x0FFF, 0x0060,
+ 0x0801, 0x8110, 0x0080, 0x8118,@|
+ 0x0406, 0x0220, 0x1FFF, 0x66E0,
+ 0x0238, 0x044F, 0x0000, 0xD800,@|
+ 0x01C0, 0x0890, 0x8FFF, 0x4000,
+ 0x0300, 0x10A6, 0x4041, 0x6000,@|
+ 0x1C00, 0x2026, 0x4FFF, 0x6000,
+ 0x60CC, 0x4026, 0x4001, 0x6000,@|
+ 0x1F33, 0x8010, 0x8FFF, 0x4000,
+ 0x0012, 0x000F, 0x0040, 0xC000,@|
+ 0x0022, 0x4000, 0x07FF, 0x4000,
+ 0x0024, 0x4000, 0x0000, 0x2000,@|
+ 0x0024, 0x4818, 0x8FFF, 0xE000,
+ 0x0024, 0x4907, 0x0040, 0x2000,@|
+ 0x0044, 0x4900, 0x1FFF, 0xE000,
+ 0x0044, 0x4900, 0x0000, 0x2000,@|
+ 0x0044, 0x4900, 0x07FF, 0xE000,
+ 0x0044, 0x4880, 0x0020, 0x2000,@|
+ 0x0044, 0x4880, 0x07FF, 0xE000,
+ 0x0044, 0x4840, 0x0000, 0x2000,@|
+ 0x0044, 0x2A20, 0x07FF, 0xE000,
+ 0x0044, 0x2410, 0x0020, 0x2000,@|
+ 0x0042, 0x2448, 0x0FFF, 0xE000,
+ 0x0042, 0x2948, 0x0000, 0x2000,@|
+ 0x0041, 0x1144, 0x07FF, 0xA000,
+ 0x0041, 0x1144, 0x2010, 0x1000,@|
+ 0x0021, 0x1126, 0x20FA, 0x1000,
+ 0x0024, 0x8925, 0x2600, 0x1000,@|
+ 0x0014, 0x8924, 0xA138, 0x7000,
+ 0x0016, 0x88A4, 0x9090, 0x6000,@|
+ 0x000A, 0x44A4, 0x4880, 0xA000,
+ 0x0002, 0x44A2, 0x4401, 0x2000,@|
+ 0x0003, 0x4492, 0x2001, 0x4000,
+ 0x0001, 0x2451, 0x3002, 0x8000,@|
+ 0x0000, 0xA251, 0x1E05, 0x0000,
+ 0x0000, 0x2248, 0xA1F9, 0x8000,@|
+ 0x0000, 0x1648, 0x9002, 0x8000,
+ 0x0000, 0x1A28, 0x4C02, 0x8000,@|
+ 0x0000, 0x1220, 0x43FC, 0x8000,
+ 0x0000, 0x0120, 0x2000, 0x8000,@|
+ 0x0000, 0x0120, 0x2003, 0x0000,
+ 0x0000, 0x0150, 0x1FFC, 0x0000
+};
+unsigned short mask_bits[]={@|
+ 0x0000, 0x0000, 0x0000, 0x1E00,
+ 0x0000, 0x0000, 0x0000, 0x0F00,@|
+ 0x001E, 0x0000, 0x0000, 0x0F80,
+ 0x007C, 0x0000, 0x0000, 0x07C0,@|
+ 0x00F8, 0x0000, 0x0000, 0x07E0,
+ 0x01F0, 0x0000, 0x0000, 0x03F0,@|
+ 0x03E0, 0x0000, 0x0000, 0x03F0,
+ 0x07E0, 0x0FCF, 0x01C0, 0x01F8,@|
+ 0x0FC0, 0x103F, 0x87F0, 0x00F8,
+ 0x1F80, 0x00FF, 0xDFF0, 0x00FC,@|
+ 0x1F80, 0x1FFF, 0xFFF8, 0x007C,
+ 0x3F00, 0xE3FF, 0xFFFC, 0x007C,@|
+ 0x7F03, 0x07FF, 0xFFFE, 0x007E,
+ 0x7E04, 0x0FFF, 0xFFFF, 0x007E,@|
+ 0xFE00, 0x7FFF, 0xFFFF, 0x80FE,
+ 0xFE03, 0x9FFF, 0xFFFF, 0xC1FE,@|
+ 0xFE04, 0x3FFF, 0xFFFF, 0xFFFC,
+ 0xFF08, 0x7FFF, 0xFFFF, 0xFFFC,@|
+ 0xFF80, 0xFFFF, 0xFFFF, 0xFFF8,
+ 0x7FC1, 0xFFFF, 0xFFFF, 0xFFF0,@|
+ 0x7FFF, 0xFFFF, 0xFFFF, 0xFFE0,
+ 0x3FFF, 0xFFFF, 0xFFFF, 0xFFC0,@|
+ 0x1FFF, 0xFFFF, 0xFFFF, 0xFFE0,
+ 0x0FFF, 0xFFFF, 0xFFFF, 0xFFF8,@|
+ 0x07FF, 0xFFFF, 0xFFFF, 0xFEE0,
+ 0x03FF, 0xFFFF, 0xFFFF, 0xF800,@|
+ 0x01FF, 0xFFFF, 0xFFFF, 0xE000,
+ 0x03FF, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x1FFF, 0xFFFF, 0xFFFF, 0xE000,
+ 0x7FFF, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x1F7F, 0xFFFF, 0xFFFF, 0xC000,
+ 0x001F, 0xFFFF, 0xFFFF, 0xC000,@|
+ 0x003F, 0xFFFF, 0xFFFF, 0xC000,
+ 0x003F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x003F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x003F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x007F, 0xFFFF, 0xFFFF, 0xE000,
+ 0x007F, 0xFFFF, 0xFFFF, 0xF000,@|
+ 0x003F, 0xFFFF, 0xFFFF, 0xF000,
+ 0x003F, 0xFFFF, 0xFFFF, 0xF000,@|
+ 0x001F, 0xFFFF, 0xFFFF, 0xF000,
+ 0x001F, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x000B, 0xFFFF, 0xFFFF, 0xE000,
+ 0x0003, 0xFFFF, 0xFFFF, 0xE000,@|
+ 0x0003, 0xFFFF, 0xFFFF, 0xC000,
+ 0x0001, 0xFFFF, 0xFFFF, 0x8000,@|
+ 0x0000, 0xBFF1, 0xFFFF, 0x0000,
+ 0x0000, 0x3FF8, 0xFFFF, 0x8000,@|
+ 0x0000, 0x1FF8, 0xFFFF, 0x8000,
+ 0x0000, 0x1FF8, 0x7FFF, 0x8000,@|
+ 0x0000, 0x13E0, 0x7FFF, 0x8000,
+ 0x0000, 0x01E0, 0x3FFF, 0x8000,@|
+ 0x0000, 0x01E0, 0x3FFF, 0x0000,
+ 0x0000, 0x0150, 0x1FFC, 0x0000
+};
+
+@* Emulating a terminal.
+We will run \.{emacs} in a ``tty subwindow,'' named after the teletype
+terminals of ancient yore.
+
+The |argv| array will be a command line that invokes
+\.{emacs} with all arguments not removed by |xv_init|, i.e., all arguments
+that remain after generic XView arguments have been removed.
+
+We have to say |WIN_IS_CLIENT_PANE|, otherwise fonts specified on the
+command line will be ignored. (This cryptic instruction is mentioned briefly
+in the XView reference manual, but not in the XView programming manual;
+I~would never have discovered it without Jeff Peck's help.)
+
+We also have to set |TTY_QUIT_ON_CHILD_DEATH| to |TRUE|. Otherwise when
+\.{emacs} exits (via control-X, control-C) there still will be a terminal
+window (into which we can type but not access the shell).
+
+Before starting \.{emacs} we set the environment variable
+\.{TERM} equal to \.{sun}.
+This will tell \.{emacs} to initialize itself with the
+programs in its source file \.{lisp/term/sun.el}, where special
+adaptations for Sun-style terminals have been recorded.
+
+@<Put a tty subwindow into the frame@>=
+argv[0]="emacs";
+putenv("TERM=sun");
+tty=(Tty)xv_create(frame,TTY,WIN_IS_CLIENT_PANE,@|
+ TTY_QUIT_ON_CHILD_DEATH,TRUE,@|
+ TTY_ARGV,argv,NULL);
+
+@ @<Global...@>=
+Tty tty;
+
+@ @<Include...@>=
+#include <xview/tty.h>
+
+@ The XView manual doesn't tell us that tty subwindows have a view part
+and a pseudo-terminal part. (The manual does mention briefly that text
+subwindows have views---at the beginning of section 6.3, and indirectly in
+one of the examples in the chapter on color.)
+
+The view window of an emulated tty will receive keyboard and
+mouse events. We need to know its ``handle,'' because we want to
+modify XView's default interpretation of many of those events.
+
+For example, we want to grab the keyboard focus (i.e., to begin receiving
+keyboard input) as soon as the user moves the mouse into the \.{emacs}
+window. The normal OpenLook default requires a user to click in the window
+first, but that is inefficient in a production book-writing environment.
+Us \.{emacs} users would rather type than point.
+
+A secret incantation makes the view window accessible. Dear reader,
+would you have guessed how to do this, from reading the manuals only,
+without looking at Jeff Peck's code? Be honest now.
+
+We don't have to enable the notification of other kinds of events;
+tty subwindows already do that.
+
+@<Prepare to be notified when the mouse enters the window@>=
+window=(Xv_window)xv_get(tty,OPENWIN_NTH_VIEW,0);
+xv_set(window,WIN_CONSUME_EVENT,LOC_WINENTER,NULL);
+
+@ @<Global...@>=
+Xv_window window; /* the view window of |tty| */
+
+@ If the user has specified reverse video with the \.{-rv} option,
+we will reverse black and white in the mouse cursor. This will make it
+more visible against a black background.
+
+Changing the cursor is another undocumented reason why we need to know
+about the tty's view window; nothing changes if we try to attach
+the new cursor to |frame| or to |tty| instead of to |window|.
+
+@<Change the cursor, to avoid black-on-black@>=
+if (rv) {Xv_singlecolor white,black;
+ Xv_cursor cursor;
+ white.red=white.green=white.blue=255;
+ black.red=black.green=black.blue=0;
+ cursor=(Xv_cursor)xv_create(NULL,CURSOR,@|
+ CURSOR_SRC_CHAR,OLC_BASIC_PTR,CURSOR_MASK_CHAR,OLC_BASIC_MASK_PTR,@|
+ CURSOR_FOREGROUND_COLOR,&white,CURSOR_BACKGROUND_COLOR,&black,NULL);
+ xv_set(window,WIN_CURSOR,cursor,NULL);
+}
+
+@ @<Include...@>=
+#include <xview/cursor.h> /* we're using the cursor package */
+
+@ What is the variable |rv| that was tested in the code above? Good question.
+We have to scan for \.{-rv} before |xv_init| looks at the command arguments.
+
+@<Scan the command line, setting |rv| nonzero if \.{-rv} is present@>=
+rv=0;
+{@+int k=argc;
+ while (--k>0) if (strcmp(argv[k],"-rv")==0 ||
+ strcmp(argv[k],"-reverse")==0) rv=1;
+}
+
+@ @<Global...@>=
+int rv;
+
+@ We need to know the height and width of characters in the font, in order
+to convert mouse positions into coordinates that \.{emacs} will like.
+If the user has specified a font explicitly, the font will presumably have
+a fixed width for all characters; we can learn the relevant dimensions
+by calling |xv_get|. But if the user has not specified a font, the
+situation is trickier; |xv_get| will report the width of the default
+{\it non\/}-fixed-width font, and this will probably differ from the width of
+the actual fixed-width font the tty subwindow will choose.
+
+Curiously, if we call |xv_find(NULL,FONT,FONT_FAMILY,
+FONT_FAMILY_DEFAULT_FIXEDWIDTH,NULL)| {\it before\/} calling |xv_init|,
+without even doing anything with the result returned by |xv_find|,
+|xv_init| will not install any fonts specified on the command line.
+The trick we used for icons---installing the default gnu icon on the first
+call to |xv_create|---will therefore fail.
+
+Thus, we have to work around two distinct bugs in XView. The solution
+is to discover the effects of the user's command line after |xv_init|
+has acted and the frame has been set up; we can determine by brute force what
+font will go into the tty window. The program below works correctly
+even if the command line specifies \.{-scale} \.{large}, say, instead of
+specifying a new font explicitly by something like \.{-font} \.{9x15}.
+
+While we are cataloguing peculiarities of XView, we might as well mention
+that the default character dimensions of the default font (Lucida) are
+reported to be $8\times13$ in the 12-point (medium) size, $8\times15$ in the
+14-point (large) size, and $12\times20$ in the 19-point (extralarge) size.
+The actual character dimensions in the window come, however, from the
+default fixed-width font (Lucida typewriter), and they are $7\times13$,
+$9\times15$, and $11\times23$ in the same three sizes. No logical progression
+is evident in either the variable-width or the fixed-width dimensions,
+although Lucida is a ``scalable font family.''
+
+@<Compute the height and width of characters in the font@>=
+{
+ Xv_font font=(Xv_font)xv_get(frame,XV_FONT);
+ Xv_font dfont=(Xv_font)xv_find(NULL,FONT,FONT_FAMILY,
+ FONT_FAMILY_DEFAULT,NULL);
+ if (strcmp((char*)xv_get(font,FONT_NAME),
+ (char*)xv_get(dfont,FONT_NAME))==0) {
+ /* the user didn't specify a new font by name */
+ dfont=(Xv_font)xv_find(NULL,FONT,FONT_FAMILY,
+ FONT_FAMILY_DEFAULT_FIXEDWIDTH,NULL);
+ /* this one will be used by the tty window */
+ } else dfont=font;
+ char_width=(int)xv_get(dfont,FONT_DEFAULT_CHAR_WIDTH);
+ char_height=(int)xv_get(dfont,FONT_DEFAULT_CHAR_HEIGHT);
+}
+
+@ @<Global...@>=
+int char_width, char_height; /* character dimensions in the font */
+
+@ @<Include...@>=
+#include <xview/font.h> /* header for the font package */
+
+@ OK, we've figured out how to install a tty subwindow with the right
+event mask and the right cursor, and how to calculate the sizes of the
+characters it will contain. All that remains is for us to do these
+operations in the proper order, and to specify a filter routine that
+will monitor and edit all communications between the keyboard and the
+Emacs processor in the window.
+
+The new ingredient is the filter specification. We tell the XView
+notifier to call |filter| when a window event occurs, instead of
+letting it call the tty subroutine event handler directly. The parameter
+|NOTIFY_SAFE| implies that the window's event handler is
+part of XView, not an alien routine.
+
+@<Install the components...@>=
+@<Scan the command line, setting |rv| nonzero if \.{-rv} is present@>;
+xv_init(XV_INIT_ARGC_PTR_ARGV,&argc,argv,NULL);
+ /* start XViewing; strip and remember the OpenWin arguments */
+@<Create a frame with the gnu icon@>;
+@<Remove the frame header...@>;
+@<Put a tty subwindow into the frame@>;
+@<Prepare to be notified when the mouse enters the window@>;
+@<Change the cursor, to avoid black-on-black@>;
+@<Compute the height and width of characters in the font@>;
+notify_interpose_event_func(window,filter,NOTIFY_SAFE);
+
+@* Keyboard events.
+The job of an interposed filter function is to look at an event and
+either process it ourselves or pass it through (possibly modified)
+to its normal recipient. In the first case we return the code
+value |NOTIFY_DONE|, since we aren't reporting any errors;
+in the second case we call the normal event handler and return the value
+it returns to us.
+
+An XView event is a data structure that has been partially
+interpreted by the XView routines, which add semantic sugar to
+the complex union type of X~Window events. We need not look
+too far inside an event structure to do the things that concern us.
+
+And what is our job? We are looking for three different kinds of events:
+
+\smallskip
+\itemitem{(1)} When the mouse enters the window,
+we want to grab the keyboard focus.
+
+\itemitem{(2)} When a mouse button goes up or down, and we have the keyboard
+focus, we want to send a coded sequence of characters to \.{emacs}.
+
+\itemitem{(3)} When a key goes down, and we have the keyboard focus, we
+want to send an appropriate sequence of characters to \.{emacs}.
+
+\itemitem{(4)} When the status of the Num Lock indicator light changes, we
+will send emacs the command {\tt turn-numlock-on} or {\tt turn-numlock-off},
+for reasons described below.
+
+\smallskip\noindent Other events, like instructions to repaint or
+resize the window, will be passed through without change to the tty window.
+
+@<Event-handling...@>=
+Notify_value filter(window,event,arg,type)
+ Xv_window window; /* the ``client'' on whom we interposed */
+ Event *event; /* the data we are filtering */
+ Notify_arg arg; /* optional communication parameter between clients */
+ Notify_event_type type; /* |NOTIFY_SAFE| or |NOTIFY_IMMEDIATE| */
+{@+register int id=event_id(event);
+#ifdef DEBUG
+ printf("event %d%s, action %d, shift %x, mouse(%d,%d)\n",
+ event_id(event),event_is_up(event)?"UP":"DOWN",event->action,
+ event_shiftmask(event),event_x(event),event_y(event));
+#endif
+ @<Update the Num Lock status@>;
+ if (id==LOC_WINENTER) @<Grab the keyboard focus and return@>;
+ if (event_is_button(event)) @<Translate a mouse event and return@>;
+ if (event_is_up(event)) return NOTIFY_DONE; /* key has been released */
+ @<Translate a function key into a special escape sequence@>;
+ @<Sanitize a keypress event so that unusual semantic actions are removed@>;
+ return notify_next_event_func(window,event,arg,type); /* pass it through */
+}
+
+@ It's easy to take charge of the keyboard and mouse, as soon as the mouse
+enters our territory.
+
+@<Grab...@>=
+{
+ win_set_kbd_focus(window,xv_get(window,XV_XID));
+ return NOTIFY_DONE;
+}
+
+@ If the event is not related to mouse buttons or special function keys,
+we want to pass it on unchanged, unless its |event_id| is less than 128.
+In that case, it represents a character code, and we want to nuke any
+semantic ``keyboard acceleration'' actions it might have been assigned
+by OpenWindows.
+
+We also make the Meta key add 128 here. An undocumented macro
+called |event_set_id|, found in \.{<xview/win\_input.h>},
+clears the |action| code as desired.
+
+@<Sanitize...@>=
+if (id<128)
+ if (event_meta_is_down(event)) event_set_id(event,id+128);
+ else event_set_action(event,ACTION_NULL_EVENT);
+
+@* Function keys.
+The Sun Type 4 keyboard has lots of keys, and these can be bound to lots
+of useful functions when we are \.{emacs}ing to the max. Besides the
+letters and punctuation marks of a normal typewriter, there are ten
+``left'' function keys, L1--L10; twelve ``top'' function keys, F1--F12;
+fifteen ``right'' function keys, R1--R15; and eight additional keys
+labeled Help, Alt, AltGraph, Ins, Del, Enter, $+$, $-$, which we will
+pretend have been labeled B1--B8.
+
+The L5 key, also known as Front, is controlled by the Open Look
+window manager; it makes a window rise above any that might overlap it,
+or shoves the window underneath in case it already was on top.
+
+The L7 key, aka Open, is likewise preempted by the
+window manager. It closes a frame to an icon, or opens an icon.
+
+The window manager traps the R2 key and calls it the ``language'' key;
+but I have no use for that feature. So I have remapped R2 to the comparatively
+useless character $3\over4$, and I will translate it back to R2 below. (The
+\.{xmodmap} program allows users to reassign the interpretation of key codes.)
+I could have recovered the L5 and L7 keys in the same way, but I like
+their functions as they stand. (L5 and L7 still come through if a
+Shift, Control, and/or Meta key is down.)
+
+I can never remember the difference between Delete and BackSpace, so I
+have mapped them both into control-?, ASCII code 127.
+
+There are two Shift keys, one at the left and one at the right, which
+are best kept indistinguishable from each other. Similarly, the left
+and right Meta keys (`\.{\char27}') are essentially identical. There's a
+Control key too. These three types of modifier keys generate keypress
+events, but we ignore them; the only thing that matters to us is whether
+they are currently up or down, when other keys are pressed.
+
+\font\ttit=cmitt10
+There also are three special keys that do not generate events, so we
+never see them. The CapsLock key toggles the Caps Lock light and
+changes lowercase letters to uppercase when the light is on. The
+NumLock key toggles the Num Lock light and changes the interpretation
+of R4--R15 and B4--B8 when that light is on. The Compose key turns the
+Compose light on until you type two characters, then it produces a
+special symbol if those two characters match a pattern. For example,
+when Compose is followed by either \.{a"} or \.{"a} you get the 8-bit
+ISO code for {\tt \"a}; when Compose is followed by either \.{th} or
+\.{ht} you get the Icelandic thorn; when it's followed by \.{??} you get {\tt
+?`}; \.{c/} and \.{L-} give \rlap{\./}\.c and {\ttit\char`\$}
+and so on. (A list of all composition patterns
+appears in \.{<X11/Suncompose.h>}, but not in any of the manuals
+I've seen.) The light goes off after two characters have been
+typed, or if your first character is not composable, or if
+you hit Compose again prematurely. If no proper two-character pattern
+was specified, only ``up'' events (key releases) are transmitted, and
+nothing will pass through to \.{emacs}.
+
+One other feature is worth noting: The key between F12 and Delete
+produces a backslash `\.\\', or a vertical line `\.{\char125}' when
+shifted. Everybody knows that, but even more is true. If you hold the
+AltGraph key down and press this key, it turns out that you get the
+broken-bar character `{\tt\hbox to1em{\hss\vbox{\hrule width 1pt height
+3pt\vskip1.5pt\hrule height2pt depth1pt}\hss}}'. This is the only key that the
+engineers chose to endow with three different graphic symbols.
+
+A few other anomalies occur; for example, AltGraph-R1 gives ASCII null,
+while AltGraph does not affect R4. But I didn't discover any additional
+combinations that are either useful or harmful.
+
+Once upon a time the Caps Lock key might have affected the |event_shiftmask|
+field of an event, but it has no effect now. The shiftmask is always an
+even number, contrary to the implications of \.{<xview/win\_input.h>}.
+
+@ The function keys will be translated into a four-character code.
+First comes control-X; then an asterisk; then a letter, \.{a}--\.{o}
+for function numbers 1--15, respectively; and then another letter,
+identifying left, right, top, or bottom. The final letter is
+ordinarily `\.l', `\.r', `\.t', or `\.b', respectively. But it is `\.L', `\.R',
+`\.T', or `\.B' if a Shift key is down. Furthermore the Control key
+subtracts 64 from the ASCII code, so you get `\.,', `\.2', `\.4', or
+`\."' with Control and no Shift. With both Control and Shift you get
+\.{\\C-L}, \.{\\C-R}, \.{\\C-T}, \.{\\C-B}. A Meta key adds another 128
+to the code. Thus, each function key leads to eight possibilities.
+
+For example, if F4 is pressed when Control and Shift are down, but not
+Meta, the four-letter code is \.{\\C-X*d\\C-T}. The user could type
+that sequence of four characters and get the same effect.
+
+Shifted function keys sometimes have a nice mnemonic significance.
+For example, key R14, also labeled PgDn, is usually bound to the Emacs
+operation `\.{scroll-up}', which moves the window down [sic] by one
+screenful; we can then bind Shift-R14 to \.{forward-page}, which advances
+down to the next page boundary. In \.{cweb-mode}, the next page boundary
+is the next \.{@@*}, beginning a major part of the program. Similarly,
+it's convenient to bind B7, the keypad `\.+' key, to \.{forward-paragraph}.
+Then in \.{cweb-mode}, Shift-B7 goes to the next module (the next
+\.{@@\ } or \.{@@*}).
+
+A Composed character will be preceded by \.{\\C-Q}, the Emacs `quote'
+character, to distinguish it from a character that was generated with the
+Meta key down. This also applies to the broken-bar character, which
+will incidentally be preceded by AltGraph, which is B3; you'll probably
+want to bind B3 to a no-op if broken bars are important to you.
+
+@ This program assumes that several key codes have been rebound from
+their normal values. Namely, the commands
+$$\vbox{\halign{\.{#}\hfil\cr
+keysym R2 = threequarters\cr
+keysym KP\_Subtract = onehalf\cr
+keysym KP\_Add = onequarter\cr
+keysym KP\_Enter = threesuperior\cr
+keysym KP\_Decimal = twosuperior\cr
+keysym KP\_0 = onesuperior\cr}}$$
+should be executed by \.{xmodmap}, preferably in the user's \.{.xinitrc} file.
+This makes the keys act as $3\over4$, $1\over2$, $1\over4$, $^3$, $^2$, and
+$^1$, respectively. The corresponding 8-bit codes are respectively
+190, 189, 188, 179, 178, 185. (By the way, can anybody explain why the ISO
+LATIN-1 code has $^0$, $^2$, and $^3$ in the positions of meta-0, meta-2,
+and meta-3, while $^1$ is in the position of meta-9?)
+@.xmodmap@>
+
+We haven't actually bound the keys this way to use them in editing.
+We did it to provide linguistically unimportant codes that OpenWindows
+wouldn't mess up; its normal conventions make those valuable keys
+unusable for editing, except as duplicates for other existing keys.
+
+We send \.{turn-numlock-on/off} commands so that \.{emacs} can keep in
+synch with the keyboard state. Namely, it will rebind the function
+keys B4--B8 to their numeric-keypad equivalents while the Num Lock light is on.
+
+On the other hand, our remapping does make the Num Lock
+feature useless in other (non-Emacs) applications. If you don't
+rebind the keys as stated, you lose the functionality of R2 and B4--B8,
+but \.{oemacs} will still work.
+
+The Help key is another special case. We don't want to remap it,
+because it gives useful help information with other OpenWindows
+applications. If Help is pressed without the shift or control key,
+the |event_id| is zero and the |event_action| is |ACTION_HELP|.
+Control-Help is similar, but with |ACTION_TEXT_HELP|. Shift-Help is
+more complicated; it invokes `helpopen: starting new Viewer', after
+generating an event that has |event_action=WIN_VISIBILITY_NOTIFY|. The
+program below considers the Help key B1 to be characterized by any
+event with |event_id=0| and either |event_action!=0| or
+|event_shiftmask!=CTRLMASK|.
+
+@<Translate a function key into a special escape sequence@>=
+{@+register int bank='b'; /* |'l'|, |'r'|, |'t'|, or |'b'| */
+ register int n; /* function key serial number, |1<=n<=15| */
+ if (id>=KEY_LEFT(1)) @<Translate an ordinary function key@>@;
+ else if (id>=256) @<Look for Alt or AltGraph@>@;
+ else if (id>=128)
+ @<Translate a special function key or composed character@>@;
+ else if (id>0 ||
+ (event_action(event)==0 && event_shiftmask(event)==CTRLMASK))
+ goto non_function;
+ else n=1; /* Help key */
+emit_function_key:@<Emit the code for a function key and |return|@>;
+non_function:;
+}
+
+@ I'm assuming here that the event id codes occur in the order left, right,
+top, bottom, and that no higher event codes exist.
+
+@<Translate an ordinary function key@>=
+{
+ if (id<KEY_RIGHT(1)) { /* on the left bank */
+ bank='l';@+n=id-KEY_LEFT(0);
+ } else if (id<KEY_TOP(1)) { /* on the right bank */
+ bank='r';@+n=id-KEY_RIGHT(0);
+ } else if (id<KEY_BOTTOM(1)) {
+ bank='t';@+n=id-KEY_TOP(0);
+ } else n=id-KEY_BOTTOM(0);
+ goto emit_function_key;
+}
+
+@ The event codes examined here appear in \.{<xview/win\_event.h>}
+but not in the XView reference manual.
+
+@<Look for Alt or AltGraph@>=
+if (id==SHIFT_ALT) {
+ n=2;@+goto emit_function_key;
+} else if (id==SHIFT_ALTG) {
+ n=3;@+goto emit_function_key;
+} else goto non_function;
+
+@ The |ttysw_input| routine sends text to a tty's view window.
+The second parameter is a string, not necessarily terminated by
+|'\0'| or anything else; the third parameter is the string length.
+
+@<Emit the code for a function key and |return|@>=
+{
+ if (event_shift_is_down(event)) bank-=32;
+ if (event_ctrl_is_down(event)) bank-=64;
+ if (event_meta_is_down(event)) bank+=128;
+ buf[2]=n+'a'-1;
+ buf[3]=bank;
+ ttysw_input(window,buf,4);
+ return NOTIFY_DONE;
+}
+
+@ @<Global...@>=
+char buf[]="\030*??\021"; /* |030| and |021| give control-X, control-Q */
+
+@ @<Translate a special function key or composed character@>=
+switch (id) {
+case 190: bank='r';@+n=2;@+goto emit_function_key;
+case 189: n=8;@+goto emit_function_key;
+case 188: n=7;@+goto emit_function_key;
+case 179: n=6;@+goto emit_function_key;
+case 178: n=5;@+goto emit_function_key;
+case 185: n=4;@+goto emit_function_key;
+default: buf[5]=id; /* composed character or broken-bar */
+ ttysw_input(window,buf+4,2);
+ return NOTIFY_DONE;
+}
+
+@* The NumLock key.
+The global variable |num_lock_state| will be 0 if the Num Lock indicator
+light is off, 1 if it is on. Whenever an event occurs, we check to see
+if |num_lock_state| should change; if so, we change it and send an
+appropriate command to \.{emacs}.
+
+To read the state of the keyboard LED indicator lights, we need an I/O
+control command called the |KIOCGLED| ioctl, described on the
+man page for \.{kb(4m)}.
+
+@<Global...@>=
+int num_lock_state;
+char turnon[]="\370turn-numlock-on\r", turnoff[]="\370turn-numlock-off\r";
+int keyboard; /* file descriptor of \.{/dev/kbd} */
+
+@ @<Include...@>=
+#include <sys/file.h> /* definition of |O_RDWR| for |open| */
+#include <sundev/kbio.h> /* definition of |KIOCGLED| for |ioctl| */
+
+@ @d LED_NUM_LOCK 0x1 /* the official definition is in \.{<server/sunevq.h>},
+ but that header file includes huge gobs of other stuff */
+
+@<Update the Num Lock status@>=
+{@+char leds; /* binary encoding of LED lights */
+ ioctl(keyboard,KIOCGLED,&leds);
+ if ((leds&LED_NUM_LOCK)!=num_lock_state) {
+ num_lock_state=leds&LED_NUM_LOCK;
+ if (num_lock_state) ttysw_input(window,turnon,17);
+ else ttysw_input(window,turnoff,18);
+ }
+}
+
+@ Any ordinary user can apparently open the keyboard as a file. I would
+have tried read-only access if read-write had failed; but read-write access
+gives a sense of power even though I won't be writing anything.
+
+@<Special initialization@>=
+keyboard=open("/dev/kbd",O_RDWR);
+if (keyboard<0) {
+ fprintf(stderr,"%s: Can't open /dev/kbd!\n",argv[0]);
+ exit(1);
+}
+
+@* Mouse events.
+When a mouse button is pressed or released, we send \.{emacs} the
+codes control-X and ASCII null, followed by a parenthesized list
+of four numbers and carriage-return.
+For example, as I was typing this paragraph, I
+clicked the left mouse button on the screen just for fun; \.{emacs}
+received the characters
+$$\.{\\030\\0(1 18 28 9999)\\r\\030\\0(129 18 28 141)\\r}$$
+as a result (according to `\.{view-lossage}'). I would have received
+the same response if I had typed these characters myself, instead
+of clicking the mouse.
+
+The first of the four numbers identifies the mouse button itself
+as the code number 1, 2, or 4 (for left, middle, right), plus 8 if
+a Shift key is down, plus 16 if the Control key is down, plus 32
+if a Meta key is down, plus 128 if the mouse key is being released
+instead of pressed.
+
+The second number is the row number in the frame, the top row being
+considered row~0.
+
+The third number is the column number in the frame, the left column being
+considered column~0.
+
+The fourth number is the elapsed time between this mouse event and the
+previous one, in milliseconds. If the elapsed time was 10 seconds or
+more, 9999 is substituted.
+
+Macros inside \.{emacs} can use the second and third numbers to
+position the cursor. The fourth number can be used to determine if the
+user is ``double clicking'' or using ``chords.'' Examples of such
+macros appear in the Emacs source file \.{lisp/sun-mouse.el}.
+
+Incidentally, the ASCII null character in mouse sequence makes us happy that
+the string parameter to |ttysw_input| is not null-terminated.
+
+@<Translate a mouse event...@>=
+{@+register int button_code,elapsed_time;
+ button_code=(id==MS_LEFT? 1: id==MS_MIDDLE? 2: 4);
+ if (event_shift_is_down(event)) button_code += 8;
+ if (event_ctrl_is_down(event)) button_code += 16;
+ if (event_meta_is_down(event)) button_code += 32;
+ if (event_is_up(event)) button_code += 128;
+ @<Compute the time elapsed since the previous mouse event@>;
+ sprintf(mouse_buf+2,"(%d %d %d %d)\r",button_code,@|
+ event_x(event)/char_width, event_y(event)/char_height,@|
+ elapsed_time);
+ ttysw_input(window,mouse_buf,12+strlen(mouse_buf+12)); /* length is at least 12 */
+ return NOTIFY_DONE;
+}
+
+@ @<Global...@>=
+char mouse_buf[24]="\030";
+
+@ XView's event structure includes |event_time(event)|, which has
+type |struct timeval|; this data type is declared in \.{<sys/time.h>},
+which is one of the files included automatically as a result of
+including \.{<xview/xview.h>}.
+A |timeval| structure consists of two |long| integers, |tv_sec| and |tv_usec|,
+denoting clock time in seconds and microseconds, respectively.
+
+@<Compute the time...@>=
+{@+struct timeval now; /* current time */
+ long delta_sec, delta_usec; /* difference between current and
+ previous time */
+ now=event_time(event);
+ delta_sec=now.tv_sec-prev_mouse_time.tv_sec;
+ delta_usec=now.tv_usec-prev_mouse_time.tv_usec;
+ if (delta_usec<0) delta_usec+=1000000,delta_sec--;
+ if (delta_sec>=10) elapsed_time=9999; /* infinity (or close enough) */
+ else elapsed_time=(delta_sec*1000)+(delta_usec/1000);
+ prev_mouse_time=now;
+}
+
+@ @<Global...@>=
+struct timeval prev_mouse_time;
+
+@* Remaining problems. There's a terribly unfortunate bug in the
+present implementation of XView, causing characters of tty subwindows
+to be badly painted at crucial times; the rightmost column of pixels
+in a character is often clobbered. If I could figure out how to
+generate repaint events for the tty subwindow, I might build a mechanism
+into \.{oemacs} that does this after the keyboard has been idle for 10
+seconds, say. This would blink the screen; maybe I'll get used to that,
+or maybe I'll prefer to refresh the window manually by binding
+\.{redraw-display} to the L2 and R1 keys. In any case a lot of screen
+refreshing is necessary at the moment, alas.
+
+(Note added later: I doubt if I'll get used to blinking, and the present
+method of manual refresh is tolerable so I won't pursue the 10-second
+timer idea. I have meanwhile noticed a procedure |wmgr_refreshwindow(window)|
+mentioned in \.{<xview/wmgr.h>}; it will presumably refresh any
+given window.
+
+Another bug, much less serious, occurs when the window is resized.
+If the window gets smaller, \.{emacs} isn't told to correct its
+assumptions; so it puts information in strange places or offscreen.
+(Internally, emacs uses the \.{TIOCGWINSZ} or \.{TIOCSWINSZ} ioctl,
+described in the man page for \.{termio}.)
+You can work around this by first making the window very small, then
+making it large.
+
+@* Index.
+
+
diff --git a/Build/source/texk/web2c/cwebdir/examples/treeprint.w b/Build/source/texk/web2c/cwebdir/examples/treeprint.w
new file mode 100644
index 00000000000..d428e26e5ee
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/treeprint.w
@@ -0,0 +1,248 @@
+\def\covernote{Copyright 1987 Norman Ramsey -- Princeton University}
+
+\def\vbar{\.{|}}
+@*Directory Trees.
+Our object is to print out a directory hierarchy in some pleasant way.
+The program takes output from {\tt find * -type d -print \vbar\ sort}
+@^system dependencies@>
+and produces a nicer-looking listing.
+More precisely, our input, which is the output of {\tt find} followed
+by {\tt sort}, is a list of fully qualified directory names (parent
+and child separated by slashes |'/'|); everything has already been
+sorted nicely into lexicographic order.
+
+The {\tt treeprint} routine takes one option, |"-p"|, which tells it
+to use the printer's line-drawing set, rather than the terminal's.
+
+@c
+@<Global definitions@>@;
+@<Global include files@>@;
+@<Global declarations@>@;
+
+@#
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+@<|main| variable declarations@>;
+@<Search for options and set special characters on |"-p"|@>;
+@<Read output from find and enter into tree@>;
+@<Write tree on standard output@>@;
+exit(0);
+}
+
+@
+We make all the siblings of a directory a linked list off of its left child,
+and the offspring a linked list off the right side.
+Data are just directory names.
+@d sibling left
+@d child right
+
+@<Global decl...@>=
+typedef struct tnode {
+ struct tnode *left, *right;
+ char *data;
+} TNODE;
+@ @<|main| variable...@>=
+struct tnode *root=NULL;
+
+
+
+@*Input.
+Reading the tree is simple---we read one line at a time, and call on the
+recursive |add_tree| procedure.
+
+@c
+read_tree (fp, rootptr)
+ FILE *fp;
+ struct tnode **rootptr;
+{
+ char buf[255], *p;
+
+ while ((fgets(buf, 255, fp))!=NULL) {
+ @<If |buf| contains a newline, make it end there@>;
+ add_tree(rootptr, buf);
+ }
+ }
+@ @<Global include...@>=
+#include <stdio.h>
+
+@ Depending what system you're on, you may or may not get a newline in |buf|.
+@<If |buf| contains a newline...@>=
+ p=buf; while (*p!='\0'&&*p!='\n') p++;
+@^system dependencies@>
+ *p='\0';
+
+@
+To add a string, we split off the first part of the name and insert it into
+the sibling list. We then do the rest of the string as a child of the new node.
+
+@c
+add_tree(rootptr, p)
+ struct tnode **rootptr;
+ char *p;
+{
+ char *s;
+ int slashed;
+
+ if (*p=='\0') return;
+
+@<Break up the string so |p| is the first word,
+ |s| points at null-begun remainder,
+ and |slashed| tells whether |*s=='/'| on entry@>;
+
+ if (*rootptr==NULL) {
+@<Allocate new node to hold string of size |strlen(p)|@>;
+ strcpy((*rootptr)->data,p);
+ }
+ if (strcmp((*rootptr)->data,p)==0) {
+ if (slashed) ++s;
+ add_tree(&((*rootptr)->child),s);
+ }
+ else {
+ if (slashed) *s='/';
+ add_tree(&((*rootptr)->sibling),p);
+ }
+ }
+
+@ We perform some nonsense to cut off the string |p| so that |p| just
+holds the first word of a multiword name. Variable |s| points at what
+was either the end of |p| or a slash delimiting names. In either case
+|*s| is made |'\0'|. Later, depending on whether we want to pass the
+whole string or the last piece, we will restore the slash or advance
+|s| one character to the right.
+
+@<Break up...@>=
+ for (s=p;*s!='\0'&&*s!='/';) s++;
+ if (*s=='/') {
+ slashed=1;
+ *s='\0';
+ } else slashed=0;
+
+@ Node allocation is perfectly standard \dots
+@<Allocate new node...@>=
+ *rootptr=(struct tnode *) malloc (sizeof(struct tnode));
+ (*rootptr)->left = (*rootptr)->right = NULL;
+ (*rootptr)->data = malloc (strlen(p)+1);
+
+@
+@<Global decl...@>= char *malloc();
+
+@ In this simple implementation, we just read from standard input.
+@<Read...@>= read_tree(stdin,&root);
+
+@*Output.
+We begin by defining some lines, tees, and corners.
+The |s| stands for screen and the |p| for printer.
+You will have to change this for your line-drawing set.
+@^system dependencies@>
+
+@<Global definitions@>=
+#define svert '|'
+#define shoriz '-'
+#define scross '+'
+#define scorner '\\' /* lower left corner */
+
+#define pvert '|'
+#define phoriz '-'
+#define pcross '+'
+#define pcorner '\\' /* lower left corner */
+
+@ The default is to use the terminal's line drawing set.
+@<Global declarations@>=
+char vert=svert;
+char horiz=shoriz;
+char cross=scross;
+char corner=scorner;
+
+@ With option |"-p"| use the printer character set.
+@<Search for options...@>=
+while (--argc>0) {
+ if (**++argv=='-') {
+ switch (*++(*argv)) {
+ case 'p':
+ vert=pvert;
+ horiz=phoriz;
+ cross=pcross;
+ corner=pcorner;
+ break;
+ default:
+ fprintf(stderr,"treeprint: bad option -%c\n",**argv);
+ break;
+ }
+ }
+}
+
+@ We play games with a character stack to figure out when to put in vertical
+bars.
+A vertical bar connects every sibling with its successor, but the last sibling
+in a list is followed by blanks, not by vertical bars. The state of
+bar-ness or space-ness for each preceding sibling is recorded in the
+|indent_string| variable, one character (bar or blank) per sibling.
+
+@<Global decl...@>=
+char indent_string[100]="";
+
+@ Children get printed
+before siblings.
+We don't bother trying to bring children up to the same line as their parents,
+because the \UNIX/ filenames are so long.
+
+We define a predicate telling us when a sibling is the last in a series.
+@d is_last(S) (S->sibling==NULL)
+
+@c
+print_node(fp, indent_string, node)
+ FILE *fp;
+ char *indent_string;
+ struct tnode *node;
+{
+ char string[255];
+ int i;
+ char *p, *is;
+
+ if (node==NULL) {
+ }
+ else {
+ *string='\0';
+ for (i=strlen(indent_string); i>0; i--)
+ strcat(string,@, " | ");
+ strcat(string,@t\ \ @> " +--");
+@<Replace chars in |string| with chars from
+ line-drawing set and from |indent_string|@>;
+ fprintf(fp,"%s%s\n",string,node->data);
+
+@#
+ /* Add vertical bar or space for this sibling (claim |*is=='\0'|) */
+ *is++ = (is_last(node) ? ' ' : vert);
+ *is='\0';
+
+ print_node(fp, indent_string, node->child); /* extended |indent_string| */
+ *--is='\0';
+ print_node(fp, indent_string, node->sibling); /* original |indent_string| */
+ }
+
+}
+@ For simplicity, we originally wrote connecting lines with |'|'|, |'+'|, and
+|'-'|.
+Now we replace those characters with appropriate characters from the
+line-drawing set.
+We take the early vertical bars and replace them with characters from
+|indent_string|, and we replace the other characters appropriately.
+We are sure to put a |corner|, not a |cross|, on the last sibling in
+a group.
+@<Replace chars...@>=
+ is=indent_string;
+ for (p=string; *p!='\0'; p++) switch(*p) {
+ case '|': *p=*is++; break;
+ case '+': *p=(is_last(node) ? corner : cross); break;
+ case '-': *p=horiz; break;
+ default: break;
+ }
+
+
+@ For this simple implementation, we just write on standard output.
+
+@<Write...@>= print_node(stdout, indent_string, root);
+
+@*Index.
diff --git a/Build/source/texk/web2c/cwebdir/examples/wc-dos.ch b/Build/source/texk/web2c/cwebdir/examples/wc-dos.ch
new file mode 100644
index 00000000000..b3da3fd3bb8
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/wc-dos.ch
@@ -0,0 +1,8 @@
+% from j.fitzsimons@genie.geis.com who compiled with Top Speed C
+% April 1995
+
+@x
+@d buf_size BUFSIZ /* \.{stdio.h}'s |BUFSIZ| is chosen for efficiency*/
+@y
+@d buf_size 2048 /* \.{stdio.h}'s |BUFSIZ| breaks DOS */
+@z
diff --git a/Build/source/texk/web2c/cwebdir/examples/wc.w b/Build/source/texk/web2c/cwebdir/examples/wc.w
new file mode 100644
index 00000000000..522cfc65739
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/wc.w
@@ -0,0 +1,254 @@
+% wc: An example of CWEB by Silvio Levy and Donald E. Knuth
+
+\nocon % omit table of contents
+\datethis % print date on listing
+\def\SPARC{SPARC\-\kern.1em station}
+
+@* An example of {\tt CWEB}. This example, based on a program by
+Klaus Guntermann and Joachim Schrod [{\sl TUGboat\/ \bf7} (1986),
+134--137] presents the ``word count'' program from \UNIX/, rewritten in
+\.{CWEB} to demonstrate literate programming in \CEE/. The level of
+detail in this document is intentionally high, for didactic purposes;
+many of the things spelled out here don't need to be explained in
+other programs.
+
+The purpose of \.{wc} is to count lines, words, and/or characters in a
+list of files. The number of lines in a file is the number of newline
+characters it contains. The number of characters is the file length in bytes.
+A ``word'' is a maximal sequence of consecutive characters other than
+newline, space, or tab, containing at least one visible ASCII code.
+(We assume that the standard ASCII code is in use.)
+
+This version of \.{wc} has a nonstandard ``silent'' option (\.{-s}),
+which suppresses printing except for the grand totals over all files.
+
+@ Most \.{CWEB} programs share a common structure. It's probably a
+good idea to state the overall structure explicitly at the outset,
+even though the various parts could all be introduced in unnamed
+sections of the code if we wanted to add them piecemeal.
+
+Here, then, is an overview of the file \.{wc.c} that is defined
+by this \.{CWEB} program \.{wc.w}:
+
+@c
+@<Header files to include@>@/
+@<Global variables@>@/
+@<Functions@>@/
+@<The main program@>
+
+@ We must include the standard I/O definitions, since we want to send
+formatted output to |stdout| and |stderr|.
+
+@<Header files...@>=
+#include <stdio.h>
+
+@ The |status| variable will tell the operating system if the run was
+successful or not, and |prog_name| is used in case there's an error message to
+be printed.
+
+@d OK 0 /* |status| code for successful run */
+@d usage_error 1 /* |status| code for improper syntax */
+@d cannot_open_file 2 /* |status| code for file access error */
+
+@<Global variables@>=
+int status=OK; /* exit status of command, initially |OK| */
+char *prog_name; /* who we are */
+
+@ Now we come to the general layout of the |main| function.
+
+@<The main...@>=
+main (argc,argv)
+ int argc; /* the number of arguments on the \UNIX/ command line */
+ char **argv; /* the arguments themselves, an array of strings */
+{
+ @<Variables local to |main|@>@;
+ prog_name=argv[0];
+ @<Set up option selection@>;
+ @<Process all the files@>;
+ @<Print the grand totals if there were multiple files @>;
+ exit(status);
+}
+
+@ If the first argument begins with a `\.{-}', the user is choosing
+the desired counts and specifying the order in which they should be
+displayed. Each selection is given by the initial character
+(lines, words, or characters). For example, `\.{-cl}' would cause
+just the number of characters and the number of lines to be printed,
+in that order. The default, if no special argument is given, is `\.{-lwc}'.
+
+We do not process this string now; we simply remember where it is.
+It will be used to control the formatting at output time.
+
+If the `\.{-}' is immediately followed by `\.{s}', only summary totals
+are printed.
+
+@<Var...@>=
+int file_count; /* how many files there are */
+char *which; /* which counts to print */
+int silent=0; /* nonzero if the silent option was selected */
+
+@ @<Set up o...@>=
+which="lwc"; /* if no option is given, print all three values */
+if (argc>1 && *argv[1] == '-') {
+ argv[1]++;
+ if (*argv[1]=='s') silent=1,argv[1]++;
+ if (*argv[1]) which=argv[1];
+ argc--; argv++;
+}
+file_count=argc-1;
+
+@ Now we scan the remaining arguments and try to open a file, if
+possible. The file is processed and its statistics are given.
+We use a |do|~\dots~|while| loop because we should read from the
+standard input if no file name is given.
+
+@<Process...@>=
+argc--;
+do@+{
+ @<If a file is given, try to open |*(++argv)|; |continue| if unsuccessful@>;
+ @<Initialize pointers and counters@>;
+ @<Scan file@>;
+ @<Write statistics for file@>;
+ @<Close file@>;
+ @<Update grand totals@>; /* even if there is only one file */
+}@+while (--argc>0);
+
+@ Here's the code to open the file. A special trick allows us to
+handle input from |stdin| when no name is given.
+Recall that the file descriptor to |stdin| is~0; that's what we
+use as the default initial value.
+
+@<Variabl...@>=
+int fd=0; /* file descriptor, initialized to |stdin| */
+
+@ @d READ_ONLY 0 /* read access code for system |open| routine */
+
+@<If a file...@>=
+if (file_count>0 && (fd=open(*(++argv),READ_ONLY))<0) {
+ fprintf (stderr, "%s: cannot open file %s\n", prog_name, *argv);
+@.cannot open file@>
+ status|=cannot_open_file;
+ file_count--;
+ continue;
+}
+
+@ @<Close file@>=
+close(fd);
+
+@ We will do some homemade buffering in order to speed things up: Characters
+will be read into the |buffer| array before we process them.
+To do this we set up appropriate pointers and counters.
+
+@d buf_size BUFSIZ /* \.{stdio.h}'s |BUFSIZ| is chosen for efficiency*/
+
+@<Var...@>=
+char buffer[buf_size]; /* we read the input into this array */
+register char *ptr; /* the first unprocessed character in |buffer| */
+register char *buf_end; /* the first unused position in |buffer| */
+register int c; /* current character, or number of characters just read */
+int in_word; /* are we within a word? */
+long word_count, line_count, char_count; /* number of words, lines,
+ and characters found in the file so far */
+
+@ @<Init...@>=
+ptr=buf_end=buffer; line_count=word_count=char_count=0; in_word=0;
+
+@ The grand totals must be initialized to zero at the beginning of the
+program. If we made these variables local to |main|, we would have to
+do this initialization explicitly; however, \CEE/'s globals are automatically
+zeroed. (Or rather, ``statically zeroed.'') (Get it?)
+@^Joke@>
+
+@<Global var...@>=
+long tot_word_count, tot_line_count, tot_char_count;
+ /* total number of words, lines, and chars */
+
+@ The present section, which does the counting that is \.{wc}'s {\it raison
+d'\^etre}, was actually one of the simplest to write. We look at each
+character and change state if it begins or ends a word.
+
+@<Scan...@>=
+while (1) {
+ @<Fill |buffer| if it is empty; |break| at end of file@>;
+ c=*ptr++;
+ if (c>' ' && c<0177) { /* visible ASCII codes */
+ if (!in_word) {word_count++; in_word=1;}
+ continue;
+ }
+ if (c=='\n') line_count++;
+ else if (c!=' ' && c!='\t') continue;
+ in_word=0; /* |c| is newline, space, or tab */
+}
+
+@ Buffered I/O allows us to count the number of characters almost for free.
+
+@<Fill |buff...@>=
+if (ptr>=buf_end) {
+ ptr=buffer; c=read(fd,ptr,buf_size);
+ if (c<=0) break;
+ char_count+=c; buf_end=buffer+c;
+}
+
+@ It's convenient to output the statistics by defining a new function
+|wc_print|; then the same function can be used for the totals.
+Additionally we must decide here if we know the name of the file
+we have processed or if it was just |stdin|.
+
+@<Write...@>=
+if (!silent) {
+ wc_print(which, char_count, word_count, line_count);
+ if (file_count) printf (" %s\n", *argv); /* not |stdin| */
+ else printf ("\n"); /* |stdin| */
+}
+
+@ @<Upda...@>=
+tot_line_count+=line_count;
+tot_word_count+=word_count;
+tot_char_count+=char_count;
+
+@ We might as well improve a bit on \UNIX/'s \.{wc} by displaying the
+number of files too.
+
+@<Print the...@>=
+if (file_count>1 || silent) {
+ wc_print(which, tot_char_count, tot_word_count, tot_line_count);
+ if (!file_count) printf("\n");
+ else printf(" total in %d file%s\n",file_count,file_count>1?"s":"");
+}
+
+@ Here now is the function that prints the values according to the
+specified options. The calling routine is supposed to supply a
+newline. If an invalid option character is found we inform
+the user about proper usage of the command. Counts are printed in
+8-digit fields so that they will line up in columns.
+
+@d print_count(n) printf("%8ld",n)
+
+@<Fun...@>=
+wc_print(which, char_count, word_count, line_count)
+char *which; /* which counts to print */
+long char_count, word_count, line_count; /* given totals */
+{
+ while (*which)
+ switch (*which++) {
+ case 'l': print_count(line_count); break;
+ case 'w': print_count(word_count); break;
+ case 'c': print_count(char_count); break;
+ default: if ((status & usage_error)==0) {
+ fprintf (stderr, "\nUsage: %s [-lwc] [filename ...]\n", prog_name);
+@.Usage: ...@>
+ status|=usage_error;
+ }
+ }
+}
+
+@ Incidentally, a test of this program against the system \.{wc}
+command on a \SPARC\ showed that the ``official'' \.{wc} was slightly
+slower. Furthermore, although that \.{wc} gave an appropriate error
+message for the options `\.{-abc}', it made no complaints about the
+options `\.{-labc}'! Dare we suggest that the system routine might have been
+better if its programmer had used a more literate approach?
+
+@* Index.
+Here is a list of the identifiers used, and where they appear. Underlined
+entries indicate the place of definition. Error messages are also shown.
diff --git a/Build/source/texk/web2c/cwebdir/examples/wmer-os2.ch b/Build/source/texk/web2c/cwebdir/examples/wmer-os2.ch
new file mode 100644
index 00000000000..ad40dc496f9
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/wmer-os2.ch
@@ -0,0 +1,21 @@
+Change file for wmerge, for OS/2 and WinNT and MSVC++ 2.2
+contributed May 1996 by Andreas Scherer, Aaxen University of TeXnology
+(scherer@physik.rwth-aachen.de)
+
+@x Line 594
+An omitted change file argument means that |'/dev/null'| should be used,
+@y
+An omitted change file argument means that |'NUL'| should be used,
+@z
+
+@x Line 620
+ else if (*s=='/') dot_pos=NULL,++s;
+@y
+ else if (*s==':' || *s=='\\' || *s=='/') dot_pos=NULL,++s;
+@z
+
+@x Line 630
+ if (!found_change) strcpy(change_file_name,"/dev/null");
+@y
+ if (!found_change) strcpy(change_file_name,"NUL");
+@z
diff --git a/Build/source/texk/web2c/cwebdir/examples/wmerg-pc.ch b/Build/source/texk/web2c/cwebdir/examples/wmerg-pc.ch
new file mode 100644
index 00000000000..912f46b7086
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/wmerg-pc.ch
@@ -0,0 +1,22 @@
+Change file for wmerge, for MSDOS and Borland C++ 3.1.
+To compile the C file: bcc -w-pro wmerge.c
+
+(This file contributed by Barry Schwartz, trashman@crud.mn.org, 28 Jun 94.)
+(Updated 17 Jul 06 by Don Knuth.)
+
+@x Section 19.
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+@y
+ cur_file_name[l]='/'; /* A valid {\mc MSDOS} pathname separator */
+@z
+
+
+@x Section 33.
+ if (*s=='.') dot_pos=s++;
+ else if (*s=='/') dot_pos=NULL,++s;
+ else s++;
+@y
+ if (*s=='.') dot_pos=s++;
+ else if (*s==':' || *s=='\\' || *s=='/') dot_pos=NULL,++s;
+ else s++;
+@z
diff --git a/Build/source/texk/web2c/cwebdir/examples/wmerge.w b/Build/source/texk/web2c/cwebdir/examples/wmerge.w
new file mode 100644
index 00000000000..616172d042f
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/wmerge.w
@@ -0,0 +1,717 @@
+% Modified 16 Jan 2002 to agree with COMMON version 3.64
+
+\def\9#1{} % this hack is explained in CWEB manual Appendix F11
+
+@* Introduction. This file contains the program \.{wmerge},
+which takes two or more files and merges them according
+to the conventions of \.{CWEB}. Namely, it takes an ordinary \.{.w}
+file and and optional \.{.ch} file and sends the corresponding
+\.{.w}-style file to standard output (or to a named file),
+expanding all ``includes''
+that might be specified by \.{@@i} in the original \.{.w} file.
+(A more precise description appears in the section on ``command line
+arguments'' below.)
+
+@c
+#include <stdio.h>
+#include <stdlib.h> /* declaration of |getenv| */
+#include <ctype.h> /* definition of |isalpha|, |isdigit| and so on */
+@<Definitions@>@;
+@<Predeclarations of functions@>@;
+@<Functions@>@;
+main (ac,av)
+int ac; char **av;
+{
+ argc=ac; argv=av;
+ @<Set the default options@>;
+ @<Scan arguments and open output file@>;
+ reset_input();
+ while (get_line())
+ put_line();
+ fflush(out_file);
+ check_complete();
+ fflush(out_file);
+ return wrap_up();
+}
+
+@ @<Definitions@>=
+typedef short boolean;
+typedef unsigned char eight_bits;
+typedef char ASCII; /* type of characters inside \.{WEB} */
+
+@ We predeclare some standard string-handling 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. (There's confusion
+between \.{<string.h>} and \.{<strings.h>}.)
+
+@<Predecl...@>=
+extern size_t strlen(); /* length of string */
+extern char* strcpy(); /* copy one string to another */
+extern int strncmp(); /* compare up to $n$ string characters */
+extern char* strncpy(); /* copy up to $n$ string characters */
+
+@ @<Predec...@>=
+
+@ The lowest level of input to the \.{WEB} programs
+is performed by |input_ln|, which must be told which file to read from.
+The return value of |input_ln| is 1 if the read is successful and 0 if
+not (generally this means the file has ended).
+The characters of the next line of the file
+are copied into the |buffer| array,
+and the global variable |limit| is set to the first unoccupied position.
+Trailing blanks are ignored. The value of |limit| must be strictly less
+than |buf_size|, so that |buffer[buf_size-1]| is never filled.
+
+Some of the routines use the fact that it is safe to refer to
+|*(limit+2)| without overstepping the bounds of the array.
+
+@d buf_size 4096
+
+@<Definitions...@>=
+ASCII buffer[buf_size]; /* where each line of input goes */
+ASCII *buffer_end=buffer+buf_size-2; /* end of |buffer| */
+ASCII *limit; /* points to the last character in the buffer */
+ASCII *loc; /* points to the next character to be read from the buffer */
+
+@ In the unlikely event that your standard I/O library does not
+support |feof|, |getc| and |ungetc|, you may have to change things here.
+@^system dependencies@>
+
+Incidentally, here's a curious fact about \.{CWEB} for those of you
+who are reading this file as an example of \.{CWEB} programming.
+The file \.{stdio.h} includes a typedef for
+the identifier |FILE|, which is not, strictly speaking, part of \CEE/.
+It turns out \.{CWEAVE} knows that |FILE| is a reserved word (after all,
+|FILE| is almost as common as |int|); indeed, \.{CWEAVE} knows all
+the types of the ISO standard \CEE/ library. But
+if you're using other types like {\bf caddr\_t},
+@:caddr_t}{\bf caddr\_t@>
+which is defined in \.{/usr/include/sys/types.h}, you should let
+\.{WEAVE} know that this is a type, either by including the \.{.h} file
+at \.{WEB} time (saying \.{@@i /usr/include/sys/types.h}), or by
+using \.{WEB}'s format command (saying \.{@@f caddr\_t int}). Either of
+these will make {\bf caddr\_t} be treated in the same way as |int|.
+
+@<Func...@>=
+input_ln(fp) /* copies a line into |buffer| or returns 0 */
+FILE *fp; /* what file to read from */
+{
+ register int c=EOF; /* character read; initialized so some compilers won't complain */
+ register char *k; /* where next character goes */
+ if (feof(fp)) return(0); /* we have hit end-of-file */
+ limit = k = buffer; /* beginning of buffer */
+ while (k<=buffer_end && (c=getc(fp)) != EOF && c!='\n')
+ if ((*(k++) = c) != ' ') limit = k;
+ if (k>buffer_end)
+ if ((c=getc(fp))!=EOF && c!='\n') {
+ ungetc(c,fp); loc=buffer; err_print("! Input line too long");
+@.Input line too long@>
+ }
+ if (c==EOF && limit==buffer) return(0); /* there was nothing after
+ the last newline */
+ return(1);
+}
+
+@ Now comes the problem of deciding which file to read from next.
+Recall that the actual text that \.{CWEB} should process comes from two
+streams: a |web_file|, which can contain possibly nested include
+commands \.{@@i}, and a |change_file|, which might also contain
+includes. The |web_file| together with the currently open include
+files form a stack |file|, whose names are stored in a parallel stack
+|file_name|. The boolean |changing| tells whether or not we're reading
+from the |change_file|.
+
+The line number of each open file is also kept for error reporting.
+
+@f line x /* make |line| an unreserved word */
+@d max_include_depth 10 /* maximum number of source files open
+ simultaneously, not counting the change file */
+@d max_file_name_length 60
+@d cur_file file[include_depth] /* current file */
+@d cur_file_name file_name[include_depth] /* current file name */
+@d cur_line line[include_depth] /* number of current line in current file */
+@d web_file file[0] /* main source file */
+@d web_file_name file_name[0] /* main source file name */
+
+@<Definitions...@>=
+int include_depth; /* current level of nesting */
+FILE *file[max_include_depth]; /* stack of non-change files */
+FILE *change_file; /* change file */
+char file_name[max_include_depth][max_file_name_length];
+ /* stack of non-change file names */
+char change_file_name[max_file_name_length]; /* name of change file */
+char alt_web_file_name[max_file_name_length]; /* alternate name to try */
+int line[max_include_depth]; /* number of current line in the stacked files */
+int change_line; /* number of current line in change file */
+int change_depth; /* where \.{@@y} originated during a change */
+boolean input_has_ended; /* if there is no more input */
+boolean changing; /* if the current line is from |change_file| */
+boolean web_file_open=0; /* if the web file is being read */
+
+@ When |changing=0|, the next line of |change_file| is kept in
+|change_buffer|, for purposes of comparison with the next
+line of |cur_file|. After the change file has been completely input, we
+set |change_limit=change_buffer|,
+so that no further matches will be made.
+
+Here's a shorthand expression for inequality between the two lines:
+
+@d lines_dont_match (change_limit-change_buffer != limit-buffer ||
+ strncmp(buffer, change_buffer, limit-buffer))
+
+@<Def...@>=
+char change_buffer[buf_size]; /* next line of |change_file| */
+char *change_limit; /* points to the last character in |change_buffer| */
+
+@ Procedure |prime_the_change_buffer| sets |change_buffer| in
+preparation for the next matching operation. Since blank lines in the change
+file are not used for matching, we have
+|(change_limit==change_buffer && !changing)| if and only if
+the change file is exhausted. This procedure is called only when
+|changing| is 1; hence error messages will be reported correctly.
+
+@<Func...@>=
+void
+prime_the_change_buffer()
+{
+ change_limit=change_buffer; /* this value is used if the change file ends */
+ @<Skip over comment lines in the change file; |return| if end of file@>;
+ @<Skip to the next nonblank line; |return| if end of file@>;
+ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>;
+}
+
+@ While looking for a line that begins with \.{@@x} in the change file, we
+allow lines that begin with \.{@@}, as long as they don't begin with \.{@@y},
+\.{@@z} or \.{@@i} (which would probably mean that the change file is fouled up).
+
+@<Skip over comment lines in the change file...@>=
+while(1) {
+ change_line++;
+ if (!input_ln(change_file)) return;
+ if (limit<buffer+2) continue;
+ if (buffer[0]!='@@') continue;
+ if (isupper(buffer[1])) buffer[1]=tolower(buffer[1]);
+ if (buffer[1]=='x') break;
+ if (buffer[1]=='y' || buffer[1]=='z' || buffer[1]=='i') {
+ loc=buffer+2;
+ err_print("! Missing @@x in change file");
+@.Missing @@x...@>
+ }
+}
+
+@ Here we are looking at lines following the \.{@@x}.
+
+@<Skip to the next nonblank line...@>=
+do {
+ change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended after @@x");
+@.Change file ended...@>
+ return;
+ }
+} while (limit==buffer);
+
+@ @<Move |buffer| and |limit| to |change_buffer| and |change_limit|@>=
+{
+ change_limit=change_buffer+(limit-buffer);
+ strncpy(change_buffer,buffer,limit-buffer+1);
+}
+
+@ The following procedure is used to see if the next change entry should
+go into effect; it is called only when |changing| is 0.
+The idea is to test whether or not the current
+contents of |buffer| matches the current contents of |change_buffer|.
+If not, there's nothing more to do; but if so, a change is called for:
+All of the text down to the \.{@@y} is supposed to match. An error
+message is issued if any discrepancy is found. Then the procedure
+prepares to read the next line from |change_file|.
+
+This procedure is called only when |buffer<limit|, i.e., when the
+current line is nonempty.
+
+@<Func...@>=
+void
+check_change() /* switches to |change_file| if the buffers match */
+{
+ int n=0; /* the number of discrepancies found */
+ if (lines_dont_match) return;
+ while (1) {
+ changing=1; change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended before @@y");
+@.Change file ended...@>
+ change_limit=change_buffer; changing=0;
+ return;
+ }
+ if (limit>buffer+1 && buffer[0]=='@@') {
+ char xyz_code=isupper(buffer[1])? tolower(buffer[1]): buffer[1];
+ @<If the current line starts with \.{@@y},
+ report any discrepancies and |return|@>;
+ }
+ @<Move |buffer| and |limit|...@>;
+ changing=0; cur_line++;
+ while (!input_ln(cur_file)) { /* pop the stack or quit */
+ if (include_depth==0) {
+ err_print("! CWEB file ended during a change");
+@.CWEB file ended...@>
+ input_has_ended=1; return;
+ }
+ include_depth--; cur_line++;
+ }
+ if (lines_dont_match) n++;
+ }
+}
+
+@ @<If the current line starts with \.{@@y}...@>=
+if (xyz_code=='x' || xyz_code=='z') {
+ loc=buffer+2; err_print("! Where is the matching @@y?");
+@.Where is the match...@>
+ }
+else if (xyz_code=='y') {
+ if (n>0) {
+ loc=buffer+2;
+ fprintf(stderr,"\n! Hmm... %d ",n);
+ err_print("of the preceding lines failed to match");
+@.Hmm... n of the preceding...@>
+ }
+ change_depth=include_depth;
+ return;
+}
+
+@ The |reset_input| procedure gets the program ready to read the
+user's \.{WEB} input.
+
+@<Func...@>=
+void
+reset_input()
+{
+ limit=buffer; loc=buffer+1; buffer[0]=' ';
+ @<Open input files@>;
+ include_depth=0; cur_line=0; change_line=0;
+ change_depth=include_depth;
+ changing=1; prime_the_change_buffer(); changing=!changing;
+ limit=buffer; loc=buffer+1; buffer[0]=' '; input_has_ended=0;
+}
+
+@ The following code opens the input files.
+@^system dependencies@>
+
+@<Open input files@>=
+if ((web_file=fopen(web_file_name,"r"))==NULL) {
+ strcpy(web_file_name,alt_web_file_name);
+ if ((web_file=fopen(web_file_name,"r"))==NULL)
+ fatal("! Cannot open input file ", web_file_name);
+}
+@.Cannot open input file@>
+@.Cannot open change file@>
+web_file_open=1;
+if ((change_file=fopen(change_file_name,"r"))==NULL)
+ fatal("! Cannot open change file ", change_file_name);
+
+@ The |get_line| procedure is called when |loc>limit|; it puts the next
+line of merged input into the buffer and updates the other variables
+appropriately. A space is placed at the right end of the line.
+This procedure returns |!input_has_ended| because we often want to
+check the value of that variable after calling the procedure.
+
+@<Fun...@>=
+int get_line() /* inputs the next line */
+{
+ restart:
+ if (changing && include_depth==change_depth)
+ @<Read from |change_file| and maybe turn off |changing|@>;
+ if (! changing || include_depth>change_depth) {
+ @<Read from |cur_file| and maybe turn on |changing|@>;
+ if (changing && include_depth==change_depth) goto restart;
+ }
+ if (input_has_ended) return 0;
+ loc=buffer; *limit=' ';
+ if (buffer[0]=='@@' && (buffer[1]=='i' || buffer[1]=='I')) {
+ loc=buffer+2; *limit='"';
+ while (*loc==' '||*loc=='\t') loc++;
+ if (loc>=limit) {
+ err_print("! Include file name not given");
+@.Include file name ...@>
+ goto restart;
+ }
+ if (include_depth>=max_include_depth-1) {
+ err_print("! Too many nested includes");
+@.Too many nested includes@>
+ goto restart;
+ }
+ include_depth++; /* push input stack */
+ @<Try to open include file, abort push if unsuccessful, go to |restart|@>;
+ }
+ return 1;
+}
+
+void put_line()
+{
+ char *ptr=buffer;
+ while (ptr<limit) putc(*ptr++,out_file);
+ putc('\n',out_file);
+}
+
+@ When an \.{@@i} line is found in the |cur_file|, we must temporarily
+stop reading it and start reading from the named include file. The
+\.{@@i} line should give a complete file name with or without
+double quotes.
+If the environment variable \.{CWEBINPUTS} is set, or if the compiler flag
+of the same name was defined at compile time,
+\.{CWEB} will look for include files in the directory thus named, if
+it cannot find them in the current directory.
+(Colon-separated paths are not supported.)
+The remainder of the \.{@@i} line after the file name is ignored.
+
+@d too_long() {include_depth--;
+ err_print("! Include file name too long"); goto restart;}
+
+@ @<Try to open...@>= {
+ char temp_file_name[max_file_name_length];
+ char *cur_file_name_end=cur_file_name+max_file_name_length-1;
+ char *k=cur_file_name, *kk;
+ int l; /* length of file name */
+
+ if (*loc=='"') {
+ loc++;
+ while (*loc!='"' && k<=cur_file_name_end) *k++=*loc++;
+ if (loc==limit) k=cur_file_name_end+1; /* unmatched quote is `too long' */
+ } else
+ while (*loc!=' '&&*loc!='\t'&&*loc!='"'&&k<=cur_file_name_end) *k++=*loc++;
+ if (k>cur_file_name_end) too_long();
+@.Include file name ...@>
+ *k='\0';
+ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
+ cur_line=0;
+ goto restart; /* success */
+ }
+ kk=getenv("CWEBINPUTS");
+ if (kk!=NULL) {
+ if ((l=strlen(kk))>max_file_name_length-2) too_long();
+ strcpy(temp_file_name,kk);
+ }
+ else {
+#ifdef CWEBINPUTS
+ if ((l=strlen(CWEBINPUTS))>max_file_name_length-2) too_long();
+ strcpy(temp_file_name,CWEBINPUTS);
+#else
+ l=0;
+#endif /* |CWEBINPUTS| */
+ }
+ if (l>0) {
+ if (k+l+2>=cur_file_name_end) too_long();
+@.Include file name ...@>
+ for (; k>= cur_file_name; k--) *(k+l+1)=*k;
+ strcpy(cur_file_name,temp_file_name);
+ cur_file_name[l]='/'; /* \UNIX/ pathname separator */
+ if ((cur_file=fopen(cur_file_name,"r"))!=NULL) {
+ cur_line=0;
+ goto restart; /* success */
+ }
+ }
+ include_depth--; err_print("! Cannot open include file"); goto restart;
+}
+
+@ @<Read from |cur_file|...@>= {
+ cur_line++;
+ while (!input_ln(cur_file)) { /* pop the stack or quit */
+ if (include_depth==0) {input_has_ended=1; break;}
+ else {
+ fclose(cur_file); include_depth--;
+ if (changing && include_depth==change_depth) break;
+ cur_line++;
+ }
+ }
+ if (!changing && !input_has_ended)
+ if (limit-buffer==change_limit-change_buffer)
+ if (buffer[0]==change_buffer[0])
+ if (change_limit>change_buffer) check_change();
+}
+
+@ @<Read from |change_file|...@>= {
+ change_line++;
+ if (!input_ln(change_file)) {
+ err_print("! Change file ended without @@z");
+@.Change file ended...@>
+ buffer[0]='@@'; buffer[1]='z'; limit=buffer+2;
+ }
+ if (limit>buffer) { /* check if the change has ended */
+ *limit=' ';
+ if (buffer[0]=='@@') {
+ if (isupper(buffer[1])) buffer[1]=tolower(buffer[1]);
+ if (buffer[1]=='x' || buffer[1]=='y') {
+ loc=buffer+2;
+ err_print("! Where is the matching @@z?");
+@.Where is the match...@>
+ }
+ else if (buffer[1]=='z') {
+ prime_the_change_buffer(); changing=!changing;
+ }
+ }
+ }
+}
+
+@ At the end of the program, we will tell the user if the change file
+had a line that didn't match any relevant line in |web_file|.
+
+@<Funct...@>=
+void
+check_complete(){
+ if (change_limit!=change_buffer) { /* |changing| is 0 */
+ strncpy(buffer,change_buffer,change_limit-change_buffer+1);
+ limit=buffer+(int)(change_limit-change_buffer);
+ changing=1; change_depth=include_depth; loc=buffer;
+ err_print("! Change file entry did not match");
+ @.Change file entry did not match@>
+ }
+}
+
+@* Reporting errors to the user.
+A global variable called |history| will contain one of four values
+at the end of every run: |spotless| means that no unusual messages were
+printed; |harmless_message| means that a message of possible interest
+was printed but no serious errors were detected; |error_message| means that
+at least one error was found; |fatal_message| means that the program
+terminated abnormally. The value of |history| does not influence the
+behavior of the program; it is simply computed for the convenience
+of systems that might want to use such information.
+
+@d spotless 0 /* |history| value for normal jobs */
+@d harmless_message 1 /* |history| value when non-serious info was printed */
+@d error_message 2 /* |history| value when an error was noted */
+@d fatal_message 3 /* |history| value when we had to stop prematurely */
+@d mark_harmless {if (history==spotless) history=harmless_message;}
+@d mark_error history=error_message
+
+@<Definit...@>=
+int history=spotless; /* indicates how bad this run was */
+
+@ The command `|err_print("! Error message")|' will report a syntax error to
+the user, by printing the error message at the beginning of a new line and
+then giving an indication of where the error was spotted in the source file.
+Note that no period follows the error message, since the error routine
+will automatically supply a period. A newline is automatically supplied
+if the string begins with |"!"|.
+
+The actual error indications are provided by a procedure called |error|.
+
+@<Predecl...@>=
+void err_print();
+
+@
+@<Functions...@>=
+void
+err_print(s) /* prints `\..' and location of error message */
+char *s;
+{
+ char *k,*l; /* pointers into |buffer| */
+ fprintf(stderr,*s=='!'? "\n%s" : "%s",s);
+ if(web_file_open) @<Print error location based on input buffer@>@;
+ else putc('\n',stderr);
+ update_terminal; mark_error;
+}
+
+@ The error locations can be indicated by using the global variables
+|loc|, |cur_line|, |cur_file_name| and |changing|,
+which tell respectively the first
+unlooked-at position in |buffer|, the current line number, the current
+file, and whether the current line is from |change_file| or |cur_file|.
+This routine should be modified on systems whose standard text editor
+has special line-numbering conventions.
+@^system dependencies@>
+
+@<Print error location based on input buffer@>=
+{if (changing && include_depth==change_depth)
+ fprintf(stderr,". (l. %d of change file)\n", change_line);
+else if (include_depth==0) fprintf(stderr,". (l. %d)\n", cur_line);
+ else fprintf(stderr,". (l. %d of include file %s)\n", cur_line, cur_file_name);
+l= (loc>=limit? limit: loc);
+if (l>buffer) {
+ for (k=buffer; k<l; k++)
+ if (*k=='\t') putc(' ',stderr);
+ else putc(*k,stderr); /* print the characters already read */
+ putc('\n',stderr);
+ for (k=buffer; k<l; k++) putc(' ',stderr); /* space out the next line */
+}
+for (k=l; k<limit; k++) putc(*k,stderr); /* print the part not yet read */
+ putc('\n',stderr);
+}
+
+@ When no recovery from some error has been provided, we have to wrap
+up and quit as graciously as possible. This is done by calling the
+function |wrap_up| at the end of the code.
+
+@d fatal(s,t) {
+ fprintf(stderr,s); err_print(t);
+ history=fatal_message; exit(wrap_up());
+}
+
+@ Some implementations may wish to pass the |history| value to the
+operating system so that it can be used to govern whether or not other
+programs are started. Here, for instance, we pass the operating system
+a status of 0 if and only if only harmless messages were printed.
+@^system dependencies@>
+
+@<Func...@>=
+wrap_up() {
+ @<Print the job |history|@>;
+ if (history > harmless_message) return(1);
+ else return(0);
+}
+
+@ @<Print the job |history|@>=
+switch (history) {
+case spotless: if (show_happiness) fprintf(stderr,"(No errors were found.)\n"); break;
+case harmless_message:
+ fprintf(stderr,"(Did you see the warning message above?)\n"); break;
+case error_message:
+ fprintf(stderr,"(Pardon me, but I think I spotted something wrong.)\n"); break;
+case fatal_message: fprintf(stderr,"(That was a fatal error, my friend.)\n");
+} /* there are no other cases */
+
+@* Command line arguments.
+The user calls \.{wmerge} with arguments on the command line.
+These are either file names or flags to be turned off (beginning with |"-"|)
+or flags to be turned on (beginning with |"+"|.
+The following globals are for communicating the user's desires to the rest
+of the program. The various file name variables contain strings with
+the names of those files. Most of the 128 flags are undefined but available
+for future extensions.
+
+@d show_banner flags['b'] /* should the banner line be printed? */
+@d show_happiness flags['h'] /* should lack of errors be announced? */
+
+@<Defin...@>=
+int argc; /* copy of |ac| parameter to |main| */
+char **argv; /* copy of |av| parameter to |main| */
+char out_file_name[max_file_name_length]; /* name of |out_file| */
+boolean flags[128]; /* an option for each 7-bit code */
+
+@ The |flags| will be initially 1.
+
+@<Set the default options@>=
+show_banner=show_happiness=1;
+
+@ We now must look at the command line arguments and set the file names
+accordingly. At least one file name must be present: the \.{WEB}
+file. It may have an extension, or it may omit it to get |'.w'|
+added.
+
+If there is another file name present among the arguments, it is the
+change file, again either with an extension or without one to get |'.ch'|
+An omitted change file argument means that |'/dev/null'| should be used,
+when no changes are desired.
+@^system dependencies@>
+
+If there's a third file name, it will be the output file.
+
+@<Pred...@>=
+void scan_args();
+
+@
+@<Function...@>=
+void
+scan_args()
+{
+ char *dot_pos; /* position of |'.'| in the argument */
+ register char *s; /* register for scanning strings */
+ boolean found_web=0,found_change=0,found_out=0;
+ /* have these names have been seen? */
+ boolean flag_change;
+
+ while (--argc > 0) {
+ if (**(++argv)=='-' || **argv=='+') @<Handle flag argument@>@;
+ else {
+ s=*argv;@+dot_pos=NULL;
+ while (*s) {
+ if (*s=='.') dot_pos=s++;
+ else if (*s=='/') dot_pos=NULL,++s;
+ else s++;
+ }
+ if (!found_web) @<Make |web_file_name|@>@;
+ else if (!found_change) @<Make |change_file_name| from |fname|@>@;
+ else if (!found_out) @<Override output file name@>@;
+ else @<Print usage error message and quit@>;
+ }
+ }
+ if (!found_web) @<Print usage error message and quit@>;
+ if (!found_change) strcpy(change_file_name,"/dev/null");
+}
+
+@ We use all of |*argv| for the |web_file_name| if there is a |'.'| in it,
+otherwise we add |".w"|. If this file can't be opened, we prepare an
+|alt_web_file_name| by adding |"web"| after the dot.
+The other file names come from adding other things
+after the dot. We must check that there is enough room in
+|web_file_name| and the other arrays for the argument.
+
+@<Make |web_file_name|...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>;
+ if (dot_pos==NULL)
+ sprintf(web_file_name,"%s.w",*argv);
+ else {
+ strcpy(web_file_name,*argv);
+ *dot_pos=0; /* string now ends where the dot was */
+ }
+ sprintf(alt_web_file_name,"%s.web",*argv);
+ *out_file_name='\0'; /* this will print to stdout */
+ found_web=1;
+}
+
+@ @<Make |change_file_name|...@>=
+{
+ if (s-*argv > max_file_name_length-4)
+ @<Complain about argument length@>;
+ if (dot_pos==NULL)
+ sprintf(change_file_name,"%s.ch",*argv);
+ else strcpy(change_file_name,*argv);
+ found_change=1;
+}
+
+@ @<Override...@>=
+{
+ if (s-*argv > max_file_name_length-5)
+ @<Complain about argument length@>;
+ if (dot_pos==NULL) sprintf(out_file_name,"%s.out",*argv);
+ else strcpy(out_file_name,*argv);
+ found_out=1;
+}
+
+@ @<Handle flag...@>=
+{
+ if (**argv=='-') flag_change=0;
+ else flag_change=1;
+ for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++)
+ flags[*dot_pos]=flag_change;
+}
+
+@ @<Print usage error message and quit@>=
+{
+ fatal("! Usage: wmerge webfile[.w] [changefile[.ch] [outfile[.out]]]\n","")@;
+}
+
+@ @<Complain about arg...@>= fatal("! Filename too long\n", *argv);
+
+@* Output. Here is the code that opens the output file:
+@^system dependencies@>
+
+@<Defin...@>=
+FILE *out_file; /* where output goes */
+
+@ @<Scan arguments and open output file@>=
+scan_args();
+if (out_file_name[0]=='\0') out_file=stdout;
+else if ((out_file=fopen(out_file_name,"w"))==NULL)
+ fatal("! Cannot open output file ", out_file_name);
+@.Cannot open output file@>
+
+@ The |update_terminal| procedure is called when we want
+to make sure that everything we have output to the terminal so far has
+actually left the computer's internal buffers and been sent.
+@^system dependencies@>
+
+@d update_terminal fflush(stderr) /* empty the terminal output buffer */
+
+@* Index.
diff --git a/Build/source/texk/web2c/cwebdir/examples/wordtest.w b/Build/source/texk/web2c/cwebdir/examples/wordtest.w
new file mode 100644
index 00000000000..98de5aedc60
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/wordtest.w
@@ -0,0 +1,540 @@
+\datethis
+@* Introduction. This program is a simple filter that sorts and outputs all
+lines of input that do not appear in a given set of sorted files. It is called
+{\tt wordtest} because each line of input is considered to be a `word' and
+each of the sorted files is considered to be a 'dictionary'. Words are
+output when they don't appear in any given dictionary.
+
+The character set and alphabetic order are flexible. Every 8-bit
+character is mapped into an integer called its {\it ord}. A character
+is called a {\it null\/} if its ord is zero; such characters are
+discarded from the input. A character is called a {\it break\/} if
+its ord is negative; such characters break the input into so-called words.
+Otherwise a character's ord is positive, and the character is called a
+{\it letter}. One letter precedes another in alphabetic order if and only
+if it has a smaller ord. Two letters are considered identical, for
+purposes of sorting, if their ords are the same.
+
+The null character |'\n'| must have ord~0; thus, it must remain null.
+Otherwise the ord mapping is arbitrary. If the user doesn't specify
+any special mapping, the default ord table simply maps every 8-bit
+character code into itself, considering characters to be unsigned char
+values in the range 0--255, except that ASCII codes {\tt a-z} are
+mapped into the corresponding codes for {\tt A-Z}, and newline is a
+break character. Optional command-line arguments, described below, can
+change this default mapping to any other desired scheme.
+
+A word is any nonempty sequence of letters that is immediately preceded
+and followed by break characters, when nulls are ignored. Technically
+speaking, we pretend that a break character is present at the beginning of a
+file but not at the end; thus, all letters following the final break character
+of a file are ignored, if any such letters are present. Two words are
+{\it equivalent\/} to each other if their letters have the same sequence
+of ord values. If two or more words of the input are equivalent, only
+the first will be output, and it will be output only if it is not
+equivalent to any word in the given dictionary files. Words in each
+dictionary are assumed to be in lexicographic order and to contain no
+nulls. Words in the output file will satisfy these conditions; therefore
+{\tt wordtest} can be used to generate and update the dictionaries it needs.
+Notice that if no dictionaries are given, {\tt wordtest} will act as a
+sorting routine that simply discards nulls and duplicate lines.
+
+@ The \UNIX/ command line `{\tt wordtest} {\tt [options]} {\tt [dictionaries]}'
+is interpreted by executing option commands from left to right and then by
+regarding any remaining arguments as the names of dictionary files.
+
+Most of the option commands are designed to specify the |ord| table.
+Initially |ord[c]=c| for each unsigned char code~|c|. The command
+$$\line{\hskip5em\tt-b\it string\hfil}$$
+makes every character in the string a break character. If the string is
+empty, {\tt-b} makes every nonnull character a break (i.e., it sets
+|ord[c]=-1| for |1<=c<=255|). The command
+$$\line{\hskip5em\tt-n\it string\hfil}$$
+makes every character in the string a null character. If the string is
+empty, {\tt-n} makes every character null. The command
+$$\line{\hskip5em\tt-a\it string\hfil}$$
+sets the ord of the $k$th element of the string equal to $\delta+k$,
+where $\delta$ is an offset value (normally zero). The command
+$$\line{\hskip5em\tt-d\it offset\hfil}$$
+sets the value of $\delta$; the offset should be a decimal integer between
+0 and 255.
+
+There is also an option that has no effect on the |ord| table:
+$$\line{\hskip5em\tt-m\it length\hfil}$$
+defines the length of the longest word. If any word of a file has
+more than this many characters, a break is artificially inserted
+so that a word of this maximum length is obtained. The default value is 50.
+The maximum legal value is 1000.
+
+If the given options do not specify at least one break character,
+{\tt wordtest} applies the option commands
+$$\vbox{\line{\hskip5em\.{-b"\\}\hfil}
+\line{\.{" -d64 -a"abcdefghijklmnopqrstuvwxyz"}\hfil}}$$
+which generate the default mapping mentioned above (unless other ords were
+changed).
+
+The program is designed to run fastest when there are at most two
+dictionary files (usually one large system dictionary and another
+personalized one), although it places no limit on the actual number of
+dictionaries that can be mentioned on the command line. Users who want
+to specify a multitude of dictionaries should ask themselves why they
+wouldn't prefer to merge their dictionaries together first (using
+{\tt wordtest}).
+
+@d MAX_LENGTH_DEFAULT 50
+@d MAX_LENGTH_LIMIT 1000
+
+@ The general organization of {\tt wordtest} is typical of applications
+written in \CEE/, and its approach is quite simple. If any errors are
+detected, an indication of the error is sent to the |stderr| file and
+a nonzero value is returned.
+
+@p
+#include <stdio.h>
+#include <stdlib.h>
+@#
+@<Typedefs@>@;
+int main(argc,argv)
+ int argc; /* the number of command-line arguments */
+ char *argv[]; /* the arguments themselves */
+{
+ @<Local variables@>;
+ @<Scan the command line arguments@>;
+ @<Sort the input into memory@>;
+ @<Output all input words that aren't in dictionaries@>;
+ return 0;
+}
+
+@ @<Typedefs@>=
+typedef unsigned char byte; /* our bytes will range from 0 to 255 */
+
+@ @<Local variables@>=
+int targc; /* temporary modifications to |argc| */
+byte **targv; /* pointer to the current argument of interest */
+unsigned delta; /* the offset used in the \.{-a} and \.{-d} options */
+unsigned max_length=MAX_LENGTH_DEFAULT; /* longest allowable word */
+byte breakchar; /* break character to use in the output */
+int ord[256]; /* table of ord values */
+register int c; /* an all-purpose index */
+register byte *u,*v; /* pointer to current string characters */
+
+@ We try to use newline as the output break character, if possible.
+
+@<Scan the command line arguments@>=
+for (c=0;c<256;c++) ord[c]=c;
+delta=0;
+targc=argc-1;@+targv=(byte**)argv+1;
+while (targc && **targv=='-') {
+ @<Execute the option command |targv|@>;
+ targc--;@+targv++;
+}
+if (ord['\n']<0) breakchar='\n';
+else {
+ breakchar='\0';
+ for (c=255;c;c--) if (ord[c]<0) breakchar=c;
+ if (!breakchar) @<Set up the default ords@>;
+}
+@<Allocate data structures for a total of |targc| files@>;
+for (;targc;targc--,targv++) @<Open the dictionary file named |*targv|@>;
+
+@ @<Execute the option...@>=
+switch((*targv)[1]) {
+case 'a': for (c=delta,u=*targv+2;*u;u++) ord[*u]=++c;@+break;
+case 'b': if ((*targv)[2]) for (u=*targv+2;*u;u++) ord[*u]=-1;
+ else for (c=1;c<256;c++) ord[c]=-1;
+ break;
+case 'n': if ((*targv)[2]) for (u=*targv+2;*u;u++) ord[*u]=0;
+ else for (c=1;c<256;c++) ord[c]=0;
+ break;
+case 'd': if (sscanf((char*)*targv+2,"%u",&delta)==1 && delta<256) break;
+ goto print_usage;
+case 'm': if (sscanf((char*)*targv+2,"%u",&max_length)==1 &&
+ max_length<=MAX_LENGTH_LIMIT) break;
+ goto print_usage;
+default: print_usage: fprintf(stderr,
+ "Usage: %s {-{{a|b|n}string|{d|m}number}}* dictionaryname*\n",*argv);
+ return-1;
+}
+
+@ @<Set up the default ords@>=
+{
+ ord['\n']=-1; /* newline is break character */
+ breakchar='\n';
+ for (c=1;c<=26;c++) ord['a'-1+c]='A'-1+c;
+}
+
+@*Treaps. The most interesting part of this program is its sorting algorithm,
+which is based on the ``treap'' data structure of Aragon and Seidel
+[{\sl 30th IEEE Symposium on Foundations of Computer Science\/} (1989),
+540--546].
+@^Aragon, Cecilia Rodriguez@>@^Seidel, Raimund@>
+A treap is a binary tree whose nodes have two key fields. The primary
+key, which in our application is a word from the input, obeys
+tree-search order: All descendants of the left child of node~$p$ have
+a primary key that is less than the primary key of~$p$, and all descendants
+of its right child have a primary key that is greater. The secondary key,
+which in our application is a unique pseudorandom integer attached to
+each input word, obeys heap order: The secondary key of~$p$'s children
+is greater than $p$'s own secondary key.
+
+A given set of nodes with distinct primary keys and distinct secondary
+keys can be made into a treap in exactly one way. This unique treap
+can be obtained, for example, by using ordinary tree insertion with
+respect to primary keys while inserting nodes in order of their
+secondary keys. It follows that, if the secondary keys are random,
+the binary tree will almost always be quite well balanced.
+
+We will compute secondary keys as unsigned long integers, assigning
+the key $(cn)\bmod 2^{32}$ to the $n$th node, where $c$ is an odd
+number. This will guarantee that the secondary keys are distinct.
+By choosing $c$ close to $2^{32}/\phi$, where $\phi$ is the golden
+ratio $(1+\sqrt5\,)/2$, we also spread the values out in a fashion that
+is unlikely to match any existing order in the data.
+
+@d PHICLONE 2654435769 /* $\approx 2^{32}/\phi$ */
+
+@<Typedefs@>=
+typedef struct node_struct {
+ struct node_struct *left,*right; /* children */
+ byte *keyword; /* primary key */
+ unsigned long rank; /* secondary key */
+} node; /* node of a treap */
+
+@ We want to be able to compare two strings rapidly with respect to
+lexicographic order, as defined by the |ord| table. This can be done
+if one string is delimited by |'\0'| as usual, while the other is
+delimited by a break character. Then we are sure to have an unequal
+comparison, and the inner loop is fast.
+
+Here is a routine that checks to see if a word is already present in the
+treap. The word is assumed to be in |buffer|, terminated by |breakchar|.
+The words in the treap are terminated by nulls. The
+treap is accessed by means of |root|, a pointer to its root node.
+
+@<Search for |buffer| in the treap; |goto found| if it's there@>=
+{@+register node *p=root;
+ while (p) {
+ for (u=buffer,v=p->keyword;ord[*u]==ord[*v];u++,v++) ;
+ if (*v=='\0' && *u==breakchar) goto found;
+ if (ord[*u]<ord[*v]) p=p->left;
+ else p=p->right;
+ }
+}
+
+@ We don't need to insert nodes into the treap as often as we need to
+look words up, so we don't mind repeating the comparisons already made
+when we discover that insertion is necessary. (Actually a more comprehensive
+study of this tradeoff ought to be done. But not today; I am trying
+here to keep the program short and sweet.)
+
+The insertion algorithm proceeds just as the lookup algorithm until
+we come to a node whose rank is larger than the rank of the node
+to be inserted. We insert the new node in its place, then split the
+old node and its descendants into two subtrees that will become the
+left and right subtrees of the new node.
+
+@<Insert the |buffer| word into the treap@>=
+{@+register node *p,**q,**qq,*r;
+ current_rank += PHICLONE; /* unsigned addition mod $2^{32}$ */
+ p=root;@+q=&root;
+ while (p) {
+ if (p->rank>current_rank) break; /* end of the first phase */
+ for (u=buffer,v=p->keyword;ord[*u]==ord[*v];u++,v++) ;
+ if (ord[*u]<ord[*v]) q=&(p->left), p=*q;
+ else q=&(p->right), p=*q;
+ }
+ @<Set |r| to the address of a new node, and move |buffer| into it@>;
+ r->rank=current_rank;
+ *q=r; /* link the new node into the tree */
+ @<Split subtree |p| and attach it below node |r|@>;
+}
+
+@ @<Local...@>=
+unsigned long current_rank=0; /* pseudorandom number */
+
+@ At this point |p| may already be empty. If not, we can hook its
+parts together easily. (A formal proof is a bit tricky, but the computer
+doesn't slow down like people do when they get to a conceptually harder
+part of an algorithm.)
+
+@<Split subtree |p| and attach it below node |r|@>=
+q=&(r->left);@+qq=&(r->right); /* slots to fill in as we split the subtree */
+while (p) {
+ for (u=buffer,v=p->keyword;ord[*u]==ord[*v];u++,v++) ;
+ if (ord[*u]<ord[*v]) {
+ *qq=p;
+ qq=&(p->left);
+ p=*qq;
+ } else {
+ *q=p;
+ q=&(p->right);
+ p=*q;
+ }
+}
+*q=*qq=NULL;
+
+@ We allocate node memory dynamically, in blocks of 100 nodes at a time.
+We also allocate string memory dynamically, 1000 characters at once
+(in addition to space for the current string).
+The variable |l| will be set to the length of the word in |buffer|.
+
+@d NODES_PER_BLOCK 100
+@d CHARS_PER_BLOCK 1000
+@d out_of_mem(x) {@+fprintf(stderr,"%s: Memory exhausted!\n",*argv);
+ return x;@+}
+
+@<Set |r| to the address of a new node, and move |buffer| into it@>=
+if (next_node==bad_node) {
+ next_node=(node*)calloc(NODES_PER_BLOCK,sizeof(node));
+ if (next_node==NULL) out_of_mem(-2);
+ bad_node=next_node+NODES_PER_BLOCK;
+}
+r=next_node++;
+@<Move |buffer| to a new place in the string memory, and make
+ |r->keyword| point to it@>;
+
+@ @<Move |buffer| to a new place...@>=
+if (next_string+l+1>=bad_string) {@+int block_size=CHARS_PER_BLOCK+l+1;
+ next_string=(byte*)malloc(block_size);
+ if (next_string==NULL) out_of_mem(-3);
+ bad_string=next_string+block_size;
+}
+r->keyword=next_string;
+for (u=buffer,v=next_string;ord[*u]>0;u++,v++) *v=*u;
+*v='\0';
+next_string=v+1;
+
+@ We had better define the variables we've been assuming in these
+storage allocation routines.
+
+@<Local variables@>=
+node *next_node=NULL, *bad_node=NULL;
+byte *next_string=NULL, *bad_string=NULL;
+node *root=NULL;
+byte *buffer;
+int l; /* length of current string in |buffer| */
+
+@ The mechanisms for sorting the input words are now all in place.
+We merely need to invoke them at the right times.
+
+@<Sort the input into memory@>=
+buffer=(byte*)malloc(max_length+1);
+if (buffer==NULL) out_of_mem(-5);
+while (1) {
+ @<Set |buffer| to the next word from |stdin|; |goto done| if file ends@>;
+ if (l) {
+ @<Search for |buffer| in the treap; |goto found| if it's there@>;
+ @<Insert the |buffer| word into the treap@>;
+ found:;
+ }
+}
+done:;
+
+@ @<Set |buffer| to the next word from |stdin|...@>=
+u=buffer;@+l=0;
+while (l<max_length) {
+ c=getchar();
+ if (c==EOF) {
+ if (ferror(stdin)) {
+ fprintf(stderr,"%s: File read error on standard input!\n",*argv);
+ return -6;
+ }
+ goto done; /* end of file; the current word, if any, is discarded */
+ }
+ if (ord[c]<=0) {
+ if (ord[c]<0) break;
+ } else {
+ *u++=(byte)c;
+ l++;
+ }
+}
+*u=breakchar;
+
+@ At the end we want to traverse the treap in symmetric order, so that
+we see its words in alphabetic order. We might as well destroy the
+treap structure as we do this. During this phase, |root| will point
+to a stack of nodes that remain to be visited (followed by traversal
+of their right subtrees).
+
+@<Output all input words that aren't in dictionaries@>=
+if (root!=NULL) {@+register node *p,*q;
+ p=root;
+ root=NULL;
+ while (1) {
+ while (p->left!=NULL) {
+ q=p->left;
+ p->left=root; /* |left| links are now used for the stack */
+ root=p;
+ p=q;
+ }
+visit: @<Output |p->keyword|, if it's not in the dictionaries@>;
+ if (p->right==NULL) {
+ if (root==NULL) break; /* the stack is empty, we're done */
+ p=root;
+ root=root->left; /* pop the stack */
+ goto visit;
+ } else p=p->right;
+ }
+}
+
+@* The dictionaries. So now all we have to do is provide a mechanism
+for reading the words in the dictionaries. The dictionaries are sorted,
+and by now the input words have been sorted too.
+So we need only scan through the
+dictionaries once; we'll try to zoom through as quickly as possible.
+
+First we need data structures. There will be an array of pointers to filenodes,
+for all dictionary files currently open. Each filenode will contain
+a buffer of size |BUFSIZ+1| for raw input bytes not yet scanned,
+as well as a buffer of size |MAX_LENGTH_LIMIT+1| for the current word
+being considered.
+
+@<Typedefs@>=
+typedef struct filenode_struct {
+ struct filenode_struct *link; /* pointer to next open file */
+ FILE *dfile; /* dictionary file */
+ byte buf[BUFSIZ+1], curword[MAX_LENGTH_LIMIT+1];
+ byte *pos; /* current position in |buf| */
+ byte *limit; /* end of input bytes in |buf| */
+ byte *endword; /* the first break character in |curword| */
+} filenode;
+
+@ @<Allocate data structures...@>=
+if (targc) {
+ curfile=(filenode*)calloc(targc,sizeof(filenode));
+ if (curfile==NULL) out_of_mem(-7);
+ for (f=curfile;f<curfile+targc-1;f++) f->link=f+1;
+ f->link=curfile; /* circular linking */
+} else curfile=NULL;
+
+@ @<Local...@>=
+filenode *curfile; /* current filenode of interest */
+filenode *f; /* temporary register for filenode list processing */
+
+@ @<Open the dictionary file named |*targv|@>=
+{
+ curfile->dfile=fopen((char*)*targv,"r");
+ if (curfile->dfile==NULL) {
+ fprintf(stderr,"%s: Can't open dictionary file %s!\n",*argv,(char*)*targv);
+ return -8;
+ }
+ curfile->pos=curfile->limit=curfile->buf; /* |buf| is empty */
+ curfile->buf[0]='\0';
+ curfile->endword=curfile->curword; /* |curword| is empty too */
+ curfile->curword[0]=breakchar;
+ curfile=curfile->link; /* move to next filenode */
+}
+
+@ We will implicitly merge the dictionaries together by using a brute force
+scheme that works fine when there are only a few of them. Namely,
+|curfile| will point to a file having the currently smallest
+current word. To get to the next word of the merge, we advance to the
+next word in that file, comparing it with the current words of the
+other files to see if |curfile| should switch to one of them.
+When we get to the end of a file, its filenode simply leaves the circular
+list. Eventually the list will be empty, and we will set |curfile| to
+|NULL|; we will then have seen all the dictionary words in order.
+
+@ @<Output |p->keyword|, if it's not in the dictionaries@>=
+while (curfile!=NULL) {
+ for (u=p->keyword,v=curfile->curword;ord[*u]==ord[*v];u++,v++) ;
+ if (*u=='\0' && *v==breakchar) goto word_done;
+ /* we found it in the dictionary */
+ if (ord[*u]<ord[*v]) break; /* we didn't find it */
+ @<Advance to the next dictionary word@>;
+}
+@<Print |p->keyword| and |breakchar| on |stdout|@>@;
+word_done:;
+
+@ @<Print |p->keyword| and |breakchar| on |stdout|@>=
+for (u=p->keyword;*u;u++) putchar(*u);
+putchar(breakchar);
+
+@ @<Advance...@>=
+@<Read a new word into |curfile->curword|, as fast as you can@>;
+@<Adjust |curfile|, if necessary, to point to a file with minimal
+ |curword|@>;
+
+@ The dictionaries are supposed to be in order, and they shouldn't
+contain nulls. But if they fail to meet these criteria, we don't want
+{\tt wordtest} to crash; it should just run more slowly and/or more
+peculiarly.
+
+The logic of the code here removes null characters, at the cost of speed.
+If the dictionary contains words out of order, say $\alpha>\beta$ where
+$\alpha$ precedes $\beta$ in the file, the effect will be as if $\beta$
+were not present. (In particular, if the dictionary would happen to have a null
+word because of a break character inserted by our |max_length| logic,
+that null word would cause no harm, because a null word is always less than
+any nonnull word.)
+
+A null character always appears in |curfile->limit|.
+
+@<Read a new word into |curfile->curword|...@>=
+v=curfile->curword;
+l=max_length; /* here |l| represents max characters to put in |curword| */
+while (1) {@+register byte *w=curfile->limit;
+ u=curfile->pos;
+ if (u+l>=w)
+ while (ord[*u]>0) *v++=*u++; /* this is the inner loop */
+ else {
+ w=u+l;
+ c=*w;
+ *w='\0'; /* temporarily store a null to avoid overlong string */
+ while (ord[*u]>0) *v++=*u++; /* this too is the inner loop */
+ *w=c; /* restore the damaged byte */
+ }
+ if (ord[*u]<0) {
+ curfile->pos=u+1; /* good, we found the next break character */
+ break;
+ }
+ l-=u-curfile->pos;
+ if (l==0) { /* |max_length| reached */
+ curfile->pos=u;
+ break;
+ }
+ if (u==w) { /* we're at |curfile->limit| */
+ @<Refill |curfile->buf|; or remove the current file from the
+ circular list and |goto update_done|, if it has ended@>;
+ } else curfile->pos=u+1; /* bypass a null character in the dictionary */
+}
+curfile->endword=v;
+*v=breakchar;
+update_done:;
+
+@ @<Refill |curfile->buf|...@>=
+if (ferror(curfile->dfile)) {
+ fprintf(stderr,"%s: File read error on dictionary file!\n",*argv);
+ return -9;
+}
+if (feof(curfile->dfile)) {
+ f=curfile->link;
+ if (f==curfile) curfile=NULL; /* the last dictionary file has ended */
+ else {
+ while (f->link!=curfile) f=f->link;
+ f->link=curfile->link; /* remove a filenode from the circular list */
+ curfile=f; /* and point to one of the remaining filenodes */
+ }
+ goto update_done;
+}
+curfile->limit=curfile->buf+fread(curfile->buf,1,BUFSIZ,curfile->dfile);
+*curfile->limit='\0';
+curfile->pos=curfile->buf;
+
+@ @<Adjust |curfile|, if necessary...@>=
+if (curfile!=NULL) {@+filenode *sentinel=curfile;
+ for (f=curfile->link;f!=sentinel;f=f->link)
+ @<Change |curfile| to |f| if |f->curword<curfile->curword|@>;
+}
+
+@ @<Change |curfile| to |f| if |f->curword<curfile->curword|@>=
+{
+ *f->endword='\0';
+ for (u=f->curword,v=curfile->curword;ord[*u]==ord[*v];u++,v++) ;
+ if (ord[*u]<ord[*v]) curfile=f;
+ *f->endword=breakchar;
+}
+
+@* Index. Here is a list of the identifiers used by {\tt wordtest},
+showing the sections in which they appear, underlined at points
+of definition.
diff --git a/Build/source/texk/web2c/cwebdir/examples/xlib_types.w b/Build/source/texk/web2c/cwebdir/examples/xlib_types.w
new file mode 100644
index 00000000000..c454c6f2eda
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/xlib_types.w
@@ -0,0 +1,92 @@
+@q This file tells CWEAVE to treat X11/Xlib types as reserved words. @>
+
+@s XExtData int
+@s XExtCodes int
+@s _XExtension int
+@s XPixmapFormatValues int
+@s XGCValues int
+@s GC int
+@s Visual int
+@s Depth int
+@s Screen int
+@s ScreenFormat int
+@s XSetWindowAttributes int
+@s XWindowAttributes int
+@s XHostAddress int
+@s XImage int
+@s XWindowChanges int
+@s XColor int
+@s XSegment int
+@s XPoint int
+@s XRectangle int
+@s XArc int
+@s XKeyboardControl int
+@s XKeyboardState int
+@s XTimeCoord int
+@s XModifierKeymap int
+@s Display int
+@s XKeyEvent int
+@s XKeyPressedEvent int
+@s XKeyReleasedEvent int
+@s XButtonEvent int
+@s XButtonPressedEvent int
+@s XButtonReleasedEvent int
+@s XMotionEvent int
+@s XPointerMovedEvent int
+@s XCrossingEvent int
+@s XEnterWindowEvent int
+@s XLeaveWindowEvent int
+@s XFocusChangeEvent int
+@s XFocusInEvent int
+@s XFocusOutEvent int
+@s XKeymapEvent int
+@s XExposeEvent int
+@s XGraphicsExposeEvent int
+@s XNoExposeEvent int
+@s XVisibilityEvent int
+@s XCreateWindowEvent int
+@s XDestroyWindowEvent int
+@s XUnmapEvent int
+@s XMapEvent int
+@s XMapRequestEvent int
+@s XReparentEvent int
+@s XConfigureEvent int
+@s XGravityEvent int
+@s XResizeRequestEvent int
+@s XConfigureRequestEvent int
+@s XCirculateEvent int
+@s XCirculateRequestEvent int
+@s XPropertyEvent int
+@s XSelectionClearEvent int
+@s XSelectionRequestEvent int
+@s XSelectionEvent int
+@s XColormapEvent int
+@s XClientMessageEvent int
+@s XMappingEvent int
+@s XErrorEvent int
+@s XAnyEvent int
+@s XEvent int
+@s _XQEvent int
+@s XCharStruct int
+@s XFontProp int
+@s XFontStruct int
+@s XTextItem int
+@s XChar2b int
+@s XTextItem16 int
+@s XEDataObject int
+@s XErrorHandler int
+@s XIOErrorHandler int
+@s XID int
+@s Window int
+@s Drawable int
+@s Font int
+@s Pixmap int
+@s Cursor int
+@s Colormap int
+@s GContext int
+@s KeySym int
+@s Mask int
+@s Atom int
+@s VisualID int
+@s Time int
+@s KeyCode int
diff --git a/Build/source/texk/web2c/cwebdir/examples/xview_types.w b/Build/source/texk/web2c/cwebdir/examples/xview_types.w
new file mode 100644
index 00000000000..168551e884a
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/examples/xview_types.w
@@ -0,0 +1,274 @@
+@q This file tells CWEAVE to treat XView types as reserved words. @>
+
+@s Attr_attribute int
+@s Attr_avlist int
+@s Attr_base_cardinality int
+@s Attr_base_type int
+@s Attr_cu_type int
+@s Attr_generic int
+@s Attr_list_ptr_type int
+@s Attr_list_type int
+@s Attr_pkg int
+@s Attr_union int
+@s Canvas int
+@s Canvas_attribute int
+@s Canvas_paint_attribute int
+@s Canvas_paint_window int
+@s Canvas_view int
+@s Canvas_view_attribute int
+@s Cms int
+@s Cms_attribute int
+@s Cms_type int
+@s Cursor_attribute int
+@s Cursor_drag_state int
+@s Cursor_drag_type int
+@s Defaults_pairs int
+@s Destroy_status int
+@s Dnd int
+@s DndDragType int
+@s Dnd_attribute int
+@s Drag_drop int
+@s Drawable_attr int
+@s Drawable_attribute int
+@s Drop_site_item int
+@s Enumerator int
+@s Error_attr int
+@s Error_attribute int
+@s Error_layer int
+@s Error_severity int
+@s Event int
+@s Firm_event int
+@s Font_attribute int
+@s Font_string_dims int
+@s Font_type int
+@s Frame int
+@s Frame_accelerator int
+@s Frame_attribute int
+@s Frame_cmd int
+@s Frame_cmd_pin_state int
+@s Frame_focus_direction int
+@s Frame_help int
+@s Frame_props int
+@s Fullscreen int
+@s Fullscreen_attr int
+@s Fullscreen_attribute int
+@s Fullscreen_grab_mode int
+@s Icon int
+@s Icon_attribute int
+@s Inputmask int
+@s Kbd_cmds_value int
+@s Menu int
+@s Menu_attribute int
+@s Menu_class int
+@s Menu_feedback int
+@s Menu_generate int
+@s Menu_item int
+@s Notice_attribute int
+@s Notify_arg int
+@s Notify_client int
+@s Notify_copy int
+@s Notify_dump_type int
+@s Notify_error int
+@s Notify_event int
+@s Notify_event_type int
+@s Notify_func int
+@s Notify_release int
+@s Notify_signal_mode int
+@s Notify_value int
+@s Openwin int
+@s Openwin_attribute int
+@s Openwin_split_direction int
+@s Panel int
+@s Panel_abbrev_menu_button_item int
+@s Panel_attr int
+@s Panel_attribute int
+@s Panel_attribute_value int
+@s Panel_button_item int
+@s Panel_choice_item int
+@s Panel_drop_target_item int
+@s Panel_gauge_item int
+@s Panel_item int
+@s Panel_item_type int
+@s Panel_list_item int
+@s Panel_list_mode int
+@s Panel_list_op int
+@s Panel_message_item int
+@s Panel_multiline_text_item int
+@s Panel_numeric_text_item int
+@s Panel_ops int
+@s Panel_paint_window int
+@s Panel_setting int
+@s Panel_slider_item int
+@s Panel_status int
+@s Panel_text_item int
+@s Panel_view int
+@s Pixwin int
+@s Pw_pixel_cache int
+@s Rect int
+@s Rectlist int
+@s Rectnode int
+@s Screen_attr int
+@s Screen_attribute int
+@s Scroll_motion int
+@s Scrollable_panel int
+@s Scrollbar int
+@s Scrollbar_attr int
+@s Scrollbar_attribute int
+@s Scrollbar_motion int
+@s Scrollbar_setting int
+@s Sel_cmpat_info int
+@s Sel_prop_info int
+@s Selection int
+@s Selection_attr int
+@s Selection_attribute int
+@s Selection_item int
+@s Selection_owner int
+@s Selection_requestor int
+@s Seln_access int
+@s Seln_attribute int
+@s Seln_client int
+@s Seln_file_info int
+@s Seln_function int
+@s Seln_function_buffer int
+@s Seln_functions_state int
+@s Seln_holder int
+@s Seln_holders_all int
+@s Seln_inform_args int
+@s Seln_level int
+@s Seln_rank int
+@s Seln_replier_data int
+@s Seln_request int
+@s Seln_requester int
+@s Seln_response int
+@s Seln_result int
+@s Seln_state int
+@s Server_attr int
+@s Server_attribute int
+@s Server_image int
+@s Server_image_attribute int
+@s Termsw int
+@s Termsw_attribute int
+@s Termsw_mode int
+@s Termsw_view int
+@s Text int
+@s Textsw int
+@s Textsw_action int
+@s Textsw_attribute int
+@s Textsw_enum int
+@s Textsw_expand_status int
+@s Textsw_filter_attribute int
+@s Textsw_filter_command int
+@s Textsw_index int
+@s Textsw_mark int
+@s Textsw_menu_cmd int
+@s Textsw_opaque int
+@s Textsw_status int
+@s Textsw_view int
+@s Tty int
+@s Tty_attribute int
+@s Tty_view int
+@s Ttysubwindow int
+@s Vuid_addr_probe int
+@s Vuid_device int
+@s WM_Direction int
+@s Win_enum_node int
+@s Win_enum_result int
+@s Win_tree_layer int
+@s Window_attr int
+@s Window_attribute int
+@s Window_handle int
+@s Window_input_event int
+@s Window_layout_op int
+@s Window_rescale_rect_obj int
+@s Window_rescale_state int
+@s Window_type int
+@s Ws_scale int
+@s Ws_scale_list int
+@s Xv_Color_info int
+@s Xv_Cursor int
+@s Xv_Drawable int
+@s Xv_Font int
+@s Xv_Notice int
+@s Xv_Screen int
+@s Xv_Server int
+@s Xv_Window int
+@s Xv_attr int
+@s Xv_attribute int
+@s Xv_base int
+@s Xv_canvas int
+@s Xv_canvas_pw int
+@s Xv_canvas_view int
+@s Xv_cms_struct int
+@s Xv_cmsdata int
+@s Xv_cursor int
+@s Xv_cursor_struct int
+@s Xv_dnd_struct int
+@s Xv_drag_drop int
+@s Xv_drawable int
+@s Xv_drawable_struct int
+@s Xv_drop_site int
+@s Xv_drop_site_struct int
+@s Xv_embedding int
+@s Xv_focus_rank int
+@s Xv_font int
+@s Xv_font_struct int
+@s Xv_frame_base int
+@s Xv_frame_class int
+@s Xv_frame_cmd int
+@s Xv_frame_help int
+@s Xv_frame_props int
+@s Xv_fullscreen int
+@s Xv_generic_attr int
+@s Xv_generic_attribute int
+@s Xv_generic_struct int
+@s Xv_icon int
+@s Xv_icon_header_info int
+@s Xv_item int
+@s Xv_menu int
+@s Xv_menu_item int
+@s Xv_Notice int
+@s Xv_notice int
+@s Xv_notice_struct int
+@s Xv_object int
+@s Xv_opaque int
+@s Xv_openwin int
+@s Xv_panel int
+@s Xv_panel_ambtn int
+@s Xv_panel_button int
+@s Xv_panel_choice int
+@s Xv_panel_drop int
+@s Xv_panel_extension_item int
+@s Xv_panel_gauge int
+@s Xv_panel_list int
+@s Xv_panel_message int
+@s Xv_panel_multiline_text int
+@s Xv_panel_num_text int
+@s Xv_panel_or_item int
+@s Xv_panel_slider int
+@s Xv_panel_text int
+@s Xv_panel_view int
+@s Xv_pkg int
+@s Xv_Screen int
+@s Xv_screen int
+@s Xv_screen_struct int
+@s Xv_scrollbar int
+@s Xv_sel int
+@s Xv_sel_item int
+@s Xv_sel_owner int
+@s Xv_sel_requestor int
+@s Xv_Server int
+@s Xv_server int
+@s Xv_server_image int
+@s Xv_server_struct int
+@s Xv_singlecolor int
+@s Xv_termsw int
+@s Xv_termsw_view int
+@s Xv_textsw int
+@s Xv_textsw_view int
+@s Xv_tty int
+@s Xv_tty_view int
+@s Xv_window int
+@s Xv_window_struct int
+@s Xv_xrectlist int
+@s icon_header_handle int
+@s icon_header_object int
diff --git a/Build/source/texk/web2c/cwebdir/makefile.bs b/Build/source/texk/web2c/cwebdir/makefile.bs
new file mode 100644
index 00000000000..5e970128049
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/makefile.bs
@@ -0,0 +1,60 @@
+# Makefile for CTANGLE and CWEAVE, pc/big versions, using
+# Borland C++ 3.1 and Borland Make.
+#
+# (This file contributed by Barry Schwartz, trashman@crud.mn.org,
+# 24 Jul 94.)
+
+
+
+CC = bcc
+
+# Redundant Load Suppression (-Z) is turned off, because it seems to
+# break the code. Likewise for Copy Propagation (-Op). (These
+# optimizations don't seem to cause any problems in common.w, but
+# better safe than sorry--compile everything with them turned off.)
+OPT = -O2-p -Z-
+
+# Compile with symbols. That way you'll be able to use the debugger if
+# you run into trouble. You can always use tdstrip later, to remove the
+# symbols.
+DEBUG = -v
+
+LCFLAGS = -mc -Ff=5000 -d -w-pro $(DEBUG)
+CFLAGS = $(LCFLAGS) $(OPT)
+COMPILE = $(CC) $(CFLAGS)
+
+LINK = $(CC) $(LCFLAGS) -e
+
+
+
+# Where to find an "old" version of ctangle, for bootstrapping. The first
+# time you make ctangle, you may have to edit the distributed ctangle.c
+# and/or common.c by hand to reduce the size of one or more arrays.
+# This will give you a functional ctangle.exe, which you can use to bootstrap
+# the "real" ctangle.exe.
+CTANGLE = ctangle
+
+
+
+
+all default: ctangle.exe cweave.exe
+
+
+ctangle.exe: ctangle.obj common.obj
+ $(LINK)$* $**
+
+cweave.exe: cweave.obj common.obj
+ $(LINK)$* $**
+
+
+common.obj: common.w comm-bs.ch
+ $(CTANGLE) common.w comm-bs.ch
+ $(COMPILE) -c common.c
+
+ctangle.obj: ctangle.w common.h ctang-bs.ch
+ $(CTANGLE) ctangle.w ctang-bs.ch
+ $(COMPILE) -c ctangle.c
+
+cweave.obj: cweave.w common.h cweav-bs.ch
+ $(CTANGLE) cweave.w cweav-bs.ch
+ $(COMPILE) -c cweave.c
diff --git a/Build/source/texk/web2c/cwebdir/po/cweb-tl.pot b/Build/source/texk/web2c/cwebdir/po/cweb-tl.pot
new file mode 100644
index 00000000000..67afbc4f32b
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/cweb-tl.pot
@@ -0,0 +1,47 @@
+# International version of CWEB (CWEBbin, TeXLive).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer.github.io>, 2021.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:43+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: comm-texlive.ch:531
+#, c-format
+msgid ""
+"\n"
+"Email bug reports to %s.\n"
+msgstr ""
+
+#: comm-texlive.ch:511
+#, c-format
+msgid "%s: Need one to three file arguments.\n"
+msgstr ""
+
+#: ctang-texlive.ch:39
+msgid "This is CTANGLE, Version 4.2"
+msgstr ""
+
+#: ctwill-texlive.ch:39
+msgid "This is CTWILL, Version 4.2"
+msgstr ""
+
+#: cweav-texlive.ch:39
+msgid "This is CWEAVE, Version 4.2"
+msgstr ""
+
+#: comm-texlive.ch:512
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr ""
diff --git a/Build/source/texk/web2c/cwebdir/po/cweb.pot b/Build/source/texk/web2c/cwebdir/po/cweb.pot
new file mode 100644
index 00000000000..f6f992a0c07
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/cweb.pot
@@ -0,0 +1,604 @@
+# International version of CWEB (CWEBbin).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer/github.io>, 2021.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:25+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: comm-i18n.ch:176
+msgid ""
+"\n"
+"! Ambiguous prefix: matches <"
+msgstr ""
+
+#: cweav-i18n.ch:295
+msgid ""
+"\n"
+"! C text in section name didn't end: <"
+msgstr ""
+
+#: cweav-i18n.ch:287
+msgid ""
+"\n"
+"! Illegal control code in section name: <"
+msgstr ""
+
+#: cweav-i18n.ch:159
+#, c-format
+msgid ""
+"\n"
+"! Line had to be broken (output l. %d):\n"
+msgstr ""
+
+#: cweav-i18n.ch:142
+msgid ""
+"\n"
+"! Never defined: <"
+msgstr ""
+
+#: cweav-i18n.ch:150
+msgid ""
+"\n"
+"! Never used: <"
+msgstr ""
+
+#: comm-i18n.ch:196
+msgid ""
+"\n"
+"! New name extends <"
+msgstr ""
+
+#: comm-i18n.ch:190
+msgid ""
+"\n"
+"! New name is a prefix of <"
+msgstr ""
+
+#: ctang-i18n.ch:57
+msgid ""
+"\n"
+"! No program text was specified."
+msgstr ""
+
+#: ctang-i18n.ch:41
+msgid ""
+"\n"
+"! Not present: <"
+msgstr ""
+
+#: comm-i18n.ch:202
+msgid ""
+"\n"
+"! Section name incompatible with <"
+msgstr ""
+
+#: ctang-i18n.ch:173 cweav-i18n.ch:67
+msgid ""
+"\n"
+"! Section name too long: "
+msgstr ""
+
+#: comm-i18n.ch:248
+#, c-format
+msgid ""
+"\n"
+"! Sorry, %s capacity exceeded"
+msgstr ""
+
+#: ctang-i18n.ch:131 cweav-i18n.ch:45
+msgid ""
+"\n"
+"! String too long: "
+msgstr ""
+
+#: cweav-i18n.ch:239
+#, c-format
+msgid ""
+"\n"
+"Irreducible scrap sequence in section %d:"
+msgstr ""
+
+#: ctang-i18n.ch:300 cweav-i18n.ch:430
+msgid ""
+"\n"
+"Memory usage statistics:"
+msgstr ""
+
+#: cweav-i18n.ch:247
+#, c-format
+msgid ""
+"\n"
+"Tracing after l. %d:\n"
+msgstr ""
+
+#: cweav-i18n.ch:377
+msgid ""
+"\n"
+"Writing the index..."
+msgstr ""
+
+#: ctang-i18n.ch:63
+#, c-format
+msgid ""
+"\n"
+"Writing the output file (%s):"
+msgstr ""
+
+#: cweav-i18n.ch:317
+msgid ""
+"\n"
+"Writing the output file..."
+msgstr ""
+
+#: ctang-i18n.ch:69
+msgid ""
+"\n"
+"Writing the output files:"
+msgstr ""
+
+#: ctang-i18n.ch:225
+msgid "! @d, @f and @c are ignored in C text"
+msgstr ""
+
+#: comm-i18n.ch:56
+msgid "! CWEB file ended during a change"
+msgstr ""
+
+#: cweav-twill.ch:1029
+msgid "! Cannot open aux output file "
+msgstr ""
+
+#: comm-i18n.ch:84
+msgid "! Cannot open change file "
+msgstr ""
+
+#: comm-i18n.ch:112
+msgid "! Cannot open include file"
+msgstr ""
+
+#: cweav-i18n.ch:383
+msgid "! Cannot open index file "
+msgstr ""
+
+#: comm-i18n.ch:78
+msgid "! Cannot open input file "
+msgstr ""
+
+#: comm-i18n.ch:300 comm-i18n.ch:306 comm-i18n.ch:312 comm-i18n.ch:318
+#: ctang-i18n.ch:83 ctang-i18n.ch:89 ctang-i18n.ch:315 ctang-i18n.ch:321
+#: cweav-i18n.ch:455
+msgid "! Cannot open output file "
+msgstr ""
+
+#: cweav-i18n.ch:389
+msgid "! Cannot open section file "
+msgstr ""
+
+#: comm-i18n.ch:42
+msgid "! Change file ended after @x"
+msgstr ""
+
+#: comm-i18n.ch:50
+msgid "! Change file ended before @y"
+msgstr ""
+
+#: comm-i18n.ch:120
+msgid "! Change file ended without @z"
+msgstr ""
+
+#: comm-i18n.ch:134
+msgid "! Change file entry did not match"
+msgstr ""
+
+#: cweav-i18n.ch:95
+msgid "! Control codes are forbidden in control text"
+msgstr ""
+
+#: cweav-i18n.ch:81
+msgid "! Control codes are forbidden in section name"
+msgstr ""
+
+#: cweav-i18n.ch:89
+msgid "! Control text didn't end"
+msgstr ""
+
+#: ctang-i18n.ch:257
+msgid "! Definition flushed, must start with identifier"
+msgstr ""
+
+#: ctang-i18n.ch:153
+msgid "! Double @ should be used in ASCII constant"
+msgstr ""
+
+#: ctang-i18n.ch:145 ctang-i18n.ch:265
+msgid "! Double @ should be used in control text"
+msgstr ""
+
+#: ctang-i18n.ch:271 cweav-i18n.ch:167 cweav-twill.ch:661 cweav-twill.ch:664
+msgid "! Double @ should be used in limbo"
+msgstr ""
+
+#: ctang-i18n.ch:241
+msgid "! Double @ should be used in string"
+msgstr ""
+
+#: cweav-i18n.ch:263
+msgid "! Double @ should be used in strings"
+msgstr ""
+
+#: cweav-i18n.ch:193
+msgid "! Extra } in comment"
+msgstr ""
+
+#: comm-i18n.ch:292
+msgid "! Filename too long\n"
+msgstr ""
+
+#: cweav-twill.ch:541
+msgid "! Identifier in meaning should be followed by space"
+msgstr ""
+
+#: cweav-i18n.ch:209
+msgid "! Illegal use of @ in comment"
+msgstr ""
+
+#: cweav-i18n.ch:353
+msgid "! Improper format definition"
+msgstr ""
+
+#: ctang-i18n.ch:279
+msgid "! Improper hex number following @l"
+msgstr ""
+
+#: cweav-i18n.ch:339 cweav-i18n.ch:345
+msgid "! Improper macro definition"
+msgstr ""
+
+#: comm-i18n.ch:92
+msgid "! Include file name not given"
+msgstr ""
+
+#: comm-i18n.ch:106
+msgid "! Include file name too long"
+msgstr ""
+
+#: comm-i18n.ch:324
+msgid "! Include path too long"
+msgstr ""
+
+#: ctang-i18n.ch:105 cweav-i18n.ch:181
+msgid "! Input ended in mid-comment"
+msgstr ""
+
+#: ctang-i18n.ch:125 cweav-i18n.ch:39
+msgid "! Input ended in middle of string"
+msgstr ""
+
+#: ctang-i18n.ch:167 cweav-i18n.ch:61
+msgid "! Input ended in section name"
+msgstr ""
+
+#: comm-i18n.ch:26
+msgid "! Input line too long"
+msgstr ""
+
+#: cweav-twill.ch:548
+msgid "! Location in meaning should be followed by space"
+msgstr ""
+
+#: ctang-i18n.ch:219
+msgid "! Misplaced @h"
+msgstr ""
+
+#: cweav-i18n.ch:271
+msgid "! Missing '|' after C text"
+msgstr ""
+
+#: comm-i18n.ch:34
+msgid "! Missing @x in change file"
+msgstr ""
+
+#: ctang-i18n.ch:233
+msgid "! Missing `@ ' before a named section"
+msgstr ""
+
+#: cweav-i18n.ch:127
+msgid "! Missing left identifier of @s"
+msgstr ""
+
+#: cweav-i18n.ch:133
+msgid "! Missing right identifier of @s"
+msgstr ""
+
+#: cweav-i18n.ch:187 cweav-i18n.ch:201
+msgid "! Missing } in comment"
+msgstr ""
+
+#: ctang-i18n.ch:187
+msgid "! Nesting of section names not allowed"
+msgstr ""
+
+#: cweav-twill.ch:1025
+msgid "! Only @$ is allowed in aux and bux files"
+msgstr ""
+
+#: ctang-i18n.ch:285
+msgid "! Replacement string in @l too long"
+msgstr ""
+
+#: ctang-i18n.ch:181 cweav-i18n.ch:75
+msgid "! Section name didn't end"
+msgstr ""
+
+#: ctang-i18n.ch:111
+msgid "! Section name ended in mid-comment"
+msgstr ""
+
+#: ctang-i18n.ch:119 ctang-i18n.ch:159 cweav-i18n.ch:33
+msgid "! String didn't end"
+msgstr ""
+
+#: cweav-i18n.ch:325
+msgid "! TeX string should be in C text only"
+msgstr ""
+
+#: comm-i18n.hch:42
+msgid "! This can't happen: "
+msgstr ""
+
+#: cweav-twill.ch:307
+msgid "! Title name didn't end"
+msgstr ""
+
+#: cweav-twill.ch:305
+msgid "! Title should be enclosed in braces or doublequotes"
+msgstr ""
+
+#: comm-i18n.ch:98
+msgid "! Too many nested includes"
+msgstr ""
+
+#: ctang-i18n.ch:249
+msgid "! Unrecognized escape sequence"
+msgstr ""
+
+#: comm-i18n.ch:272
+msgid ""
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+msgstr ""
+
+#: comm-i18n.ch:281
+msgid ""
+"! Usage: ctwill [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+msgstr ""
+
+#: comm-i18n.ch:277
+msgid ""
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+msgstr ""
+
+#: ctang-i18n.ch:139 cweav-i18n.ch:53 cweav-i18n.ch:119
+msgid "! Use @l in limbo only"
+msgstr ""
+
+#: ctang-i18n.ch:195 cweav-i18n.ch:103
+msgid "! Verbatim string didn't end"
+msgstr ""
+
+#: comm-i18n.ch:64
+msgid "! Where is the matching @y?"
+msgstr ""
+
+#: comm-i18n.ch:126
+msgid "! Where is the matching @z?"
+msgstr ""
+
+#: cweav-i18n.ch:369
+msgid "! You can't do that in C text"
+msgstr ""
+
+#: cweav-i18n.ch:331
+msgid "! You can't do that in TeX text"
+msgstr ""
+
+#: cweav-i18n.ch:361
+msgid "! You need an = sign after the section name"
+msgstr ""
+
+#: ctang-i18n.ch:305 cweav-i18n.ch:436 cweav-twill.ch:1335 cweav-twill.ch:1338
+#, c-format
+msgid "%ld bytes (out of %ld)\n"
+msgstr ""
+
+#: cweav-i18n.ch:434
+#, c-format
+msgid "%ld cross-references (out of %ld)\n"
+msgstr ""
+
+#: cweav-i18n.ch:445 cweav-i18n.ch:448
+#, c-format
+msgid "%ld levels (out of %ld)\n"
+msgstr ""
+
+#: ctang-i18n.ch:301 cweav-i18n.ch:432
+#, c-format
+msgid "%ld names (out of %ld)\n"
+msgstr ""
+
+#: ctang-i18n.ch:303
+#, c-format
+msgid "%ld replacement texts (out of %ld)\n"
+msgstr ""
+
+#: cweav-i18n.ch:439
+#, c-format
+msgid "%ld scraps (out of %ld)\n"
+msgstr ""
+
+#: cweav-twill.ch:1340
+#, c-format
+msgid "%ld temp meanings (out of %ld)\n"
+msgstr ""
+
+#: cweav-i18n.ch:441
+#, c-format
+msgid "%ld texts (out of %ld)\n"
+msgstr ""
+
+#: cweav-twill.ch:1343
+#, c-format
+msgid "%ld titles (out of %ld)\n"
+msgstr ""
+
+#: ctang-i18n.ch:307 cweav-i18n.ch:443
+#, c-format
+msgid "%ld tokens (out of %ld)\n"
+msgstr ""
+
+#: comm-i18n.ch:236
+msgid "(Did you see the warning message above?)"
+msgstr ""
+
+#: comm-i18n.ch:234
+msgid "(No errors were found.)"
+msgstr ""
+
+#: comm-i18n.ch:238
+msgid "(Pardon me, but I think I spotted something wrong.)"
+msgstr ""
+
+#: comm-i18n.ch:240
+msgid "(That was a fatal error, my friend.)"
+msgstr ""
+
+#: comm-i18n.ch:218
+#, c-format
+msgid ". (l. %d of change file)\n"
+msgstr ""
+
+#: comm-i18n.ch:220
+#, c-format
+msgid ". (l. %d of include file %s)\n"
+msgstr ""
+
+#: comm-i18n.ch:219
+#, c-format
+msgid ". (l. %d)\n"
+msgstr ""
+
+#: comm-i18n.ch:182
+msgid ""
+">\n"
+" and <"
+msgstr ""
+
+#: comm-i18n.ch:208
+msgid ""
+">,\n"
+" which abbreviates <"
+msgstr ""
+
+#: ctang-i18n.ch:75 cweav-i18n.ch:395
+msgid "Done."
+msgstr ""
+
+#: cweav-i18n.ch:438
+msgid "Parsing:"
+msgstr ""
+
+#: cweav-i18n.ch:447
+msgid "Sorting:"
+msgstr ""
+
+#: ctang-i18n.ch:17
+msgid "This is CTANGLE (Version 4.2 [CWEBbin 2021])"
+msgstr ""
+
+#: cweav-twill.ch:61
+msgid "This is CTWILL (Version 4.2 [CWEBbin 2021])"
+msgstr ""
+
+#: cweav-i18n.ch:17 cweav-twill.ch:42
+msgid "This is CWEAVE (Version 4.2 [CWEBbin 2021])"
+msgstr ""
+
+#: cweav-i18n.ch:301 cweav-i18n.ch:309
+msgid "buffer"
+msgstr ""
+
+#: comm-i18n.ch:143 comm-i18n.ch:153 comm-i18n.ch:168
+msgid "byte memory"
+msgstr ""
+
+#: cweav-i18n.ch:25
+msgid "cross-reference"
+msgstr ""
+
+#: cweav-twill.ch:818
+msgid "find type"
+msgstr ""
+
+#: cweav-twill.ch:757
+msgid "inner"
+msgstr ""
+
+#: ctang-i18n.ch:97
+msgid "macro defs have strange char"
+msgstr ""
+
+#: comm-i18n.ch:144 comm-i18n.ch:154 comm-i18n.ch:162
+msgid "name"
+msgstr ""
+
+#: comm-i18n.ch:70
+msgid "of the preceding lines failed to match"
+msgstr ""
+
+#: ctang-i18n.ch:49
+msgid "output files"
+msgstr ""
+
+#: cweav-i18n.ch:255
+msgid "scrap/token/text"
+msgstr ""
+
+#: cweav-i18n.ch:111
+msgid "section number"
+msgstr ""
+
+#: cweav-i18n.ch:403
+msgid "sorting"
+msgstr ""
+
+#: ctang-i18n.ch:33 cweav-i18n.ch:279
+msgid "stack"
+msgstr ""
+
+#: cweav-twill.ch:561
+msgid "temp meanings"
+msgstr ""
+
+#: ctang-i18n.ch:211 cweav-i18n.ch:223
+msgid "text"
+msgstr ""
+
+#: cweav-twill.ch:308
+msgid "titles"
+msgstr ""
+
+#: ctang-i18n.ch:25 ctang-i18n.ch:203 cweav-i18n.ch:175 cweav-i18n.ch:217
+#: cweav-i18n.ch:231
+msgid "token"
+msgstr ""
diff --git a/Build/source/texk/web2c/cwebdir/po/de/cweb-tl.po b/Build/source/texk/web2c/cwebdir/po/de/cweb-tl.po
new file mode 100644
index 00000000000..bd086345a9e
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/de/cweb-tl.po
@@ -0,0 +1,49 @@
+# International version of CWEB (CWEBbin, TeXLive).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer.github.io>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:43+0100\n"
+"PO-Revision-Date: 2021-02-06 15:58+0100\n"
+"Last-Translator: Andreas Scherer <andreas_github@freenet.de>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: comm-texlive.ch:531
+#, c-format
+msgid ""
+"\n"
+"Email bug reports to %s.\n"
+msgstr ""
+"\n"
+"Sende Fehler per Email an %s.\n"
+
+#: comm-texlive.ch:511
+#, c-format
+msgid "%s: Need one to three file arguments.\n"
+msgstr "%s: Benötige ein bis drei Dateiargumente.\n"
+
+#: ctang-texlive.ch:39
+msgid "This is CTANGLE, Version 4.2"
+msgstr "Dies ist CTANGLE, Version 4.2"
+
+#: ctwill-texlive.ch:39
+msgid "This is CTWILL, Version 4.2"
+msgstr "Dies ist CTWILL, Version 4.2"
+
+#: cweav-texlive.ch:39
+msgid "This is CWEAVE, Version 4.2"
+msgstr "Dies ist CWEAVE, Version 4.2"
+
+#: comm-texlive.ch:512
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Versuche `%s --help' für weitere Informationen.\n"
diff --git a/Build/source/texk/web2c/cwebdir/po/de/cweb.po b/Build/source/texk/web2c/cwebdir/po/de/cweb.po
new file mode 100644
index 00000000000..3bc760ff2af
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/de/cweb.po
@@ -0,0 +1,684 @@
+# International version of CWEB (CWEBbin, TeXLive).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer/github.io>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:25+0100\n"
+"PO-Revision-Date: 2021-02-06 15:57+0100\n"
+"Last-Translator: Andreas Scherer <andreas_github@freenet.de>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: comm-i18n.ch:176
+msgid ""
+"\n"
+"! Ambiguous prefix: matches <"
+msgstr ""
+"\n"
+"! Mehrdeutiger Präfix: passt zu <"
+
+#: cweav-i18n.ch:295
+msgid ""
+"\n"
+"! C text in section name didn't end: <"
+msgstr ""
+"\n"
+"! C-Text in Abschnittnamen nicht beendet: <"
+
+#: cweav-i18n.ch:287
+msgid ""
+"\n"
+"! Illegal control code in section name: <"
+msgstr ""
+"\n"
+"! Unerlaubtes Kontrollzeichen in Abschnittnamen: <"
+
+#: cweav-i18n.ch:159
+#, c-format
+msgid ""
+"\n"
+"! Line had to be broken (output l. %d):\n"
+msgstr ""
+"\n"
+"! Zeile musste umbrochen werden (Ausgabezeile %d):\n"
+
+#: cweav-i18n.ch:142
+msgid ""
+"\n"
+"! Never defined: <"
+msgstr ""
+"\n"
+"! Nicht definiert: <"
+
+#: cweav-i18n.ch:150
+msgid ""
+"\n"
+"! Never used: <"
+msgstr ""
+"\n"
+"! Nicht benutzt: <"
+
+#: comm-i18n.ch:196
+msgid ""
+"\n"
+"! New name extends <"
+msgstr ""
+"\n"
+"! Neuer Name erweitert <"
+
+#: comm-i18n.ch:190
+msgid ""
+"\n"
+"! New name is a prefix of <"
+msgstr ""
+"\n"
+"! Neuer Name ist Präfix von <"
+
+#: ctang-i18n.ch:57
+msgid ""
+"\n"
+"! No program text was specified."
+msgstr ""
+"\n"
+"! Kein Programmtext vorhanden."
+
+#: ctang-i18n.ch:41
+msgid ""
+"\n"
+"! Not present: <"
+msgstr ""
+"\n"
+"! Nicht vorhanden: <"
+
+#: comm-i18n.ch:202
+msgid ""
+"\n"
+"! Section name incompatible with <"
+msgstr ""
+"\n"
+"! Abschnittname passt nicht zu <"
+
+#: ctang-i18n.ch:173 cweav-i18n.ch:67
+msgid ""
+"\n"
+"! Section name too long: "
+msgstr ""
+"\n"
+"! Abschnittname ist zu lang: "
+
+#: comm-i18n.ch:248
+#, c-format
+msgid ""
+"\n"
+"! Sorry, %s capacity exceeded"
+msgstr ""
+"\n"
+"! Tut mir leid, Kapazität für %s überschritten"
+
+#: ctang-i18n.ch:131 cweav-i18n.ch:45
+msgid ""
+"\n"
+"! String too long: "
+msgstr ""
+"\n"
+"! Zeichenkette ist zu lang: "
+
+#: cweav-i18n.ch:239
+#, c-format
+msgid ""
+"\n"
+"Irreducible scrap sequence in section %d:"
+msgstr ""
+"\n"
+"Nicht reduzierbare Scrap-Folge in Abschnitt %d:"
+
+#: ctang-i18n.ch:300 cweav-i18n.ch:430
+msgid ""
+"\n"
+"Memory usage statistics:"
+msgstr ""
+"\n"
+"Statistik über den Speicherbedarf:"
+
+#: cweav-i18n.ch:247
+#, c-format
+msgid ""
+"\n"
+"Tracing after l. %d:\n"
+msgstr ""
+"\n"
+"Analyse nach Zeile %d:\n"
+
+#: cweav-i18n.ch:377
+msgid ""
+"\n"
+"Writing the index..."
+msgstr ""
+"\n"
+"Schreibe den Index..."
+
+#: ctang-i18n.ch:63
+#, c-format
+msgid ""
+"\n"
+"Writing the output file (%s):"
+msgstr ""
+"\n"
+"Schreibe die Ausgabedatei (%s):"
+
+#: cweav-i18n.ch:317
+msgid ""
+"\n"
+"Writing the output file..."
+msgstr ""
+"\n"
+"Schreibe die Ausgabedatei..."
+
+#: ctang-i18n.ch:69
+msgid ""
+"\n"
+"Writing the output files:"
+msgstr ""
+"\n"
+"Schreibe die Ausgabedateien:"
+
+#: ctang-i18n.ch:225
+msgid "! @d, @f and @c are ignored in C text"
+msgstr "! @d, @f und @c werden im C-Text ignoriert"
+
+#: comm-i18n.ch:56
+msgid "! CWEB file ended during a change"
+msgstr "! CWEB-Datei endete während einer Änderung"
+
+#: cweav-twill.ch:1029
+msgid "! Cannot open aux output file "
+msgstr "! Kann aux-Ausgabedatei nicht öffnen: "
+
+#: comm-i18n.ch:84
+msgid "! Cannot open change file "
+msgstr "! Kann Änderungsdatei nicht öffnen: "
+
+#: comm-i18n.ch:112
+msgid "! Cannot open include file"
+msgstr "! Kann Einfügedatei nicht öffnen"
+
+#: cweav-i18n.ch:383
+msgid "! Cannot open index file "
+msgstr "! Kann Indexdatei nicht öffnen: "
+
+#: comm-i18n.ch:78
+msgid "! Cannot open input file "
+msgstr "! Kann Eingabedatei nicht öffnen: "
+
+#: comm-i18n.ch:300 comm-i18n.ch:306 comm-i18n.ch:312 comm-i18n.ch:318
+#: ctang-i18n.ch:83 ctang-i18n.ch:89 ctang-i18n.ch:315 ctang-i18n.ch:321
+#: cweav-i18n.ch:455
+msgid "! Cannot open output file "
+msgstr "! Kann Ausgabedatei nicht öffnen: "
+
+#: cweav-i18n.ch:389
+msgid "! Cannot open section file "
+msgstr "! Kann die Abschnittdatei nicht öffnen: "
+
+#: comm-i18n.ch:42
+msgid "! Change file ended after @x"
+msgstr "! Änderungsdatei endete nach @x"
+
+#: comm-i18n.ch:50
+msgid "! Change file ended before @y"
+msgstr "! Änderungsdatei endete vor @y"
+
+#: comm-i18n.ch:120
+msgid "! Change file ended without @z"
+msgstr "! Änderungsdatei endete ohne @z"
+
+#: comm-i18n.ch:134
+msgid "! Change file entry did not match"
+msgstr "! Eintrag in der Änderungsdatei stimmt nicht überein"
+
+#: cweav-i18n.ch:95
+msgid "! Control codes are forbidden in control text"
+msgstr "! Kontrollzeichen sind in Kontrolltexten verboten"
+
+#: cweav-i18n.ch:81
+msgid "! Control codes are forbidden in section name"
+msgstr "! Kontrollzeichen sind in Abschnittnamen verboten"
+
+#: cweav-i18n.ch:89
+msgid "! Control text didn't end"
+msgstr "! Kontrolltext nicht beendet"
+
+#: ctang-i18n.ch:257
+msgid "! Definition flushed, must start with identifier"
+msgstr "! Definition übergangen, muss mit einem Bezeichner anfangen"
+
+#: ctang-i18n.ch:153
+msgid "! Double @ should be used in ASCII constant"
+msgstr "! In ASCII Konstanten sollten doppelte @ verwendet werden"
+
+#: ctang-i18n.ch:145 ctang-i18n.ch:265
+msgid "! Double @ should be used in control text"
+msgstr "! In Kontrolltexten sollten doppelte @ verwendet werden"
+
+#: ctang-i18n.ch:271 cweav-i18n.ch:167 cweav-twill.ch:661 cweav-twill.ch:664
+msgid "! Double @ should be used in limbo"
+msgstr "! Im Einführungsteil sollten doppelte @ verwendet werden"
+
+#: ctang-i18n.ch:241
+msgid "! Double @ should be used in string"
+msgstr "! In einer Zeichenkette sollten doppelte @ verwendet werden"
+
+#: cweav-i18n.ch:263
+msgid "! Double @ should be used in strings"
+msgstr "! In Zeichenketten sollten doppelte @ verwendet werden"
+
+#: cweav-i18n.ch:193
+msgid "! Extra } in comment"
+msgstr "! Zusätzliche } in Kommentar"
+
+#: comm-i18n.ch:292
+msgid "! Filename too long\n"
+msgstr "! Dateiname zu lang\n"
+
+#: cweav-twill.ch:541
+msgid "! Identifier in meaning should be followed by space"
+msgstr "! Bezeichner in Bedeutung sollte Leerzeichen folgen"
+
+#: cweav-i18n.ch:209
+msgid "! Illegal use of @ in comment"
+msgstr "! Unerlaubte Verwendung von @ in Kommentar"
+
+#: cweav-i18n.ch:353
+msgid "! Improper format definition"
+msgstr "! Ungültige Formatdefinition"
+
+#: ctang-i18n.ch:279
+msgid "! Improper hex number following @l"
+msgstr "! Ungültige Hexadezimalzahl nach @l"
+
+#: cweav-i18n.ch:339 cweav-i18n.ch:345
+msgid "! Improper macro definition"
+msgstr "! Ungültige Makrodefinition"
+
+#: comm-i18n.ch:92
+msgid "! Include file name not given"
+msgstr "! Name der Einfügedatei nicht angegeben"
+
+#: comm-i18n.ch:106
+msgid "! Include file name too long"
+msgstr "! Name der Einfügedatei zu lang"
+
+#: comm-i18n.ch:324
+msgid "! Include path too long"
+msgstr "! Einfügepfad zu lang"
+
+#: ctang-i18n.ch:105 cweav-i18n.ch:181
+msgid "! Input ended in mid-comment"
+msgstr "! Eingabe endete mitten in einem Kommentar"
+
+#: ctang-i18n.ch:125 cweav-i18n.ch:39
+msgid "! Input ended in middle of string"
+msgstr "! Eingabe endete mitten in einer Zeichenkette"
+
+#: ctang-i18n.ch:167 cweav-i18n.ch:61
+msgid "! Input ended in section name"
+msgstr "! Eingabe endete in einem Abschnittnamen"
+
+#: comm-i18n.ch:26
+msgid "! Input line too long"
+msgstr "! Eingabezeile zu lang"
+
+#: cweav-twill.ch:548
+msgid "! Location in meaning should be followed by space"
+msgstr "! Herkunftsort in Bedeutung sollte Leerzeichen folgen"
+
+#: ctang-i18n.ch:219
+msgid "! Misplaced @h"
+msgstr "! Falsch platziertes @h"
+
+#: cweav-i18n.ch:271
+msgid "! Missing '|' after C text"
+msgstr "! Fehlendes `|' nach C-Text"
+
+#: comm-i18n.ch:34
+msgid "! Missing @x in change file"
+msgstr "! Fehlendes @x in der Änderungsdatei"
+
+#: ctang-i18n.ch:233
+msgid "! Missing `@ ' before a named section"
+msgstr "! Fehlendes `@ ' vor einem Abschnittnamen"
+
+#: cweav-i18n.ch:127
+msgid "! Missing left identifier of @s"
+msgstr "! Fehlender linker Bezeichner von @s"
+
+#: cweav-i18n.ch:133
+msgid "! Missing right identifier of @s"
+msgstr "! Fehlender rechter Bezeichner von @s"
+
+#: cweav-i18n.ch:187 cweav-i18n.ch:201
+msgid "! Missing } in comment"
+msgstr "! Fehlende } in Kommentar"
+
+#: ctang-i18n.ch:187
+msgid "! Nesting of section names not allowed"
+msgstr "! Verschachtelung von Abschnittnamen nicht erlaubt"
+
+#: cweav-twill.ch:1025
+msgid "! Only @$ is allowed in aux and bux files"
+msgstr "! Nur @$ ist in aux- und bux-Dateien erlaubt"
+
+#: ctang-i18n.ch:285
+msgid "! Replacement string in @l too long"
+msgstr "! Ersetzungstext in @l zu lang"
+
+#: ctang-i18n.ch:181 cweav-i18n.ch:75
+msgid "! Section name didn't end"
+msgstr "! Abschnittname nicht beendet"
+
+#: ctang-i18n.ch:111
+msgid "! Section name ended in mid-comment"
+msgstr "! Abschnittname endete mitten in einem Kommentar"
+
+#: ctang-i18n.ch:119 ctang-i18n.ch:159 cweav-i18n.ch:33
+msgid "! String didn't end"
+msgstr "! Zeichenkette nicht beendet"
+
+#: cweav-i18n.ch:325
+msgid "! TeX string should be in C text only"
+msgstr "! TeX-Zeichenkette sollte nur in C-Text stehen"
+
+#: comm-i18n.hch:42
+msgid "! This can't happen: "
+msgstr "! Das kann nicht sein: "
+
+#: cweav-twill.ch:307
+msgid "! Title name didn't end"
+msgstr "! Titel nicht beendet"
+
+#: cweav-twill.ch:305
+msgid "! Title should be enclosed in braces or doublequotes"
+msgstr "! Titel sollte in geschweiften Klammern oder Anführungszeichen stehen"
+
+#: comm-i18n.ch:98
+msgid "! Too many nested includes"
+msgstr "! Zu viele verschachtelte Einfügungen"
+
+#: ctang-i18n.ch:249
+msgid "! Unrecognized escape sequence"
+msgstr "! Unbekannte Escape-Sequenz"
+
+#: comm-i18n.ch:272
+msgid ""
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+msgstr ""
+"! Aufruf: ctangle [Optionen] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+"Optionen sind (+ schaltet ein, - schaltet aus, Vorgabe in Klammern):\n"
+"b [+] Gib eine Startmeldung aus\n"
+"h [+] Bestätige einen fehlerfreien Lauf\n"
+"p [+] Zeige einen Zwischenbericht\n"
+"s [-] Melde die Verbrauchsstatistik\n"
+"t [+] Vergleiche temporäre Ausgabe nach Änderungen\n"
+
+#: comm-i18n.ch:281
+msgid ""
+"! Usage: ctwill [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+msgstr ""
+"! Aufruf: ctwill [Optionen] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+"Optionen sind (+ schaltet ein, - schaltet aus, Vorgabe in Klammern):\n"
+"b [+] Gib eine Startmeldung aus\n"
+"h [+] Bestätige einen fehlerfreien Lauf\n"
+"p [+] Zeige einen Zwischenbericht\n"
+"e [+] Schließe C-Material in \\PB-Klammern ein\n"
+"f [+] Erzwinge Zeilenumbrüche nach jeder Anweisung\n"
+"i [+] Rücke Parameterdeklarationen ein\n"
+"o [+] Trenne Deklarationen und Anweisungen\n"
+"x [+] Füge Indexe und Inhaltsverzeichnisse ein\n"
+"P [-] Benutze 'proofmac.tex' statt 'ctwimac.tex'\n"
+"lX [] Verwende die Makros für Sprache X aus X{ctwimac|proofmac}.tex\n"
+"s [-] Melde die Verbrauchsstatistik\n"
+"t [+] Vergleiche temporäre Ausgabe nach Änderungen\n"
+
+#: comm-i18n.ch:277
+msgid ""
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+msgstr ""
+"! Aufruf: cweave [Optionen] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+"Optionen sind (+ schaltet ein, - schaltet aus, Vorgabe in Klammern):\n"
+"b [+] Gib eine Startmeldung aus\n"
+"h [+] Bestätige einen fehlerfreien Lauf\n"
+"p [+] Zeige einen Zwischenbericht\n"
+"e [+] Schließe C-Material in \\PB-Klammern ein\n"
+"f [+] Erzwinge Zeilenumbrüche nach jeder Anweisung\n"
+"i [+] Rücke Parameterdeklarationen ein\n"
+"o [+] Trenne Deklarationen und Anweisungen\n"
+"x [+] Füge Indexe und Inhaltsverzeichnisse ein\n"
+"lX [] Verwende die Makros für Sprache X aus Xcwebmac.tex\n"
+"s [-] Melde die Verbrauchsstatistik\n"
+"t [+] Vergleiche temporäre Ausgabe nach Änderungen\n"
+
+#: ctang-i18n.ch:139 cweav-i18n.ch:53 cweav-i18n.ch:119
+msgid "! Use @l in limbo only"
+msgstr "! Verwende @l ausschließlich im Einführungsteil"
+
+#: ctang-i18n.ch:195 cweav-i18n.ch:103
+msgid "! Verbatim string didn't end"
+msgstr "! Verbatim-Zeichenkette nicht beendet"
+
+#: comm-i18n.ch:64
+msgid "! Where is the matching @y?"
+msgstr "! Wo ist das zugehörige @y?"
+
+#: comm-i18n.ch:126
+msgid "! Where is the matching @z?"
+msgstr "! Wo ist das zugehörige @z?"
+
+#: cweav-i18n.ch:369
+msgid "! You can't do that in C text"
+msgstr "! Das geht nicht im C-Text"
+
+#: cweav-i18n.ch:331
+msgid "! You can't do that in TeX text"
+msgstr "! Das geht nicht im TeX-Text"
+
+#: cweav-i18n.ch:361
+msgid "! You need an = sign after the section name"
+msgstr "! Hinter dem Abschnittnamen muss ein = Zeichen stehen"
+
+#: ctang-i18n.ch:305 cweav-i18n.ch:436 cweav-twill.ch:1335 cweav-twill.ch:1338
+#, c-format
+msgid "%ld bytes (out of %ld)\n"
+msgstr "%ld Bytes (von %ld)\n"
+
+#: cweav-i18n.ch:434
+#, c-format
+msgid "%ld cross-references (out of %ld)\n"
+msgstr "%ld Querverweise (von %ld)\n"
+
+#: cweav-i18n.ch:445 cweav-i18n.ch:448
+#, c-format
+msgid "%ld levels (out of %ld)\n"
+msgstr "%ld Ebenen (von %ld)\n"
+
+#: ctang-i18n.ch:301 cweav-i18n.ch:432
+#, c-format
+msgid "%ld names (out of %ld)\n"
+msgstr "%ld Namen (von %ld)\n"
+
+#: ctang-i18n.ch:303
+#, c-format
+msgid "%ld replacement texts (out of %ld)\n"
+msgstr "%ld Ersetzungstexte (von %ld)\n"
+
+#: cweav-i18n.ch:439
+#, c-format
+msgid "%ld scraps (out of %ld)\n"
+msgstr "%ld Scraps (von %ld)\n"
+
+#: cweav-twill.ch:1340
+#, c-format
+msgid "%ld temp meanings (out of %ld)\n"
+msgstr "%ld temporäre Bedeutungen (von %ld)\n"
+
+#: cweav-i18n.ch:441
+#, c-format
+msgid "%ld texts (out of %ld)\n"
+msgstr "%ld Texte (von %ld)\n"
+
+#: cweav-twill.ch:1343
+#, c-format
+msgid "%ld titles (out of %ld)\n"
+msgstr "%ld Titel (von %ld)\n"
+
+#: ctang-i18n.ch:307 cweav-i18n.ch:443
+#, c-format
+msgid "%ld tokens (out of %ld)\n"
+msgstr "%ld Token (von %ld)\n"
+
+#: comm-i18n.ch:236
+msgid "(Did you see the warning message above?)"
+msgstr "(Hast du die obige Warnung gesehen?)"
+
+#: comm-i18n.ch:234
+msgid "(No errors were found.)"
+msgstr "(Keine Fehler gefunden.)"
+
+#: comm-i18n.ch:238
+msgid "(Pardon me, but I think I spotted something wrong.)"
+msgstr "(Entschuldige bitte, aber ich glaube, etwas stimmt nicht.)"
+
+#: comm-i18n.ch:240
+msgid "(That was a fatal error, my friend.)"
+msgstr "(Mensch, das war ein böser Fehler.)"
+
+#: comm-i18n.ch:218
+#, c-format
+msgid ". (l. %d of change file)\n"
+msgstr ". (Zeile %d der Änderungsdatei)\n"
+
+#: comm-i18n.ch:220
+#, c-format
+msgid ". (l. %d of include file %s)\n"
+msgstr ". (Zeile %d der Einfügedatei %s)\n"
+
+#: comm-i18n.ch:219
+#, c-format
+msgid ". (l. %d)\n"
+msgstr ". (Zeile %d)\n"
+
+#: comm-i18n.ch:182
+msgid ""
+">\n"
+" and <"
+msgstr ""
+">\n"
+" und <"
+
+#: comm-i18n.ch:208
+msgid ""
+">,\n"
+" which abbreviates <"
+msgstr ""
+">,\n"
+" einer Abkürzung von <"
+
+#: ctang-i18n.ch:75 cweav-i18n.ch:395
+msgid "Done."
+msgstr "Fertig."
+
+#: cweav-i18n.ch:438
+msgid "Parsing:"
+msgstr "Parsen:"
+
+#: cweav-i18n.ch:447
+msgid "Sorting:"
+msgstr "Sortieren:"
+
+#: ctang-i18n.ch:17
+msgid "This is CTANGLE (Version 4.2 [CWEBbin 2021])"
+msgstr "Dies ist CTANGLE (Version 4.2 [CWEBbin 2021])"
+
+#: cweav-twill.ch:61
+msgid "This is CTWILL (Version 4.2 [CWEBbin 2021])"
+msgstr "Dies ist CTWILL (Version 4.2 [CWEBbin 2021])"
+
+#: cweav-i18n.ch:17 cweav-twill.ch:42
+msgid "This is CWEAVE (Version 4.2 [CWEBbin 2021])"
+msgstr "Dies ist CWEAVE (Version 4.2 [CWEBbin 2021])"
+
+#: cweav-i18n.ch:301 cweav-i18n.ch:309
+msgid "buffer"
+msgstr "Puffer"
+
+#: comm-i18n.ch:143 comm-i18n.ch:153 comm-i18n.ch:168
+msgid "byte memory"
+msgstr "Byte-Speicher"
+
+#: cweav-i18n.ch:25
+msgid "cross-reference"
+msgstr "Querverweise"
+
+#: cweav-twill.ch:818
+msgid "find type"
+msgstr "Auffindetyp"
+
+#: cweav-twill.ch:757
+msgid "inner"
+msgstr "inner"
+
+#: ctang-i18n.ch:97
+msgid "macro defs have strange char"
+msgstr "Unpassendes Zeichen in einer Makrodefinition"
+
+#: comm-i18n.ch:144 comm-i18n.ch:154 comm-i18n.ch:162
+msgid "name"
+msgstr "Bezeichner"
+
+#: comm-i18n.ch:70
+msgid "of the preceding lines failed to match"
+msgstr "der vorangegangenen Zeilen stimmen nicht überein"
+
+#: ctang-i18n.ch:49
+msgid "output files"
+msgstr "Ausgabedateien"
+
+#: cweav-i18n.ch:255
+msgid "scrap/token/text"
+msgstr "Scrap/Token/Text"
+
+#: cweav-i18n.ch:111
+msgid "section number"
+msgstr "Abschnittnummer"
+
+#: cweav-i18n.ch:403
+msgid "sorting"
+msgstr "Sortieren"
+
+#: ctang-i18n.ch:33 cweav-i18n.ch:279
+msgid "stack"
+msgstr "Stack"
+
+#: cweav-twill.ch:561
+msgid "temp meanings"
+msgstr "Temporäre Bedeutung"
+
+#: ctang-i18n.ch:211 cweav-i18n.ch:223
+msgid "text"
+msgstr "Text"
+
+#: cweav-twill.ch:308
+msgid "titles"
+msgstr "Titel"
+
+#: ctang-i18n.ch:25 ctang-i18n.ch:203 cweav-i18n.ch:175 cweav-i18n.ch:217
+#: cweav-i18n.ch:231
+msgid "token"
+msgstr "Token"
diff --git a/Build/source/texk/web2c/cwebdir/po/de/web2c-help.po b/Build/source/texk/web2c/cwebdir/po/de/web2c-help.po
new file mode 100644
index 00000000000..45bc6a54f99
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/de/web2c-help.po
@@ -0,0 +1,140 @@
+# International version of CWEB (CWEBbin, TeXLive).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer.github.io>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:10+0200\n"
+"PO-Revision-Date: 2021-02-06 15:58+0100\n"
+"Last-Translator: Andreas Scherer <andreas_github@freenet.de>\n"
+"Language-Team: German\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: help.h:52
+msgid ""
+"Usage: ctangle [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.c]]]"
+msgstr ""
+"Aufruf: ctangle [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.c]]]"
+
+#: help.h:53
+msgid " Tangle WEBFILE with CHANGEFILE into a C/C++ program."
+msgstr " Verknüpfe WEBFILE mit CHANGEFILE in ein C/C++ Programm."
+
+#: help.h:54 help.h:74 help.h:100
+msgid " Default CHANGEFILE is /dev/null;"
+msgstr " Vorgabe für CHANGEFILE ist /dev/null;"
+
+#: help.h:55
+msgid " C output goes to the basename of WEBFILE extended with `.c'"
+msgstr " C Ausgabe geht in den Hauptnamen des WEBFILE erweitert um `.c',"
+
+#: help.h:56 help.h:76 help.h:102
+msgid " unless otherwise specified by OUTFILE; in this case, '-' specifies"
+msgstr " sofern nicht ein anderes OUTFILE angegeben ist; in diesem Fall"
+
+#: help.h:57 help.h:77 help.h:103
+msgid " a null CHANGEFILE."
+msgstr " bezeichnet '-' ein leeres CHANGEFILE."
+
+#: help.h:59 help.h:79 help.h:105
+msgid "+b print banner line on terminal"
+msgstr "+b schreibe die Startmeldung"
+
+#: help.h:64 help.h:85 help.h:112
+msgid "-dN set 'kpathsea_debug' to N (0..127)"
+msgstr "-dN setze 'kpathsea_debug' auf N (0..127)"
+
+#: help.h:60 help.h:80 help.h:106
+msgid "+h print success message on completion"
+msgstr "+h schreibe die Erfolgsmeldung am Ende"
+
+#: help.h:61 help.h:81 help.h:107
+msgid "+p print progress report messages"
+msgstr "+p schreibe die Fortschrittsmeldungen"
+
+#: help.h:62 help.h:82 help.h:108
+msgid "+/-q shortcut for '-bhp'; also '--quiet' (default)"
+msgstr "+/-q Kurzform für '-bhp'; auch '--quiet' (Vorgabe)"
+
+#: help.h:63 help.h:83 help.h:109
+msgid "+/-v shortcut for '+bhp'; also '--verbose'"
+msgstr "+/-v Kurzform für '+bhp'; auch '--verbose'"
+
+#: help.h:64 help.h:90 help.h:117
+msgid "+s print usage statistics"
+msgstr "+s melde die Verbrauchsstatistik"
+
+#: help.h:65 help.h:91 help.h:118
+msgid "-t ignore temporary output irrespective of changes"
+msgstr "-t ignoriere temporäre Ausgabe unabhängig von Änderungen"
+
+#: help.h:66 help.h:92 help.h:119
+msgid "--help display this help and exit"
+msgstr "--help zeige diesen Hilfetext und ende"
+
+#: help.h:67 help.h:93 help.h:120
+msgid "--version output version information and exit"
+msgstr "--version zeige die Versionsinformation und ende"
+
+#: help.h:72
+msgid ""
+"Usage: cweave [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]"
+msgstr ""
+"Aufruf: cweave [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]"
+
+#: help.h:73
+msgid " Weave WEBFILE with CHANGEFILE into a TeX document."
+msgstr " Verwebe WEBFILE mit CHANGEFILE in ein TeX Dokument."
+
+#: help.h:75 help.h:101
+msgid " TeX output goes to the basename of WEBFILE extended with `.tex'"
+msgstr " TeX Ausgabe geht in den Hauptnamen des WEBFILE erweitert um `.tex',"
+
+#: help.h:84 help.h:110
+msgid "-e do not enclose C material in \\PB{...}"
+msgstr "-e schließe C Material nicht in \\PB{...} ein"
+
+#: help.h:85 help.h:111
+msgid "-f do not force a newline after every C statement in output"
+msgstr "-f erzwinge keinen Zeilenumbruch nach jedem C Statement"
+
+#: help.h:86 help.h:112
+msgid "-i suppress indentation of parameter declarations"
+msgstr "-i unterdrücke die Einrückung von Parameterdeklarationen"
+
+#: help.h:87 help.h:113
+msgid "-o suppress separation of declarations and statements"
+msgstr "-o unterdrücke die Trennung von Deklarationen und Statements"
+
+#: help.h:88 help.h:114
+msgid "-x omit indices, section names, table of contents"
+msgstr "-x verzichte auf Indexe, Abschnittnamen und Inhaltsverzeichnis"
+
+#: help.h:89
+msgid "+lX use macros for language X as of Xcwebmac.tex"
+msgstr "+lX benutze Macros für Sprache X aus Xcwebmac.tex"
+
+#: help.h:98
+msgid ""
+"Usage: ctwill [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]"
+msgstr ""
+"Aufruf: ctwill [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]"
+
+#: help.h:99
+msgid " Weave WEBFILE with CHANGEFILE into a TeX document with mini-indexes."
+msgstr " Verwebe WEBFILE mit CHANGEFILE in ein TeX Dokument mit Miniindexen."
+
+#: help.h:115
+msgid "+P \\input ctproofmac.tex instead of ctwimac.tex"
+msgstr "+P \\input ctproofmac.tex an Stelle von ctwimac.tex"
+
+#: help.h:116
+msgid "+/-lX use macros for language X as of Xct{wi|proof}mac.tex"
+msgstr "+/-lX benutze Macros für Sprache X aus Xct{wi|proof}mac.tex"
diff --git a/Build/source/texk/web2c/cwebdir/po/it/cweb.po b/Build/source/texk/web2c/cwebdir/po/it/cweb.po
new file mode 100644
index 00000000000..7001ea086b1
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/it/cweb.po
@@ -0,0 +1,679 @@
+# International version of CWEB (CWEBbin, TeXLive).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer/github.io>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:25+0100\n"
+"PO-Revision-Date: 2021-02-06 15:57+0100\n"
+"Last-Translator: Andreas Scherer <andreas_github@freenet.de>\n"
+"Language-Team: Italian\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: comm-i18n.ch:182
+msgid ""
+"\n"
+"! Ambiguous prefix: matches <"
+msgstr ""
+"\n"
+"! Prefisso ambiguo: corrispondenze trovate <"
+
+#: cweav-i18n.ch:295
+msgid ""
+"\n"
+"! C text in section name didn't end: <"
+msgstr ""
+"\n"
+"! Testo C nel nome di una sezione, non terminato: <"
+
+#: cweav-i18n.ch:287
+msgid ""
+"\n"
+"! Illegal control code in section name: <"
+msgstr ""
+"\n"
+"! Codice di controllo illegale nella sezione: <"
+
+#: cweav-i18n.ch:157
+#, c-format
+msgid ""
+"\n"
+"! Line had to be broken (output l. %d):\n"
+msgstr ""
+"\n"
+"! La linea deve essere spezzata (output l. %d):\n"
+
+#: cweav-i18n.ch:141
+msgid ""
+"\n"
+"! Never defined: <"
+msgstr ""
+"\n"
+"! Mai definito: <"
+
+#: cweav-i18n.ch:148
+msgid ""
+"\n"
+"! Never used: <"
+msgstr ""
+"\n"
+"! Mai usato: <"
+
+#: comm-i18n.ch:202
+msgid ""
+"\n"
+"! New name extends <"
+msgstr ""
+"\n"
+"! Il nuovo nome estende <"
+
+#: comm-i18n.ch:196
+msgid ""
+"\n"
+"! New name is a prefix of <"
+msgstr ""
+"\n"
+"! Il nuovo nome è un prefisso per <"
+
+#: ctang-i18n.ch:57
+msgid ""
+"\n"
+"! No program text was specified."
+msgstr ""
+"\n"
+"! Nessun testo di programma è stato specificato."
+
+#: ctang-i18n.ch:41
+msgid ""
+"\n"
+"! Not present: <"
+msgstr ""
+"\n"
+"! Non presente: <"
+
+#: comm-i18n.ch:208
+msgid ""
+"\n"
+"! Section name incompatible with <"
+msgstr ""
+"\n"
+"! Nome sezione incompatibile con <"
+
+#: ctang-i18n.ch:167 cweav-i18n.ch:67
+msgid ""
+"\n"
+"! Section name too long: "
+msgstr ""
+"\n"
+"! Nome sezione troppo lungo: "
+
+#: comm-i18n.ch:254
+#, c-format
+msgid ""
+"\n"
+"! Sorry, %s capacity exceeded"
+msgstr ""
+"\n"
+"! Spiacente, %s capacità superata"
+
+#: ctang-i18n.ch:125 cweav-i18n.ch:45
+msgid ""
+"\n"
+"! String too long: "
+msgstr ""
+"\n"
+"! Stringa troppo lunga: "
+
+#: cweav-i18n.ch:239
+#, c-format
+msgid ""
+"\n"
+"Irreducible scrap sequence in section %d:"
+msgstr ""
+"\n"
+"Sequenza scrap irriducibile nella sezione %d:"
+
+#: ctang-i18n.ch:292 cweav-i18n.ch:431
+msgid ""
+"\n"
+"Memory usage statistics:"
+msgstr ""
+"\n"
+"Statistiche uso memoria:"
+
+#: cweav-i18n.ch:247
+#, c-format
+msgid ""
+"\n"
+"Tracing after l. %d:\n"
+msgstr ""
+"\n"
+"Tracing dopo l. %d:\n"
+
+#: cweav-i18n.ch:377
+msgid ""
+"\n"
+"Writing the index..."
+msgstr ""
+"\n"
+"Scrittura dell'indice..."
+
+#: ctang-i18n.ch:63
+#, c-format
+msgid ""
+"\n"
+"Writing the output file (%s):"
+msgstr ""
+"\n"
+"Scrittura del file di output (%s):"
+
+#: cweav-i18n.ch:317
+msgid ""
+"\n"
+"Writing the output file..."
+msgstr ""
+"\n"
+"Scrittura file di output..."
+
+#: ctang-i18n.ch:69
+msgid ""
+"\n"
+"Writing the output files:"
+msgstr ""
+"\n"
+"Scrittura dei file di output:"
+
+#: ctang-i18n.ch:217
+msgid "! @d, @f and @c are ignored in C text"
+msgstr "! @d, @f e @c sono ignorati nella parte C"
+
+#: comm-i18n.ch:60
+msgid "! CWEB file ended during a change"
+msgstr "! File CWEB terminato durante un change"
+
+#: cweav-twill.ch:1033
+msgid "! Cannot open aux output file "
+msgstr "! Non posso aprire il file di aux output "
+
+#: comm-i18n.ch:88
+msgid "! Cannot open change file "
+msgstr "! Non posso aprire il change file "
+
+#: comm-i18n.ch:118
+msgid "! Cannot open include file"
+msgstr "! Non posso aprire il file include"
+
+#: cweav-i18n.ch:383
+msgid "! Cannot open index file "
+msgstr "! Non posso aprire il file per l'indice "
+
+#: comm-i18n.ch:82
+msgid "! Cannot open input file "
+msgstr "! Non posso aprire il file di input "
+
+#: comm-i18n.ch:300 comm-i18n.ch:308 ctang-i18n.ch:83 ctang-i18n.ch:307
+#: cweav-i18n.ch:457
+msgid "! Cannot open output file "
+msgstr "! Non posso aprire il file di output "
+
+#: cweav-i18n.ch:389
+msgid "! Cannot open section file "
+msgstr "! Non posso aprire il section file "
+
+#: comm-i18n.ch:46
+msgid "! Change file ended after @x"
+msgstr "! Change file terminato dopo @x"
+
+#: comm-i18n.ch:54
+msgid "! Change file ended before @y"
+msgstr "! Change file terminato prima di @y"
+
+#: comm-i18n.ch:126
+msgid "! Change file ended without @z"
+msgstr "! Change file terminato senza un @z"
+
+#: comm-i18n.ch:140
+msgid "! Change file entry did not match"
+msgstr "! C'è una voce nel change file che non corrisponde"
+
+#: cweav-i18n.ch:95
+msgid "! Control codes are forbidden in control text"
+msgstr "! I codici di controllo sono vietati nel \"control text\""
+
+#: cweav-i18n.ch:81
+msgid "! Control codes are forbidden in section name"
+msgstr ""
+"! I codici di controllo sono vietati all'interno dei nomi delle sezioni"
+
+#: cweav-i18n.ch:89
+msgid "! Control text didn't end"
+msgstr "! Control text non terminato"
+
+#: ctang-i18n.ch:249
+msgid "! Definition flushed, must start with identifier"
+msgstr "! Definizione liberata (flushed), iniziare con un identificatore"
+
+#: ctang-i18n.ch:147
+msgid "! Double @ should be used in ASCII constant"
+msgstr "! I doppi @ dovrebbero essere usati nelle costanti ASCII"
+
+#: ctang-i18n.ch:139 ctang-i18n.ch:257
+msgid "! Double @ should be used in control text"
+msgstr "! I doppi @ dovrebbero essere usati nel \"control text\""
+
+#: ctang-i18n.ch:263 cweav-i18n.ch:165
+msgid "! Double @ should be used in limbo"
+msgstr "! I doppi @ dovrebbero essere usati nel limbo"
+
+#: ctang-i18n.ch:233
+msgid "! Double @ should be used in string"
+msgstr "! I doppi @ dovrebbero essere usati nelle stringhe"
+
+#: cweav-i18n.ch:263
+msgid "! Double @ should be used in strings"
+msgstr "! I doppi @ dovrebbero essere usati nelle stringhe"
+
+#: cweav-i18n.ch:193
+msgid "! Extra } in comment"
+msgstr "! Extra } nel commento"
+
+#: comm-i18n.ch:300
+msgid "! Filename too long\n"
+msgstr "! Nome file troppo lungo\n"
+
+#: cweav-twill.ch:550
+msgid "! Identifier in meaning should be followed by space"
+msgstr "! Identifier in meaning should be followed by space"
+
+#: cweav-i18n.ch:209
+msgid "! Illegal use of @ in comment"
+msgstr "! Uso illegale di @ nel commento"
+
+#: cweav-i18n.ch:353
+msgid "! Improper format definition"
+msgstr "! Definizione di formato impropria"
+
+#: ctang-i18n.ch:271
+msgid "! Improper hex number following @l"
+msgstr "! Un numero decimale improprio segue @l"
+
+#: cweav-i18n.ch:339 cweav-i18n.ch:345
+msgid "! Improper macro definition"
+msgstr "! Definizione di macro impropria"
+
+#: comm-i18n.ch:96
+msgid "! Include file name not given"
+msgstr "! Nome del file include assente"
+
+#: comm-i18n.ch:110
+msgid "! Include file name too long"
+msgstr "! Nome file include troppo lungo"
+
+#: comm-i18n.ch:320
+msgid "! Include path too long"
+msgstr "! Path include troppo lungo"
+
+#: ctang-i18n.ch:99 cweav-i18n.ch:181
+msgid "! Input ended in mid-comment"
+msgstr "! Input terminato nel commento intermedio"
+
+#: ctang-i18n.ch:119 cweav-i18n.ch:39
+msgid "! Input ended in middle of string"
+msgstr "! Input terminato nel mezzo di una stringa"
+
+#: ctang-i18n.ch:161 cweav-i18n.ch:61
+msgid "! Input ended in section name"
+msgstr "! Input terminato all'interno del nome di una sezione"
+
+#: comm-i18n.ch:30
+msgid "! Input line too long"
+msgstr "! Linea in input troppo lunga"
+
+#: cweav-twill.ch:550
+msgid "! Location in meaning should be followed by space"
+msgstr "! Location in meaning should be followed by space"
+
+#: ctang-i18n.ch:211
+msgid "! Misplaced @h"
+msgstr "! Mal riposto @h"
+
+#: cweav-i18n.ch:271
+msgid "! Missing '|' after C text"
+msgstr "! Omesso `|' dopo il testo in C"
+
+#: comm-i18n.ch:38
+msgid "! Missing @x in change file"
+msgstr "! Omesso @x nel change file"
+
+#: ctang-i18n.ch:225
+msgid "! Missing `@ ' before a named section"
+msgstr "! Omesso `@ ' prima di una sezione con nome"
+
+#: cweav-i18n.ch:127
+msgid "! Missing left identifier of @s"
+msgstr "! Omesso identificatore sinistro di @s"
+
+#: cweav-i18n.ch:133
+msgid "! Missing right identifier of @s"
+msgstr "! Omesso identificatore destro di @s"
+
+#: cweav-i18n.ch:187 cweav-i18n.ch:201
+msgid "! Missing } in comment"
+msgstr "! Omesso } nel commento"
+
+#: ctang-i18n.ch:181
+msgid "! Nesting of section names not allowed"
+msgstr "! Nomi di sezioni l'uno dentro l'altro non consentiti"
+
+#: cweav-twill.ch:1029
+msgid "! Only @$ is allowed in aux and bux files"
+msgstr "! Only @$ is allowed in aux and bux files"
+
+#: ctang-i18n.ch:277
+msgid "! Replacement string in @l too long"
+msgstr "! Stringa sostitutiva in @l troppo lunga"
+
+#: ctang-i18n.ch:175 cweav-i18n.ch:75
+msgid "! Section name didn't end"
+msgstr "! Nome sezione non terminato"
+
+#: ctang-i18n.ch:99
+msgid "! Section name ended in mid-comment"
+msgstr "! Nome sezione terminato all'interno del commento intermedio"
+
+#: ctang-i18n.ch:113 ctang-i18n.ch:153 cweav-i18n.ch:33
+msgid "! String didn't end"
+msgstr "! Stringa non terminata"
+
+#: cweav-i18n.ch:325
+msgid "! TeX string should be in C text only"
+msgstr "! Stringa TeX dovrebbe stare solo nel testo in C"
+
+#: comm-i18n.ch:262 comm-i18n.hch:33
+msgid "! This can't happen: "
+msgstr "! Questo non può avvenire: "
+
+#: cweav-twill.ch:316
+msgid "! Title name didn't end"
+msgstr "! Nome titolo non terminato"
+
+#: cweav-twill.ch:314
+msgid "! Title should be enclosed in braces or doublequotes"
+msgstr "! Title should be enclosed in braces or doublequotes"
+
+#: comm-i18n.ch:102
+msgid "! Too many nested includes"
+msgstr "! Troppi include annidati"
+
+#: ctang-i18n.ch:241
+msgid "! Unrecognized escape sequence"
+msgstr "! Sequenza di escape non riconosciuta"
+
+#: comm-i18n.ch:283
+msgid ""
+"! Usage: ctangle [options] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+msgstr ""
+"! Uso: ctangle [Opzioni] webfile[.w] [{changefile[.ch]|-} [outfile[.c]]]\n"
+"Opzioni (+ attiva, - disattiva, default indicato tra parentesi quadre):\n"
+"b [+] stampa una riga di titoli\n"
+"h [+] stampa un messaggio di \"buon fine\"\n"
+"p [+] mostra andamento elaborazione\n"
+"s [-] mostra statistiche\n"
+"t [+] compare temporary output for changes\n"
+
+#: comm-i18n.ch:287
+msgid ""
+"! Usage: cweave [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+msgstr ""
+"! Uso: cweave [Opzioni] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+"Opzioni (+ attiva, - disattiva, default indicato tra parentesi quadre):\n"
+"b [+] stampa una riga di titoli\n"
+"h [+] stampa un messaggio di \"buon fine\"\n"
+"p [+] mostra andamento elaborazione\n"
+"e [+] C material in \\PB parentesi\n"
+"f [+] forza i line break\n"
+"i [+] rientranza delle dichiarazioni\n"
+"o [+] separa dichiarazioni e statement\n"
+"x [+] include indici\n"
+"lX [] usa macro in lingua X contenute in Xcwebmac.tex\n"
+"s [-] mostra statistiche\n"
+"t [+] compare temporary output for changes\n"
+
+#: comm-i18n.ch:290
+msgid ""
+"! Usage: ctwill [options] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+msgstr ""
+"! Uso: ctwill [Opzioni] webfile[.w] [{changefile[.ch]|-} [outfile[.tex]]]\n"
+"Opzioni (+ attiva, - disattiva, default indicato tra parentesi quadre):\n"
+"b [+] stampa una riga di titoli\n"
+"h [+] stampa un messaggio di \"buon fine\"\n"
+"p [+] mostra andamento elaborazione\n"
+"e [+] C material in \\PB parentesi\n"
+"f [+] forza i line break\n"
+"i [+] rientranza delle dichiarazioni\n"
+"o [+] separa dichiarazioni e statement\n"
+"x [+] include indici\n"
+"P [-] include 'proofmac.tex' invece di 'ctwimac.tex'\n"
+"lX [] usa macro in lingua X contenute in X{ctwi|proof}mac.tex\n"
+"s [-] mostra statistiche\n"
+"t [+] compare temporary output for changes\n"
+
+#: ctang-i18n.ch:131 cweav-i18n.ch:53 cweav-i18n.ch:119
+msgid "! Use @l in limbo only"
+msgstr "! Usare @l solo nel limbo"
+
+#: ctang-i18n.ch:189 cweav-i18n.ch:103
+msgid "! Verbatim string didn't end"
+msgstr "! Stringa verbatim non terminata"
+
+#: comm-i18n.ch:68
+msgid "! Where is the matching @y?"
+msgstr "! Dov'è il corrispondente @y?"
+
+#: comm-i18n.ch:132
+msgid "! Where is the matching @z?"
+msgstr "! Dov'è il corrispondente @z?"
+
+#: cweav-i18n.ch:369
+msgid "! You can't do that in C text"
+msgstr "! Non puoi fare quello nella parte in C"
+
+#: cweav-i18n.ch:331
+msgid "! You can't do that in TeX text"
+msgstr "! Non puoi fare quello nel testo in TeX"
+
+#: cweav-i18n.ch:361
+msgid "! You need an = sign after the section name"
+msgstr "! È necessario un segno di = dopo il nome della sezione"
+
+#: ctang-i18n.ch:297 cweav-i18n.ch:437
+#, c-format
+msgid "%ld bytes (out of %ld)\n"
+msgstr "%ld byte (fuori da %ld)\n"
+
+#: cweav-i18n.ch:435
+#, c-format
+msgid "%ld cross-references (out of %ld)\n"
+msgstr "%ld riferimenti incrociati (fuori da %ld)\n"
+
+#: cweav-i18n.ch:446 cweav-i18n.ch:449
+#, c-format
+msgid "%ld levels (out of %ld)\n"
+msgstr "%ld livelli (fuori da %ld)\n"
+
+#: ctang-i18n.ch:293 cweav-i18n.ch:433
+#, c-format
+msgid "%ld names (out of %ld)\n"
+msgstr "%ld nomi (fuori da %ld)\n"
+
+#: ctang-i18n.ch:295
+#, c-format
+msgid "%ld replacement texts (out of %ld)\n"
+msgstr "%ld replacement text (fuori da %ld)\n"
+
+#: cweav-i18n.ch:440
+#, c-format
+msgid "%ld scraps (out of %ld)\n"
+msgstr "%ld scrap (fuori da %ld)\n"
+
+#: cweav-twill.ch:1346
+#, c-format
+msgid "%ld temp meanings (out of %ld)\n"
+msgstr "%ld temp meanings (fuori da %ld)\n"
+
+#: cweav-i18n.ch:442
+#, c-format
+msgid "%ld texts (out of %ld)\n"
+msgstr "%ld text (fuori da %ld)\n"
+
+#: ctang-i18n.ch:299 cweav-i18n.ch:444
+#, c-format
+msgid "%ld tokens (out of %ld)\n"
+msgstr "%ld token (fuori da %ld)\n"
+
+#: comm-i18n.ch:242
+msgid "(Did you see the warning message above?)"
+msgstr "(Hai visto i messaggi di warning sopra?)"
+
+#: comm-i18n.ch:240
+msgid "(No errors were found.)"
+msgstr "(Nessun errore trovato.)"
+
+#: comm-i18n.ch:244
+msgid "(Pardon me, but I think I spotted something wrong.)"
+msgstr "(Scusa, ma credo che sia avvenuto qualcosa di errato.)"
+
+#: comm-i18n.ch:246
+msgid "(That was a fatal error, my friend.)"
+msgstr "(Caro amico, si è verificato un errore importante.)"
+
+#: comm-i18n.ch:224
+#, c-format
+msgid ". (l. %d of change file)\n"
+msgstr ". (l. %d del change file)\n"
+
+#: comm-i18n.ch:226
+#, c-format
+msgid ". (l. %d of include file %s)\n"
+msgstr ". (l. %d del file include %s)\n"
+
+#: comm-i18n.ch:225
+#, c-format
+msgid ". (l. %d)\n"
+msgstr ". (l. %d)\n"
+
+#: comm-i18n.ch:188
+msgid ""
+">\n"
+" and <"
+msgstr ""
+">\n"
+" e <"
+
+#: comm-i18n.ch:214
+msgid ""
+">,\n"
+" which abbreviates <"
+msgstr ""
+">,\n"
+" che abbrevia <"
+
+#: ctang-i18n.ch:75 cweav-i18n.ch:395
+msgid "Done."
+msgstr "Fatto."
+
+#: cweav-i18n.ch:439
+msgid "Parsing:"
+msgstr "Analisi:"
+
+#: cweav-i18n.ch:448
+msgid "Sorting:"
+msgstr "Ordinamento:"
+
+#: ctang-i18n.ch:17
+msgid "This is CTANGLE (Version 4.2 [CWEBbin 2021])"
+msgstr "Questo è CTANGLE (Versione 4.2 [CWEBbin 2021])"
+
+#: cweav-i18n.ch:17
+msgid "This is CWEAVE (Version 4.2 [CWEBbin 2021])"
+msgstr "Questo è CWEAVE (Versione 4.2 [CWEBbin 2021])"
+
+#: cweav-twill.ch:68
+msgid "This is CTWILL (Version 4.2 [CWEBbin 2021])"
+msgstr "Questo è CTWILL (Versione 4.2 [CWEBbin 2021])"
+
+#: cweav-i18n.ch:301 cweav-i18n.ch:309
+msgid "buffer"
+msgstr "buffer"
+
+#: comm-i18n.ch:149 comm-i18n.ch:159 comm-i18n.ch:174
+msgid "byte memory"
+msgstr "byte di memoria"
+
+#: cweav-i18n.ch:25
+msgid "cross-reference"
+msgstr "referimento incrociato"
+
+#: cweav-twill.ch:822
+msgid "find type"
+msgstr "find type"
+
+#: cweav-twill.ch:761
+msgid "inner"
+msgstr "inner"
+
+#: ctang-i18n.ch:91
+msgid "macro defs have strange char"
+msgstr "definizione macro contiene uno strano carattere"
+
+#: comm-i18n.ch:150 comm-i18n.ch:160 comm-i18n.ch:168
+msgid "name"
+msgstr "nome"
+
+#: comm-i18n.ch:74
+msgid "of the preceding lines failed to match"
+msgstr "delle linee precedenti, corrispondenza non trovata"
+
+#: ctang-i18n.ch:49
+msgid "output files"
+msgstr "files di output"
+
+#: cweav-i18n.ch:255
+msgid "scrap/token/text"
+msgstr "scrap/token/text"
+
+#: cweav-i18n.ch:111
+msgid "section number"
+msgstr "numero sezione"
+
+#: cweav-i18n.ch:403
+msgid "sorting"
+msgstr "ordinamento"
+
+#: ctang-i18n.ch:33 cweav-i18n.ch:279
+msgid "stack"
+msgstr "stack"
+
+#: cweav-twill.ch:570
+msgid "temp meanings"
+msgstr "temp meanings"
+
+#: ctang-i18n.ch:203 cweav-i18n.ch:223
+msgid "text"
+msgstr "text"
+
+#: cweav-twill.ch:317
+msgid "titles"
+msgstr "titles"
+
+#: ctang-i18n.ch:25 ctang-i18n.ch:197 cweav-i18n.ch:173 cweav-i18n.ch:217
+#: cweav-i18n.ch:231
+msgid "token"
+msgstr "token"
diff --git a/Build/source/texk/web2c/cwebdir/po/web2c-help.pot b/Build/source/texk/web2c/cwebdir/po/web2c-help.pot
new file mode 100644
index 00000000000..87444595f4a
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/po/web2c-help.pot
@@ -0,0 +1,137 @@
+# International version of CWEB (CWEBbin, TeXLive).
+# Copyright (C) 2021 Andreas Scherer et al.
+# This file is distributed under the same license as the CWEB package.
+# Andreas Scherer <https://ascherer.github.io>, 2021.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: CWEBbin 2021\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-06 15:10+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: help.h:52
+msgid ""
+"Usage: ctangle [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.c]]]"
+msgstr ""
+
+#: help.h:53
+msgid " Tangle WEBFILE with CHANGEFILE into a C/C++ program."
+msgstr ""
+
+#: help.h:54 help.h:74 help.h:100
+msgid " Default CHANGEFILE is /dev/null;"
+msgstr ""
+
+#: help.h:55
+msgid " C output goes to the basename of WEBFILE extended with `.c'"
+msgstr ""
+
+#: help.h:56 help.h:76 help.h:102
+msgid " unless otherwise specified by OUTFILE; in this case, '-' specifies"
+msgstr ""
+
+#: help.h:57 help.h:77 help.h:103
+msgid " a null CHANGEFILE."
+msgstr ""
+
+#: help.h:59 help.h:79 help.h:105
+msgid "+b print banner line on terminal"
+msgstr ""
+
+#: help.h:64 help.h:85 help.h:112
+msgid "-dN set 'kpathsea_debug' to N (0..127)"
+msgstr ""
+
+#: help.h:60 help.h:80 help.h:106
+msgid "+h print success message on completion"
+msgstr ""
+
+#: help.h:61 help.h:81 help.h:107
+msgid "+p print progress report messages"
+msgstr ""
+
+#: help.h:62 help.h:82 help.h:108
+msgid "+/-q shortcut for '-bhp'; also '--quiet' (default)"
+msgstr ""
+
+#: help.h:63 help.h:83 help.h:109
+msgid "+/-v shortcut for '+bhp'; also '--verbose'"
+msgstr ""
+
+#: help.h:64 help.h:90 help.h:117
+msgid "+s print usage statistics"
+msgstr ""
+
+#: help.h:65 help.h:91 help.h:118
+msgid "-t ignore temporary output irrespective of changes"
+msgstr ""
+
+#: help.h:66 help.h:92 help.h:119
+msgid "--help display this help and exit"
+msgstr ""
+
+#: help.h:67 help.h:93 help.h:120
+msgid "--version output version information and exit"
+msgstr ""
+
+#: help.h:72
+msgid ""
+"Usage: cweave [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]"
+msgstr ""
+
+#: help.h:73
+msgid " Weave WEBFILE with CHANGEFILE into a TeX document."
+msgstr ""
+
+#: help.h:75 help.h:101
+msgid " TeX output goes to the basename of WEBFILE extended with `.tex'"
+msgstr ""
+
+#: help.h:84 help.h:110
+msgid "-e do not enclose C material in \\PB{...}"
+msgstr ""
+
+#: help.h:85 help.h:111
+msgid "-f do not force a newline after every C statement in output"
+msgstr ""
+
+#: help.h:86 help.h:112
+msgid "-i suppress indentation of parameter declarations"
+msgstr ""
+
+#: help.h:87 help.h:113
+msgid "-o suppress separation of declarations and statements"
+msgstr ""
+
+#: help.h:88 help.h:114
+msgid "-x omit indices, section names, table of contents"
+msgstr ""
+
+#: help.h:89
+msgid "+lX use macros for language X as of Xcwebmac.tex"
+msgstr ""
+
+#: help.h:98
+msgid ""
+"Usage: ctwill [OPTIONS] WEBFILE[.w] [{CHANGEFILE[.ch]|-} [OUTFILE[.tex]]]"
+msgstr ""
+
+#: help.h:99
+msgid " Weave WEBFILE with CHANGEFILE into a TeX document with mini-indexes."
+msgstr ""
+
+#: help.h:115
+msgid "+P \\input ctproofmac.tex instead of ctwimac.tex"
+msgstr ""
+
+#: help.h:116
+msgid "+/-lX use macros for language X as of Xct{wi|proof}mac.tex"
+msgstr ""
diff --git a/Build/source/texk/web2c/cwebdir/prod-twill.w b/Build/source/texk/web2c/cwebdir/prod-twill.w
new file mode 100644
index 00000000000..ae2ab30b383
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/prod-twill.w
@@ -0,0 +1,303 @@
+% This file is part of CTWILL, a modification of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 3.6 --- May 2000
+%
+@ 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 |mathness|. In this way we never get double {\tt\$\$}.
+
+% The following kludge is needed because \newcount, \newdimen, and \+
+% are "\outer" control sequences that cannot be used in skipped text!
+\fi \newcount\prodno \newdimen\midcol \let\+\relax \ifon
+
+\def\v{\char'174}
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+
+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 |make_underlined|. Two asterisks$^{**}$ means that both
+|make_underlined| and |make_reserved| are called; that is, the
+identifier's ilk becomes |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 |indent|, |outdent|, |backup| and
+|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
+\prodno=0 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}
+|insert| & \altt\\{any} {\\{any} \\{any}} {\\{any} \\{any} \\{any}}
+& stmt; \ /$\ast\,$comment$\,*$/\cr
+\+& |exp| \altt|lbrace| |int_like| |decl|
+ & |fn_decl| \altt|lbrace| |int_like| |decl|
+ \hfill $F=E^*\,|in|\,|in|$ & \malt {\\{main}()$\{$}
+ {\\{main}$(\\{ac},\\{av})$ \&{int} \\{ac};} \cr
+\+& |exp| |unop| & |exp| & |x++|\cr
+\+& |exp| \alt |binop| |ubinop| |exp| & |exp| & \malt {|x/y|} {|x+y|} \cr
+\+& |exp| |comma| |exp| & |exp| \hfill $EC\,|opt|9\,E$& |f(x,y)|\cr
+\+& |exp| \alt {|lpar| |rpar|} |cast| |colon| &
+ |exp| \alt {|lpar| |rpar|} |cast| |base| &
+ \malt \&C|()|: {\&C|int i)|:} \cr
+\+& |exp| |semi| & |stmt| & |x=0;|\cr
+\+& |exp| |colon| & |tag| \hfill $E^*C$ & |found:|\cr
+\+& |exp| |rbrace| & |stmt| |rbrace| & end of \&{enum} list\cr
+\+& |exp| \alt {|lpar| |rpar|} |cast| \alt|const_like| |case_like| &
+ |exp| \alt {|lpar| |rpar|} |cast| \hfill
+ \alt $R=R\.\ C$ $C_1=C_1\.\ C_2$ &
+ \malt {|f() const|} {|f(int) throw|} \cr
+\+& |exp| \alt |exp| |cast| & |exp| & |time()|\cr
+\+& |lpar| \alt |exp| |ubinop| |rpar| & |exp| & \malt{|(x)|} {|(*)|} \cr
+\+& |lpar| |rpar| & |exp| \hfill $L\.{\\,}R$ & functions, declarations\cr
+\+& |lpar| \altt |decl_head| |int_like| |cast| |rpar| & |cast| & |(char*)|\cr
+\+& |lpar| \altt |decl_head| |int_like| |exp| |comma| & |lpar| \hfill
+ $L$\,\altt $D$ $I$ $E$ $C$\,|opt|9 & |(int,|\cr
+\+& |lpar| \alt |stmt| |decl| & |lpar| \hfill \alt {$LS\.\ $} {$LD\.\ $} &
+ \malt {|(k=5;|} {|(int k=5;|} \cr
+\+& |unop| \alt |exp| |int_like| & |exp| &
+ \malt |!x| |~|\&C \cr
+\+& |ubinop| |cast| |rpar| & |cast| |rpar| \hfill
+ $C=\.\{U\.\}C$ & |*|\&{CPtr}) \cr
+\+& |ubinop| \alt|exp| |int_like| & \alt|exp| |int_like| \hfill
+ \.\{$U$\.\}\alt$E$ $I$ & \malt |*x| |*|\&{CPtr} \cr
+\+& |ubinop| |binop| & |binop| \hfill $|math_rel|\,U\.\{B\.\}\.\}$ & |*=|\cr
+\+& |binop| |binop| & |binop| \hfill
+ $|math_rel|\,\.\{B_1\.\}\.\{B_2\.\}\.\}$ & |>>=|\cr
+\+& |cast| \alt |lpar| |exp| & \alt |lpar| |exp| \hfill
+ \alt $CL$ $C\.\ E$ & \malt |(double)(x+2)| |(double)x| \cr
+\+& |cast| |semi| & |exp| |semi| & |(int);|\cr
+\+& |sizeof_like| |cast| & |exp| & |sizeof (double)|\cr
+\+& |sizeof_like| |exp| & |exp| \hfill $S\.\ E$ & |sizeof x|\cr
+\+& |int_like| \alt|int_like| |struct_like| &
+ \alt|int_like| |struct_like| \hfill $I\.\ $\alt $I$ $S$
+ \unskip& |extern char|\cr
+\+& |int_like| |exp| \alt|raw_int| |struct_like| &
+ |int_like| \alt|raw_int| |struct_like| & |extern "Ada" int|\cr
+\+& |int_like| \altt|exp| |ubinop| |colon| &
+ |decl_head| \altt|exp| |ubinop| |colon| \hfill
+ $D=I$\.\ & \maltt|int x| |int*x| |unsigned:| \cr
+\+& |int_like| \alt |semi| |binop| & |decl_head| \alt |semi| |binop| &
+ \malt |int x;| {\&{int} $f(\&{int}=4)$} \cr
+\+& |public_like| |colon| & |tag| & \&{private}:\cr
+\+& |public_like| & |int_like| & \&{private}\cr
+\+& |colcol| \alt|exp| |int_like| & \alt|exp| |int_like| \hfill
+ |qualifier| $C$ \alt$E$ $I$ & \&C\DC$x$\cr
+\+& |colcol| |colcol| & |colcol| & \&C\DC\&B\DC\cr
+\+& |decl_head| |comma| & |decl_head| \hfill $DC\.\ $ & |int x,|\cr
+\+& |decl_head| |ubinop| & |decl_head| \hfill $D\.\{U\.\}$ & |int *|\cr
+\+\dagit& |decl_head| |exp| & |decl_head| \hfill $DE^*$ & |int x|\cr
+\+& |decl_head| \alt|binop| |colon| |exp| \altt|comma| |semi| |rpar| &
+ |decl_head| \altt|comma| |semi| |rpar| \hfill
+ $D=D$\alt $B$ $C$ \unskip$E$ & \malt {\&{int} $f(\&{int}\ x=2)$} |int b:1| \cr
+\+& |decl_head| |cast| & |decl_head| & |int f(int)|\cr
+\+& |decl_head| \altt|int_like| |lbrace| |decl| & |fn_decl|
+ \altt|int_like| |lbrace| |decl| \hfill $F=D\,|in|\,|in|$
+ & |long time () {|\cr
+\+& |decl_head| |semi| & |decl| & |int n;|\cr
+\+& |decl| |decl| & |decl| \hfill $D_1\,|force|\,D_2$ & |int n;double x;|\cr
+\+& |decl| \alt|stmt| |function| & \alt|stmt| |function|
+ \hfill $D\,|big_force|\,$\alt $S$ $F$ \unskip& \&{extern} $n$;
+ \\{main} ()|{}|\cr
+\+& |base| \alt |int_like| |exp| |comma| & |base| \hfill
+ $B$\.\ \alt $I$ $E$ \unskip$C$\,|opt|9
+ & \malt {: \&{public} \&A,} {: $i(5)$,} \cr
+\+& |base| \alt |int_like| |exp| |lbrace| & |lbrace| \hfill
+ $B$\.\ \alt $I$ $E$ \unskip\.\ $L$ & \&D : \&{public} \&A $\{$\cr
+\+& |struct_like| |lbrace| & |struct_head| \hfill $S\.\ L$ & |struct {|\cr
+\+& |struct_like| \alt|exp| |int_like| |semi| & |decl_head| |semi|
+ \hfill $S\.\ $\alt $E^{**}$ $I^{**}$ & \&{struct} \&{forward};\cr
+\+& |struct_like| \alt|exp| |int_like| |lbrace| & |struct_head| \hfill
+ $S\.\ $\alt $E^{**}$ $I^{**}$ \unskip $\.\ L$ &
+ \&{struct} \&{name\_info} $\{$\cr
+\+& |struct_like| \alt|exp| |int_like| |colon| &
+ |struct_like| \alt|exp| |int_like| |base| & |class| \&C :\cr
+\+\dagit& |struct_like| \alt|exp| |int_like| & |int_like|
+ \hfill $S\.\ $\alt$E$ $I$ & \&{struct} \&{name\_info} $z$;\cr
+\+& |struct_head| \altt|decl| |stmt| |function| |rbrace| & |int_like|\hfill
+ $S\,\\{in}\,|force|$\altt$D$ $S$ $F$ $\\{out}\,|force|\,R$ &
+ |struct {| declaration |}|\cr
+\+& |struct_head| |rbrace| & |int_like|\hfill $S\.{\\,}R$ & |class C{}|\cr
+\+& |fn_decl| |decl| & |fn_decl| \hfill $F\,|force|\,D$
+ & $f(z)$ \&{double} $z$; \cr
+\+& |fn_decl| |stmt| & |function| \hfill $F\,|out|\,|out|\,|force|\,S$
+ & \\{main}() {\dots}\cr
+\+& |function| \altt|stmt| |decl| |function| & \altt |stmt| |decl| |function|
+ \hfill $F\,|big_force|\,$\altt $S$ $D$ $F$ & outer block\cr
+\+& |lbrace| |rbrace| & |stmt| \hfill $L\.{\\,}R$ & empty statement\cr
+\advance\midcol35pt
+\+& |lbrace| \altt|stmt| |decl| |function| |rbrace| & |stmt| \hfill
+ $|force|\,L\,\\{in}\,|force|\,S\,
+ |force|\,\\{back}\,R\,\\{out}\,|force|$ & compound statement\cr
+\advance\midcol-20pt
+\+& |lbrace| |exp| [|comma|] |rbrace| & |exp| & initializer\cr
+\+& |if_like| |exp| & |if_clause| \hfill $I\.{\ }E$ & |if (z)|\cr
+\+& |else_like| |colon| & |else_like| |base| & \&{try} :\cr
+\+& |else_like| |lbrace| & |else_head| |lbrace| & \&{else} $\{$\cr
+\+& |else_like| |stmt| & |stmt| \hfill
+ $|force|\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|$ & |else x=0;|\cr
+\+& |else_head| \alt|stmt| |exp| & |stmt| \hfill
+ $|force|\,E\,\\{bsp}\,|noop|\,|cancel|\,S\,\\{bsp}$ & |else{x=0;}|\cr
+\+& |if_clause| |lbrace| & |if_head| |lbrace| & |if (x) {|\cr
+\+& |if_clause| |stmt| |else_like| |if_like| & |if_like| \hfill
+ $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E\,\.\ I$ &
+ |if (x) y; else if|\cr
+\+& |if_clause| |stmt| |else_like| & |else_like| \hfill
+ $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E$ &
+ |if (x) y; else|\cr
+\+& |if_clause| |stmt| & |else_like| |stmt| & |if (x)|\cr
+\+& |if_head| \alt|stmt| |exp| |else_like| |if_like| & |if_like| \hfill
+ $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E\,\.\ I$ &
+ |if (x){y;}else if|\cr
+\+& |if_head| \alt|stmt| |exp| |else_like| & |else_like| \hfill
+ $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E$ &
+ |if (x){y;}else|\cr
+\+& |if_head| \alt|stmt| |exp| & |else_head| \alt|stmt| |exp| & |if (x){y;}|\cr
+\advance\midcol20pt
+\+& |do_like| |stmt| |else_like| |semi| & |stmt| \hfill
+ $D\,\\{bsp}\,|noop|\,|cancel|\,S\,|cancel|\,|noop|\,\\{bsp}\,ES$%
+ & |do f(x); while (g(x));|\cr
+\advance\midcol-20pt
+\+& |case_like| |semi| & |stmt| & |return;|\cr
+\+& |case_like| |colon| & |tag| & |default:|\cr
+\+& |case_like| |exp| & |exp| \hfill $C\.\ E$ & |return 0|\cr
+\+& |catch_like| \alt|cast| |exp| & |fn_decl| \hfill
+ $C$\alt $C$ $E$ \\{in}\,\\{in} & |catch (...)|\cr
+\+& |tag| |tag| & |tag| \hfill $T_1\,\\{bsp}\,T_2$ & |case 0: case 1:|\cr
+\+& |tag| \altt|stmt| |decl| |function| & \altt|stmt| |decl| |function|
+ \hfill $|force|\,\\{back}\,T\,\\{bsp}\,S$ & |case 0: z=0;|\cr
+\+\dagit& |stmt| \altt|stmt| |decl| |function| &
+ \altt|stmt| |decl| |function|
+ \hfill $S\,$\altt$|force|\,S$ $|big_force|\,D$ $|big_force|\,F$ &
+ |x=1;y=2;|\cr
+\+& |semi| & |stmt| \hfill \.\ $S$& empty statement\cr
+\+\dagit& |lproc| \altt |if_like| |else_like| |define_like| & |lproc| &
+ \maltt {{\bf \#include}} {\bf\#else} {\bf\#define} \cr
+\+& |lproc| |rproc| & |insert| & {\bf\#endif} \cr
+\+& |lproc| \alt {|exp| [|exp|]} |function| |rproc| & |insert| \hfill
+ $I$\.\ \alt {$E{[\.{\ \\5}E]}$} {$F$} &
+ \malt{{\bf\#define} $a$\enspace 1} {{\bf\#define} $a$\enspace$\{\,b;\,\}$} \cr
+\+& |section_scrap| |semi| & |stmt|\hfill $MS$ |force|
+ &$\langle\,$section name$\,\rangle$;\cr
+\+& |section_scrap| & |exp| &$\langle\,$section name$\,\rangle$\cr
+\+& |insert| |any| & |any| & \.{\v\#include\v}\cr
+\+& |prelangle| & |binop| \hfill \.< & $<$ not in template\cr
+\+& |prerangle| & |binop| \hfill \.> & $>$ not in template\cr
+\+& |langle| |prerangle| & |cast| \hfill $L\.{\\,}P$ & $\langle\,\rangle$\cr
+\+& |langle| \altt|decl_head| |int_like| |exp| |prerangle| & |cast| &
+ $\langle\&{class}\,\&C\rangle$\cr
+\+& |langle| \altt|decl_head| |int_like| |exp| |comma| & |langle| \hfill
+ $L$\,\altt $D$ $I$ $E$ $C$\,|opt|9 & $\langle\&{class}\,\&C,$\cr
+\+& |template_like| |exp| |prelangle| & |template_like| |exp| |langle| &
+ \&{template} $a\langle100\rangle$\cr
+\+& |template_like| \alt|exp| |raw_int| & \alt|exp| |raw_int| \hfill
+ $T$\.\ \alt$E$ $R$ & \&C\DC\&{template} |a()|\cr
+\+& |template_like| & |raw_int| & \&{template}$\langle\&{class}\,\&T\rangle$\cr
+\+& |new_like| |lpar| |exp| |rpar| & |new_like| & \&{new}(\\{nothrow})\cr
+\+& |new_like| |cast| & |exp| \hfill $N\.\ C$ & |new(int*)|\cr
+\+\dagit& |new_like| & |new_exp| & \&{new} \&C|()|\cr
+\+& |new_exp| \alt|int_like| |const_like| & |new_exp| \hfill
+ $N$\.\ \alt $I$ $C$ & |new const int|\cr
+\+& |new_exp| |struct_like| \alt |exp| |int_like| & |new_exp| \hfill
+ $N\.\ S$\.\ \alt $E$ $I$ & \&{new} \&{struct} \&S\cr
+\+& |new_exp| |raw_ubin| & |new_exp| \hfill $N\.\{R\.\}$ & |new int*[2]|\cr
+\+& |new_exp| \alt |lpar| |exp| & |exp| \alt |lpar| |exp| \hfill
+ $E=N$\,\alt {} {\.\ } & \malt |operator[](int)| {|new int(2)|} \cr
+\+\dagit& |new_exp| & |exp| & |new int;|\cr
+\+& |ftemplate| |prelangle| & |ftemplate| |langle| & |make_pair<int,int>|\cr
+\+& |ftemplate| & |exp| & |make_pair(1,2)|\cr
+\+& |for_like| |exp| & |else_like| \hfill $F\.\ E$ & |while (1)|\cr
+\+& |raw_ubin| |const_like| & |raw_ubin| \hfill $RC$\.{\\\ }
+ & $*$\&{const} |x|\cr
+\+& |raw_ubin| & |ubinop| & $*$ |x|\cr
+\+& |const_like| & |int_like| & \&{const} |x|\cr
+\+& |raw_int| |prelangle| & |raw_int| |langle| & \&C$\langle$\cr
+\+& |raw_int| |colcol| & |colcol| & \&C\DC\cr
+\+& |raw_int| |cast| & |raw_int| & \&C$\langle\&{class}\ \&T\rangle$\cr
+\+& |raw_int| |lpar| & |exp| |lpar| & \&{complex}$(x,y)$\cr
+\+\dagit& |raw_int| & |int_like| & \&{complex} |z|\cr
+\+\dagit& |operator_like| \altt|binop| |unop| |ubinop| & |exp|
+ \hfill $O$\.\{\altt $B$ $U$ $U$ \unskip\.\} & |operator+|\cr
+\+& |operator_like| \alt|new_like| |delete_like| & |exp| \hfill
+ $O$\.\ \alt $N$ $S$ & |operator delete|\cr
+\+& |operator_like| |comma| & |exp| & \&{operator},\cr
+\+\dagit& |operator_like| & |new_exp| & |operator char*|\cr
+\advance\midcol-3pt
+\+\dag200\enspace& |typedef_like| |decl_head| \alt|exp| |int_like| &
+ |typedef_like| |decl_head| \hfill $D=D$\alt $E^{**}$ $I^{**}$ \unskip &
+ \&{typedef} \&{char} \&{ch};\cr
+\advance\midcol+3pt
+\+201\enspace& |typedef_like| |decl_head| |semi| & |decl| \hfill $T\.\ D$ &
+ \&{typedef} \&{int} $\&x,\&y$;\cr
+\+\dag202\enspace& |typedef_like| |int_like| |raw_int| & |typedef_like| |int_like| |exp| &
+ \&{typedef} \&{int} \&{foo}\cr
+\global\prodno=121
+\+& |delete_like| |lpar| |rpar| & |delete_like|\hfill $DL\.{\\,}R$ &
+ \&{delete}|[]| \cr
+\+& |delete_like| |exp| & |exp| \hfill $D\.\ E$ & |delete p| \cr
+\+\dagit& |question| |exp| \alt |colon| |base| & |binop| &
+ \malt |?x:| |?f():| \cr
+\+& |begin_arg| |end_arg| & |exp| & \.{@@[}\&{char}$*$\.{@@]}\cr
+\+& |any_other| |end_arg| & |end_arg| & \&{char}$*$\.{@@]}\cr
+\yskip
+\yskip
+\yskip
+\parindent=0pt
+\dag{\bf Notes}
+\yskip
+Rule 35: The |exp| must not be immediately followed by |lpar|, |exp|,
+ or~|cast|.
+
+Rule 48: The |exp| or |int_like| must not be immediately followed by |base|.
+
+Rule 76: The |force| in the |stmt| line becomes \\{bsp} if \.{CWEAVE} has
+been invoked with the \.{-f} option.
+
+Rule 78: The |define_like| case calls |make_underlined| on the following scrap.
+
+Rule 94: The |new_like| must not be immediately followed by |lpar|.
+
+Rule 99: The |new_exp| must not be immediately followed by |raw_int|,
+|struct_like|, or |colcol|.
+
+Rule 110: The |raw_int| must not be immediately followed by |langle|.
+
+Rule 111: The operator after |operator_like|
+must not be immediately followed by a |binop|.
+
+Rule 114: The |operator_like| must not be immediately followed by
+|raw_ubin|.
+
+Rule 123: The mathness of the |colon| or |base| changes to `yes'.
+
+Rule 200: The |exp| must not be immediately followed by |lpar| or~|exp|.
+
+Rule 202: The |raw_int| must be immediately followed by |semi| or |comma|.
+
+\endgroup
diff --git a/Build/source/texk/web2c/cwebdir/prod.w b/Build/source/texk/web2c/cwebdir/prod.w
new file mode 100644
index 00000000000..5f76a193794
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/prod.w
@@ -0,0 +1,307 @@
+% This file is part of CWEB.
+% This program by Silvio Levy and Donald E. Knuth
+% is based on a program by Knuth.
+% It is distributed WITHOUT ANY WARRANTY, express or implied.
+% Version 3.6 --- May 2000
+%
+@ 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 |mathness|. In this way we never get double {\tt\$\$}.
+
+% The following kludge is needed because \newcount, \newdimen, and \+
+% are "\outer" control sequences that cannot be used in skipped text!
+\fi \newcount\prodno \newdimen\midcol \let\+\relax \ifon
+
+\def\v{\char'174}
+\mathchardef\RA="3221 % right arrow
+\mathchardef\BA="3224 % double arrow
+
+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 |make_underlined|. Two asterisks$^{**}$ means that both
+|make_underlined| and |make_reserved| are called; that is, the
+identifier's ilk becomes |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 |indent|, |outdent|, |backup| and
+|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
+\prodno=0 \midcol=2.5in
+\def\theprodno{\number\prodno \global\advance\prodno by1\enspace}
+\def\dagit{\dag\theprodno}
+\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}}
+|insert| & \altt\\{any} {\\{any} \\{any}} {\\{any} \\{any} \\{any}}
+& stmt; \ /$\ast\,$comment$\,*$/\cr
+\+& |exp| \altt|lbrace| |int_like| |decl|
+ & |fn_decl| \altt|lbrace| |int_like| |decl|
+ \hfill $F=E^*\,|in|\,|in|$ & \malt {\\{main}()$\{$}
+ {\\{main}$(\\{ac},\\{av})$ \&{int} \\{ac};} \cr
+\+& |exp| |unop| & |exp| & |x++|\cr
+\+& |exp| \alt |binop| |ubinop| |exp| & |exp| & \malt {|x/y|} {|x+y|} \cr
+\+& |exp| |comma| |exp| & |exp| \hfill $EC\,|opt|9\,E$& |f(x,y)|\cr
+\+& |exp| \alt {|lpar| |rpar|} |cast| |colon| &
+ |exp| \alt {|lpar| |rpar|} |cast| |base| &
+ \malt \&C|()|: {\&C|int i)|:} \cr
+\+& |exp| |semi| & |stmt| & |x=0;|\cr
+\+& |exp| |colon| & |tag| \hfill $E^*C$ & |found:|\cr
+\+& |exp| |rbrace| & |stmt| |rbrace| & end of \&{enum} list\cr
+\+& |exp| \alt {|lpar| |rpar|} |cast| \alt|const_like| |case_like| &
+ |exp| \alt {|lpar| |rpar|} |cast| \hfill
+ \alt $R=R\.\ C$ $C_1=C_1\.\ C_2$ &
+ \malt {|f() const|} {|f(int) throw|} \cr
+\+& |exp| \alt |exp| |cast| & |exp| & |time()|\cr
+\+& |lpar| \alt |exp| |ubinop| |rpar| & |exp| & \malt{|(x)|} {|(*)|} \cr
+\+& |lpar| |rpar| & |exp| \hfill $L\.{\\,}R$ & functions, declarations\cr
+\+& |lpar| \altt |decl_head| |int_like| |cast| |rpar| & |cast| & |(char*)|\cr
+\+& |lpar| \altt |decl_head| |int_like| |exp| |comma| & |lpar| \hfill
+ $L$\,\altt $D$ $I$ $E$ $C$\,|opt|9 & |(int,|\cr
+\+& |lpar| \alt |stmt| |decl| & |lpar| \hfill \alt {$LS\.\ $} {$LD\.\ $} &
+ \malt {|(k=5;|} {|(int k=5;|} \cr
+\+& |unop| \alt |exp| |int_like| & |exp| &
+ \malt |!x| |~|\&C \cr
+\+& |ubinop| |cast| |rpar| & |cast| |rpar| \hfill
+ $C=\.\{U\.\}C$ & |*|\&{CPtr}) \cr
+\+& |ubinop| \alt|exp| |int_like| & \alt|exp| |int_like| \hfill
+ \.\{$U$\.\}\alt$E$ $I$ & \malt |*x| |*|\&{CPtr} \cr
+\+& |ubinop| |binop| & |binop| \hfill $|math_rel|\,U\.\{B\.\}\.\}$ & |*=|\cr
+\+& |binop| |binop| & |binop| \hfill
+ $|math_rel|\,\.\{B_1\.\}\.\{B_2\.\}\.\}$ & |>>=|\cr
+\+& |cast| \alt |lpar| |exp| & \alt |lpar| |exp| \hfill
+ \alt $CL$ $C\.\ E$ & \malt |(double)(x+2)| |(double)x| \cr
+\+& |cast| |semi| & |exp| |semi| & |(int);|\cr
+\+& |sizeof_like| |cast| & |exp| & |sizeof (double)|\cr
+\+& |sizeof_like| |exp| & |exp| \hfill $S\.\ E$ & |sizeof x|\cr
+\+& |int_like| \alt|int_like| |struct_like| &
+ \alt|int_like| |struct_like| \hfill $I\.\ $\alt $I$ $S$
+ \unskip& |extern char|\cr
+\+& |int_like| |exp| \alt|raw_int| |struct_like| &
+ |int_like| \alt|raw_int| |struct_like| & |extern "Ada" int|\cr
+\+& |int_like| \altt|exp| |ubinop| |colon| &
+ |decl_head| \altt|exp| |ubinop| |colon| \hfill
+ $D=I$\.\ & \maltt|int x| |int*x| |unsigned:| \cr
+\+& |int_like| \alt |semi| |binop| & |decl_head| \alt |semi| |binop| &
+ \malt |int x;| {\&{int} $f(\&{int}=4)$} \cr
+\+& |public_like| |colon| & |tag| & \&{private}:\cr
+\+& |public_like| & |int_like| & \&{private}\cr
+\+& |colcol| \alt|exp| |int_like| & \alt|exp| |int_like| \hfill
+ |qualifier| $C$ \alt$E$ $I$ & \&C\DC$x$\cr
+\+& |colcol| |colcol| & |colcol| & \&C\DC\&B\DC\cr
+\+& |decl_head| |comma| & |decl_head| \hfill $DC\.\ $ & |int x,|\cr
+\+& |decl_head| |ubinop| & |decl_head| \hfill $D\.\{U\.\}$ & |int *|\cr
+\+\dagit& |decl_head| |exp| & |decl_head| \hfill $DE^*$ & |int x|\cr
+\+& |decl_head| \alt|binop| |colon| |exp| \altt|comma| |semi| |rpar| &
+ |decl_head| \altt|comma| |semi| |rpar| \hfill
+ $D=D$\alt $B$ $C$ \unskip$E$ & \malt {\&{int} $f(\&{int}\ x=2)$} |int b:1| \cr
+\+& |decl_head| |cast| & |decl_head| & |int f(int)|\cr
+\+& |decl_head| \altt|int_like| |lbrace| |decl| & |fn_decl|
+ \altt|int_like| |lbrace| |decl| \hfill $F=D\,|in|\,|in|$
+ & |long time () {|\cr
+\+& |decl_head| |semi| & |decl| & |int n;|\cr
+\+& |decl| |decl| & |decl| \hfill $D_1\,|force|\,D_2$ & |int n;double x;|\cr
+\+& |decl| \alt|stmt| |function| & \alt|stmt| |function|
+ \hfill $D\,|big_force|\,$\alt $S$ $F$ \unskip& \&{extern} $n$;
+ \\{main} ()|{}|\cr
+\+& |base| \alt |int_like| |exp| |comma| & |base| \hfill
+ $B$\.\ \alt $I$ $E$ \unskip$C$\,|opt|9
+ & \malt {: \&{public} \&A,} {: $i(5)$,} \cr
+\+& |base| \alt |int_like| |exp| |lbrace| & |lbrace| \hfill
+ $B$\.\ \alt $I$ $E$ \unskip\.\ $L$ & \&D : \&{public} \&A $\{$\cr
+\+& |struct_like| |lbrace| & |struct_head| \hfill $S\.\ L$ & |struct {|\cr
+\+& |struct_like| \alt|exp| |int_like| |semi| & |decl_head| |semi|
+ \hfill $S\.\ $\alt $E^{**}$ $I^{**}$ & \&{struct} \&{forward};\cr
+\+& |struct_like| \alt|exp| |int_like| |lbrace| & |struct_head| \hfill
+ $S\.\ $\alt $E^{**}$ $I^{**}$ \unskip $\.\ L$ &
+ \&{struct} \&{name\_info} $\{$\cr
+\+& |struct_like| \alt|exp| |int_like| |colon| &
+ |struct_like| \alt|exp| |int_like| |base| & |class| \&C :\cr
+\+\dagit& |struct_like| \alt|exp| |int_like| & |int_like|
+ \hfill $S\.\ $\alt$E$ $I$ & \&{struct} \&{name\_info} $z$;\cr
+\+& |struct_head| \altt|decl| |stmt| |function| |rbrace| & |int_like|\hfill
+ $S\,\\{in}\,|force|$\altt$D$ $S$ $F$ $\\{out}\,|force|\,R$ &
+ |struct {| declaration |}|\cr
+\+& |struct_head| |rbrace| & |int_like|\hfill $S\.{\\,}R$ & |class C{}|\cr
+\+& |fn_decl| |decl| & |fn_decl| \hfill $F\,|force|\,D$
+ & $f(z)$ \&{double} $z$; \cr
+\+& |fn_decl| |stmt| & |function| \hfill $F\,|out|\,|out|\,|force|\,S$
+ & \\{main}() {\dots}\cr
+\+& |function| \altt|stmt| |decl| |function| & \altt |stmt| |decl| |function|
+ \hfill $F\,|big_force|\,$\altt $S$ $D$ $F$ & outer block\cr
+\+& |lbrace| |rbrace| & |stmt| \hfill $L\.{\\,}R$ & empty statement\cr
+\advance\midcol35pt
+\+& |lbrace| \altt|stmt| |decl| |function| |rbrace| & |stmt| \hfill
+ $|force|\,L\,\\{in}\,|force|\,S\,
+ |force|\,\\{back}\,R\,\\{out}\,|force|$ & compound statement\cr
+\advance\midcol-20pt
+\+& |lbrace| |exp| [|comma|] |rbrace| & |exp| & initializer\cr
+\+& |if_like| |exp| & |if_clause| \hfill $I\.{\ }E$ & |if (z)|\cr
+\+& |else_like| |colon| & |else_like| |base| & \&{try} :\cr
+\+& |else_like| |lbrace| & |else_head| |lbrace| & \&{else} $\{$\cr
+\+& |else_like| |stmt| & |stmt| \hfill
+ $|force|\,E\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|$ & |else x=0;|\cr
+\+& |else_head| \alt|stmt| |exp| & |stmt| \hfill
+ $|force|\,E\,\\{bsp}\,|noop|\,|cancel|\,S\,\\{bsp}$ & |else{x=0;}|\cr
+\+& |if_clause| |lbrace| & |if_head| |lbrace| & |if (x) {|\cr
+\+& |if_clause| |stmt| |else_like| |if_like| & |if_like| \hfill
+ $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E\,\.\ I$ &
+ |if (x) y; else if|\cr
+\+& |if_clause| |stmt| |else_like| & |else_like| \hfill
+ $|force|\,I\,\\{in}\,\\{bsp}\,S\,\\{out}\,|force|\,E$ &
+ |if (x) y; else|\cr
+\+& |if_clause| |stmt| & |else_like| |stmt| & |if (x)|\cr
+\+& |if_head| \alt|stmt| |exp| |else_like| |if_like| & |if_like| \hfill
+ $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E\,\.\ I$ &
+ |if (x){y;}else if|\cr
+\+& |if_head| \alt|stmt| |exp| |else_like| & |else_like| \hfill
+ $|force|\,I\,\\{bsp}\,|noop|\,|cancel|\,S\,|force|\,E$ &
+ |if (x){y;}else|\cr
+\+& |if_head| \alt|stmt| |exp| & |else_head| \alt|stmt| |exp| & |if (x){y;}|\cr
+\advance\midcol20pt
+\+& |do_like| |stmt| |else_like| |semi| & |stmt| \hfill
+ $D\,\\{bsp}\,|noop|\,|cancel|\,S\,|cancel|\,|noop|\,\\{bsp}\,ES$%
+ & |do f(x); while (g(x));|\cr
+\advance\midcol-20pt
+\+& |case_like| |semi| & |stmt| & |return;|\cr
+\+& |case_like| |colon| & |tag| & |default:|\cr
+\+& |case_like| |exp| & |exp| \hfill $C\.\ E$ & |return 0|\cr
+\+& |catch_like| \alt|cast| |exp| & |fn_decl| \hfill
+ $C$\alt $C$ $E$ \\{in}\,\\{in} & |catch (...)|\cr
+\+& |tag| |tag| & |tag| \hfill $T_1\,\\{bsp}\,T_2$ & |case 0: case 1:|\cr
+\+& |tag| \altt|stmt| |decl| |function| & \altt|stmt| |decl| |function|
+ \hfill $|force|\,\\{back}\,T\,\\{bsp}\,S$ & |case 0: z=0;|\cr
+\+\dagit& |stmt| \altt|stmt| |decl| |function| &
+ \altt|stmt| |decl| |function|
+ \hfill $S\,$\altt$|force|\,S$ $|big_force|\,D$ $|big_force|\,F$ &
+ |x=1;y=2;|\cr
+\+& |semi| & |stmt| \hfill \.\ $S$& empty statement\cr
+\+\dagit& |lproc| \altt |if_like| |else_like| |define_like| & |lproc| &
+ \maltt {{\bf \#include}} {\bf\#else} {\bf\#define} \cr
+\+& |lproc| |rproc| & |insert| & {\bf\#endif} \cr
+\+& |lproc| \alt {|exp| [|exp|]} |function| |rproc| & |insert| \hfill
+ $I$\.\ \alt {$E{[\.{\ \\5}E]}$} {$F$} &
+ \malt{{\bf\#define} $a$\enspace 1} {{\bf\#define} $a$\enspace$\{\,b;\,\}$} \cr
+\+& |section_scrap| |semi| & |stmt|\hfill $MS$ |force|
+ &$\langle\,$section name$\,\rangle$;\cr
+\+& |section_scrap| & |exp| &$\langle\,$section name$\,\rangle$\cr
+\+& |insert| |any| & |any| & \.{\v\#include\v}\cr
+\+& |prelangle| & |binop| \hfill \.< & $<$ not in template\cr
+\+& |prerangle| & |binop| \hfill \.> & $>$ not in template\cr
+\+& |langle| |prerangle| & |cast| \hfill $L\.{\\,}P$ & $\langle\,\rangle$\cr
+\+& |langle| \altt|decl_head| |int_like| |exp| |prerangle| & |cast| &
+ $\langle\&{class}\,\&C\rangle$\cr
+\+& |langle| \altt|decl_head| |int_like| |exp| |comma| & |langle| \hfill
+ $L$\,\altt $D$ $I$ $E$ $C$\,|opt|9 & $\langle\&{class}\,\&C,$\cr
+\+& |template_like| |exp| |prelangle| & |template_like| |exp| |langle| &
+ \&{template} $a\langle100\rangle$\cr
+\+& |template_like| \alt|exp| |raw_int| & \alt|exp| |raw_int| \hfill
+ $T$\.\ \alt$E$ $R$ & \&C\DC\&{template} |a()|\cr
+\+& |template_like| & |raw_int| & \&{template}$\langle\&{class}\,\&T\rangle$\cr
+\+& |new_like| |lpar| |exp| |rpar| & |new_like| & \&{new}(\\{nothrow})\cr
+\+& |new_like| |cast| & |exp| \hfill $N\.\ C$ & |new(int*)|\cr
+\+\dagit& |new_like| & |new_exp| & \&{new} \&C|()|\cr
+\+& |new_exp| \alt|int_like| |const_like| & |new_exp| \hfill
+ $N$\.\ \alt $I$ $C$ & |new const int|\cr
+\+& |new_exp| |struct_like| \alt |exp| |int_like| & |new_exp| \hfill
+ $N\.\ S$\.\ \alt $E$ $I$ & \&{new} \&{struct} \&S\cr
+\+& |new_exp| |raw_ubin| & |new_exp| \hfill $N\.\{R\.\}$ & |new int*[2]|\cr
+\+& |new_exp| \alt |lpar| |exp| & |exp| \alt |lpar| |exp| \hfill
+ $E=N$\,\alt {} {\.\ } & \malt |operator[](int)| {|new int(2)|} \cr
+\+\dagit& |new_exp| & |exp| & |new int;|\cr
+\+& |ftemplate| |prelangle| & |ftemplate| |langle| & |make_pair<int,int>|\cr
+\+& |ftemplate| & |exp| & |make_pair(1,2)|\cr
+\+& |for_like| |exp| & |else_like| \hfill $F\.\ E$ & |while (1)|\cr
+\+& |raw_ubin| |const_like| & |raw_ubin| \hfill $RC$\.{\\\ }
+ & $*$\&{const} |x|\cr
+\+& |raw_ubin| & |ubinop| & $*$ |x|\cr
+\+& |const_like| & |int_like| & \&{const} |x|\cr
+\+& |raw_int| |prelangle| & |raw_int| |langle| & \&C$\langle$\cr
+\+& |raw_int| |colcol| & |colcol| & \&C\DC\cr
+\+& |raw_int| |cast| & |raw_int| & \&C$\langle\&{class}\ \&T\rangle$\cr
+\+& |raw_int| |lpar| & |exp| |lpar| & \&{complex}$(x,y)$\cr
+\+\dagit& |raw_int| & |int_like| & \&{complex} |z|\cr
+\+\dagit& |operator_like| \altt|binop| |unop| |ubinop| & |exp|
+ \hfill $O$\.\{\altt $B$ $U$ $U$ \unskip\.\} & |operator+|\cr
+\+& |operator_like| \alt|new_like| |delete_like| & |exp| \hfill
+ $O$\.\ \alt $N$ $S$ & |operator delete|\cr
+\+& |operator_like| |comma| & |exp| & \&{operator},\cr
+\+\dagit& |operator_like| & |new_exp| & |operator char*|\cr
+\advance\midcol-8pt
+\+& |typedef_like| \alt|int_like| |cast| \alt|comma| |semi| &
+ |typedef_like| |exp| \alt|comma| |semi| & \&{typedef} \&{int} \&I,\cr
+\advance\midcol+8pt
+\+& |typedef_like| |int_like| & |typedef_like| \hfill $T\.\ I$ &
+ \&{typedef} \&{char}\cr
+\+\dagit& |typedef_like| |exp| & |typedef_like| \hfill $T\.\ E^{**}$ &
+ \&{typedef} \&I \.{@@[@@]} (|*|\&P)\cr
+\+& |typedef_like| |comma| & |typedef_like| \hfill $TC\.\ $ &
+ \&{typedef} \&{int} \&x,\cr
+\+& |typedef_like| |semi| & |decl| & \&{typedef} \&{int} $\&x,\&y$;\cr
+\+& |typedef_like| |ubinop| \alt |cast| |ubinop| &
+ |typedef_like| \alt |cast| |ubinop| \hfill
+ \alt $C=\.\{U\.\}C$ $U_2=\.\{U_1\.\}U_2$ \unskip &
+ \&{typedef} |*|{}|*|(\&{CPtr})\cr
+\+& |delete_like| |lpar| |rpar| & |delete_like|\hfill $DL\.{\\,}R$ &
+ \&{delete}|[]| \cr
+\+& |delete_like| |exp| & |exp| \hfill $D\.\ E$ & |delete p| \cr
+\+\dagit& |question| |exp| \alt |colon| |base| & |binop| &
+ \malt |?x:| |?f():| \cr
+\+& |begin_arg| |end_arg| & |exp| & \.{@@[}\&{char}$*$\.{@@]}\cr
+\+& |any_other| |end_arg| & |end_arg| & \&{char}$*$\.{@@]}\cr
+\yskip
+\yskip
+\yskip
+\parindent=0pt
+\dag{\bf Notes}
+\yskip
+Rule 35: The |exp| must not be immediately followed by |lpar|, |exp|,
+ or~|cast|.
+
+Rule 48: The |exp| or |int_like| must not be immediately followed by |base|.
+
+Rule 76: The |force| in the |stmt| line becomes \\{bsp} if \.{CWEAVE} has
+been invoked with the \.{-f} option.
+
+Rule 78: The |define_like| case calls |make_underlined| on the following scrap.
+
+Rule 94: The |new_like| must not be immediately followed by |lpar|.
+
+Rule 99: The |new_exp| must not be immediately followed by |raw_int|,
+|struct_like|, or |colcol|.
+
+Rule 110: The |raw_int| must not be immediately followed by |langle|.
+
+Rule 111: The operator after |operator_like|
+must not be immediately followed by a |binop|.
+
+Rule 114: The |operator_like| must not be immediately followed by
+|raw_ubin|.
+
+Rule 117: The |exp| must not be immediately followed by |lpar|, |exp|,
+or |cast|.
+
+Rule 123: The mathness of the |colon| or |base| changes to `yes'.
+
+\endgroup
diff --git a/Build/source/texk/web2c/cwebdir/readme.ql b/Build/source/texk/web2c/cwebdir/readme.ql
new file mode 100644
index 00000000000..907d4c3192b
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/readme.ql
@@ -0,0 +1,84 @@
+This is the readme file for CWEB for QDOS/SMSQ systems
+
+(These instructions are for systems with Toolkit II,
+ please report any problems to me, the address is at the
+ end of the file)
+
+If you want to compile CWEB for your QL system, you must first
+convert the ASCII code to the QL's character set. Therefore you
+can use the little BASIC program appended at the end of the file.
+
+For a first version you have to alter the supplied ctangle_c file.
+Set your DATA_USE to the directory you have the CWEB sources in, and
+the PROG_USE to C68's directory.
+compile it with:
+ex cc;'common_c ctangle_c -bufp500K -octangle'
+
+then ctangle the source files with:
+ex datad$&'ctangle';'common_w comm-ql_ch'
+ex datad$&'ctangle';'ctangle_w ctang-ql_ch'
+ex datad$&'ctangle';'cweave_w cweav-ql_ch'
+
+Compile the following way (C68v4.14 +):
+
+ex cc;'-c common_c'
+ex cc;'-c ctangle_c'
+ex cc;'-c cweave_c'
+ex ld;'-bufp500K common_o ctangle_o -octangle'
+ex ld;'-bufp500K common_o cweave_o -ocweave'
+
+After that copy the ctangle and cweave executables into your
+programs directory (if you want them there).
+
+The DATA default may be used as usual. E.g. if you have
+a file win2_data_test_w and the DATA default set to
+win2_data_ you may call ctangle with
+ ex ctangle;'test'
+assuming that ctangle is in your PROG default.
+
+Please report any problems with the QL version to:
+Robert Klein
+Bluecherstrasse 24
+D-56349 Kaub
+Germany
+
+
+**************** ASCII Conversion program ***************
+With this program you can convert DOS and Unix 7-Bit ASCII
+files to the QL's character set. You'll need Toolkit II.
+The program will take all the files in the source directory
+and put them converted into the destination&source directory,
+e.g. you have as drive1$='win2_', drive2$='win3_',
+path1$='cweb_' and path2$='ql_'. Then the routine will take
+all files in win2_cweb_ (wthout subdirectories!) convert them
+and write them to 'win3_ql_cweb_'. It's only a lousy hack,
+but it'll do it's job.
+
+1000 DEFine PROCedure dos2ql (drive1$,path1$,drive2$,path2$)
+1002 LOCal zx$,zx%,ishl,ashl
+1005 DELETE drive2$&path2$&'dirlist'
+1010 OPEN_NEW#5,drive2$&path2$&'dirlist'
+1020 DIR#5,drive1$&path1$
+1030 CLOSE#5
+1040 OPEN_IN#5,drive2$&path2$&'dirlist'
+1050 INPUT#5,zx$:INPUT#5,zx$:REMark devicename and sectors
+1060 REPeat ashl
+1070 IF EOF(#5)THEN EXIT ashl
+1080 INPUT#5,zx$
+1085 IF '->' INSTR zx$ THEN NEXT ashl
+1090 OPEN_IN#3,drive1$&zx$
+1100 OPEN_NEW#4,drive2$&path2$&zx$
+1110 REPeat ishl
+1120 IF EOF(#3)THEN EXIT ishl
+1130 BGET#3,zx%
+1140 SELect ON zx%
+1150 = 13:REMark do nothing (DOS LineFeed)
+1155 = 26:REMark do nothing (DOS EOF sign)
+1160 = 96: BPUT#4,159:REMark Unix/DOS beginning quote sign
+1170 = REMAINDER : BPUT#4,zx%
+1180 END SELect
+1190 END REPeat ishl
+1195 CLOSE#3:CLOSE#4
+1200 END REPeat ashl
+1205 CLOSE#5
+1210 END DEFine dos2ql
diff --git a/Build/source/texk/web2c/cwebdir/refsort.w b/Build/source/texk/web2c/cwebdir/refsort.w
new file mode 100644
index 00000000000..162f696f568
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/refsort.w
@@ -0,0 +1,165 @@
+% usage: refsort <foo.ref >foo.sref (after first pass with ctwimac)
+\datethis
+
+@* Introduction. This short program sorts the mini-indexes of listings
+prepared by \.{CTWILL}.
+
+More precisely, suppose you have said \.{ctwill} \.{foo.w},
+getting a file \.{foo.tex}, and that you've then said \.{tex} \.{foo.tex},
+getting files \.{foo.dvi} and \.{foo.ref}. If you're happy with \.{foo.dvi}
+except for the alphabetic order of the mini-indexes, you can then say
+$$\hbox{\tt refsort <foo.ref >foo.sref}$$
+after which \.{tex} \.{foo} will produce \.{foo.dvi} again, this time
+with the mini-indexes in order.
+
+Still more precisely, this program reads from standard input a file consisting
+of groups of unsorted lines and writes to standard output a file consisting
+of groups of sorted lines. Each input group begins with an identification
+line whose first character is \.!; the remaining characters are a page number.
+The other lines in the group all have the form
+$$\.{+\ }\alpha\.{\ \\?\{}\kappa\.{\}}\omega$$
+where $\alpha$ is a string containing no spaces, \.? is a single
+character, $\kappa$ is a string of
+letters, digits, and \.{\\\_}'s, and $\omega$ is an arbitrary string.
+The output groups contain the same lines without the initial \.{+\ },
+sorted alphabetically with respect to the $\kappa$ fields, followed by
+a closing line that says `\.{\\donewithpage}' followed by the page number
+copied from the original identification line.
+
+Exception: In the case of a ``custom'' identifier, \.{\\?\{$\kappa$\}}
+takes the alternative form \.{\$\\$\kappa$\ \$} instead.
+
+We define limits on the number and size of mini-index entries that should
+be plenty big enough.
+
+@d max_key 30 /* greater than the length of the longest identifier */
+@d max_size 100 /* greater than the length of the longest mini-index entry */
+@d max_items 300 /* the maximum number of items in a single mini-index */
+
+@ Here's the layout of the \Cee\ program:
+
+@d abort(c,m) { fprintf(stderr,"%s!\n%s",m,buf); return c; }
+@c
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+@#
+typedef struct {
+ char key[max_key];
+ char entry[max_size];
+} item;
+item items[max_items]; /* all items of current group */
+item *sorted[max_items]; /* pointers to items in alphabetic order */
+char cur_page[10]; /* page number, as a string */
+char buf[max_size]; /* current line of input */
+char *input_status; /* |NULL| if end of input reached, else |buf| */
+@#
+int main()
+{
+ register char *p,*q;
+ register int n; /* current number of items */
+ register item *x, **y;
+ input_status=fgets(buf,max_size,stdin);
+ while (input_status) {
+ @<Check that |buf| contains a valid page-number line@>;
+ @<Read and sort additional lines, until |buf| terminates a group@>;
+ @<Output the current group@>;
+ }
+ return 0; /* normal exit */
+}
+
+@ @<Check that |buf| contains a valid page-number line@>=
+if (*buf!='!') abort(-1,"missing '!'");
+if (strlen(buf+1)>11) abort (-2,"page number too long");
+for (p=buf+1,q=cur_page;*p!='\n';p++) *q++=*p;
+*q='\0';
+
+@ @<Read and sort additional lines, until |buf| terminates a group@>=
+n=0;
+while (1) {
+ input_status=fgets(buf,max_size,stdin);
+ if (input_status==NULL || *buf!='+') break;
+ x=&items[n];
+ @<Copy |buf| to item |x|@>;
+ @<Sort the new item into its proper place@>;
+ if (++n>max_items) abort(-11,"too many lines in group");
+}
+
+@ @<Output the current group@>=
+{
+ for (y=sorted;y<sorted+n;y++) printf("%s\n",(*y)->entry);
+ printf("\\donewithpage%s\n",cur_page);
+}
+
+@* Sorting. We convert the key to lowercase as we copy it,
+and we omit backslashes. We also convert \.{\_} to \.{\ }.
+Then \.{\\\_} will be alphabetically less
+than alphabetic letters, as desired.
+
+@<Copy |buf|...@>=
+if (*(buf+1)!=' ') abort(-3,"missing blank after +");
+@<Scan past $\alpha$@>;
+if (*p!=' ') abort(-4,"missing blank after alpha");
+if (*(p+1)=='$') @<Process a custom-formatted identifier@>@;
+else {
+ if (*(p+1)!='\\') abort(-5,"missing backslash");
+ if (!*(p+2)) abort(-6,"missing control code");
+ if (*(p+3)!='{') abort(-7,"missing left brace");
+ for (p+=4,q=x->key;*p!='}'&&*p;p++) {
+ if (*p!='\\') {
+ if (isupper(*p)) *q++=*p+('a'-'A');
+ else if (*p=='_') *q++=' ';
+ else *q++=*p;
+ }
+ }
+ if (*p!='}') abort(-8,"missing right brace");
+}
+if (q>=&x->key[max_key]) abort(-9,"key too long");
+*q='\0';
+@<Copy the buffer to |x->entry|@>;
+if (p==buf+max_size-1) abort(-10,"entry too long");
+*(q-1)='\0';
+
+@ @<Process a custom...@>=
+{
+ if (*(p+2)!='\\') abort(-11,"missing custom backlash");
+ for (p+=3,q=x->key;*p!=' '&&*p;p++) {
+ if (isupper(*p)) *q++=*p+('a'-'A');
+ else *q++=*p;
+ }
+ if (*p!=' ') abort(-12,"missing custom space");
+ if (*(p+1)!='$') abort(-13,"missing custom dollarsign");
+}
+
+@ @<Sort...@>=
+for (y=&sorted[n];
+ y>&sorted[0] && strcmp((*(y-1))->key,x->key)>0;
+ y--)
+ *y=*(y-1);
+*y=x;
+
+@*A bugfix.
+The program specification had a subtle bug: There are cases where
+$\alpha$ includes spaces that should be removed in the output.
+
+These cases occur when a space occurs after an odd number of doublequote
+characters. Ergo, the following routine replaced a simpler original loop.
+
+@<Scan past $\alpha$@>=
+{ register int toggle=0;
+ for (p=buf+2;(*p!=' '||toggle)&&*p;p++)
+ if (*p=='"') toggle^=1;
+}
+
+@ A corresponding change to the copying loop is also needed.
+
+@<Copy the buffer to |x->entry|@>=
+{ register int toggle=0;
+ for (p=buf+2,q=x->entry;(*p!=' '||toggle)&&*p;p++) {
+ if (*p=='"') toggle^=1;
+ if (*p!=' ') *q++=*p;
+ }
+ for (;*p;p++) *q++=*p;
+}
+
+@* Index.
diff --git a/Build/source/texk/web2c/cwebdir/system.bux b/Build/source/texk/web2c/cwebdir/system.bux
new file mode 100644
index 00000000000..8a895b161b5
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/system.bux
@@ -0,0 +1,49 @@
+@$memcmp "<string.h>" \zip@>
+@$memcpy "<string.h>" \zip@>
+@$strcat "<string.h>" \zip@>
+@$strcmp "<string.h>" \zip@>
+@$strcpy "<string.h>" \zip@>
+@$strlen "<string.h>" \zip@>
+@$strncmp "<string.h>" \zip@>
+@$strncpy "<string.h>" \zip@>
+
+@$BUFSIZ "<stdio.h>" \zip@>
+@$fclose "<stdio.h>" \zip@>
+@$feof "<stdio.h>" \zip@>
+@$fflush "<stdio.h>" \zip@>
+@$fopen "<stdio.h>" \zip@>
+@$fprintf "<stdio.h>" \zip@>
+@$fputs "<stdio.h>" \zip@>
+@$fread "<stdio.h>" \zip@>
+@$fwrite "<stdio.h>" \zip@>
+@$printf "<stdio.h>" \zip@>
+@$putc "<stdio.h>" \zip@>
+@$putchar "<stdio.h>" \zip@>
+@$puts "<stdio.h>" \zip@>
+@$rename "<stdio.h>" \zip@>
+@$remove "<stdio.h>" \zip@>
+@$sprintf "<stdio.h>" \zip@>
+@$stdout "<stdio.h>" \zip@>
+
+@$getenv "<stdlib.h>" \zip@>
+@$exit "<stdlib.h>" \zip@>
+
+@$isalpha "<ctype.h>" \zip@>
+@$isdigit "<ctype.h>" \zip@>
+@$islower "<ctype.h>" \zip@>
+@$isspace "<ctype.h>" \zip@>
+@$isupper "<ctype.h>" \zip@>
+@$isxdigit "<ctype.h>" \zip@>
+@$tolower "<ctype.h>" \zip@>
+@$toupper "<ctype.h>" \zip@>
+
+@$gettext "<libintl.h>" \zip@>
+@$textdomain "<libintl.h>" \zip@>
+
+@$bool "<stdbool.h>" \zip@>
+@$false "<stdbool.h>" \zip@>
+@$true "<stdbool.h>" \zip@>
+@$ptrdiff_t "<stddef.h>" \zip@>
+@$size_t "<stddef.h>" \zip@>
+@$uint8_t "<stdint.h>" \zip@>
+@$uint16_t "<stdint.h>" \zip@>
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/Xcwebmac.tex b/Build/source/texk/web2c/cwebdir/texinputs/Xcwebmac.tex
new file mode 100644
index 00000000000..c2a8b4115ad
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/Xcwebmac.tex
@@ -0,0 +1,41 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 2.4 --- Don Knuth, June 1992
+% Version 2.4 [p5] --- Hans-Hermann Bode, July 1992
+% Version 2.7 --- Don Knuth, July 1992
+% Version 2.7 [p6] --- Hans-Hermann Bode, September 1992
+% Version 2.8 --- Don Knuth, September 1992
+% Version 2.8 [p7] --- Andreas Scherer, October 1993
+% Version 3.0 --- Don Knuth, June 1993
+% Version 3.0 [p8c] --- Hans-Hermann Bode, June 1993
+% Version 3.0 [p8d] --- Andreas Scherer, October 1993
+% Version 3.0 [p8e] --- Andreas Scherer, November 1993
+% Version 3.1 [p9b] --- Andreas Scherer, January 1994
+% Version 3.1 [p9c] --- Andreas Scherer, June 1994
+% Version 3.2 [p10] --- Andreas Scherer, September 1994
+% Version 3.3 [p11] --- Andreas Scherer, December 1994
+% Version 3.3 [p11a] --- Andreas Scherer, January 1995
+% Version 3.3 [p11b] --- Andreas Scherer, March 1995
+% Version 3.4 [p13] --- Andreas Scherer, May 1996
+% Version 3.4 [p14] --- Andreas Scherer, March 1997
+% Version 3.42 [p15] --- Andreas Scherer, August 1998
+% Version 3.43 [p16] --- Andreas Scherer, October 1998
+% Version 3.5 [p17] --- Andreas Scherer, December 1999
+% Version 3.61 [p18] --- Andreas Scherer, July 2000
+% Version 3.63 [p19] --- Andreas Scherer, January 2001
+% Version 3.64 [p20] --- Andreas Scherer, March 2002
+% Version 3.64 [p21] --- Andreas Scherer, Octobre 2005
+% Version 3.64 [2018] --- Andreas Scherer, Octobre 2018
+% Version 3.64 [2020] --- Andreas Scherer, May 2020
+
+\ifx\undefined\botofcontents\input cwebmac.tex\fi
+
+\xdef\fmtversion{\fmtversion[2020]}
+
+\def\Cpp{\CPLUSPLUS/} % for backward compatibility
+
+\font\tenss=cmss10 \let\cmntfont\tenss % comment font
+
+\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+\def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+
+\let\K=\leftarrow % "honest" alternative to standard assignment operator
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/cweb_ecma94.sty b/Build/source/texk/web2c/cwebdir/texinputs/cweb_ecma94.sty
new file mode 100644
index 00000000000..1ab5bd927ab
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/cweb_ecma94.sty
@@ -0,0 +1,206 @@
+%
+% TEX/LATEX $VER: CWEB_ECMA94.STY 1.12 (13.01.2019)
+%
+% SYNOPSIS:
+% Conversion of umlauts and special characters of the
+% ECMA-94/ISO-Latin-1/ISO-8859-1 charset for plain TeX
+% with the encoding of Computer Modern Font. ISO-8859-1
+% seems to be a standard charset for many conputers and
+% printers (https://en.m.wikipedia.org/wiki/ISO/IEC_8859-1).
+% Some (but not all) characters with codes higher than
+% code 127 are replaced by their TeX equivalents.
+% This encoding is *different* to the DC encoding, which
+% is very popular in the international TeX community.
+%
+% DATE OF CREATION:
+% 11.01.94: Derived from AMIGA.TEX by Georg He{\ss}mann (V1.0)
+%
+% AUTHOR:
+% Andreas Scherer <https://ascherer.github.io/>
+%
+% Please send suggestions (pull requests) and bug reports (issues)
+% to https://github.com/ascherer/cwebbin
+%
+% CHANGES:
+% 12.01.1994: Portable encoding with ^^xx notation for all systems
+% relying on ECMA-94/ISO-Latin-1. Intermediate systems
+% won't destroy its usability. (V1.1)
+% 14.01.1994: $^1$ added for ^^b9 (V1.2)
+% 15.03.1994: `\Cstringchars' implemented for use with
+% the CWEB macros (V1.3)
+% 27.07.1994: Two `\lccode' and `\uccode' bugs fixed. (V1.4)
+% 25.10.1994: Renamed for LaTeX package support. (V1.5)
+% 24.12.1994: Some more characters added. (V1.6)
+% 03.01.1995: Works with LaTeX again. Several modifications
+% according to Alain Aubord's `codepage' package. (V1.7)
+% 25.03.1996: New postal address. (V1.8)
+% 13.08.1998: New e-mail address. (V1.9)
+% 18.08.2011: New postal address. (V1.10)
+% 10.07.2017: Complete overhaul. (V1.11)
+% 13.01.2019: Non-generic names. (V1.12)
+%
+% COPYRIGHT:
+% There is no restriction to the usage of this file.
+%
+% if not(TeX >= 3.0) do_nothing, else ...
+\ifx\undefined\inputlineno \else
+\ifnum\inputlineno=-1 \else
+
+\newif\ifTeX % plain TeX or LaTeX?
+\ifx\undefined\documentclass\TeXtrue\else\TeXfalse\fi
+
+\message{ECMA94-to-TeX conversion}
+
+\lccode`^^a0=`^^a0 \uccode`^^a0=`^^a0 \catcode`^^a0=\active \def ^^a0{~}
+\lccode`^^a1=`^^a1 \uccode`^^a1=`^^a1 \catcode`^^a1=\active \def ^^a1{{!`}}
+% ^^a2 would be ¢
+\lccode`^^a3=`^^a3 \uccode`^^a3=`^^a3 \catcode`^^a3=\active
+ \def ^^a3{\ifTeX{\it\$}\else\pounds\fi}
+
+\lccode`^^a7=`^^a7 \uccode`^^a7=`^^a7 \catcode`^^a7=\active \def ^^a7{{\S}}
+\lccode`^^a8=`^^a8 \uccode`^^a8=`^^a8 \catcode`^^a8=\active \def ^^a8{\"{}}
+\lccode`^^a9=`^^a9 \uccode`^^a9=`^^a9 \catcode`^^a9=\active \def ^^a9{{\copyright}}
+\lccode`^^aa=`^^aa \uccode`^^aa=`^^aa \catcode`^^aa=\active
+ \def ^^aa{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}$\fi}
+% ^^ab would be closing guillemet («)
+\lccode`^^ac=`^^ac \uccode`^^ac=`^^ac \catcode`^^ac=\active
+ \def ^^ac{\ifmmode\lnot\else$\lnot$\fi}
+\lccode`^^ad=`^^ad \uccode`^^ad=`^^ad \catcode`^^ad=\active \def ^^ad{--}
+% ^^ae would be 'registered trade mark' (circled R)
+\lccode`^^af=`^^af \uccode`^^af=`^^af \catcode`^^af=\active \def ^^af{\={}}
+
+\lccode`^^b0=`^^b0 \uccode`^^b0=`^^b0 \catcode`^^b0=\active
+ \def ^^b0{\ifmmode^\circ\else$^\circ$\fi}
+\lccode`^^b1=`^^b1 \uccode`^^b1=`^^b1 \catcode`^^b1=\active
+ \def ^^b1{\ifmmode\pm\else$\pm$\fi}
+\lccode`^^b2=`^^b2 \uccode`^^b2=`^^b2 \catcode`^^b2=\active
+ \def ^^b2{\ifmmode{}^2\else$^2$\fi}
+\lccode`^^b3=`^^b3 \uccode`^^b3=`^^b3 \catcode`^^b3=\active
+ \def ^^b3{\ifmmode{}^3\else$^3$\fi}
+\lccode`^^b4=`^^b4 \uccode`^^b4=`^^b4 \catcode`^^b4=\active \def ^^b4{\'{}}
+\lccode`^^b5=`^^b5 \uccode`^^b5=`^^b5 \catcode`^^b5=\active
+ \def ^^b5{\ifmmode\mu\else$\mu$\fi}
+\lccode`^^b6=`^^b6 \uccode`^^b6=`^^b6 \catcode`^^b6=\active \def ^^b6{{\P}}
+\lccode`^^b7=`^^b7 \uccode`^^b7=`^^b7 \catcode`^^b7=\active
+ \def ^^b7{\ifmmode\cdot\else$\cdot$\fi}
+\lccode`^^b8=`^^b8 \uccode`^^b8=`^^b8 \catcode`^^b8=\active \def ^^b8{\c{}}
+\lccode`^^b9=`^^b9 \uccode`^^b9=`^^b9 \catcode`^^b9=\active
+ \def ^^b9{\ifmmode{}^1\else$^1$\fi}
+\lccode`^^ba=`^^ba \uccode`^^ba=`^^ba \catcode`^^ba=\active
+ \def ^^ba{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}$\fi}
+% ^^bb would be opening guillemet (»)
+
+\def\Fraction#1#2{\ifmmode\ifTeX{#1\over#2}\else\frac{#1}{#2}\fi\else
+ \ifTeX$#1\over#2$\else$\frac{#1}{#2}$\fi\fi}
+
+\lccode`^^bc=`^^bc \uccode`^^bc=`^^bc \catcode`^^bc=\active
+ \def ^^bc{\Fraction{1}{4}}
+\lccode`^^bd=`^^bd \uccode`^^bd=`^^bd \catcode`^^bd=\active
+ \def ^^bd{\Fraction{1}{2}}
+\lccode`^^be=`^^be \uccode`^^be=`^^be \catcode`^^be=\active
+ \def ^^be{\Fraction{3}{4}}
+\lccode`^^bf=`^^bf \uccode`^^bf=`^^bf \catcode`^^bf=\active \def ^^bf{{?`}}
+
+\lccode`^^c0=`^^e0 \uccode`^^c0=`^^c0 \catcode`^^c0=\active \def ^^c0{\`A}
+\lccode`^^c1=`^^e1 \uccode`^^c1=`^^c1 \catcode`^^c1=\active \def ^^c1{\'A}
+\lccode`^^c2=`^^e2 \uccode`^^c2=`^^c2 \catcode`^^c2=\active \def ^^c2{\^A}
+\lccode`^^c3=`^^e3 \uccode`^^c3=`^^c3 \catcode`^^c3=\active \def ^^c3{\~A}
+\lccode`^^c4=`^^e4 \uccode`^^c4=`^^c4 \catcode`^^c4=\active \def ^^c4{\"A}
+\lccode`^^c5=`^^e5 \uccode`^^c5=`^^c5 \catcode`^^c5=\active \def ^^c5{{\AA}}
+\lccode`^^c6=`^^e6 \uccode`^^c6=`^^c6 \catcode`^^c6=\active \def ^^c6{{\AE}}
+\lccode`^^c7=`^^e7 \uccode`^^c7=`^^c7 \catcode`^^c7=\active \def ^^c7{\c{C}}
+\lccode`^^c8=`^^e8 \uccode`^^c8=`^^c8 \catcode`^^c8=\active \def ^^c8{\`E}
+\lccode`^^c9=`^^e9 \uccode`^^c9=`^^c9 \catcode`^^c9=\active \def ^^c9{\'E}
+\lccode`^^ca=`^^ea \uccode`^^ca=`^^ca \catcode`^^ca=\active \def ^^ca{\^E}
+\lccode`^^cb=`^^eb \uccode`^^cb=`^^cb \catcode`^^cb=\active \def ^^cb{\"E}
+\lccode`^^cc=`^^ec \uccode`^^cc=`^^cc \catcode`^^cc=\active \def ^^cc{\`I}
+\lccode`^^cd=`^^ed \uccode`^^cd=`^^cd \catcode`^^cd=\active \def ^^cd{\'I}
+\lccode`^^ce=`^^ee \uccode`^^ce=`^^ce \catcode`^^ce=\active \def ^^ce{\^I}
+\lccode`^^cf=`^^ef \uccode`^^cf=`^^cf \catcode`^^cf=\active \def ^^cf{\"I}
+
+% ^^d0 would be capital 'eth'
+\lccode`^^d1=`^^f1 \uccode`^^d1=`^^d1 \catcode`^^d1=\active \def ^^d1{\~N}
+\lccode`^^d2=`^^f2 \uccode`^^d2=`^^d2 \catcode`^^d2=\active \def ^^d2{\`O}
+\lccode`^^d3=`^^f3 \uccode`^^d3=`^^d3 \catcode`^^d3=\active \def ^^d3{\'O}
+\lccode`^^d4=`^^f4 \uccode`^^d4=`^^d4 \catcode`^^d4=\active \def ^^d4{\^O}
+\lccode`^^d5=`^^f5 \uccode`^^d5=`^^d5 \catcode`^^d5=\active \def ^^d5{\~O}
+\lccode`^^d6=`^^f6 \uccode`^^d6=`^^d6 \catcode`^^d6=\active \def ^^d6{\"O}
+\lccode`^^d7=`^^d7 \uccode`^^d7=`^^d7 \catcode`^^d7=\active
+ \def ^^d7{\ifmmode\times\else$\times$\fi}
+\lccode`^^d8=`^^f8 \uccode`^^d8=`^^d8 \catcode`^^d8=\active \def ^^d8{{\O}}
+\lccode`^^d9=`^^f9 \uccode`^^d9=`^^d9 \catcode`^^d9=\active \def ^^d9{\`U}
+\lccode`^^da=`^^fa \uccode`^^da=`^^da \catcode`^^da=\active \def ^^da{\'U}
+\lccode`^^db=`^^fb \uccode`^^db=`^^db \catcode`^^db=\active \def ^^db{\^U}
+\lccode`^^dc=`^^fc \uccode`^^dc=`^^dc \catcode`^^dc=\active \def ^^dc{\"U}
+\lccode`^^dd=`^^fd \uccode`^^dd=`^^dd \catcode`^^dd=\active \def ^^dd{\'Y}
+% ^^de would be capital 'thorn'
+\lccode`^^df=`^^df \uccode`^^df=`^^df \catcode`^^df=\active \def ^^df{{\ss}}
+
+\lccode`^^e0=`^^e0 \uccode`^^e0=`^^c0 \catcode`^^e0=\active \def ^^e0{\`a}
+\lccode`^^e1=`^^e1 \uccode`^^e1=`^^c1 \catcode`^^e1=\active \def ^^e1{\'a}
+\lccode`^^e2=`^^e2 \uccode`^^e2=`^^c2 \catcode`^^e2=\active \def ^^e2{\^a}
+\lccode`^^e3=`^^e3 \uccode`^^e3=`^^c3 \catcode`^^e3=\active \def ^^e3{\~a}
+\lccode`^^e4=`^^e4 \uccode`^^e4=`^^c4 \catcode`^^e4=\active \def ^^e4{\"a}
+\lccode`^^e5=`^^e5 \uccode`^^e5=`^^c5 \catcode`^^e5=\active \def ^^e5{{\aa}}
+\lccode`^^e6=`^^e6 \uccode`^^e6=`^^c6 \catcode`^^e6=\active \def ^^e6{{\ae}}
+\lccode`^^e7=`^^e7 \uccode`^^e7=`^^c7 \catcode`^^e7=\active \def ^^e7{\c{c}}
+\lccode`^^e8=`^^e8 \uccode`^^e8=`^^c8 \catcode`^^e8=\active \def ^^e8{\`e}
+\lccode`^^e9=`^^e9 \uccode`^^e9=`^^c9 \catcode`^^e9=\active \def ^^e9{\'e}
+\lccode`^^ea=`^^ea \uccode`^^ea=`^^ca \catcode`^^ea=\active \def ^^ea{\^e}
+\lccode`^^eb=`^^eb \uccode`^^eb=`^^cb \catcode`^^eb=\active \def ^^eb{\"e}
+\lccode`^^ec=`^^ec \uccode`^^ec=`^^cc \catcode`^^ec=\active \def ^^ec{{\`\i}}
+\lccode`^^ed=`^^ed \uccode`^^ed=`^^cd \catcode`^^ed=\active \def ^^ed{{\'\i}}
+\lccode`^^ee=`^^ee \uccode`^^ee=`^^ce \catcode`^^ee=\active \def ^^ee{{\^\i}}
+\lccode`^^ef=`^^ef \uccode`^^ef=`^^cf \catcode`^^ef=\active \def ^^ef{{\"\i}}
+
+% ^^f0 would be miniscule 'eth'
+\lccode`^^f1=`^^f1 \uccode`^^f1=`^^d1 \catcode`^^f1=\active \def ^^f1{\~n}
+\lccode`^^f2=`^^f2 \uccode`^^f2=`^^d2 \catcode`^^f2=\active \def ^^f2{\`o}
+\lccode`^^f3=`^^f3 \uccode`^^f3=`^^d3 \catcode`^^f3=\active \def ^^f3{\'o}
+\lccode`^^f4=`^^f4 \uccode`^^f4=`^^d4 \catcode`^^f4=\active \def ^^f4{\^o}
+\lccode`^^f5=`^^f5 \uccode`^^f5=`^^d5 \catcode`^^f5=\active \def ^^f5{\~o}
+\lccode`^^f6=`^^f6 \uccode`^^f6=`^^d6 \catcode`^^f6=\active \def ^^f6{\"o}
+\lccode`^^f7=`^^f7 \uccode`^^f7=`^^f7 \catcode`^^f7=\active
+ \def ^^f7{\ifmmode\div\else$\div$\fi}
+\lccode`^^f8=`^^f8 \uccode`^^f8=`^^d8 \catcode`^^f8=\active \def ^^f8{{\o}}
+\lccode`^^f9=`^^f9 \uccode`^^f9=`^^d9 \catcode`^^f9=\active \def ^^f9{\`u}
+\lccode`^^fa=`^^fa \uccode`^^fa=`^^da \catcode`^^fa=\active \def ^^fa{\'u}
+\lccode`^^fb=`^^fb \uccode`^^fb=`^^db \catcode`^^fb=\active \def ^^fb{\^u}
+\lccode`^^fc=`^^fc \uccode`^^fc=`^^dc \catcode`^^fc=\active \def ^^fc{\"u}
+\lccode`^^fd=`^^fd \uccode`^^fd=`^^dd \catcode`^^fd=\active \def ^^fd{\'y}
+% ^^fe would be miniscule 'thorn'
+\lccode`^^ff=`^^ff \uccode`^^ff=`^^ff \catcode`^^ff=\active \def ^^ff{\"y}
+
+% The following macro supports 8-bit characters in "strings".
+% Not all definitions above are repeated, so you can't use
+% all text characters in strings.
+
+\def\Cstringchars{% Avoid any whitespace!
+ \def ^^a1{{\tt !`}}\def ^^bf{{\tt ?`}}\def ^^c0{{\tt\`A}}%
+ \def ^^c1{{\tt\'A}}\def ^^c2{{\tt\^A}}\def ^^c3{{\tt\~A}}%
+ \def ^^c4{{\tt\"A}}\def ^^c5{{\tt\AA}}\def ^^c6{{\tt\AE}}%
+ \def ^^c7{{\tt\c{C}}}\def ^^c8{{\tt\`E}}\def ^^c9{{\tt\'E}}%
+ \def ^^ca{{\tt\^E}}\def ^^cb{{\tt\"E}}\def ^^cc{{\tt\`I}}%
+ \def ^^cd{{\tt\'I}}\def ^^ce{{\tt\^I}}\def ^^cf{{\tt\"I}}%
+ \def ^^d1{{\tt\~N}}\def ^^d2{{\tt\`O}}\def ^^d3{{\tt\'O}}%
+ \def ^^d4{{\tt\^O}}\def ^^d5{{\tt\~O}}\def ^^d6{{\tt\"O}}%
+ \def ^^d8{{\tt\O}}\def ^^d9{{\tt\`U}}\def ^^da{{\tt\'U}}%
+ \def ^^db{{\tt\^U}}\def ^^dc{{\tt\"U}}\def ^^dd{{\tt\'Y}}%
+ \def ^^df{{\tt\ss}}\def ^^e0{{\tt\`a}}\def ^^e1{{\tt\'a}}%
+ \def ^^e2{{\tt\^a}}\def ^^e3{{\tt\~a}}\def ^^e4{{\tt\"a}}%
+ \def ^^e5{{\tt\aa}}\def ^^e6{{\tt\ae}}\def ^^e7{{\tt\c{c}}}%
+ \def ^^e8{{\tt\`e}}\def ^^e9{{\tt\'e}}\def ^^ea{{\tt\^e}}%
+ \def ^^eb{{\tt\"e}}\def ^^ec{{\tt\`\i}}\def ^^ed{{\tt\'\i}}%
+ \def ^^ee{{\tt\^\i}}\def ^^ef{{\tt\"\i}}\def ^^f1{{\tt\~n}}%
+ \def ^^f2{{\tt\`o}}\def ^^f3{{\tt\'o}}\def ^^f4{{\tt\^o}}%
+ \def ^^f5{{\tt\~o}}\def ^^f6{{\tt\"o}}\def ^^f8{{\tt\o}}%
+ \def ^^f9{{\tt\`u}}\def^^fa{{\tt\'u}}\def ^^fb{{\tt\^u}}%
+ \def ^^fc{{\tt\"u}}\def ^^fd{{\tt\'y}}\def ^^ff{{\tt\"y}}}%
+
+\fi\fi
+
+\endinput
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/cweb_hp8.sty b/Build/source/texk/web2c/cwebdir/texinputs/cweb_hp8.sty
new file mode 100644
index 00000000000..08bac73eb63
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/cweb_hp8.sty
@@ -0,0 +1,184 @@
+%
+% TEX/LATEX $VER: CWEB_HP8.STY 1.9 (13.01.2019)
+%
+% SYNOPSIS:
+% Conversion of umlauts and special characters of the
+% HP Roman8 charset for plain TeX with the encoding of
+% Computer Modern Font. HP Roman8 seems to be a standard
+% charset for some conputers and printers.
+% Some (but not all) characters with codes higher than
+% code 127 are replaced by their TeX equivalents.
+% This encoding is *different* to the DC encoding, which
+% is very popular in the international TeX community.
+%
+% DATE OF CREATION:
+% 14.01.94: Derived from ECMA94.TEX by manual encoding. (V1.0)
+%
+% AUTHOR: Andreas Scherer
+%
+% CHANGES:
+% 15.03.1994: `\Cstringchars' implemented for use with
+% the CWEB macros (V1.1)
+% 27.07.1994: Two `\lccode' and `\uccode' bugs fixed. (V1.2)
+% 25.10.1994: Renamed for LaTeX package support. (V1.3)
+% 24.12.1994: Some more characters added. (V1.4)
+% 03.01.1995: Works with LaTeX again. Several modifications
+% accoding to Alain Aubord's `codepage' package. (V1.5)
+% 25.03.1996: New postal address. (V1.6)
+% 13.08.1998: New e-mail address. (V1.7)
+% 18.08.2011: New postal address. (V1.8)
+% 13.01.2019: Non-generic names. (V1.9)
+%
+% COPYRIGHT:
+% There is no restriction to the usage of this file.
+%
+% if not(TeX >= 3.0) do_nothing, else ...
+\ifx\undefined\inputlineno \else
+\ifnum\inputlineno=-1 \else
+
+\newif\ifTeX % plain TeX or LaTeX?
+\ifx\undefined\documentclass\TeXtrue\else\TeXfalse\fi
+
+\message{HP8-to-TeX conversion}
+
+\lccode`^^a0=`^^a0 \uccode`^^a0=`^^a0 \catcode`^^a0=\active \def ^^a0{~}
+\lccode`^^a1=`^^c8 \uccode`^^a1=`^^a1 \catcode`^^a1=\active \def ^^a1{\`A}
+\lccode`^^a2=`^^c0 \uccode`^^a2=`^^a2 \catcode`^^a2=\active \def ^^a2{\^A}
+\lccode`^^a3=`^^c9 \uccode`^^a3=`^^a3 \catcode`^^a3=\active \def ^^a3{\`E}
+\lccode`^^a4=`^^c1 \uccode`^^a4=`^^a4 \catcode`^^a4=\active \def ^^a4{\^E}
+\lccode`^^a5=`^^cd \uccode`^^a5=`^^a5 \catcode`^^a5=\active \def ^^a5{\"E}
+\lccode`^^a6=`^^d1 \uccode`^^a6=`^^a6 \catcode`^^a6=\active \def ^^a6{\^I}
+\lccode`^^a7=`^^dd \uccode`^^a7=`^^a7 \catcode`^^a7=\active \def ^^a7{\"I}
+\lccode`^^a8=`^^a8 \uccode`^^a8=`^^a8 \catcode`^^a8=\active \def ^^a8{\'{}}
+\lccode`^^a9=`^^a9 \uccode`^^a9=`^^a9 \catcode`^^a9=\active \def ^^a9{\`{}}
+\lccode`^^aa=`^^aa \uccode`^^aa=`^^aa \catcode`^^aa=\active \def ^^aa{\^{}}
+\lccode`^^ab=`^^ab \uccode`^^ab=`^^ab \catcode`^^ab=\active \def ^^ab{\"{}}
+\lccode`^^ac=`^^ac \uccode`^^ac=`^^ac \catcode`^^ac=\active \def ^^ac{\~{}}
+\lccode`^^ad=`^^cb \uccode`^^ad=`^^ad \catcode`^^ad=\active \def ^^ad{\`U}
+\lccode`^^ae=`^^c3 \uccode`^^ae=`^^ae \catcode`^^ae=\active \def ^^ae{\^U}
+\lccode`^^af=`^^af \uccode`^^af=`^^af \catcode`^^af=\active
+ \def ^^af{\ifTeX{\it\$}\else\pounds\fi}
+
+\lccode`^^b0=`^^b0 \uccode`^^b0=`^^b0 \catcode`^^b0=\active \def ^^b0{\={}}
+\lccode`^^b1=`^^b2 \uccode`^^b1=`^^b1 \catcode`^^b1=\active \def ^^b1{\'Y}
+\lccode`^^b2=`^^b2 \uccode`^^b2=`^^b1 \catcode`^^b2=\active \def ^^b2{\'y}
+\lccode`^^b3=`^^b3 \uccode`^^b3=`^^b3 \catcode`^^b3=\active
+ \def ^^b3{\ifmmode^\circ\else$^\circ$\fi}
+\lccode`^^b4=`^^b5 \uccode`^^b4=`^^b4 \catcode`^^b4=\active \def ^^b4{\c{C}}
+\lccode`^^b5=`^^b5 \uccode`^^b5=`^^b4 \catcode`^^b5=\active \def ^^b5{\c{c}}
+\lccode`^^b6=`^^b7 \uccode`^^b6=`^^b6 \catcode`^^b6=\active \def ^^b6{\~N}
+\lccode`^^b7=`^^b7 \uccode`^^b7=`^^b6 \catcode`^^b7=\active \def ^^b7{\~n}
+\lccode`^^b8=`^^b8 \uccode`^^b8=`^^b8 \catcode`^^b8=\active \def ^^b8{{!`}}
+\lccode`^^b9=`^^b9 \uccode`^^b9=`^^b9 \catcode`^^b9=\active \def ^^b9{{?`}}
+
+\lccode`^^bb=`^^bb \uccode`^^bb=`^^bb \catcode`^^bb=\active
+ \def ^^bb{\ifTeX{\it\$}\else\pounds\fi}
+
+\lccode`^^bd=`^^bd \uccode`^^bd=`^^bd \catcode`^^bd=\active \def ^^bd{{\S}}
+\lccode`^^be=`^^be \uccode`^^be=`^^be \catcode`^^be=\active \def ^^be{{\it f\/}}
+
+\lccode`^^c0=`^^c0 \uccode`^^c0=`^^a2 \catcode`^^c0=\active \def ^^c0{\^a}
+\lccode`^^c1=`^^c1 \uccode`^^c1=`^^a4 \catcode`^^c1=\active \def ^^c1{\^e}
+\lccode`^^c2=`^^c2 \uccode`^^c2=`^^df \catcode`^^c2=\active \def ^^c2{\^o}
+\lccode`^^c3=`^^c3 \uccode`^^c3=`^^ae \catcode`^^c3=\active \def ^^c3{\^u}
+\lccode`^^c4=`^^c4 \uccode`^^c4=`^^e0 \catcode`^^c4=\active \def ^^c4{\'a}
+\lccode`^^c5=`^^c5 \uccode`^^c5=`^^dc \catcode`^^c5=\active \def ^^c5{\'e}
+\lccode`^^c6=`^^c6 \uccode`^^c6=`^^e7 \catcode`^^c6=\active \def ^^c6{\'o}
+\lccode`^^c7=`^^c7 \uccode`^^c7=`^^ed \catcode`^^c7=\active \def ^^c7{\'u}
+\lccode`^^c8=`^^c8 \uccode`^^c8=`^^a1 \catcode`^^c8=\active \def ^^c8{\`a}
+\lccode`^^c9=`^^c9 \uccode`^^c9=`^^a3 \catcode`^^c9=\active \def ^^c9{\`e}
+\lccode`^^ca=`^^ca \uccode`^^ca=`^^e8 \catcode`^^ca=\active \def ^^ca{\`o}
+\lccode`^^cb=`^^cb \uccode`^^cb=`^^ad \catcode`^^cb=\active \def ^^cb{\`u}
+\lccode`^^cc=`^^cc \uccode`^^cc=`^^d8 \catcode`^^cc=\active \def ^^cc{\"a}
+\lccode`^^cd=`^^cd \uccode`^^cd=`^^a5 \catcode`^^cd=\active \def ^^cd{\"e}
+\lccode`^^ce=`^^ce \uccode`^^ce=`^^da \catcode`^^ce=\active \def ^^ce{\"o}
+\lccode`^^cf=`^^cf \uccode`^^cf=`^^db \catcode`^^cf=\active \def ^^cf{\"u}
+
+\lccode`^^d0=`^^d4 \uccode`^^d0=`^^d0 \catcode`^^d0=\active \def ^^d0{{\AA}}
+\lccode`^^d1=`^^d1 \uccode`^^d1=`^^a6 \catcode`^^d1=\active \def ^^d1{{\^\i}}
+\lccode`^^d2=`^^d6 \uccode`^^d2=`^^d2 \catcode`^^d2=\active \def ^^d2{{\O}}
+\lccode`^^d3=`^^d7 \uccode`^^d3=`^^d3 \catcode`^^d3=\active \def ^^d3{{\AE}}
+\lccode`^^d4=`^^d4 \uccode`^^d4=`^^d0 \catcode`^^d4=\active \def ^^d4{{\aa}}
+\lccode`^^d5=`^^d5 \uccode`^^d5=`^^e5 \catcode`^^d5=\active \def ^^d5{{\'\i}}
+\lccode`^^d6=`^^d6 \uccode`^^d6=`^^d2 \catcode`^^d6=\active \def ^^d6{{\o}}
+\lccode`^^d7=`^^d7 \uccode`^^d7=`^^d3 \catcode`^^d7=\active \def ^^d7{{\ae}}
+\lccode`^^d8=`^^cc \uccode`^^d8=`^^d8 \catcode`^^d8=\active \def ^^d8{\"A}
+\lccode`^^d9=`^^d9 \uccode`^^d9=`^^e6 \catcode`^^d9=\active \def ^^d9{{\`\i}}
+\lccode`^^da=`^^ce \uccode`^^da=`^^da \catcode`^^da=\active \def ^^da{\"O}
+\lccode`^^db=`^^cf \uccode`^^db=`^^db \catcode`^^db=\active \def ^^db{\"U}
+\lccode`^^dc=`^^c5 \uccode`^^dc=`^^dc \catcode`^^dc=\active \def ^^dc{\'E}
+\lccode`^^dd=`^^dd \uccode`^^dd=`^^a7 \catcode`^^dd=\active \def ^^dd{{\"\i}}
+\lccode`^^de=`^^de \uccode`^^de=`^^de \catcode`^^de=\active \def ^^de{{\ss}}
+\lccode`^^df=`^^c2 \uccode`^^df=`^^df \catcode`^^df=\active \def ^^df{\^O}
+
+\lccode`^^e0=`^^c4 \uccode`^^e0=`^^e0 \catcode`^^e0=\active \def ^^e0{\'A}
+\lccode`^^e1=`^^e2 \uccode`^^e1=`^^e1 \catcode`^^e1=\active \def ^^e1{\~A}
+\lccode`^^e2=`^^e2 \uccode`^^e2=`^^e1 \catcode`^^e2=\active \def ^^e2{\~a}
+
+\lccode`^^e5=`^^d5 \uccode`^^e5=`^^e5 \catcode`^^e5=\active \def ^^e5{\'I}
+\lccode`^^e6=`^^d9 \uccode`^^e6=`^^e6 \catcode`^^e6=\active \def ^^e6{\`I}
+\lccode`^^e7=`^^c6 \uccode`^^e7=`^^e7 \catcode`^^e7=\active \def ^^e7{\'O}
+\lccode`^^e8=`^^ca \uccode`^^e8=`^^e8 \catcode`^^e8=\active \def ^^e8{\`O}
+\lccode`^^e9=`^^ea \uccode`^^e9=`^^e9 \catcode`^^e9=\active \def ^^e9{\~O}
+\lccode`^^ea=`^^ea \uccode`^^ea=`^^e9 \catcode`^^ea=\active \def ^^ea{\~o}
+\lccode`^^eb=`^^ec \uccode`^^eb=`^^eb \catcode`^^eb=\active \def ^^eb{\v{S}}
+\lccode`^^ec=`^^ec \uccode`^^ec=`^^ec \catcode`^^ec=\active \def ^^ec{\v{s}}
+\lccode`^^ed=`^^c7 \uccode`^^ed=`^^ed \catcode`^^ed=\active \def ^^ed{\'U}
+\lccode`^^ee=`^^ef \uccode`^^ee=`^^ee \catcode`^^ee=\active \def ^^ee{\"Y}
+\lccode`^^ef=`^^ef \uccode`^^ef=`^^ee \catcode`^^ef=\active \def ^^ef{\"y}
+
+\lccode`^^f2=`^^f2 \uccode`^^f2=`^^f2 \catcode`^^f2=\active
+ \def ^^f2{\ifmmode\cdot\else$\cdot$\fi}
+\lccode`^^f3=`^^f3 \uccode`^^f3=`^^f3 \catcode`^^f3=\active
+ \def ^^f3{\ifmmode\mu\else$\mu$\fi}
+\lccode`^^f4=`^^f4 \uccode`^^f4=`^^f4 \catcode`^^f4=\active \def ^^f4{{\P}}
+
+\def\Fraction#1#2{\ifmmode\ifTeX{#1\over#2}\else\frac{#1}{#2}\fi\else
+ \ifTeX$#1\over#2$\else$\frac{#1}{#2}$\fi\fi}
+
+\lccode`^^f5=`^^f5 \uccode`^^f5=`^^f5 \catcode`^^f5=\active
+ \def ^^f5{\Fraction{3}{4}}
+\lccode`^^f6=`^^f6 \uccode`^^f6=`^^f6 \catcode`^^f6=\active \def ^^f6{---}
+\lccode`^^f7=`^^f7 \uccode`^^f7=`^^f7 \catcode`^^f7=\active
+ \def ^^f7{\Fraction{1}{4}}
+\lccode`^^f8=`^^f8 \uccode`^^f8=`^^f8 \catcode`^^f8=\active
+ \def ^^f8{\Fraction{1}{2}}
+\lccode`^^f9=`^^f9 \uccode`^^f9=`^^f9 \catcode`^^f9=\active
+ \def ^^f9{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}$\fi}
+\lccode`^^fa=`^^fa \uccode`^^fa=`^^fa \catcode`^^fa=\active
+ \def ^^fa{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}$\fi}
+
+\lccode`^^fe=`^^fe \uccode`^^fe=`^^fe \catcode`^^fe=\active
+ \def ^^fe{\ifmmode\pm\else$\pm$\fi}
+\lccode`^^ff=`^^ff \uccode`^^ff=`^^ff \catcode`^^ff=\active \def ^^ff{~}
+
+\def\Cstringchars{% Avoid any whitespace!
+ \def ^^a1{{\tt\`A}}\def ^^a2{{\tt\^A}}\def ^^a3{{\tt\`E}}%
+ \def ^^a4{{\tt\^E}}\def ^^a5{{\tt\"E}}\def ^^a6{{\tt\^I}}%
+ \def ^^a7{{\tt\"I}}\def ^^ad{{\tt\`U}}\def ^^ae{{\tt\^U}}%
+ \def ^^b1{{\tt\'Y}}\def ^^b2{{\tt\'y}}\def ^^b4{{\tt\c{C}}}%
+ \def ^^b5{{\tt\c{c}}}\def ^^b6{{\tt\~N}}\def ^^b7{{\tt\~n}}%
+ \def ^^b8{{\tt!`}}\def ^^b9{{\tt?`}}\def ^^c0{{\tt\^a}}%
+ \def ^^c1{{\tt\^e}}\def ^^c2{{\tt\^o}}\def ^^c3{{\tt\^u}}%
+ \def ^^c4{{\tt\'a}}\def ^^c5{{\tt\'e}}\def ^^c6{{\tt\'o}}%
+ \def ^^c7{{\tt\'u}}\def ^^c8{{\tt\`a}}\def ^^c9{{\tt\`e}}%
+ \def ^^ca{{\tt\`o}}\def ^^cb{{\tt\`u}}\def ^^cc{{\tt\"a}}%
+ \def ^^cd{{\tt\"e}}\def ^^ce{{\tt\"o}}\def ^^cf{{\tt\"u}}%
+ \def ^^d0{{\tt\AA}}\def ^^d1{{\tt\^\i}}\def ^^d2{{\tt\O}}%
+ \def ^^d3{{\tt\AE}}\def ^^d4{{\tt\aa}}\def ^^d5{{\tt\'\i}}%
+ \def ^^d6{{\tt\o}}\def ^^d7{{\tt\ae}}\def ^^d8{{\tt\"A}}%
+ \def ^^d9{{\tt\`\i}}\def ^^da{{\tt\"O}}\def ^^db{{\tt\"U}}%
+ \def ^^dc{{\tt\'E}}\def ^^dd{{\tt\"\i}}\def ^^de{{\tt\ss}}%
+ \def ^^df{{\tt\^O}}\def ^^e0{{\tt\'A}}\def ^^e1{{\tt\~A}}%
+ \def ^^e2{{\tt\~a}}\def ^^e5{{\tt\'I}}\def ^^e6{{\tt\`I}}%
+ \def ^^e7{{\tt\'O}}\def^^e8{{\tt\`O}}\def ^^e9{{\tt\~O}}%
+ \def ^^ea{{\tt\~o}}\def ^^ed{{\tt\'U}}\def ^^ee{{\tt\"Y}}%
+ \def ^^ef{{\tt\"y}}}%
+
+\fi\fi
+
+\endinput
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/cweb_mac8.sty b/Build/source/texk/web2c/cwebdir/texinputs/cweb_mac8.sty
new file mode 100644
index 00000000000..8c2402a5586
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/cweb_mac8.sty
@@ -0,0 +1,232 @@
+%
+% TEX/LATEX $VER: CWEB_MAC8.STY 1.7 (13.01.2019)
+%
+% SYNOPSIS:
+% Conversion of umlauts and special characters of the
+% Macintosh 8-bit charset for plain TeX with the encoding
+% of Computer Modern Font. Some (but not all) characters
+% with codes higher than code 127 are replaced by their
+% TeX equivalents. This encoding is *different* to the
+% DC encoding, which is very popular in the international
+% TeX community.
+%
+% DATE OF CREATION:
+% 23.06.94: Derived from ECMA94.TEX by manual encoding according
+% to the font table presented by Yannis Haralambous in
+% his article ``A typewriter font for the Macintosh
+% 8-bit font table'', TUGboat 13/4 (1992). (V1.0)
+%
+% AUTHOR: Andreas Scherer
+%
+% CHANGES:
+% 27.07.1994: Two `\lccode' and `\uccode' bugs fixed. (V1.1)
+% 25.10.1994: Renamed for LaTeX package support. (V1.2)
+% 25.12.1994: Some more characters added. (V1.3)
+% 03.01.1995: Works with LaTeX again. Several modifications
+% according to Alain Aubord's `codepage' package. (V1.4)
+% 13.08.1998: New e-mail address. (V1.5)
+% 18.08.2011: New postal address. (V1.6)
+% 13.01.2019: Non-generic names. (V1.7)
+%
+% COPYRIGHT: There is no restriction to the usage of this file.
+%
+% if not(TeX >= 3.0) do_nothing, else ...
+\ifx\undefined\inputlineno \else
+\ifnum\inputlineno=-1 \else
+
+\newif\ifTeX % plain TeX or LaTeX?
+\ifx\undefined\documentclass\TeXtrue\else\TeXfalse\fi
+
+\message{MAC8-to-TeX conversion}
+
+\lccode`^^80=`^^8a \uccode`^^80=`^^80 \catcode`^^80=\active \def ^^80{\"A}
+\lccode`^^81=`^^8c \uccode`^^81=`^^81 \catcode`^^81=\active \def ^^81{{\AA}}
+\lccode`^^82=`^^8d \uccode`^^82=`^^82 \catcode`^^82=\active \def ^^82{\c{C}}
+\lccode`^^83=`^^8e \uccode`^^83=`^^83 \catcode`^^83=\active \def ^^83{\'E}
+\lccode`^^84=`^^96 \uccode`^^84=`^^84 \catcode`^^84=\active \def ^^84{\~N}
+\lccode`^^85=`^^9a \uccode`^^85=`^^85 \catcode`^^85=\active \def ^^85{\"O}
+\lccode`^^86=`^^9f \uccode`^^86=`^^86 \catcode`^^86=\active \def ^^86{\"U}
+\lccode`^^87=`^^87 \uccode`^^87=`^^e7 \catcode`^^87=\active \def ^^87{\'a}
+\lccode`^^88=`^^88 \uccode`^^88=`^^cb \catcode`^^88=\active \def ^^88{\`a}
+\lccode`^^89=`^^89 \uccode`^^89=`^^e5 \catcode`^^89=\active \def ^^89{\^a}
+\lccode`^^8a=`^^8a \uccode`^^8a=`^^80 \catcode`^^8a=\active \def ^^8a{\"a}
+\lccode`^^8b=`^^8b \uccode`^^8b=`^^cc \catcode`^^8b=\active \def ^^8b{\~a}
+\lccode`^^8c=`^^8c \uccode`^^8c=`^^81 \catcode`^^8c=\active \def ^^8c{{\aa}}
+\lccode`^^8d=`^^8d \uccode`^^8d=`^^82 \catcode`^^8d=\active \def ^^8d{\c{c}}
+\lccode`^^8e=`^^8e \uccode`^^8e=`^^83 \catcode`^^8e=\active \def ^^8e{\'e}
+\lccode`^^8f=`^^8f \uccode`^^8f=`^^e9 \catcode`^^8f=\active \def ^^8f{\`e}
+
+\lccode`^^90=`^^90 \uccode`^^90=`^^e6 \catcode`^^90=\active \def ^^90{\^e}
+\lccode`^^91=`^^91 \uccode`^^91=`^^e8 \catcode`^^91=\active \def ^^91{\"e}
+\lccode`^^92=`^^92 \uccode`^^92=`^^ea \catcode`^^92=\active \def ^^92{{\'\i}}
+\lccode`^^93=`^^93 \uccode`^^93=`^^ed \catcode`^^93=\active \def ^^93{{\`\i}}
+\lccode`^^94=`^^94 \uccode`^^94=`^^eb \catcode`^^94=\active \def ^^94{{\^\i}}
+\lccode`^^95=`^^95 \uccode`^^95=`^^ec \catcode`^^95=\active \def ^^95{{\"\i}}
+\lccode`^^96=`^^96 \uccode`^^96=`^^84 \catcode`^^96=\active \def ^^96{\~n}
+\lccode`^^97=`^^97 \uccode`^^97=`^^ee \catcode`^^97=\active \def ^^97{\'o}
+\lccode`^^98=`^^98 \uccode`^^98=`^^f1 \catcode`^^98=\active \def ^^98{\`o}
+\lccode`^^99=`^^99 \uccode`^^99=`^^ef \catcode`^^99=\active \def ^^99{\^o}
+\lccode`^^9a=`^^9a \uccode`^^9a=`^^85 \catcode`^^9a=\active \def ^^9a{\"o}
+\lccode`^^9b=`^^9b \uccode`^^9b=`^^cd \catcode`^^9b=\active \def ^^9b{\~o}
+\lccode`^^9c=`^^9c \uccode`^^9c=`^^f2 \catcode`^^9c=\active \def ^^9c{\'u}
+\lccode`^^9d=`^^9d \uccode`^^9d=`^^f4 \catcode`^^9d=\active \def ^^9d{\`u}
+\lccode`^^9e=`^^9e \uccode`^^9e=`^^f3 \catcode`^^9e=\active \def ^^9e{\^u}
+\lccode`^^9f=`^^9f \uccode`^^9f=`^^86 \catcode`^^9f=\active \def ^^9f{\"u}
+
+\lccode`^^a0=`^^a0 \uccode`^^a0=`^^a0 \catcode`^^a0=\active \def ^^a0{{\dag}}
+\lccode`^^a1=`^^a1 \uccode`^^a1=`^^a1 \catcode`^^a1=\active
+ \def ^^a1{\ifmmode{}^\circ\else$^\circ$\fi}
+
+\lccode`^^a3=`^^a3 \uccode`^^a3=`^^a3 \catcode`^^a3=\active
+ \def ^^a3{\ifTeX{\it\$}\else\pounds\fi}
+\lccode`^^a4=`^^a4 \uccode`^^a4=`^^a4 \catcode`^^a4=\active \def ^^a4{{\S}}
+\lccode`^^a5=`^^a5 \uccode`^^a5=`^^a5 \catcode`^^a5=\active
+ \def ^^a5{\ifmmode\bullet\else$\bullet$\fi}
+\lccode`^^a6=`^^a6 \uccode`^^a6=`^^a6 \catcode`^^a6=\active \def ^^a6{{\P}}
+\lccode`^^a7=`^^a7 \uccode`^^a7=`^^a7 \catcode`^^a7=\active \def ^^a7{{\ss}}
+
+\lccode`^^a9=`^^a9 \uccode`^^a9=`^^a9 \catcode`^^a9=\active \def ^^a9{{\copyright}}
+
+\lccode`^^ac=`^^ac \uccode`^^ac=`^^ac \catcode`^^ac=\active \def ^^ac{\'{}}
+\lccode`^^ad=`^^ad \uccode`^^ad=`^^ad \catcode`^^ad=\active \def ^^ad{\"{}}
+\lccode`^^ae=`^^be \uccode`^^ae=`^^ae \catcode`^^ae=\active \def ^^ae{{\AE}}
+\lccode`^^af=`^^bf \uccode`^^af=`^^af \catcode`^^af=\active \def ^^af{{\O}}
+
+\lccode`^^b0=`^^b0 \uccode`^^b0=`^^b0 \catcode`^^b0=\active
+ \def ^^b0{\ifmmode\infty\else$\infty$\fi}
+\lccode`^^b1=`^^b1 \uccode`^^b1=`^^b1 \catcode`^^b1=\active
+ \def ^^b1{\ifmmode\pm\else$\pm$\fi}
+\lccode`^^b2=`^^b2 \uccode`^^b2=`^^b2 \catcode`^^b2=\active
+ \def ^^b2{\ifmmode\leq\else$\leq$\fi}
+\lccode`^^b3=`^^b3 \uccode`^^b3=`^^b3 \catcode`^^b3=\active
+ \def ^^b3{\ifmmode\geq\else$\geq$\fi}
+
+\lccode`^^b5=`^^b5 \uccode`^^b5=`^^b5 \catcode`^^b5=\active
+ \def ^^b5{\ifmmode\mu\else$\mu$\fi}
+\lccode`^^b6=`^^b6 \uccode`^^b6=`^^b6 \catcode`^^b6=\active
+ \def ^^b6{\ifmmode\partial\else$\partial$\fi}
+\lccode`^^b7=`^^b7 \uccode`^^b7=`^^b7 \catcode`^^b7=\active
+ \def ^^b7{\ifmmode\Sigma\else$\Sigma$\fi}
+\lccode`^^b8=`^^b9 \uccode`^^b8=`^^b8 \catcode`^^b8=\active
+ \def ^^b8{\ifmmode\Pi\else$\Pi$\fi}
+\lccode`^^b9=`^^b9 \uccode`^^b9=`^^b8 \catcode`^^b9=\active
+ \def ^^b9{\ifmmode\pi\else$\pi$\fi}
+\lccode`^^ba=`^^ba \uccode`^^ba=`^^ba \catcode`^^ba=\active
+ \def ^^ba{\ifmmode\int\else$\int$\fi}
+\lccode`^^bb=`^^bb \uccode`^^bb=`^^bb \catcode`^^bb=\active
+ \def ^^bb{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}$\fi}
+\lccode`^^bc=`^^bc \uccode`^^bc=`^^bc \catcode`^^bc=\active
+ \def ^^bc{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}$\fi}
+\lccode`^^bd=`^^bd \uccode`^^bd=`^^bd \catcode`^^bd=\active
+ \def ^^bd{\ifmmode\Omega\else$\Omega$\fi}
+\lccode`^^be=`^^be \uccode`^^be=`^^ae \catcode`^^be=\active \def ^^be{{\ae}}
+\lccode`^^bf=`^^bf \uccode`^^bf=`^^af \catcode`^^bf=\active \def ^^bf{{\o}}
+
+\lccode`^^c0=`^^c0 \uccode`^^c0=`^^c0 \catcode`^^c0=\active \def ^^c0{{?`}}
+\lccode`^^c1=`^^c1 \uccode`^^c1=`^^c1 \catcode`^^c1=\active \def ^^c1{{!`}}
+\lccode`^^c2=`^^c2 \uccode`^^c2=`^^c2 \catcode`^^c2=\active
+ \def ^^c2{\ifmmode\lnot\else$\lnot$\fi}
+\lccode`^^c3=`^^c3 \uccode`^^c3=`^^c3 \catcode`^^c3=\active
+ \def ^^c3{\ifmmode\sqrt{}\else$\sqrt{}$\fi}
+\lccode`^^c4=`^^c4 \uccode`^^c4=`^^c4 \catcode`^^c4=\active \def ^^c4{{\it f\/}}
+\lccode`^^c5=`^^c5 \uccode`^^c5=`^^c5 \catcode`^^c5=\active
+ \def ^^c5{\ifmmode\approx\else$\approx$\fi}
+\lccode`^^c6=`^^c6 \uccode`^^c6=`^^c6 \catcode`^^c6=\active
+ \def ^^c6{\ifmmode\Delta\else$\Delta$\fi}
+
+\lccode`^^c9=`^^c9 \uccode`^^c9=`^^c9 \catcode`^^c9=\active
+ \def ^^c9{\ifmmode\ldots\else$\ldots$\fi}
+\lccode`^^ca=`^^ca \uccode`^^ca=`^^ca \catcode`^^ca=\active \def ^^ca{~}
+\lccode`^^cb=`^^88 \uccode`^^cb=`^^cb \catcode`^^cb=\active \def ^^cb{\`A}
+\lccode`^^cc=`^^8b \uccode`^^cc=`^^cc \catcode`^^cc=\active \def ^^cc{\~A}
+\lccode`^^cd=`^^9b \uccode`^^cd=`^^cd \catcode`^^cd=\active \def ^^cd{\~O}
+\lccode`^^ce=`^^cf \uccode`^^ce=`^^ce \catcode`^^ce=\active \def ^^ce{{\OE}}
+\lccode`^^cf=`^^cf \uccode`^^cf=`^^ce \catcode`^^cf=\active \def ^^cf{{\oe}}
+
+\lccode`^^d0=`^^d0 \uccode`^^d0=`^^d0 \catcode`^^d0=\active \def ^^d0{--}
+\lccode`^^d1=`^^d1 \uccode`^^d1=`^^d1 \catcode`^^d1=\active \def ^^d1{---}
+\lccode`^^d2=`^^d2 \uccode`^^d2=`^^d2 \catcode`^^d2=\active \def ^^d2{``}
+\lccode`^^d3=`^^d3 \uccode`^^d3=`^^d3 \catcode`^^d3=\active \def ^^d3{''}
+\lccode`^^d4=`^^d4 \uccode`^^d4=`^^d4 \catcode`^^d4=\active \def ^^d4{`}
+\lccode`^^d5=`^^d5 \uccode`^^d5=`^^d5 \catcode`^^d5=\active \def ^^d5{'}
+\lccode`^^d6=`^^d6 \uccode`^^d6=`^^d6 \catcode`^^d6=\active
+ \def ^^d6{\ifmmode\div\else$\div$\fi}
+\lccode`^^d7=`^^d7 \uccode`^^d7=`^^d7 \catcode`^^d7=\active
+ \def ^^d7{\ifmmode\diamond\else$\diamond$\fi}
+\lccode`^^d8=`^^d8 \uccode`^^d8=`^^d9 \catcode`^^d8=\active \def ^^d8{\"y}
+\lccode`^^d9=`^^d8 \uccode`^^d9=`^^d9 \catcode`^^d9=\active \def ^^d9{\"Y}
+\lccode`^^da=`^^da \uccode`^^da=`^^da \catcode`^^da=\active
+ \def ^^da{\ifmmode/\else$/$\fi}
+
+\lccode`^^dc=`^^dc \uccode`^^dc=`^^dc \catcode`^^dc=\active
+ \def ^^dc{\ifmmode<\else$<$\fi}
+\lccode`^^dd=`^^dd \uccode`^^dd=`^^dd \catcode`^^dd=\active
+ \def ^^dd{\ifmmode>\else$>$\fi}
+\lccode`^^de=`^^de \uccode`^^de=`^^de \catcode`^^de=\active \def ^^de{fi}
+\lccode`^^df=`^^df \uccode`^^df=`^^df \catcode`^^df=\active \def ^^df{fl}
+
+\lccode`^^e0=`^^e0 \uccode`^^e0=`^^e0 \catcode`^^e0=\active \def ^^e0{\ddag}
+\lccode`^^e1=`^^e1 \uccode`^^e1=`^^e1 \catcode`^^e1=\active
+ \def ^^e1{\ifmmode\cdot\else$\cdot$\fi}
+\lccode`^^e2=`^^e2 \uccode`^^e2=`^^e2 \catcode`^^e2=\active \def ^^e2{,}
+\lccode`^^e3=`^^e3 \uccode`^^e3=`^^e3 \catcode`^^e3=\active \def ^^e3{,\kern-.1em,\/}
+
+\lccode`^^e5=`^^89 \uccode`^^e5=`^^e5 \catcode`^^e5=\active \def ^^e5{\^A}
+\lccode`^^e6=`^^90 \uccode`^^e6=`^^e6 \catcode`^^e6=\active \def ^^e6{\^E}
+\lccode`^^e7=`^^87 \uccode`^^e7=`^^e7 \catcode`^^e7=\active \def ^^e7{\'A}
+\lccode`^^e8=`^^91 \uccode`^^e8=`^^e8 \catcode`^^e8=\active \def ^^e8{\"E}
+\lccode`^^e9=`^^8f \uccode`^^e9=`^^e9 \catcode`^^e9=\active \def ^^e9{\`E}
+\lccode`^^ea=`^^92 \uccode`^^ea=`^^ea \catcode`^^ea=\active \def ^^ea{\'I}
+\lccode`^^eb=`^^94 \uccode`^^eb=`^^eb \catcode`^^eb=\active \def ^^eb{\^I}
+\lccode`^^ec=`^^95 \uccode`^^ec=`^^ec \catcode`^^ec=\active \def ^^ec{\"I}
+\lccode`^^ed=`^^93 \uccode`^^ed=`^^ed \catcode`^^ed=\active \def ^^ed{\`I}
+\lccode`^^ee=`^^97 \uccode`^^ee=`^^ee \catcode`^^ee=\active \def ^^ee{\'O}
+\lccode`^^ef=`^^99 \uccode`^^ef=`^^ef \catcode`^^ef=\active \def ^^ef{\^O}
+
+\lccode`^^f1=`^^98 \uccode`^^f1=`^^f1 \catcode`^^f1=\active \def ^^f1{\`O}
+\lccode`^^f2=`^^9c \uccode`^^f2=`^^f2 \catcode`^^f2=\active \def ^^f2{\'U}
+\lccode`^^f3=`^^9e \uccode`^^f3=`^^f3 \catcode`^^f3=\active \def ^^f3{\^U}
+\lccode`^^f4=`^^9d \uccode`^^f4=`^^f4 \catcode`^^f4=\active \def ^^f4{\`U}
+\lccode`^^f5=`^^f5 \uccode`^^f5=`^^f5 \catcode`^^f5=\active \def ^^f5{{\i}}
+\lccode`^^f6=`^^f6 \uccode`^^f6=`^^f6 \catcode`^^f6=\active \def ^^f6{\^{}}
+\lccode`^^f7=`^^f7 \uccode`^^f7=`^^f7 \catcode`^^f7=\active \def ^^f7{\~{}}
+\lccode`^^f8=`^^f8 \uccode`^^f8=`^^f8 \catcode`^^f8=\active \def ^^f8{\={}}
+\lccode`^^f9=`^^f9 \uccode`^^f9=`^^f9 \catcode`^^f9=\active \def ^^f9{\u{}}
+\lccode`^^fa=`^^fa \uccode`^^fa=`^^fa \catcode`^^fa=\active \def ^^fa{%
+ \ifx\datecontentspage\undefined\.{}\else\:{}\fi}
+\lccode`^^fb=`^^fb \uccode`^^fb=`^^fb \catcode`^^fb=\active \def ^^fb{%
+ \ifx\datecontentspage\undefined\.{}\else\:{}\fi}
+\lccode`^^fc=`^^fc \uccode`^^fc=`^^fc \catcode`^^fc=\active \def ^^fc{\c{}}
+\lccode`^^fd=`^^fd \uccode`^^fd=`^^fd \catcode`^^fd=\active \def ^^fd{\H{}}
+\lccode`^^fe=`^^fe \uccode`^^fe=`^^fe \catcode`^^fe=\active \def ^^fe{\c{}}
+\lccode`^^ff=`^^ff \uccode`^^ff=`^^ff \catcode`^^ff=\active \def ^^ff{\v{}}
+
+\def\Cstringchars{% Avoid any whitespace!
+ \def ^^80{{\tt\"A}}\def ^^81{{\tt\AA}}\def ^^82{{\tt\c{C}}}%
+ \def ^^83{{\tt\'E}}\def ^^84{{\tt\~N}}\def ^^85{{\tt\"O}}%
+ \def ^^86{{\tt\"U}}\def ^^87{{\tt\'a}}\def ^^88{{\tt\`a}}%
+ \def ^^89{{\tt\^a}}\def ^^8a{{\tt\"a}}\def ^^8b{{\tt\~a}}%
+ \def ^^8c{{\tt\aa}}\def ^^8d{{\tt\c{c}}}\def ^^8e{{\tt\'e}}%
+ \def ^^8f{{\tt\`e}}\def ^^90{{\tt\^e}}\def ^^91{{\tt\"e}}%
+ \def ^^92{{\tt\'\i}}\def ^^93{{\tt\`\i}}\def ^^94{{\tt\^\i}}%
+ \def ^^95{{\tt\"\i}}\def ^^96{{\tt\~n}}\def ^^97{{\tt\'o}}%
+ \def ^^98{{\tt\`o}}\def ^^99{{\tt\^o}}\def ^^9a{{\tt\"o}}%
+ \def ^^9b{{\tt\~o}}\def ^^9c{{\tt\'u}}\def ^^9d{{\tt\`u}}%
+ \def ^^9e{{\tt\^u}}\def ^^9f{{\tt\"u}}\def ^^a7{{\tt\ss}}%
+ \def ^^ae{{\tt\AE}}\def ^^af{{\tt\O}}\def ^^be{{\tt\ae}}%
+ \def ^^bf{{\tt\o}}\def ^^c0{{\tt?`}}\def ^^c1{{\tt!`}}%
+ \def ^^cb{{\tt\`A}}\def ^^cc{{\tt\~A}}\def ^^cd{{\tt\~O}}%
+ \def ^^d8{{\tt\"y}}\def ^^d9{{\tt\"Y}}\def ^^e5{{\tt\^A}}%
+ \def ^^e6{{\tt\^E}}\def ^^e7{{\tt\'A}}\def ^^e8{{\tt\"E}}%
+ \def ^^e9{{\tt\`E}}\def ^^ea{{\tt\'I}}\def ^^eb{{\tt\^I}}%
+ \def ^^ec{{\tt\"I}}\def ^^ed{{\tt\`I}}\def ^^ee{{\tt\'O}}%
+ \def ^^ef{{\tt\^O}}\def ^^f1{{\tt\`O}}\def ^^f2{{\tt\'U}}%
+ \def ^^f3{{\tt\^U}}\def ^^f4{{\tt\`U}}}
+
+\fi\fi
+
+\endinput
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/cweb_pc850.sty b/Build/source/texk/web2c/cwebdir/texinputs/cweb_pc850.sty
new file mode 100644
index 00000000000..338795f5619
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/cweb_pc850.sty
@@ -0,0 +1,194 @@
+%
+% TEX/LATEX $VER: CWEB_PC850.STY 1.10 (13.01.2019)
+%
+% SYNOPSIS:
+% Conversion of umlauts and special characters of the
+% PC-850 charset for plain TeX with the encoding of
+% Computer Modern Font. PC-850 seems to be a standard
+% charset for some conputers and printers. Some (but
+% not all) characters with codes higher than code 127
+% are replaced by their TeX equivalents. PC-850 should
+% be almost identical to CodePage 437 used for DOS.
+% This encoding is *different* to the DC encoding, which
+% is very popular in the international TeX community.
+%
+% DATE OF CREATION:
+% 14.01.94: Derived from ECMA94.TEX by manual encoding. (V1.0)
+%
+% AUTHOR: Andreas Scherer
+%
+% COPYRIGHT:
+% There is no restriction to the usage of this file.
+%
+% CHANGES:
+% 15.03.1994: `\Cstringchars' implemented for use with
+% the CWEB macros (V1.1)
+% 13.07.1994: Exchange character positions O374 and 0375. (V1.2)
+% 27.07.1994: Two `\lccode' and `\uccode' bugs fixed. (V1.3)
+% 25.10.1994: Renamed for LaTeX package support. (V1.4)
+% 24.12.1994: Some more characters added. (V1.5)
+% 03.01.1995: Works with LaTeX again. Several modifications
+% according to Alain Aubord's `codepage' package. (V1.6)
+% 25.03.1996: New postal address. (V1.7)
+% 13.08.1998: New e-mail address. (V1.8)
+% 18.08.2011: New postal address. (V1.9)
+% 13.01.2019: Non-generic names. (V1.10)
+%
+% if not(TeX >= 3.0) do_nothing, else ...
+\ifx\undefined\inputlineno \else
+\ifnum\inputlineno=-1 \else
+
+\newif\ifTeX % plain TeX or LaTeX?
+\ifx\undefined\documentclass\TeXtrue\else\TeXfalse\fi
+
+\message{PC850-to-TeX conversion}
+
+\lccode`^^80=`^^87 \uccode`^^80=`^^80 \catcode`^^80=\active \def ^^80{\c{C}}
+\lccode`^^81=`^^81 \uccode`^^81=`^^9a \catcode`^^81=\active \def ^^81{\"u}
+\lccode`^^82=`^^82 \uccode`^^82=`^^90 \catcode`^^82=\active \def ^^82{\'e}
+\lccode`^^83=`^^83 \uccode`^^83=`^^b6 \catcode`^^83=\active \def ^^83{\^a}
+\lccode`^^84=`^^84 \uccode`^^84=`^^8e \catcode`^^84=\active \def ^^84{\"a}
+\lccode`^^85=`^^85 \uccode`^^85=`^^b7 \catcode`^^85=\active \def ^^85{\`a}
+\lccode`^^86=`^^86 \uccode`^^86=`^^8f \catcode`^^86=\active \def ^^86{{\aa}}
+\lccode`^^87=`^^87 \uccode`^^87=`^^80 \catcode`^^87=\active \def ^^87{\c{c}}
+\lccode`^^88=`^^88 \uccode`^^88=`^^d2 \catcode`^^88=\active \def ^^88{\^e}
+\lccode`^^89=`^^89 \uccode`^^89=`^^d3 \catcode`^^89=\active \def ^^89{\"e}
+\lccode`^^8a=`^^8a \uccode`^^8a=`^^d4 \catcode`^^8a=\active \def ^^8a{\`e}
+\lccode`^^8b=`^^8b \uccode`^^8b=`^^d8 \catcode`^^8b=\active \def ^^8b{{\"\i}}
+\lccode`^^8c=`^^8c \uccode`^^8c=`^^d7 \catcode`^^8c=\active \def ^^8c{{\^\i}}
+\lccode`^^8d=`^^8d \uccode`^^8d=`^^de \catcode`^^8d=\active \def ^^8d{{\`\i}}
+\lccode`^^8e=`^^84 \uccode`^^8e=`^^8e \catcode`^^8e=\active \def ^^8e{\"A}
+\lccode`^^8f=`^^86 \uccode`^^8f=`^^8f \catcode`^^8f=\active \def ^^8f{{\AA}}
+
+\lccode`^^90=`^^82 \uccode`^^90=`^^90 \catcode`^^90=\active \def ^^90{\'E}
+\lccode`^^91=`^^91 \uccode`^^91=`^^92 \catcode`^^91=\active \def ^^91{{\ae}}
+\lccode`^^92=`^^91 \uccode`^^92=`^^92 \catcode`^^92=\active \def ^^92{{\AE}}
+\lccode`^^93=`^^93 \uccode`^^93=`^^e2 \catcode`^^93=\active \def ^^93{\^o}
+\lccode`^^94=`^^94 \uccode`^^94=`^^99 \catcode`^^94=\active \def ^^94{\"o}
+\lccode`^^95=`^^95 \uccode`^^95=`^^e3 \catcode`^^95=\active \def ^^95{\`o}
+\lccode`^^96=`^^96 \uccode`^^96=`^^ea \catcode`^^96=\active \def ^^96{\^u}
+\lccode`^^97=`^^97 \uccode`^^97=`^^eb \catcode`^^97=\active \def ^^97{\`u}
+\lccode`^^98=`^^98 \uccode`^^98=`^^98 \catcode`^^98=\active \def ^^98{\"y}
+\lccode`^^99=`^^94 \uccode`^^99=`^^99 \catcode`^^99=\active \def ^^99{\"O}
+\lccode`^^9a=`^^81 \uccode`^^9a=`^^9a \catcode`^^9a=\active \def ^^9a{\"U}
+\lccode`^^9b=`^^9b \uccode`^^9b=`^^9d \catcode`^^9b=\active \def ^^9b{{\o}}
+\lccode`^^9c=`^^9c \uccode`^^9c=`^^9c \catcode`^^9c=\active
+ \def ^^9c{\ifTeX{\it\$}\else\pounds\fi}
+\lccode`^^9d=`^^9b \uccode`^^9d=`^^9d \catcode`^^9d=\active \def ^^9d{{\O}}
+\lccode`^^9e=`^^9e \uccode`^^9e=`^^9e \catcode`^^9e=\active
+ \def ^^9e{\ifmmode\times\else$\times$\fi}
+\lccode`^^9f=`^^9f \uccode`^^9f=`^^9f \catcode`^^9f=\active \def ^^9f{{\it f\/}}
+
+\lccode`^^a0=`^^a0 \uccode`^^a0=`^^b5 \catcode`^^a0=\active \def ^^a0{\'a}
+\lccode`^^a1=`^^a1 \uccode`^^a1=`^^d6 \catcode`^^a1=\active \def ^^a1{{\'\i}}
+\lccode`^^a2=`^^a2 \uccode`^^a2=`^^e0 \catcode`^^a2=\active \def ^^a2{\'o}
+\lccode`^^a3=`^^a3 \uccode`^^a3=`^^e9 \catcode`^^a3=\active \def ^^a3{\'u}
+\lccode`^^a4=`^^a4 \uccode`^^a4=`^^a5 \catcode`^^a4=\active \def ^^a4{\~n}
+\lccode`^^a5=`^^a4 \uccode`^^a5=`^^a5 \catcode`^^a5=\active \def ^^a5{\~N}
+\lccode`^^a6=`^^a6 \uccode`^^a6=`^^a6 \catcode`^^a6=\active
+ \def ^^a6{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{a}}}$\fi}
+\lccode`^^a7=`^^a7 \uccode`^^a7=`^^a7 \catcode`^^a7=\active
+ \def ^^a7{\ifmmode
+ {}^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}\else
+ $^{\hbox{\ifTeX\sevenrm\else\small\fi\b{o}}}$\fi}
+\lccode`^^a8=`^^a8 \uccode`^^a8=`^^a8 \catcode`^^a8=\active \def ^^a8{{?`}}
+
+\lccode`^^aa=`^^aa \uccode`^^aa=`^^aa \catcode`^^aa=\active
+ \def ^^aa{\ifmmode\lnot\else$\lnot$\fi}
+
+\def\Fraction#1#2{\ifmmode\ifTeX{#1\over#2}\else\frac{#1}{#2}\fi\else
+ \ifTeX$#1\over#2$\else$\frac{#1}{#2}$\fi\fi}
+
+\lccode`^^ab=`^^ab \uccode`^^ab=`^^ab \catcode`^^ab=\active
+ \def ^^ab{\Fraction{1}{2}}
+\lccode`^^ac=`^^ac \uccode`^^ac=`^^ac \catcode`^^ac=\active
+ \def ^^ac{\Fraction{1}{4}}
+\lccode`^^ad=`^^ad \uccode`^^ad=`^^ad \catcode`^^ad=\active \def ^^ad{{!`}}
+
+\lccode`^^b5=`^^a0 \uccode`^^b5=`^^b5 \catcode`^^b5=\active \def ^^b5{\'A}
+\lccode`^^b6=`^^83 \uccode`^^b6=`^^b6 \catcode`^^b6=\active \def ^^b6{\^A}
+\lccode`^^b7=`^^85 \uccode`^^b7=`^^b7 \catcode`^^b7=\active \def ^^b7{\`A}
+\lccode`^^b8=`^^b8 \uccode`^^b8=`^^b8 \catcode`^^b8=\active \def ^^b8{{\copyright}}
+
+\lccode`^^c6=`^^c6 \uccode`^^c6=`^^c7 \catcode`^^c6=\active \def ^^c6{\~a}
+\lccode`^^c7=`^^c6 \uccode`^^c7=`^^c7 \catcode`^^c7=\active \def ^^c7{\~A}
+
+\lccode`^^d2=`^^88 \uccode`^^d2=`^^d2 \catcode`^^d2=\active \def ^^d2{\^E}
+\lccode`^^d3=`^^89 \uccode`^^d3=`^^d3 \catcode`^^d3=\active \def ^^d3{\"E}
+\lccode`^^d4=`^^8a \uccode`^^d4=`^^d4 \catcode`^^d4=\active \def ^^d4{\`E}
+\lccode`^^d5=`^^d5 \uccode`^^d5=`^^d5 \catcode`^^d5=\active \def ^^d5{{\i}}
+\lccode`^^d6=`^^a1 \uccode`^^d6=`^^d6 \catcode`^^d6=\active \def ^^d6{\'I}
+\lccode`^^d7=`^^8c \uccode`^^d7=`^^d7 \catcode`^^d7=\active \def ^^d7{\^I}
+\lccode`^^d8=`^^8b \uccode`^^d8=`^^d8 \catcode`^^d8=\active \def ^^d8{\"I}
+
+\lccode`^^de=`^^8d \uccode`^^de=`^^de \catcode`^^de=\active \def ^^de{\`I}
+
+\lccode`^^e0=`^^a2 \uccode`^^e0=`^^e0 \catcode`^^e0=\active \def ^^e0{\'O}
+\lccode`^^e1=`^^e1 \uccode`^^e1=`^^e1 \catcode`^^e1=\active \def ^^e1{{\ss}}
+\lccode`^^e2=`^^93 \uccode`^^e2=`^^e2 \catcode`^^e2=\active \def ^^e2{\^O}
+\lccode`^^e3=`^^95 \uccode`^^e3=`^^e3 \catcode`^^e3=\active \def ^^e3{\`O}
+\lccode`^^e4=`^^e4 \uccode`^^e4=`^^e5 \catcode`^^e4=\active \def ^^e4{\~o}
+\lccode`^^e5=`^^e4 \uccode`^^e5=`^^e5 \catcode`^^e5=\active \def ^^e5{\~O}
+\lccode`^^e6=`^^e6 \uccode`^^e6=`^^e6 \catcode`^^e6=\active
+ \def ^^e6{\ifmmode\mu\else$\mu$\fi}
+
+\lccode`^^e9=`^^a3 \uccode`^^e9=`^^e9 \catcode`^^e9=\active \def ^^e9{\'U}
+\lccode`^^ea=`^^96 \uccode`^^ea=`^^ea \catcode`^^ea=\active \def ^^ea{\^U}
+\lccode`^^eb=`^^97 \uccode`^^eb=`^^eb \catcode`^^eb=\active \def ^^eb{\`U}
+\lccode`^^ec=`^^ec \uccode`^^ec=`^^ed \catcode`^^ec=\active \def ^^ec{\'y}
+\lccode`^^ed=`^^ec \uccode`^^ed=`^^ed \catcode`^^ed=\active \def ^^ed{\'Y}
+\lccode`^^ee=`^^ee \uccode`^^ee=`^^ee \catcode`^^ee=\active \def ^^ee{\={}}
+\lccode`^^ef=`^^ef \uccode`^^ef=`^^ef \catcode`^^ef=\active \def ^^ef{\'{}}
+
+\lccode`^^f0=`^^f0 \uccode`^^f0=`^^f0 \catcode`^^f0=\active \def ^^f0{--}
+\lccode`^^f1=`^^f1 \uccode`^^f1=`^^f1 \catcode`^^f1=\active
+ \def ^^f1{\ifmmode\pm\else$\pm$\fi}
+
+\lccode`^^f3=`^^f3 \uccode`^^f3=`^^f3 \catcode`^^f3=\active
+ \def ^^f3{\Fraction{3}{4}}
+\lccode`^^f4=`^^f4 \uccode`^^f4=`^^f4 \catcode`^^f4=\active \def ^^f4{{\P}}
+\lccode`^^f5=`^^f5 \uccode`^^f5=`^^f5 \catcode`^^f5=\active \def ^^f5{{\S}}
+\lccode`^^f6=`^^f6 \uccode`^^f6=`^^f6 \catcode`^^f6=\active
+ \def ^^f6{\ifmmode\div\else$\div$\fi}
+\lccode`^^f7=`^^f7 \uccode`^^f7=`^^f7 \catcode`^^f7=\active \def ^^f7{\c{}}
+\lccode`^^f8=`^^f8 \uccode`^^f8=`^^f8 \catcode`^^f8=\active
+ \def ^^f8{\ifmmode{}^\circ\else$^\circ$\fi}
+\lccode`^^f9=`^^f9 \uccode`^^f9=`^^f9 \catcode`^^f9=\active \def ^^f9{\"{}}
+\lccode`^^fa=`^^fa \uccode`^^fa=`^^fa \catcode`^^fa=\active
+ \def ^^fa{\ifmmode\cdot\else$\cdot$\fi}
+\lccode`^^fb=`^^fb \uccode`^^fb=`^^fb \catcode`^^fb=\active
+ \def ^^fb{\ifmmode{}^1\else${}^1$\fi}
+\lccode`^^fc=`^^fc \uccode`^^fc=`^^fc \catcode`^^fc=\active
+ \def ^^fc{\ifmmode{}^3\else${}^3$\fi}
+\lccode`^^fd=`^^fd \uccode`^^fd=`^^fd \catcode`^^fd=\active
+ \def ^^fd{\ifmmode{}^2\else${}^2$\fi}
+
+\lccode`^^ff=`^^ff \uccode`^^ff=`^^ff \catcode`^^ff=\active \def ^^ff{~}
+
+\def\Cstringchars{% Avoid any whitespace!
+ \def ^^80{{\tt\c{C}}}\def ^^81{{\tt\"u}}\def ^^82{{\tt\'e}}%
+ \def ^^83{{\tt\^a}}\def ^^84{{\tt\"a}}\def ^^85{{\tt\`a}}%
+ \def ^^86{{\tt\aa}}\def ^^87{{\tt\c{c}}}\def ^^88{{\tt\^e}}%
+ \def ^^89{{\tt\"e}}\def ^^8a{{\tt\`e}}\def ^^8b{{\tt\"\i}}%
+ \def ^^8c{{\tt\^\i}}\def ^^8d{{\tt\`\i}}\def ^^8e{{\tt\"A}}%
+ \def ^^8f{{\tt\AA}}\def ^^90{{\tt\'E}}\def ^^91{{\tt\ae}}%
+ \def ^^92{{\tt\AE}}\def ^^93{{\tt\^o}}\def ^^94{{\tt\"o}}%
+ \def ^^95{{\tt\`o}}\def ^^96{{\tt\^u}}\def ^^97{{\tt\`u}}%
+ \def ^^98{{\tt\"y}}\def ^^99{{\tt\"O}}\def ^^9a{{\tt\"U}}%
+ \def ^^9b{{\tt\o}}\def ^^9d{{\tt\O}}\def ^^a0{{\tt\'a}}%
+ \def ^^a1{{\tt\'\i}}\def ^^a2{{\tt\'o}}\def ^^a3{{\tt\'u}}%
+ \def ^^a4{{\tt\~n}}\def ^^a5{{\tt\~N}}\def ^^a8{{\tt?`}}%
+ \def ^^ad{{\tt!`}}\def ^^b5{{\tt\'A}}\def ^^b6{{\tt\^A}}%
+ \def ^^b7{{\tt\`A}}\def ^^c6{{\tt\~a}}\def ^^c7{{\tt\~A}}%
+ \def ^^d2{{\tt\^E}}\def ^^d3{{\tt\"E}}\def ^^d4{{\tt\`E}}%
+ \def ^^d6{{\tt\'I}}\def ^^d7{{\tt\^I}}\def ^^d8{{\tt\"I}}%
+ \def ^^de{{\tt\`I}}\def ^^e0{{\tt\'O}}\def ^^e1{{\tt\ss}}%
+ \def ^^e2{{\tt\^O}}\def ^^e3{{\tt\`O}}\def ^^e4{{\tt\~o}}%
+ \def ^^e5{{\tt\~O}}\def^^e9{{\tt\'U}}\def ^^ea{{\tt\^U}}%
+ \def ^^eb{{\tt\`U}}\def ^^ec{{\tt\'y}}\def ^^ed{{\tt\'Y}}}%
+
+\fi\fi
+
+\endinput
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/dctproofmac.tex b/Build/source/texk/web2c/cwebdir/texinputs/dctproofmac.tex
new file mode 100644
index 00000000000..09a8de346b6
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/dctproofmac.tex
@@ -0,0 +1,28 @@
+\ifx\undefined\documentclass\input ctproofmac.tex
+\else\endinput\fi % LaTeX will use other macros
+
+\let\acrofalse=\relax
+\input dcwebstrings.tex
+
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \parfillskip 0pt plus 1fil
+ \let\topsecno=\nullsec
+ \redeffin
+ \output={\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1~##2.}}
+ \def\I{\par\hangindent 2em}\let\*=*
+ \readsections}
+\def\con{\par\vfill\eject % finish the section names
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage \output={\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber
+ \redefcon
+ \topofcontents
+ \line{\headerline}
+ \let\ZZ=\contentsline
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/dctwimac.tex b/Build/source/texk/web2c/cwebdir/texinputs/dctwimac.tex
new file mode 100644
index 00000000000..aaba94d4ba2
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/dctwimac.tex
@@ -0,0 +1,12 @@
+\ifx\undefined\documentclass\input ctwimac.tex
+\else\endinput\fi % LaTeX will use other macros
+
+\let\acrofalse=\relax
+\input dcwebstrings.tex
+
+\def\fin{\parfillskip 0pt plus 1fil
+ \let\topsecno=\nullsec
+ \redeffin
+ \def\note##1##2.{\quad{\eightrm##1~##2.}}
+ \def\I{\par\hangindent 2em}\let\*=*
+ \readsections}
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/dcwebmac.tex b/Build/source/texk/web2c/cwebdir/texinputs/dcwebmac.tex
new file mode 100644
index 00000000000..d74e5bff025
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/dcwebmac.tex
@@ -0,0 +1,105 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% modified for use with "tex2pdf" --- March 1997
+% Version 2.0 --- Don Knuth, July 1990
+% Version 2.0 [german] --- Carsten Steger, October 1991
+% Version 2.0 [german] --- Andreas Scherer, February 1993
+% Version 2.7 --- Don Knuth, July 1992
+% Version 2.7 [p6c] --- Andreas Scherer, September 1993
+% Version 2.8 --- Don Knuth, September 1992
+% Version 2.8 [german] --- Carsten Steger, 1993
+% Version 2.8 [p7] --- Andreas Scherer, October 1993
+% Version 3.0 --- Don Knuth, June 1993
+% Version 3.0 [p8e] --- Andreas Scherer, November 1993
+% Version 3.1 [p9b] --- Andreas Scherer, January 1994
+% Version 3.1 [p9c] --- Andreas Scherer, March 1994
+% Version 3.1 [p9d] --- Andreas Scherer, July 1994
+% Version 3.2 [p10] --- Andreas Scherer, August 1994
+% Version 3.2 [p10b] --- Andreas Scherer, October 1994
+% Version 3.3 [p11a] --- Andreas Scherer, December 1994
+% Version 3.3 [p11b] --- Andreas Scherer, March 1995
+% Version 3.4 [p13] --- Andreas Scherer, August 1995
+% Version 3.4 [p14] --- Andreas Scherer, March 1997
+% Version 3.42 [p15] --- Andreas Scherer, August 1998
+% Version 3.43 [p16] --- Andreas Scherer, October 1998
+% Version 3.5 [p17] --- Andreas Scherer, December 1999
+% Version 3.61 [p18] --- Andreas Scherer, July 2000
+% Version 3.63 [p19] --- Andreas Scherer, January 2001
+% Version 3.64 [p20] --- Andreas Scherer, March 2002
+% Version 3.64 [p21] --- Andreas Scherer, Octobre 2005
+% Version 3.64 [p22] --- Andreas Scherer, March 2016
+
+\ifx\undefined\botofcontents\input cwebmac.tex\fi
+
+\input dcwebstrings.tex % German translations for some tags and strings
+
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \ifx\Cstringchars\undefined\else\Cstringchars\fi % special string characters
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ \ifx\originalTeX\undefined\else\originalTeX\fi#1\kern.05em}}
+
+\def\postATL#1 #2 {\bf Buchstabe \\{\uppercase{\char"#1}}
+ wird getangled als \tentex "#2"\egroup\par}
+
+\gtitle={\.{CWEB} Ausgabe} % this running head is reset by starred sections
+\mark{\noexpand\nullsec0{\the\gtitle}}
+
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \ifpdftex \makebookmarks \fi % added in Version 3.68
+ \parfillskip 0pt plus 1fil
+ \let\topsecno=\nullsec
+ \redeffin
+ \output={\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1~\ifacro{\pdfnote##2.}\else{##2}\fi.}}
+ \def\I{\par\hangindent 2em}\let\*=*
+ \ifacro \let\Xpdf\X
+ \ifpdftex \pdfdest name {NOS} fith
+ \pdfoutline goto name {NOS} count -\secno {\outsecname}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
+ \else\ifpdf
+ \special{pdf: outline -1 << /Title (\outsecname)
+ /Dest [ @thispage /FitH @ypos ] >>}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \special{pdf: outline 0 << /Title (\the\toksE)
+ /A << /S /GoTo /D (\romannumeral\the\toksA) >> >>}}
+ \fi\fi\fi
+ \readsections}
+\def\con{\par\vfill\eject % finish the section names
+% \ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage \output={\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber
+ \redefcon
+ \topofcontents \startpdf
+ \line{\headerline}
+ \let\ZZ=\contentsline
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+\def\today{\number\day.~\ifcase\month\or
+ Januar\or Februar\or M\"arz\or April\or Mai\or Juni\or
+ Juli\or August\or September\or Oktober\or November\or Dezember\fi
+ \space\number\year}
+\def\hours{\twodigits=\time \divide\twodigits by60 \printtwodigits
+ \null\space\sc Uhr\space % distinguish between time and year
+ \multiply\twodigits by-60 \advance\twodigits by\time \printtwodigits}
+\def\datethis{\def\startsection{\leftline{\sc\today\ um \hours}\bigskip
+ \let\startsection=\stsec\stsec}}
+ % say `\datethis' in limbo, to get your listing timestamped before section 1
+\def\datecontentspage{% changed in version 3.66
+ \def\botofcontents{\vfill
+ \centerline{\covernote}
+ \bigskip
+ \leftline{\sc\today\ um \hours}}} % timestamps the contents page
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/dcwebstrings.tex b/Build/source/texk/web2c/cwebdir/texinputs/dcwebstrings.tex
new file mode 100644
index 00000000000..055f0ea45b8
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/dcwebstrings.tex
@@ -0,0 +1,40 @@
+% In case `german.sty' has been loaded, we have to redefine the `\3'
+% macro for an optional break within a statement. This should be the
+% first command after `\input german.sty' in your CWEB source.
+\def\originalthree{\def\3##1{\hfil\penalty##10\hfilneg}}
+
+\def\ATH{{\acrofalse\X\kern-.5em:Pr\"aprozessor Definitionen\X}}
+
+\def\A{\note{Siehe auch Abschnitt}} % xref for doubly defined section name
+\def\As{\note{Siehe auch die Abschnitte}}
+ % xref for multiply defined section name
+
+\def\ET{ und~} % conjunction between two section numbers
+\def\ETs{ und~} % conjunction between the last two of several section numbers
+
+\def\Q{\note{Dieser Programmteil wird zitiert in Abschnitt}}
+ % xref for mention of a section
+\def\Qs{\note{Dieser Programmteil wird zitiert in den Abschnitten}}
+ % xref for mentions of a section
+
+\def\U{\note{Dieser Programmteil wird verwendet in Abschnitt}}
+ % xref for use of a section
+\def\Us{\note{Dieser Programmteil wird verwendet in den Abschnitten}}
+ % xref for uses of a section
+
+\def\ch{\note{Die folgenden Abschnitte sind vom Change-File ver\"andert worden:}
+ \let\*=\relax}
+
+\def\redeffin{\message{Abschnittsnamen:}
+ \def\grouptitle{ABSCHNITTSNAMEN}
+ \def\outsecname{Abschnittsnamen}
+ \def\Q{\note{Zitiert in Abschnitt}} % crossref for mention of a section
+ \def\Qs{\note{Zitiert in den Abschnitten}} % crossref for mentions of a section
+ \def\U{\note{Verwendet in Abschnitt}} % crossref for use of a section
+ \def\Us{\note{Verwendet in den Abschnitten}} % crossref for uses of a section
+}
+
+\def\redefcon{\message{Inhaltsverzeichnis:}
+ \def\grouptitle{INHALTSVERZEICHNIS:}
+ \def\headerline{\hfil Abschnitt\hbox to3em{\hss Seite}}
+}
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/fcwebmac.tex b/Build/source/texk/web2c/cwebdir/texinputs/fcwebmac.tex
new file mode 100644
index 00000000000..dde54141b16
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/fcwebmac.tex
@@ -0,0 +1,135 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% modified for use with "tex2pdf" --- March 1997
+% Version 2.0 --- Don Knuth, July 1990
+% Version 2.0 [german] --- Carsten Steger, October 1991
+% Version 2.0 [german] --- Andreas Scherer, February 1993
+% Version 2.7 --- Don Knuth, July 1992
+% Version 2.7 [p6c] --- Andreas Scherer, September 1993
+% Version 2.8 --- Don Knuth, September 1992
+% Version 2.8 [german] --- Carsten Steger, 1993
+% Version 2.8 [p7] --- Andreas Scherer, October 1993
+% Version 3.0 --- Don Knuth, June 1993
+% Version 3.0 [p8e] --- Andreas Scherer, November 1993
+% Version 3.1 [p9b] --- Andreas Scherer, January 1994
+% Version 3.1 [p9c] --- Andreas Scherer, March 1994
+% Version 3.1 [p9d] --- Andreas Scherer, July 1994
+% Version 3.2 [p10] --- Andreas Scherer, July 1994
+% Version 3.2 [p10a] --- Denis B. Roegel, September 1994
+% Version 3.3 [p10b] --- Andreas Scherer, October 1994
+% Version 3.3 [p11b] --- Andreas Scherer, March 1995
+% Version 3.4 [p13] --- Andreas Scherer, August 1995
+% Version 3.4 [p14] --- Andreas Scherer, March 1997
+% Version 3.42 [p15] --- Andreas Scherer, August 1998
+% Version 3.43 [p16] --- Andreas Scherer, October 1998
+% Version 3.5 [p17] --- Andreas Scherer, December 1999
+% Version 3.61 [p18] --- Andreas Scherer, July 2000
+% Version 3.63 [p19] --- Andreas Scherer, January 2001
+% Version 3.64 [p20] --- Andreas Scherer, March 2002
+% Version 3.64 [p21] --- Andreas Scherer, Octobre 2005
+% Version 3.64 [p22] --- Andreas Scherer, March 2016
+
+% french translations --- Denis Roegel, 18 September 1994
+
+\ifx\undefined\botofcontents\input cwebmac.tex\fi
+
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \ifx\Cstringchars\undefined\else\Cstringchars\fi % special string characters
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+
+\def\postATL#1 #2 {\bf La lettre \\{\uppercase{\char"#1}}
+ est \string`\string`tanglee\string'\string' en \tentex "#2"\egroup\par}
+\def\ATH{{\acrofalse\X\kern-.5em:D\'efinitions du pr\'eprocesseur\X}}
+
+\def\A{\note{Voir aussi la section}} % xref for doubly defined section name
+\def\As{\note{Voir aussi les sections}} % xref for multiply defined section name
+
+\def\ET{ et~} % conjunction between two section numbers
+\def\ETs{ et~} % conjunction between the last two of several section numbers
+
+\def\Q{\note{Cette partie du programme est cit\'ee dans la section}}
+ % xref for mention of a section
+\def\Qs{\note{Cette partie du programme est cit\'ee dans les sections}}
+ % xref for mentions of a section
+
+\def\U{\note{Cette partie du programme est utilis\'ee dans la section}}
+ % xref for use of a section
+\def\Us{\note{Cette partie du programme est utilis\'ee dans les sections}}
+ % xref for uses of a section
+
+\gtitle={Sortie \.{CWEB}} % this running head is reset by starred sections
+\mark{\noexpand\nullsec0{\the\gtitle}}
+
+\def\ch{\note{Les sections suivantes ont \'et\'e modifi\'ees dans le
+ Change-File:}\let\*=\relax}
+
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \ifpdftex \makebookmarks \fi % added in Version 3.68
+ \parfillskip 0pt plus 1fil
+ \def\grouptitle{NOMS DES SECTIONS}
+ \let\topsecno=\nullsec
+ \message{Noms des sections:}
+ \output={\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1~\ifacro{\pdfnote##2.}\else{##2}\fi.}}
+ \def\Q{\note{Cit\'e dans la section}} % crossref for mention of a section
+ \def\Qs{\note{Cit\'e dans les sections}} % crossref for mentions of a section
+ \def\U{\note{Utilis\'e dans la section}} % crossref for use of a section
+ \def\Us{\note{Utilis\'e dans les sections}} % crossref for uses of a section
+ \def\I{\par\hangindent 2em}\let\*=*
+ \ifacro \def\outsecname{Noms des sections} \let\Xpdf\X
+% \ifpdftex \makebookmarks \pdfdest name {NOS} fitb % in versions < 3.68
+ \ifpdftex \pdfdest name {NOS} fith % changed in version 3.69
+ \pdfoutline goto name {NOS} count -\secno {\outsecname}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
+ \else\ifpdf
+ \special{pdf: outline -1 << /Title (\outsecname)
+ /Dest [ @thispage /FitH @ypos ] >>}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \special{pdf: outline 0 << /Title (\the\toksE)
+ /A << /S /GoTo /D (\romannumeral\the\toksA) >> >>}}
+ \fi\fi\fi
+ \readsections}
+\def\con{\par\vfill\eject % finish the section names
+% \ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage \output={\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber
+ \def\grouptitle{SOMMAIRE:}
+ \message{Sommaire:}
+ \topofcontents \startpdf
+ \line{\hfil Section\hbox to3em{\hss Page}}
+ \let\ZZ=\contentsline
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+\def\today{\number\day.~\ifcase\month\or
+ Janvier\or F\'evrier\or Mars\or Avril\or Mai\or Juin\or
+ Juillet\or Ao\^ut\or Septembre\or Octobre\or Novembre\or D\'ecembre\fi
+ \space\number\year}
+\def\hours{\twodigits=\time \divide\twodigits by60 \printtwodigits
+ \null\space\sc h\space % distinguish between time and year
+ \multiply\twodigits by-60 \advance\twodigits by\time \printtwodigits}
+\def\datethis{\def\startsection{\leftline{\sc\today\ \`a \hours}\bigskip
+ \let\startsection=\stsec\stsec}}
+ % say `\datethis' in limbo, to get your listing timestamped before section 1
+%\def\datecontentspage{% versions up to 3.65
+% \def\topofcontents{\leftline{\sc\today\ \`a \hours}\bigskip
+% \centerline{\titlefont\title}\vfill}} % timestamps the contents page
+\def\datecontentspage{% changed in version 3.66
+ \def\botofcontents{\vfill
+ \centerline{\covernote}
+ \bigskip
+ \leftline{\sc\today\ \`a \hours}}} % timestamps the contents page
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/icwebmac.tex b/Build/source/texk/web2c/cwebdir/texinputs/icwebmac.tex
new file mode 100644
index 00000000000..6fcafb9e6d7
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/icwebmac.tex
@@ -0,0 +1,156 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% modified for use with "tex2pdf" --- March 1997
+% Version 2.0 --- Don Knuth, July 1990
+% Version 2.0 [german] --- Carsten Steger, October 1991
+% Version 2.0 [german] --- Andreas Scherer, February 1993
+% Version 2.7 --- Don Knuth, July 1992
+% Version 2.7 [p6c] --- Andreas Scherer, September 1993
+% Version 2.8 --- Don Knuth, September 1992
+% Version 2.8 [german] --- Carsten Steger, 1993
+% Version 2.8 [p7] --- Andreas Scherer, October 1993
+% Version 3.0 --- Don Knuth, June 1993
+% Version 3.0 [p8e] --- Andreas Scherer, November 1993
+% Version 3.1 [p9b] --- Andreas Scherer, January 1994
+% Version 3.1 [p9c] --- Andreas Scherer, March 1994
+% Version 3.1 [p9d] --- Andreas Scherer, July 1994
+% Version 3.2 [p10] --- Andreas Scherer, July 1994
+% Version 3.2 [p10a] --- Giuseppe Ghibò, September 1994
+% Version 3.2 [p10b] --- Andreas Scherer, October 1994
+% Version 3.3 [p11b] --- Andreas Scherer, March 1995
+% Version 3.4 [p13] --- Andreas Scherer, August 1995
+% Version 3.4 [p14] --- Andreas Scherer, March 1997
+% Version 3.42 [p15] --- Andreas Scherer, August 1998
+% Version 3.43 [p16] --- Andreas Scherer, October 1998
+% Version 3.5 [p17] --- Andreas Scherer, December 1999
+% Version 3.61 [p18] --- Andreas Scherer, July 2000
+% Version 3.63 [p19] --- Andreas Scherer, January 2001
+% Version 3.64 [p20] --- Andreas Scherer, March 2002
+% Version 3.64 [p21] --- Andreas Scherer, Octobre 2005
+% Version 3.64 [p22] --- Andreas Scherer, March 2016
+
+\ifx\undefined\botofcontents\input cwebmac.tex\fi
+
+\def\.#1{\leavevmode\hbox{\tentex % typewriter type for strings
+ \ifx\Cstringchars\undefined\else\Cstringchars\fi % special string characters
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+
+\def\postATL#1 #2 {\bf lettera \\{\uppercase{\char"#1}}
+ tangles as \tentex "#2"\egroup\par}
+\def\ATH{{\acrofalse\X\kern-.5em:Definizioni preprocessore\X}}
+
+\def\A{\note{Vedi anche sezione}} % xref for doubly defined section name
+\def\As{\note{Vedi anche sezioni}} % xref for multiply defined section name
+
+\def\ET{ e~} % conjunction between two section numbers
+\def\ETs{ e~} % conjunction between the last two of several section numbers
+
+\def\Q{\note{Questo codice \`e citato nella sezione}}
+ % xref for mention of a section
+\def\Qs{\note{Questo codice \`e citato nelle sezioni}}
+ % xref for mentions of a section
+
+\def\U{\note{Questo codice \`e usato nella sezione}}
+ % xref for use of a section
+\def\Us{\note{Questo codice \`e usato nelle sezioni}}
+ % xref for uses of a section
+
+\gtitle={Output \.{CWEB}} % this running head is reset by starred sections
+\mark{\noexpand\nullsec0{\the\gtitle}}
+
+\def\ch{\note{Le seguenti sezioni sono state modificate tramite il change-file:}
+ \let\*=\relax}
+
+\def\inx{\par\vskip6pt plus 1fil % we are beginning the index
+ \def\page{\box255 } \normalbottom
+ \write\cont{} % ensure that the contents file isn't empty
+ \write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+ \closeout\cont % the contents information has been fully gathered
+ \output{\ifpagesaved\normaloutput{\box\sbox}\lheader\rheader\fi
+ \global\setbox\sbox=\page \global\pagesavedtrue}
+ \pagesavedfalse \eject % eject the page-so-far and predecessors
+ \setbox\sbox\vbox{\unvbox\sbox} % take it out of its box
+ \vsize=\pageheight \advance\vsize by -\ht\sbox % the remaining height
+ \hsize=.5\pagewidth \advance\hsize by -10pt
+ % column width for the index (20pt between cols)
+ \parfillskip 0pt plus .6\hsize % try to avoid almost empty lines
+ \def\lr{L} % this tells whether the left or right column is next
+ \output{\if L\lr\global\setbox\lbox=\page \gdef\lr{R}
+ \else\normaloutput{\vbox to\pageheight{\box\sbox\vss
+ \hbox to\pagewidth{\box\lbox\hfil\page}}}\lheader\rheader
+ \global\vsize\pageheight\gdef\lr{L}\global\pagesavedfalse\fi}
+ \message{Indice Analitico:}
+ \parskip 0pt plus .5pt
+ \outer\def\I##1, ##2.{\par\hangindent2em\noindent##1:\kern1em
+ \ifacro\pdfnote##2.\else##2\fi.} % index entry
+ \def\[##1]{$\underline{##1}$} % underlined index item
+ \rm \rightskip0pt plus 2.5em \tolerance 10000 \let\*=\lapstar
+ \hyphenpenalty 10000 \parindent0pt
+ \readindex}
+\def\fin{\par\vfill\eject % this is done when we are ending the index
+ \ifpagesaved\null\vfill\eject\fi % output a null index column
+ \if L\lr\else\null\vfill\eject\fi % finish the current page
+ \ifpdftex \makebookmarks \fi % added in Version 3.68
+ \parfillskip 0pt plus 1fil
+ \def\grouptitle{NOMI DELLE SEZIONI}
+ \let\topsecno=\nullsec
+ \message{Nomi delle sezioni:}
+ \output={\normaloutput\page\lheader\rheader}
+ \setpage
+ \def\note##1##2.{\quad{\eightrm##1~\ifacro{\pdfnote##2.}\else{##2}\fi.}}
+ \def\Q{\note{Citato nella sezione}} % crossref for mention of a section
+ \def\Qs{\note{Citato nelle sezioni}} % crossref for mentions of a section
+ \def\U{\note{Usato nella sezione}} % crossref for use of a section
+ \def\Us{\note{Usato nelle sezioni}} % crossref for uses of a section
+ \def\I{\par\hangindent 2em}\let\*=*
+ \ifacro \def\outsecname{Nomi delle sezioni} \let\Xpdf\X
+% \ifpdftex \makebookmarks \pdfdest name {NOS} fitb % in versions < 3.68
+ \ifpdftex \pdfdest name {NOS} fith % changed in version 3.69
+ \pdfoutline goto name {NOS} count -\secno {\outsecname}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
+ \else\ifpdf
+ \special{pdf: outline -1 << /Title (\outsecname)
+ /Dest [ @thispage /FitH @ypos ] >>}
+ \def\X##1:##2\X{\Xpdf##1:##2\X \firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \special{pdf: outline 0 << /Title (\the\toksE)
+ /A << /S /GoTo /D (\romannumeral\the\toksA) >> >>}}
+ \fi\fi\fi
+ \readsections}
+\def\con{\par\vfill\eject % finish the section names
+% \ifodd\pageno\else\titletrue\null\vfill\eject\fi % for duplex printers
+ \rightskip 0pt \hyphenpenalty 50 \tolerance 200
+ \setpage \output={\normaloutput\page\lheader\rheader}
+ \titletrue % prepare to output the table of contents
+ \pageno=\contentspagenumber
+ \def\grouptitle{INDICE}
+ \message{Indice:}
+ \topofcontents \startpdf
+ \line{\hfil Sezione\hbox to3em{\hss Pag.}}
+ \let\ZZ=\contentsline
+ \readcontents\relax % read the contents info
+ \botofcontents \end} % print the contents page(s) and terminate
+\def\today{\number\day\space\ifcase\month\or
+ gennaio\or febbraio\or marzo\or aprile\or maggio\or giugno\or
+ luglio\or agosto\or settembre\or ottobre\or novembre\or dicembre\fi
+ \space\number\year}
+\def\datethis{\def\startsection{\leftline{\sc\today, ore \hours}\bigskip
+ \let\startsection=\stsec\stsec}}
+ % say `\datethis' in limbo, to get your listing timestamped before section 1
+%\def\datecontentspage{% versions up to 3.65
+% \def\topofcontents{\leftline{\sc\today, ore \hours}\bigskip
+% \centerline{\titlefont\title}\vfill}} % timestamps the contents page
+\def\datecontentspage{% changed in version 3.66
+ \def\botofcontents{\vfill
+ \centerline{\covernote}
+ \bigskip
+ \leftline{\sc\today, ore \hours}}} % timestamps the contents page
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/pdfctwimac.tex b/Build/source/texk/web2c/cwebdir/texinputs/pdfctwimac.tex
new file mode 100644
index 00000000000..346b24095d9
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/pdfctwimac.tex
@@ -0,0 +1,693 @@
+% standard macros for CWEB listings (in addition to plain.tex)
+% Version 4.0 --- February 2021
+% modified for pages produced by CTWILL
+% further modified for page size of the MMIXware book
+% modified for PDF output with 'tex "\let\pdf+', 'pdftex', and 'xetex'
+% This file is not copyrighted and can be used freely.
+\ifx\renewenvironment\undefined\else\endinput\fi % LaTeX will use other macros
+\xdef\fmtversion{\fmtversion+CTWILL4.0+LNCS+PDF}
+
+\newif\ifpdf
+\ifx\pdf+\pdftrue\fi
+% Uncomment the following line if you want PDF goodies to be the default
+%\ifx\pdf-\else\pdftrue\fi
+\def\pdflinkcolor{0 0 1} % the RGB values for hyperlink color
+\ifx\undefined\XeTeXrevision\else\pdftrue\fi % XeTeX produces PDF output
+\newif\ifpdftex
+\ifx\pdfoutput\undefined \pdftexfalse \else\ifnum\pdfoutput=0 \pdftexfalse
+\else \pdftextrue \pdfoutput=1
+ \def\Black{\pdfliteral{0 g 0 G}} % use rgb colors for direct PDF output too
+ \def\PDFlinkcolor{\pdfliteral{\pdflinkcolor\space rg \pdflinkcolor\space RG}}
+\fi\fi
+\newif\ifacro \ifpdf\acrotrue\fi \ifpdftex\acrotrue\fi
+
+\let\:=\. % preserve a way to get the dot accent
+ % (all other accents will still work as usual)
+
+\newdimen\em \em=10pt % this "em" will not change with font size
+\parskip 0pt plus .1pt % almost no stretch between paragraphs
+\parindent 1\em % for paragraphs and for the first line of C text
+
+\newif\ifsorted
+\newread\sreffile
+\newwrite\reffile
+\ifx\norefs\def\else
+ \openin\sreffile=\jobname.sref
+ \ifeof\sreffile \immediate\openout\reffile=\jobname.ref
+ \sortedfalse \message{This is the first pass!}
+ \else \sortedtrue \message{This is the second pass!} \fi
+\fi
+
+\font\ninerm=cmr9
+\let\mc=\ninerm % medium caps
+\def\CEE/{{\mc C\spacefactor1000}}
+\def\UNIX/{{\mc U\kern-.05emNIX\spacefactor1000}}
+\def\TEX/{\TeX}
+\def\CPLUSPLUS/{{\mc C\PP\spacefactor1000}}
+\def\Cee{\CEE/} % for backward compatibility
+\def\9#1{}
+\font\eightrm=cmr8
+\font\sixrm=cmr6
+\font\ninei=cmmi9
+\font\eighti=cmmi8
+\font\sixi=cmmi6
+\skewchar\ninei='177 \skewchar\eighti='177 \skewchar\sixi='177
+\font\ninesy=cmsy9
+\font\eightsy=cmsy8
+\font\sixsy=cmsy6
+\skewchar\ninesy='60 \skewchar\eightsy='60 \skewchar\sixsy='60
+\font\ninebf=cmbx9
+\font\eightbf=cmbx8
+\font\sixbf=cmbx6
+\font\ninett=cmtt9
+\font\eighttt=cmtt8
+\hyphenchar\ninett=-1 \hyphenchar\eighttt=-1
+\font\ninesl=cmsl9
+\font\eightsl=cmsl8
+\font\nineit=cmti9
+\font\eightit=cmti8
+\font\tentex=cmtex10
+\font\ninetex=cmtex9 % TeX extended character set (used in strings)
+\font\eighttex=cmtex8
+\fontdimen7\tentex=0pt % no double space after sentences
+\fontdimen7\ninetex=0pt
+\fontdimen7\eighttex=0pt
+
+\newif\iftenpoint
+\def\tenpoint{\tenpointtrue
+ \def\rm{\fam0\tenrm}%
+ \textfont0=\tenrm \scriptfont0=\sevenrm \scriptscriptfont0=\fiverm
+ \textfont1=\teni \scriptfont1=\seveni \scriptscriptfont1=\fivei
+ \textfont2=\tensy \scriptfont2=\sevensy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\tenit}%
+ \textfont\itfam=\tenit
+ \def\sl{\fam\slfam\tensl}%
+ \textfont\slfam=\tensl
+ \def\bf{\fam\bffam\tenbf}%
+ \textfont\bffam=\tenbf \scriptfont\bffam=\sevenbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\tentt}%
+ \textfont\ttfam=\tentt
+ \def\ttx{\tentex}%
+ \normalbaselineskip=12pt
+ \let\cmntfont=\tenrm
+ \let\mc=\ninerm
+ \let\sc=\eightrm
+ \let\big=\tenbig
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width 0pt}%
+ \normalbaselines\rm}
+
+\def\ninepoint{\tenpointfalse
+ \def\rm{\fam0\ninerm}%
+ \textfont0=\ninerm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\ninei \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\ninesy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\nineit}%
+ \textfont\itfam=\nineit
+ \def\sl{\fam\slfam\ninesl}%
+ \textfont\slfam=\ninesl
+ \def\bf{\fam\bffam\ninebf}%
+ \textfont\bffam=\ninebf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\ninett}%
+ \textfont\ttfam=\ninett
+ \def\ttx{\ninetex}%
+ \normalbaselineskip=11pt
+ \let\cmntfont=\ninerm
+ \let\mc=\eightrm
+ \let\sc=\sevenrm
+ \let\big=\ninebig
+ \setbox\strutbox=\hbox{\vrule height8pt depth3pt width 0pt}%
+ \normalbaselines\rm}
+
+\def\eightpoint{%
+ \def\rm{\fam0\eightrm}%
+ \textfont0=\eightrm \scriptfont0=\sixrm \scriptscriptfont0=\fiverm
+ \textfont1=\eighti \scriptfont1=\sixi \scriptscriptfont1=\fivei
+ \textfont2=\eightsy \scriptfont2=\sixsy \scriptscriptfont2=\fivesy
+ \textfont3=\tenex \scriptfont3=\tenex \scriptscriptfont3=\tenex
+ \def\it{\fam\itfam\eightit}%
+ \textfont\itfam=\eightit
+ \def\sl{\fam\slfam\eightsl}%
+ \textfont\slfam=\eightsl
+ \def\bf{\fam\bffam\eightbf}%
+ \textfont\bffam=\eightbf \scriptfont\bffam=\sixbf
+ \scriptscriptfont\bffam=\fivebf
+ \def\tt{\fam\ttfam\eighttt}%
+ \textfont\ttfam=\eighttt
+ \def\ttx{\eighttex}%
+ \normalbaselineskip=9pt
+ \let\cmntfont=\eightrm
+ \let\mc=\sevenrm
+ \let\sc=\sixrm
+ \let\big=\eightbig
+ \setbox\strutbox=\hbox{\vrule height7pt depth2pt width 0pt}%
+ \normalbaselines\rm}
+
+\tenpoint
+\def\tenbig#1{{\hbox{$\left#1\vbox to8.5pt{}\right.\nulldelimiterspace=0pt$}}}
+\def\ninebig#1{{\hbox{$\textfont0=\tenrm\textfont2=\tensy
+ \left#1\vbox to7.25pt{}\right.\nulldelimiterspace=0pt$}}}
+\def\eightbig#1{{\hbox{$\textfont0=\ninerm\textfont2=\ninesy
+ \left#1\vbox to6.5pt{}\right.\nulldelimiterspace=0pt$}}}
+
+%\font\tenss=cmss10 \let\cmntfont\tenss % alternative comment font
+\font\titlefont=cmr7 scaled\magstep4 % title on the contents page
+\font\ttitlefont=cmtt10 scaled\magstep2 % typewriter type in title
+
+\def\\#1{\leavevmode\hbox{\it#1\/\kern.05em}} % italic type for identifiers
+\def\|#1{\leavevmode\hbox{$#1$}} % one-letter identifiers look better this way
+\def\&#1{\leavevmode\hbox{\bf
+ \def\_{\kern.04em\vbox{\hrule width.3em height .6pt}\kern.08em}%
+ #1\/\kern.05em}} % boldface type for reserved words
+\def\.#1{\leavevmode\hbox{\ttx % typewriter type for strings
+ \let\\=\BS % backslash in a string
+ \let\{=\LB % left brace in a string
+ \let\}=\RB % right brace in a string
+ \let\~=\TL % tilde in a string
+ \let\ =\SP % space in a string
+ \let\_=\UL % underline in a string
+ \let\&=\AM % ampersand in a string
+ \let\^=\CF % circumflex in a string
+ #1\kern.05em}}
+\def\){{\tentex\kern-.05em}\discretionary{\hbox{\tentex\BS}}{}{}}
+\def\AT{@} % at sign for control text (not needed in versions >= 2.9)
+\def\ATL{\par\noindent\bgroup\catcode`\_=12 \postATL} % print @l in limbo
+\def\postATL#1 #2 {\bf letter \\{\uppercase{\char"#1}}
+ tangles as \tentex "#2"\egroup\par}
+\def\noATL#1 #2 {}
+\def\noatl{\let\ATL=\noATL} % suppress output from @l
+\def\ATH{{\acrofalse\X\kern-.5em:Preprocessor definitions\X}}
+\let\PB=\relax % hook for program brackets |...| in TeX part or section name
+
+\chardef\AM=`\& % ampersand character in a string
+\chardef\BS=`\\ % backslash in a string
+\chardef\LB=`\{ % left brace in a string
+\chardef\RB=`\} % right brace in a string
+\def\SP{{\tt\char`\ }} % (visible) space in a string
+\chardef\TL=`\~ % tilde in a string
+\chardef\UL=`\_ % underline character in a string
+\chardef\CF=`\^ % circumflex character in a string
+
+\newbox\PPbox % symbol for ++
+\setbox\PPbox=\hbox{\kern.5pt\raise1pt\hbox{\sevenrm+\kern-1pt+}\kern.5pt}
+\def\PP{\copy\PPbox}
+\newbox\MMbox \setbox\MMbox=\hbox{\kern.5pt\raise1pt\hbox{\sevensy\char0
+ \kern-1pt\char0}\kern.5pt}
+\def\MM{\copy\MMbox}
+\newbox\MGbox % symbol for ->
+\setbox\MGbox=\hbox{\kern-2pt\lower3pt\hbox{\teni\char'176}\kern1pt}
+\def\MG{\copy\MGbox}
+\def\MRL#1{\mathrel{\let\K==#1}}
+\let\GG=\gg
+\let\LL=\ll
+\let\NULL=\Lambda
+\mathchardef\AND="2026 % bitwise and; also \& (unary operator)
+\let\OR=\mid % bitwise or
+\let\XOR=\oplus % bitwise exclusive or
+\def\CM{{\sim}} % bitwise complement
+\newbox\MODbox \setbox\MODbox=\hbox{\eightrm\%}
+\def\MOD{\mathbin{\copy\MODbox}}
+\def\DC{\kern.1em{::}\kern.1em} % symbol for ::
+\def\PA{\mathbin{.*}} % symbol for .*
+\def\MGA{\mathbin{\MG*}} % symbol for ->*
+\def\this{\&{this}}
+
+\newbox\bak \setbox\bak=\hbox to -1\em{} % backspace one em
+\newbox\bakk\setbox\bakk=\hbox to -2\em{} % backspace two ems
+
+\newcount\ind % current indentation in ems
+\def\1{\global\advance\ind by1\hangindent\ind\em} % indent one more notch
+\def\2{\global\advance\ind by-1} % indent one less notch
+\def\3#1{\hfil\penalty#10\hfilneg} % optional break within a statement
+\def\4{\copy\bak} % backspace one notch
+\def\5{\hfil\penalty-1\hfilneg\kern2.5\em\copy\bakk\ignorespaces}% optional break
+\def\6{\ifmmode\else\par % forced break
+ \hangindent\ind\em\noindent\kern\ind\em\copy\bakk\ignorespaces\fi}
+\def\7{\Y\6} % forced break and a little extra space
+\def\8{\hskip-\ind\em\hskip 2\em} % no indentation
+
+\newcount\gdepth % depth of current major group, plus one
+\newtoks\gtitle % title of current major group
+\newskip\intersecskip \intersecskip=12pt minus 3pt % space between sections
+\let\yskip=\smallskip
+\def\?{\mathrel?}
+\def\note#1#2.{\par\penalty5000
+ \Y\noindent{\hangindent2\em\baselineskip10pt%
+ \eightrm#1~\ifacro{\pdfnote#2.}\else#2\fi.\par}}
+
+\newtoks\toksA \newtoks\toksB \newtoks\toksC \newtoks\toksD
+\newtoks\toksE \newtoks\toksF \newtoks\usersanitizer
+\newcount\countA \countA=0 \newcount\countB \countB=0
+\newcount\countC \countC=0
+\newif\iftokprocessed \newif\ifTnum \newif\ifinstr
+{\def\\{\global\let\spacechar= }\\ }
+
+\ifacro % The following are pdf macros
+\def\thewidth{\the\wd0 \space}
+\def\theheight{\the\ht\strutbox\space}
+\def\thedepth{\the\dp\strutbox\space}
+\ifpdftex
+ \ifx\pdfannotlink\undefined\let\pdfannotlink\pdfstartlink\fi% for pdfTeX 0.14
+ \def\pdflink#1#2{\hbox{\pdfannotlink height\ht\strutbox depth\dp\strutbox
+ attr{/Border [0 0 0]} goto num #1 \PDFlinkcolor #1\Black\pdfendlink}}
+\else\def\pdflink#1#2{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth height \theheight
+ depth \thedepth << /Type /Annot /Subtype /Link
+ /Border [0 0 0] /A << /S /GoTo /D (#2) >> >>}\box0\relax}\fi
+\def\pdfnote#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}\maketoks}\the\toksA}
+\def\firstsecno#1.{\setbox0=\hbox{\toksA={#1.}\toksB={}%
+ \def\makenote{\addtokens\toksB{\the\toksC}\def\makenote{\toksD={}
+ \toksC={}\let\space\empty}\makenote}\maketoks}}
+\def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+\def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}%
+ \ifcat\noexpand\first0\countB=`#1\else\countB=0\fi\toksA={#2}}
+\def\maketoks{\expandafter\poptoks\the\toksA|ENDTOKS|%
+ \ifnum\countB>`9 \countB=0 \fi
+ \ifnum\countB<`0
+ \ifnum0=\countC\else\makenote\fi
+ \ifx\first.\let\next=\maketoksdone\else
+ \let\next=\maketoks
+ \addtokens\toksB{\the\toksD}
+ \ifx\first,\addtokens\toksB{\space}\fi
+ \fi
+ \else \addtokens\toksC{\the\toksD}\global\countC=1\let\next=\maketoks
+ \fi
+ \next
+}
+\def\makenote{\addtokens\toksB
+ {\noexpand\pdflink{\the\toksC}{\romannumeral\the\toksC}}\toksC={}\global\countC=0}
+\def\maketoksdone{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\def\pdfURL#1#2{\ifpdftex\pdfannotlink height\ht\strutbox depth\dp\strutbox
+ attr {/Border [0 0 0]} user {/Type /Action /Subtype /Link /A
+ << /S /URI /URI (#2) >>}\PDFlinkcolor #1\Black \pdfendlink
+ \else\ifpdf{\setbox0=\hbox{\special{pdf: bc [ \pdflinkcolor ]}{#1}%
+ \special{pdf: ec}}\special{pdf: ann width \thewidth\space height \theheight
+ \space depth \thedepth\space << /Border [0 0 0]
+ /Type /Action /Subtype /Link /A << /S /URI /URI (#2) >> >>}\box0\relax}%
+ \else #1 ({\tt#2})\fi\fi}
+{\catcode`\~=12 \gdef\TILDE/{~}} % ~ in a URL
+{\catcode`\_=12 \gdef\UNDER/{_}} % _ in a URL
+\def\sanitizecommand#1#2{\addtokens\usersanitizer
+ {\noexpand\dosanitizecommand\noexpand#1{#2}}}
+\def\dosanitizecommand#1#2{\ifx\nxt#1\addF{#2}\fi}
+
+\catcode`\[=1 \catcode`\]=2 \catcode`\{=12 \catcode`\}=12
+ \def\lbchar[{] \def\rbchar[}]
+\catcode`\[=12 \catcode`\]=12 \catcode`\{=1 \catcode`\}=2
+\catcode`\~=12 \def\tildechar{~} \catcode`\~=13
+\catcode`\|=0 |catcode`|\=12 |def|bschar{\} |catcode`|\=0 \catcode`\|=12
+\def\makeoutlinetoks{\Tnumfalse\afterassignment\makeolproctok\let\nxt= }
+\def\makeolnexttok{\afterassignment\makeolproctok\let\nxt= }
+\def\makeolgobbletok{\afterassignment\makeolnexttok\let\nxt= }
+\def\addF#1{\addtokens\toksF{#1}\tokprocessedtrue}
+% now comes a routine to "sanitize" section names, for pdf outlines
+\def\makeolproctok{\tokprocessedfalse
+ \let\next\makeolnexttok % default
+ \ifx\nxt\outlinedone\let\next\outlinedone
+ \else\ifx{\nxt \else\ifx}\nxt \Tnumfalse \instrfalse % skip braces
+ \else\ifx$\nxt % or a $ sign
+ \else\ifx^\nxt \addF^\else\ifx_\nxt \addF_% sanitize ^ and _
+ \else\ifx\nxt\spacechar \addF\space
+ \else\if\noexpand\nxt\relax % we have a control sequence; is it one we know?
+ \ifx\nxt~\addF\space
+ \else\ifx\nxt\onespace\addF\space
+ \else\the\usersanitizer
+ \iftokprocessed\else\makeolproctokctli
+ \iftokprocessed\else\makeolproctokctlii
+ \iftokprocessed\else\makeolproctokctliii % if not recognised, skip it
+ \fi\fi\fi\fi\fi
+ \else % we don't have a control sequence, it's an ordinary char
+ \ifx/\nxt \addF{\string\/}% quote chars special to PDF with backslash
+ \else\ifx(\nxt \addF{\string\(}\else\ifx)\nxt \addF{\string\)}%
+ \else\ifx[\nxt \addF{\string\[}\else\ifx]\nxt \addF{\string\]}%
+ \else\expandafter\makeolproctokchar\meaning\nxt
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \next
+}
+\def\makeolproctokchar#1 #2 #3{\addF{#3}}
+\def\makeolproctokctli{%
+ \ifx\nxt\CEE\addF{C}\let\next\makeolgobbletok % \CEE/
+ \else\ifx\nxt\UNIX\addF{UNIX}\let\next\makeolgobbletok % \UNIX/
+ \else\ifx\nxt\TEX\addF{TeX}\let\next\makeolgobbletok % \TEX/
+ \else\ifx\nxt\TeX\addF{TeX}\else\ifx\nxt\LaTeX\addF{LaTeX}%
+ \else\ifx\nxt\CPLUSPLUS\addF{C++}\let\next\makeolgobbletok % \CPLUSPLUS/
+ \else\ifx\nxt\Cee\addF{C}%
+ \else\ifx\nxt\PB \let\next\makeolgobbletok \tokprocessedtrue % \PB{...}
+ \else\ifx\nxt\.\tokprocessedtrue\instrtrue % \.{...}
+ % skip \|
+ \else\ifx\nxt\\\ifinstr\addF{\bschar\bschar}\else\tokprocessedtrue\fi
+ \else\ifx\nxt\&\ifinstr\addF&\else\tokprocessedtrue\fi
+ \else\ifx\nxt\~\ifTnum\addF{0}\else\addF\tildechar\fi % 077->\T{\~77}
+ \else\ifx\nxt\_\ifTnum\addF{E}\else\addF_\fi % 0.1E5->\T{0.1\_5}
+ \else\ifx\nxt\^\ifTnum\addF{0x}\else\addF^\fi % 0x77 -> \T{\^77}
+ \else\ifx\nxt\$\ifTnum\tokprocessedtrue\else\addF$\fi %$% \T{77\$L}
+ \else\ifx\nxt\{\addF\lbchar \else\ifx\nxt\}\addF\rbchar
+ \else\ifx\nxt\ \addF\space \else\ifx\nxt\#\addF{\string\#}%
+ \else\ifx\nxt\PP\addF{++}\else\ifx\nxt\MM\addF{--}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+}
+\def\makeolproctokctlii{%
+ \ifx\nxt\MG\addF{->}\else\ifx\nxt\GG\addF{>>}%
+ \else\ifx\nxt\LL\addF{<<}\else\ifx\nxt\NULL\addF{NULL}%
+ \else\ifx\nxt\AND\addF&\else\ifx\nxt\OR\addF|%
+ \else\ifx\nxt\XOR\addF^\else\ifx\nxt\CM\addF\tildechar
+ \else\ifx\nxt\MOD\addF{\string\%}\else\ifx\nxt\DC\addF{::}%
+ \else\ifx\nxt\PA\addF{.*}\else\ifx\nxt\MGA\addF{->*}%
+ \else\ifx\nxt\this\addF{this}\else\ifx\nxt\?\addF?%
+ \else\ifx\nxt\E\addF{==}\else\ifx\nxt\G\addF{>=}%
+ \else\ifx\nxt\I\addF{!=}\else\ifx\nxt\K\addF{=}%
+ \else\ifx\nxt\l\addF{l}\else\ifx\nxt\L\addF{L}%
+ \else\ifx\nxt\o\addF{o}\else\ifx\nxt\O\addF{O}%
+ \else\ifx\nxt\R\addF!%
+ \else\ifx\nxt\T \Tnumtrue \let\next\makeolgobbletok
+ \tokprocessedtrue % \T{number}
+ \else\ifx\nxt\AM\addF&\else\ifx\nxt\%\addF{\string\%}%
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi \fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi\fi
+}
+\def\makeolproctokctliii{%
+ \ifx\nxt\V\addF{||}\else\ifx\nxt\W\addF{&&}\else\ifx\nxt\Z\addF{<=}%
+ \else\ifx\nxt\*\addF*\else\ifx\nxt\Xand\addF{\space and\space}%
+ \else\ifx\nxt\Xandxeq\addF{\space and_eq\space}%
+ \else\ifx\nxt\Xbitand\addF{\space bitand\space}%
+ \else\ifx\nxt\Xbitor\addF{\space bitor\space}%
+ \else\ifx\nxt\Xcompl\addF{\space compl\space}%
+ \else\ifx\nxt\Xnot\addF{\space not\space}%
+ \else\ifx\nxt\Xnotxeq\addF{\space not_eq\space}%
+ \else\ifx\nxt\Xor\addF{\space or\space}%
+ \else\ifx\nxt\Xorxeq\addF{\space or_eq\space}%
+ \else\ifx\nxt\Xxor\addF{\space xor\space}%
+ \else\ifx\nxt\Xxorxeq\addF{\space xor_eq\space}%
+ \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+ \fi\fi\fi\fi\fi
+}
+\def\outlinedone{\edef\outlinest{\global\noexpand\toksE={\the\toksF}}%
+ \outlinest\let\outlinedone=\relax}
+\fi % End of pdf macros
+
+\def\lapstar{\rlap{*}}
+\def\stsec{\tenpoint\rightskip=0pt % get out of C mode (cf. \B)
+ \sfcode`;=1500 \pretolerance 200 \hyphenpenalty 50 \exhyphenpenalty 50
+ \noindent\strut{\let\*=\lapstar\bf\secno.\quad}%
+ \ifacro \smash{\raise\baselineskip\hbox to0pt{\let\*=\empty
+ \ifpdftex \pdfdest num \secstar fith%
+ \else \special{pdf: dest (\romannumeral\secstar)
+ [ @thispage /FitH @ypos ]}\fi}}\fi}
+\def\startsection{\titletrue
+ \line{\smash{\titlefont\title}\quad\hrulefill}\bigskip
+ \let\startsection=\stsec\stsec}
+\def\defin#1{\global\advance\ind by 2 \1\&{#1 } } % begin `define' or `format'
+\def\A{\note{See also section}} % xref for doubly defined section name
+\def\As{\note{See also sections}} % xref for multiply defined section name
+\def\B{\iftenpoint\ninepoint\fi
+ \font\niness=cmss9 \let\cmntfont\niness % alternative comment font
+ \rightskip=0pt plus 100pt minus 10pt % go into C mode
+ \sfcode`;=3000
+ \pretolerance 10000
+ \hyphenpenalty 9999 % so strings can be broken (discretionary \ is inserted)
+ \exhyphenpenalty 10000
+ \global\ind=2 \1\ \unskip}
+%\def\C#1{\5\5\quad$/\ast\,${\cmntfont #1}$\,\ast/$}
+%\let\SHC\C % "// short comments" treated like "/* ordinary comments */"
+\def\C#1{\5\5\quad$\triangleright\,${\cmntfont#1}$\,\triangleleft$}
+\def\SHC#1{\5\5\quad$\diamond\,${\cmntfont#1}}
+\def\D{\defin{\#define}} % macro definition
+\let\E=\equiv % equivalence sign
+\def\ET{ and~} % conjunction between two section numbers
+\def\ETs{, and~} % conjunction between the last two of several section numbers
+\def\F{\defin{format}} % format definition
+\let\G=\ge % greater than or equal sign
+% \H is long Hungarian umlaut accent
+\let\I=\ne % unequal sign
+\def\J{\.{@\&}} % TANGLE's join operation
+%\let\K== % assignment operator
+\let\K=\leftarrow % "honest" alternative to standard assignment operator
+% \L is Polish letter suppressed-L
+\outer\def\M#1{%
+ {\xdef\secstar{#1}\let\*=\empty\xdef\secno{#1}}% remove \* from section name
+ \vskip\intersecskip\startsection\ignorespaces}
+\outer\def\N{\ifvoid\partialpage\lefttrue
+ \else\ifdim\ht\partialpage<\pageht \leftfalse\else\lefttrue\fi\fi\NNN}
+\outer\def\NN{\ifvoid\partialpage\leftfalse
+ \else\ifdim\ht\partialpage<\pageht \lefttrue\else\leftfalse\fi\fi\NNN}
+\outer\def\NNN#1#2#3.{% beginning of starred section
+ \ifacro{\toksF={}\makeoutlinetoks#3\outlinedone\outlinedone}\fi
+ \gdepth=#1\gtitle={#3}\def\secno{#2}\xdef\secstar{#2}
+ \ifleft \flushout
+ \gdef\rlhead{\let\i=I\uppercase{\ignorespaces#3}} % running left headline
+ \global\let\rrhead=\rlhead % running right headline
+ \else\global\setbox\partialpage=\vbox{
+ \vbox to\pageht{\unvbox\partialpage\vfill}\break}
+ \gdef\rrhead{\let\i=I\uppercase{\ignorespaces#3}}
+ \fi
+ \message{*\secno} % progress report
+ \ifpdftex\def\stripprefix##1>{}\def\gtitletoks{#3}%
+ \edef\gtitletoks{\expandafter\stripprefix\meaning\gtitletoks}%
+ {\immediate\write\cont{\ZZ{\gtitletoks}{#1}{\secno}% write to contents file
+ {\noexpand\the\pageno}{\the\toksE}}} % \ZZ{title}{depth}{sec}{page}{ss}
+ \expandafter\xdef\csname curr#1\endcsname{\secno}
+ \ifnum#1>0\countB=#1 \advance\countB by-1
+ \advancenumber{chunk\the\countB.\expnumber{curr\the\countB}}\fi
+ \else\ifpdf\special{pdf: outline #1 << /Title (\the\toksE) /Dest
+ [ @thispage /FitH @ypos ] >>}\fi\fi
+ \startsection{\bf\ignorespaces#3.\quad}\ignorespaces}
+\def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+ \else \csname#1\endcsname \fi} % Petr Olsak's macros from texinfo.tex
+\def\advancenumber#1{\countA=\expnumber{#1}\relax \advance\countA by1
+ \expandafter\xdef\csname#1\endcsname{\the\countA}}
+% \O is Scandinavian letter O-with-slash
+% \P is paragraph sign
+\def\Q{\note{This code is cited in section}} % xref for mention of a section
+\def\Qs{\note{This code is cited in sections}} % xref for mentions of a section
+\let\R=\lnot % logical not
+% \S is section sign
+\def\T#1{\leavevmode % octal, hex or decimal constant
+ \hbox{$\def\?{\kern.2em}%$%
+ \def\$##1{\egroup_{\,\rm##1}\bgroup}% suffix to constant
+ \def\_{\cdot 10^{\aftergroup}}% power of ten (via dirty trick)
+ \let\~=\oct \let\^=\hex {#1}$}}%$%
+\def\U{\note{This code is used in section}} % xref for use of a section
+\def\Us{\note{This code is used in sections}} % xref for uses of a section
+\let\V=\lor % logical or
+\let\W=\land % logical and
+\def\X#1:#2\X{\ifmmode\gdef\XX{\null$\null}\else\gdef\XX{}\fi %$% section name
+ \XX$\langle\,${\let\I=\ne#2\sevenrm\kern.5em
+ \ifacro{\pdfnote#1.}\else#1\fi}$\,\rangle$\XX}
+\def\Y{\par\yskip}
+\let\Z=\le
+\let\ZZ=\let % now you can \write the control sequence \ZZ
+\let\*=*
+
+%\def\oct{\hbox{\rm\char'23\kern-.2em\it\aftergroup\?\aftergroup}} % WEB style
+%\def\hex{\hbox{\rm\char"7D\tt\aftergroup}} % WEB style
+\def\oct{\hbox{$^\circ$\kern-.1em\it\aftergroup\?\aftergroup}}% CWEB style
+\def\hex{\hbox{$^{\scriptscriptstyle\#}$\tt\aftergroup}} % CWEB style
+\def\vb#1{\leavevmode\hbox{\kern2pt\vrule\vtop{\vbox{\hrule
+ \hbox{\strut\kern2pt\.{#1}\kern2pt}}
+ \hrule}\vrule\kern2pt}} % verbatim string
+
+\def\TeX{{\ifmmode\it\fi
+ \leavevmode\hbox{T\kern-.1667em\lower.424ex\hbox{E}\hskip-.125em X}}}
+\def\,{\relax\ifmmode\mskip\thinmuskip\else\thinspace\fi}
+
+% now here's the mini-index formatting control
+\newcount\nrefs % total number of references in partial page
+\newcount\baseno % smallest section number in partial page
+\toksdef\prefs=199 % references to previous sections in current program
+\toksdef\frefs=220 % references to future sections in current program
+\toksdef\erefs=221 % references to sections in another program
+% \count and \toks registers 200--219 are also used to keep track of refs
+\catcode`\@=11
+\newcount\@n \newcount\@m \newcount\@p
+\newdimen\pageht \pageht=19cm
+\newdimen\pagewd \pagewd=13cm
+\newdimen\colwd \colwd=\pagewd
+ \advance\colwd by -2pc \divide\colwd by 3 % for three columns
+\newdimen\fullpageht \fullpageht=\pageht \advance\fullpageht by 4pc
+\newdimen\pagethresh \pagethresh=2\pageht
+\newdimen\nsize \newdimen\msize
+\newskip\intersecskip \intersecskip=8pt plus 2pt minus 3pt
+\newbox\partialpage
+\newbox\newsec
+\newtoks\newrefs
+\newtoks\ttoks
+\newdimen\ninept \ninept=9pt
+\newif\iftitle \newif\ifleft
+
+\def\flushout{\ifvoid\partialpage\else
+ \setbox0=\vsplit\partialpage to \pageht
+ \shipout\vbox{
+ \vbox to 3pc{\leftheadline\vfill}
+ \nointerlineskip\box0}
+ \global\advance\pageno 1
+ \global\let\[=\makeinref \global\let\]=\makeoutref
+ \ifsorted \let\readin=\readln \readrefs
+ \else \immediate\write\reffile{!\the\pageno}\let\readin=\readrefs \fi
+ \setbox0=\vbox{\eightpoint \hsize=\colwd
+ \rightskip=0pt plus 100pt minus 10pt
+ \pretolerance 10000
+ \hyphenpenalty 10000 \exhyphenpenalty 10000
+ \noindent\vbox to1pt{}\par % 1pt = \topskip - \ninept
+ \readin}
+ \shipout\vbox to\fullpageht{
+ \vbox to 3pc{\rightheadline\vfill}
+ \unvbox\partialpage
+ \vfill
+ \ifdim\ht0>1pt \kern11pt\hrule \hbox{%
+ \nsize=\ht0 \advance\nsize-\topskip
+ \divide\nsize by 3 \divide\nsize by\ninept
+ \multiply\nsize by\ninept \advance\nsize\topskip
+ \vsplit0 to\nsize \kern1pc
+ \msize=\ht0 \advance\msize-\topskip
+ \divide\msize by 2 \divide\msize by\ninept
+ \multiply\msize by\ninept \advance\msize\topskip
+ \vbox to\nsize{\vsplit0 to\msize\vss}\kern1pc
+ \vbox to\nsize{\box0\vss}} \fi}
+ \global\advance\pageno 1 \global\let\rlhead=\rrhead\fi
+ {\globaldefs=1
+ \@n=199 \loop \ifnum\@n<222 \toks\@n={} \count\@n=0 \advance\@n 1 \repeat
+ \nrefs=0
+ \baseno=\secno}}
+\def\leftheadline{\hbox to\pagewd{\vbox to10pt{}%
+ \iftitle\global\titlefalse\else\ninerm\title:\enspace \eightsl\rlhead\fi
+ \hfil\eightrm\folio}}
+\def\rightheadline{\hbox to\pagewd{\vbox to10pt{}%
+ \eightrm\folio\hfil\ninerm\title:\enspace \eightsl\rrhead\/}}
+
+\def\mini{\begingroup \obeylines \globaldefs=1 \newrefs=\bgroup}
+\def\FI{\@n=\secno \advance\@n-\baseno \advance\@n 200
+ \advance\nrefs-\count\@n \@n=\nrefs
+ \let\[=\countnewref \let\]=\cn \the\newrefs \endgroup
+ \nobreak\null\nobreak\vskip-\baselineskip\penalty-500\vfil\eject}
+\def\twillout{\setbox\newsec=\vbox{\unvbox255}
+ \ifnum\@n=0 \nsize=0pt
+ \else \nsize=3pt \multiply\nsize\@n \advance\nsize 1.25pc \fi
+ \ifvoid\partialpage\else\advance\nsize 5pt \advance\nsize\ht\partialpage\fi
+ \advance\nsize\ht\newsec
+ \message{\the\nsize} % show the page break decision amount
+ \ifbr \global\brfalse \flushout \message{/\secno}\fi
+ \ifdim\nsize>\pagethresh \flushout \message{\secno}\fi
+ \addtopartialpage}
+\def\addtopartialpage{\globaldefs=1
+ \let\[=\addnewref \let\]=\addneweref \the\newrefs
+ \setbox\partialpage=\ifvoid\partialpage \box\newsec
+ \else \vbox{\unvbox\partialpage \vfilneg
+ \vskip\intersecskip \unvbox\newsec}\fi}
+\def\shortpage{\par\vskip-2\baselineskip
+ \null\vfill\penalty-5000\message{(shortpage)}}
+\newif\ifbr
+\def\forcebr{\global\brtrue}
+
+\def\countnewref #1 {\ifnum#1<\baseno \let\next\cn
+ \else\ifnum#1>\secno \let\next\cn \else\let\next\flushref\fi\fi\next#1 }
+\def\cn #1 #2 {\begintest{#1 #2}\cnr\endtest}
+
+% here's a tricky way to present \cnr with a csname unexpanded inside:
+\def\begintest#1{\def\TEST{#1}\expandafter\expandafter\expandafter}
+\def\endtest{\csname\expandafter\gobb\meaning\TEST\endcsname}
+\expandafter\def\expandafter\gobb\meaning\empty{}
+
+{\obeylines\gdef\cnr#1#2
+ {\ifx#1\relax \advance\@n 1 \fi}}
+{\obeylines\gdef\flushref#1
+ {}}
+\def\addnewref #1 {\ifnum#1<\baseno \let\next\an \@n=199
+ \else\ifnum#1>\secno \let\next\an \@n=#1 \advance\@n-\baseno
+ \advance\@n200 \ifnum\@n>219 \@n=220 \fi
+ \else\let\next\flushref\fi\fi\next#1 }
+\def\an#1 #2 {\begintest{#1 #2}\anr\endtest\[#1 #2 }
+\def\addneweref#1 #2 {\@n=221 \begintest{#1 #2}\anr\endtest\]#1 #2 }
+{\obeylines\gdef\anr#1#2
+ {\ifx#1\relax \advance\nrefs1 \advance\count\@n 1 %
+ \def#1{#2
+ }\toks\@n=\expandafter{\the\toks\@n\lmda#1}\fi}}
+\ifsorted \def\lmda#1{\global\let#1\relax}
+\else \def\lmda#1{#1\global\let#1\relax} \fi
+{\obeylines\gdef\makeinref#1 #2 #3
+ {\ifsorted\else\ttoks={\[#1 #2 #3}\immediate\write\reffile{+ \the\ttoks}\fi %
+ \hangindent=1em \noindent #2\miniform#3, %<== space!
+ \S\ifacro{\pdfnote#1.}\else{#1}\fi.\par}}
+{\obeylines\gdef\makeoutref#1 #2 #3
+ {\ifsorted\else\ttoks={\]#1 #2 #3}\immediate\write\reffile{+ \the\ttoks}\fi %
+ \hangindent=1em \noindent #2\miniform#3, \extref#1.\par}}
+\def\miniform{\futurelet\next\miniforma}
+\def\miniforma{\ifx\next\zip
+ \else\if=\noexpand\next \let\next\gobbleq
+ \else\let\next\colon\fi\fi\next}
+\def\zip{}
+\def\gobbleq={\,=\,}
+\def\colon{: }
+\def\extref{\futurelet\next\extrefa}
+\def\extrefa{\if"\next\let\next\gobblest\else\let\next\cite\fi\next}
+\def\gobblest"#1"{{\ttx#1}}
+\def\cite#1#2.{{\sc#1}\,\S#2.}
+\def\uninitialized{???}
+
+\def\readrefs{\the\prefs \@m=\secno \advance\@m-\baseno \advance\@m200
+ {\def\lmda##1{\global\let##1\relax}\@p=200
+ \loop\ifnum\@p<\@m \the\toks\@p \advance\@p 1 \repeat}
+ \loop\ifnum\@m<222 \the\toks\@m \advance\@m 1 \repeat}
+\def\readln{\read\sreffile to\next \expandafter\next\newline \readin}
+{\obeylines\gdef\newline{\unskip\noexpand
+ }}
+\def\donewithpage#1 {\let\readin=\relax}
+\catcode`\@=12
+
+\hsize=\pagewd \vsize=\maxdimen \output={\twillout}
+
+\def\contentspagenumber{0} % default page number for table of contents
+\def\contentsfile{\jobname.toc} % file that gets table of contents info
+\def\readcontents{\input \contentsfile}
+\def\readsections{\input \jobname.scn}
+
+\newwrite\cont
+\ifpdftex
+ \immediate\openout\cont=\contentsfile
+ \immediate\write\cont{\catcode `\noexpand\@=11\relax} % \makeatletter
+\fi
+
+\def\inx{\flushout % No full index at the end
+ \ifpdftex
+ \immediate\write\cont{\catcode `\noexpand\@=12\relax} % \makeatother
+ \immediate\closeout\cont % the contents information has been fully gathered
+ \fi}
+\def\fin{\ifacro \message{Section names:}
+ \def\U##1.{} \def\Us##1.{} \let\I=\relax \let\*=*
+ \def\outsecname{Names of the sections}
+ \ifpdftex \makebookmarks
+ \pdfoutline goto num 1 count -\secno {\outsecname}
+ \def\X##1:##2\X{\firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \pdfoutline goto num \the\toksA \expandafter{\the\toksE}}
+ \else \output={\shipout\box255}
+ \special{pdf: outline -1 << /Title (\outsecname) >>}%
+ \def\X##1:##2\X{\firstsecno##1.%
+ {\toksF={}\makeoutlinetoks##2\outlinedone\outlinedone}%
+ \special{pdf: outline 0 << /Title (\the\toksE)
+ /A << /S /GoTo /D (\romannumeral\the\toksA) >> >>}}
+ \fi \readsections \fi}
+\def\makebookmarks{\let\ZZ=\writebookmarkline \readcontents\relax}
+\def\writebookmarkline#1#2#3#4#5{{%
+ \let\(=\let \let\)=\let \let\[=\let \let\]=\let \let\/=\let
+ \pdfoutline goto num #3 count -\expnumber{chunk#2.#3} {#5}}}
+\let\con=\end % no table of contents
+\def\datethis{} \def\datecontentspage{}
+
+% To produce only a subset of pages, put the page numbers on separate
+% lines in a file called pages.tex
+\let\Shipout=\shipout
+\newread\pages \newcount\nextpage \openin\pages=pages
+\def\getnextpage{\ifeof\pages\else
+ {\endlinechar=-1\read\pages to\next
+ \ifx\next\empty % in this case we should have eof now
+ \else\global\nextpage=\next\fi}\fi}
+\ifeof\pages\else\message{OK, I'll ship only the requested pages!}
+ \getnextpage\fi
+\def\shipout{\ifeof\pages\let\next=\Shipout
+ \else\ifnum\pageno=\nextpage\getnextpage\let\next=\Shipout
+ \else\let\next=\Tosspage\fi\fi \next}
+\newbox\garbage \def\Tosspage{\deadcycles=0\setbox\garbage=}
diff --git a/Build/source/texk/web2c/cwebdir/texinputs/pdfwebtocfront.tex b/Build/source/texk/web2c/cwebdir/texinputs/pdfwebtocfront.tex
new file mode 100644
index 00000000000..3fc5f64de2f
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/texinputs/pdfwebtocfront.tex
@@ -0,0 +1,85 @@
+% pdfwebtofront.tex
+% Code from knuth.drv in https://github.com/oberdiek/latex-tds
+% 2020/06/20 v2.0 by Andreas Scherer.
+%
+% This file is part of project https://github.com/ascherer/cwebbin
+% and may be distributed under the MIT License or the LaTeX Project
+% Public License.
+%
+% Move table-of-contents page to the front in PDF output.
+% Works with pdftex and xetex in connection with either 'webmac.tex'
+% for Pascal/WEB programs or 'cwebmac.tex' for C/CWEB programs.
+%
+\ifx\detokenize\undefined\endinput\fi
+\def\contentsfile{\jobname.toc} % file that gets table of contents info
+\newif\iftexmf\texmffalse % special toc treatment for TeX, Metafont, etc.
+\newread\testread
+\openin\testread=\contentsfile\relax
+\ifeof\testread % First run
+\else % Second run
+ % Redefine '\con' to be invoked before the first '\N' (starred section).
+ \let\ORGcon\con
+ \def\con{%
+ % reduce size of PDF pages for more screen space
+ \pdfpagewidth=\pagewidth \advance\pdfpagewidth by 2cm
+ \pdfpageheight=\pageheight \advance\pdfpageheight by 3cm
+ \ifpdftex \pdfhorigin=1cm \pdfvorigin=1cm
+ \else \advance\pdfpageheight by 1cm \global\pageshift=-1.54cm
+ \global\hoffset=-1.54cm \global\voffset=-1.54cm \fi
+ \begingroup
+ \let\end\relax
+ \ORGcon
+ \endgroup
+ \let\con\end
+ }%
+ % Special variant for 'mf.web' and 'tex.web' (et al.).
+ % They all define a peculiar version of '\N' in their preamble.
+ % And they put their tables-of-contents on a sparse 'page 2' and
+ % start the main body on page '3'.
+ \edef\x{\jobname}%
+ \edef\y{\detokenize{tex}}%
+ \ifx\x\y \texmftrue\else
+ \edef\y{\detokenize{mf}}%
+ \ifx\x\y \texmftrue\else
+ \edef\y{\detokenize{pdftex}}%
+ \ifx\x\y \texmftrue\else
+ \edef\y{\detokenize{xetex}}%
+ \ifx\x\y \texmftrue\fi\fi\fi\fi
+ \iftexmf
+ \expandafter\let\csname ORGN\expandafter\endcsname
+ \csname N\endcsname
+ \expandafter\outer\expandafter\def\csname N\endcsname{%
+ \titletrue \con \pageno=2
+ \expandafter\let\csname N\expandafter\endcsname
+ \csname ORGN\endcsname
+ \csname N\endcsname
+ }%
+ \else % Much more general approach for WEB and CWEB programs.
+ % In fact, '\con' will be invoked _inside_ the first '\N' right _after_
+ % '\MN', but _before_ '\eject'. And '\topofcontents' gets in the twist
+ % as well.
+ \let\ORGtopofcontents\topofcontents \let\ORGrheader\rheader
+ \def\topofcontents{%
+ \def\:{\par\hangindent 2em} % Fix for 'bibtex.web'; from '\def\fin'.
+ \ORGtopofcontents
+ \let\topofcontents\relax
+ }%
+ % Squeeze '\con' between '\MN' and '\eject' in the very first '\N'.
+ \expandafter\let\csname ORGvfil\expandafter\endcsname
+ \csname vfil\endcsname
+ \expandafter\let\csname ORGeject\expandafter\endcsname
+ \csname eject\endcsname
+ \expandafter\outer\expandafter\def\csname vfil\endcsname{%
+ \let\eject\relax
+ \titletrue % prepare to output the table of contents
+ \topofcontents \con
+ \advance\pageno by -1\relax
+ \expandafter\let\csname vfil\expandafter\endcsname
+ \csname ORGvfil\endcsname
+ \expandafter\let\csname eject\expandafter\endcsname
+ \csname ORGeject\endcsname
+ \vfil\eject
+ \let\rheader\ORGrheader
+ }%
+ \fi
+\fi
diff --git a/Build/source/texk/web2c/cwebdir/twinx.w b/Build/source/texk/web2c/cwebdir/twinx.w
new file mode 100644
index 00000000000..ecfce0c8da8
--- /dev/null
+++ b/Build/source/texk/web2c/cwebdir/twinx.w
@@ -0,0 +1,460 @@
+\datethis
+
+@*Introduction. This short program compiles a master index for a
+set of programs that have been processed by \.{CTWILL}.
+To use it, you say, e.g., \.{twinx} \.{*.tex} \.{>index.tex}.
+The individual programs should define their names with a line of
+the form `\.{\\def\\title\{NAME\}}'.
+
+@c
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+@<Type definitions@>@;
+@<Global variables@>@;
+@<Procedures@>@;
+@#
+int main(
+ int argc,
+ char *argv[])
+{ @<Local variables@>;
+ @<Initialize the data structures@>;
+ while (--argc) {
+ f=fopen(*++argv,"r");
+ if (!f)
+ fprintf(stderr,"twinx: Couldn't open file %s for reading!\n",*argv);
+ else {
+ @<Scan file |f| until coming to the title@>;
+ fclose(f);
+ strncpy(*argv+strlen(*argv)-3,"idx",3);
+ f=fopen(*argv,"r");
+ if (!f)
+ fprintf(stderr,"twinx: Couldn't open file %s for reading!\n",*argv);
+ else {
+ @<Copy the index file |f| into the data structures@>;
+ fclose(f);
+ }
+ }
+ }
+ @<Output the data structures to make a master index@>;
+ return 0;
+}
+
+@ @d buf_size 100 /* input lines won't be this long */
+
+@<Glob...@>=
+FILE *f;
+char buf[buf_size];
+char title[buf_size];
+char cur_name[buf_size];
+
+@ @<Scan file |f|...@>=
+while (1) {
+ if (fgets(buf,buf_size,f)==NULL) {
+ fprintf(stderr,"twinx: (no title found in file %s)\n",*argv);
+ title[0]='\0';
+ break;
+ }
+ if (strncmp(buf,"\\def\\title\{",11)==0) {@+register char *p,*q;
+ for (p=buf+11,q=title;*p && *p!='}';p++) *q++=*p;
+ *q='\0';
+ break;
+ }
+}
+
+@* Data structures.
+Our main task is to collate a bunch of texts associated with keys that
+have already been sorted. It seems easiest to do this by repeatedly merging
+the new data into the old, even though this means we'll be passing over
+some of the same keys 30 times or more; the computer is fast, and this
+program won't be run often.
+
+Further examination shows that a merging strategy isn't so easy after all,
+because the sorting done by \.{CTWILL} (and by \.{CWEAVE}) is weird
+in certain cases. When two index entries agree except for their
+``ilk,'' the order in which they appear in the index depends on the order in
+which they appear in the program. Thus, they might well appear in
+different order in two of the indexes we are merging.
+(There's also another glitch, although not quite as devasting:
+When two index entries have the
+same letters and the same ilk, but differ with respect to uppercase
+versus lowercase, the order in which they appear depends on the
+hash code used in \.{CWEB}'s \.{common.w} code!)
+
+So we'll use Plan B: All index entries will first be copied into a long
+list. The list will almost always consist of many sorted sublists,
+but we will not assume anything about its order. After all the copying
+has been done, we will use a list-merge sort to finish the job.
+
+The data structure is built from nodes that each contain three pointers.
+The first pointer is to an |id| string; the third pointer is to the
+|next| node; and the second pointer is either |data.s|, a pointer to
+a string of text, or |data.n|, a pointer to a node. In the main list,
+the |id| fields are the keys of the index, and the |data.n| fields
+point to lists of associated texts. In the latter lists, the |id| fields
+are the individual program titles, while the |data.s| fields are the
+texts.
+
+@<Type...@>=
+typedef union {
+ char *s;
+ struct node_struct *n;
+} mixed;
+typedef struct node_struct {
+ const char *id;
+ mixed data;
+ struct node_struct *next;
+} node;
+
+@ We copy strings into blocks of storage that are allocated as needed.
+Here's a routine that stashes away a given string. It makes no attempt to
+handle extremely long strings, because such strings will arise only
+if the input is all screwed up.
+
+@d string_block_size 8192 /* number of bytes per string block */
+
+@<Proc...@>=
+char *save_string(
+ char *s)
+{
+ register char *p,*q; register int l;
+ for (p=s;*p;p++) ;
+ l=p-s+1;
+ if (l>string_block_size) {
+ fprintf(stderr,"twinx: Huge string `%.20s...' will be truncated!\n",s);
+ l=string_block_size;
+ s[l-1]='\0';
+ }
+ if (next_string+l>=bad_string) {
+ next_string=(char*)malloc(string_block_size);
+ if (next_string==NULL) {
+ fprintf(stderr,"twinx: Not enough room for strings!\n");
+ exit(-1);
+ }
+ bad_string=next_string+string_block_size;
+ }
+ for (p=s,q=next_string;*p;p++) *q++=*p;
+ *q='\0';
+ next_string=q+1;
+ return next_string-l;
+}
+
+@ Nodes are allocated with a similar but simpler mechanism.
+
+@d nodes_per_block 340
+
+@<Proc...@>=
+node *new_node(void)
+{
+ if (next_node==bad_node) {
+ next_node=(node*)calloc(nodes_per_block,sizeof(node));
+ if (next_node==NULL) {
+ fprintf(stderr,"twinx: Not enough room for nodes!\n");
+ exit(-2);
+ }
+ bad_node=next_node+nodes_per_block;
+ }
+ next_node++;
+ return next_node-1;
+}
+
+@ @<Glob...@>=
+char *next_string,*bad_string;
+node *next_node,*bad_node;
+node header; /* the main list begins at |header.next| */
+node sentinel; /* intermediate lists will end at this node */
+
+@ We don't really have to initialize the string and node storage
+pointers, because global variables are zero already. But we might as
+well be tidy and state the initial conditions explicitly.
+
+It will be convenient to have extremely small and large keys in
+the dummy nodes.
+
+@<Initialize the data structures@>=
+next_string=bad_string=NULL;
+next_node=bad_node=NULL;
+header.next=NULL;
+header.id=" {"; /* smaller than any valid |id| */
+sentinel.id=" {\200}"; /* larger than any valid |id| */
+main_node=&header;
+
+@ @<Local v...@>=
+register node* main_node; /* current end of main list */
+
+@* Copying.
+Lines in the index file |f| that we're reading either begin a new
+entry or continue a long entry. In the first case, the line begins with
+\.{\\I} and then either \.{\\\\\{key\}} or \.{\\\char'174\{key\}} or
+\.{\\.\{key\}} or \.{\\\&\{key\}} or \.{\\\$\{key\}} or \.{\\9\{key\}}
+or just \.{\ \ \{key\}}. (These correspond to multi-character italic,
+single-digit italic, typewriter, bold, custom, variable, and roman styles.)
+In the second case, the line begins with a page number or \.{\\[};
+however, we recognize the second case by the fact that the previous line
+did not end with a period.
+
+@<Copy the index...@>=
+while (1) {@+register node *cur_node;
+ if (fgets(buf,buf_size,f)==NULL) break; /* end of file */
+ if (strncmp(buf,"\\I",2)==0) {
+ @<Copy a new index entry into |cur_name| and |cur_node|@>;
+ main_node->next=new_node();@+main_node=main_node->next;
+ main_node->id=save_string(cur_name);
+ main_node->data.n=cur_node;
+ }
+ else if (buf[0]!='\n')
+ fprintf(stderr,"twinx: couldn't deal with `%.10s...' in file %s!\n",
+ buf,*argv);
+}
+
+@ @<Copy a new index entry...@>=
+if (buf[4]!='{') {
+ fprintf(stderr,"twinx: missing brace in file %s: `%.20s...'\n",*argv,buf);
+ break;
+}
+{@+register char *p,*q;@+register int bal=1;
+ cur_name[0]=buf[2];@+cur_name[1]=buf[3];@+cur_name[2]='{';
+ for (p=buf+5,q=cur_name+3;*p&&(bal||*p=='{');p++) {
+ if (*p=='{') bal++;
+ else if (*p=='}') bal--;
+ *q++=*p;
+ }
+ if (bal) {
+ fprintf(stderr,"twinx: unbalanced entry in file %s: `%.20s...'\n",*argv,buf);
+ break;
+ }
+ if (*p++!=',') {
+ fprintf(stderr,"twinx: missing comma in file %s: `%.20s...'\n",*argv,buf);
+ break;
+ }
+ if (*p++!=' ') {
+ fprintf(stderr,"twinx: missing space in file %s: `%.20s...'\n",*argv,buf);
+ break;
+ }
+ *q='\0';
+ @<Copy the text part of the index entry into |cur_node|@>;
+}
+
+@ When we get here, |p| points to the beginning of the text following a key
+in the index. The index entry ends with the next period, possibly several
+lines hence. In the multiple-line case, |cur_node| will point to the
+final line, which points to the penultimate line, etc.
+
+@<Copy the text part of the index entry...@>=
+{@+int period_sensed=0;
+ node *continuation;
+ cur_node=new_node();
+ cur_node->id=save_string(title);
+ do@+{
+ for (q=p;*q&&*q!='\n'&&*q!='.';q++) ;
+ if (*q=='.') period_sensed=1;
+ *q='\0';
+ cur_node->data.s=save_string(p);
+ if (period_sensed) break;
+ continuation=new_node(); /* the |id| field is |NULL| */
+ continuation->next=cur_node;
+ cur_node=continuation;
+ p=buf;
+ }@+while(fgets(buf,buf_size,f));
+ if (!period_sensed) {
+ fprintf(stderr,"twinx: File %s ended in middle of entry for %s!\n",
+ *argv,cur_name);
+ break;
+ }
+}
+
+@* Sorting.
+Let us opt for simplicity instead of tuning up for speed. The idea in
+this step is to take a list that contains $k$ ascending runs and reduce it
+to a list that contains $\lceil k/2\rceil$ runs, repeating until $k=1$.
+We could make the program about twice as fast if we took the trouble to
+remember the boundaries of runs on the previous pass; here, every
+pass will be the same.
+
+@<Output the data structures to make a master index@>=
+@<Sort the main list, collapsing entries with the same |id|@>;
+@<Output the main list in suitable \TeX\ format@>;
+
+@ The |compare| subroutine, which specifies the relative order of
+|id| fields in two nodes, appears below. Let's get the sorting logic
+right first.
+
+The algorithm is, in fact, rather pretty---I hate to say cute, but
+that's the word that comes to mind. Some day I must write out the
+nice invariant relations in these loops. Too bad it's not more efficient.
+
+Remember that |header.id| is $-\infty$ and |sentinel.id| is $+\infty$.
+Also remember that the main list begins and ends at the header node.
+
+@<Sort the main list, collapsing entries with the same |id|@>=
+main_node->next=&header;
+while (1) {@+register node *p,*q,*r,*s,*t;
+ t=&header;
+ r=t->next;
+ while (1) {
+ if (r==&header) break;
+ p=s=r;
+ @<Advance |s| until it exceeds |r=s->next|@>;
+ if (r==&header) break;
+ s->next=&sentinel;
+ q=s=r;
+ @<Advance |s| until it exceeds |r=s->next|@>;
+ s->next=&sentinel;
+ @<Merge |p| and |q|, appending to |t|@>;
+ t->next=r;
+ }
+ if (t==&header) break;
+}
+
+@ @<Advance...@>=
+do@+{@+register int d;
+ r=s->next;
+ d=compare(s,r);
+ if (d>0) break; /* |s->id>r->id| */
+ if (d==0) { /* |s->id=r->id| */
+ collapse(s,r); /* put |r|'s data into |s|'s list */
+ s->next=r->next; /* node |r| will be unclaimed garbage */
+ } else s=r; /* this is the normal case, |s->id<r->id| */
+}@+while(1);
+
+@ Merging takes place in such a way that sorting is stable.
+Thus, index entries for a key that appears in different programs
+will remain in the order of the \.{.tex} files on the command line.
+
+@<Merge...@>=
+do@+{@+register int d;
+ d=compare(p,q);
+ if (d>0) { /* |p->id>q->id| */
+ t->next=q;
+ t=q;
+ q=q->next;
+ } else if (d<0) { /* |p->id<q->id| */
+ t->next=p; /* |p->id<q->id| */
+ t=p;
+ p=p->next;
+ } else if (p==&sentinel) break;
+ else {
+ collapse(p,q); /* put |q|'s data into |p|'s list */
+ q=q->next;
+ }
+}@+while(1);
+
+@ Comparison is a three-stage process in general. First we compare the
+keys without regarding case or format type. If they are equal with
+respect to that criterion, we try again, with case significant.
+If they are still equal, we look at the format characters (the first
+two characters of the |id| field).
+
+@<Proc...@>=
+int compare(
+ node *p, node *q)
+{@+register unsigned char *pp,*qq;
+ for (pp=(unsigned char*)p->id+3,qq=(unsigned char*)q->id+3;
+ *pp&&ord[*pp]==ord[*qq];pp++,qq++) ;
+ if (*pp || *qq) return ord[*pp]-ord[*qq];
+ for (pp=(unsigned char*)p->id+3,qq=(unsigned char*)q->id+3;
+ *pp&&*pp==*qq;pp++,qq++) ;
+ if (*pp || *qq) return (int)*pp-(int)*qq;
+ if (p->id[0]!=q->id[0]) return p->id[0]-q->id[0];
+ return p->id[1]-q->id[1];
+}
+
+@ The collation order follows a string copied from \.{CWEAVE}.
+
+@<Glob...@>=
+char collate[102]; /* collation order */
+char ord[256]; /* rank in collation order */
+
+@ The right brace is placed lowest in collating order, because each
+key is actually followed by a right brace when we are sorting.
+
+Apology: I haven't had time to update this part of the program to
+allow 8-bit characters. At present the data is assumed to be
+7-bit ASCII, as it was in the early versions of \.{CWEAVE}.
+
+@<Init...@>=
+collate[0]=0; strcpy(collate+1,"} \1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\
+\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\
+!\42#$%&'()*+,-./:;<=>?@@[\\]^`{|~_\
+abcdefghijklmnopqrstuvwxyz0123456789");
+{@+register int j;
+ for (j=1;collate[j];j++) ord[(int)collate[j]]=j;
+ ord[128]=j; /* this affects the ordering of |sentinel.id| */
+ for (j='A';j<='Z';j++) ord[j]=ord[tolower(j)];
+}
+
+@ When two lists are combined, we put the data from the second node
+before the data from the first node, because we are going to reverse
+the order when printing. After this procedure has acted, the field
+|q->data.n| should not be considered an active pointer.
+
+@<Proc...@>=
+void collapse(
+ node *p, node *q)
+{@+register node *x;
+ for (x=q->data.n;x->next;x=x->next) ;
+ x->next=p->data.n;
+ p->data.n=q->data.n;
+}
+
+@ The only remaining trick is to format the underline characters
+properly, especially in the ``custom'' format when they must become
+\.x's.
+
+@<Output the main list in suitable \TeX\ format@>=
+{@+register node *x;
+ printf("\\input cttwinxmac\n");
+ for (x=header.next;x!=&header;x=x->next) {
+ printf("\\I");
+ @<Output |x->id| in suitable \TeX\ format@>;
+ @<Output the lines of |x->data.n| in reverse order@>;
+ }
+ printf("\\fin\n");
+}
+
+@ @<Output |x->id|...@>=
+{@+register const char *p=x->id;
+ if (*p==' ') {
+ if (*(p+1)!=' ') goto unknown;
+ goto known;
+ }
+ if (*p!='\\') goto unknown;
+ switch (*(p+1)) {
+ case '\\': case '|': case '.': case '&': case '9':
+ printf("\\%c",*(p+1));
+ goto known;
+ case '$': printf("$\\");
+ for (p+=3;*p!='}';p++)
+ if (*p=='_') putchar('x');
+ else putchar(*p);
+ putchar('$');
+ goto done;
+ default: goto unknown;
+ }
+ unknown: fprintf(stderr,"twinx: `%s' has unknown format!\n",p);
+ known: for (p+=2;*p;p++) {
+ if (*p=='_') putchar('\\');
+ putchar(*p);
+ }
+done:;
+}
+
+@ @<Output the lines of |x->data.n| in reverse order@>=
+{@+register node *y=x->data.n,*z=NULL;
+ while (y) {@+register node *w;
+ w=y->next;
+ y->next=z;
+ z=y;
+ y=w;
+ }
+ while (z) {
+ if (z->id) printf("\\unskip, {\\sc %s}~",z->id);
+ fputs(z->data.s,stdout);
+ z=z->next;
+ if (z) putchar('\n');
+ else puts(".");
+ }
+}
+
+@* Index.