From ad547a6b5986815fda458221149728d9d9ab1d87 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 25 Feb 2021 19:22:25 +0000 Subject: restore Build,TODO from r57911 git-svn-id: svn://tug.org/texlive/trunk@57915 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/cwebdir/ChangeLog | 635 +++ Build/source/texk/web2c/cwebdir/Makefile | 200 + Build/source/texk/web2c/cwebdir/README | 109 + Build/source/texk/web2c/cwebdir/c++lib.w | 85 + Build/source/texk/web2c/cwebdir/comm-amiga.ch | 17 + Build/source/texk/web2c/cwebdir/comm-bs.ch | 223 + Build/source/texk/web2c/cwebdir/comm-mac.ch | 155 + Build/source/texk/web2c/cwebdir/comm-man.ch | 22 + Build/source/texk/web2c/cwebdir/comm-os2.ch | 24 + Build/source/texk/web2c/cwebdir/comm-pc.ch | 33 + Build/source/texk/web2c/cwebdir/comm-ql.ch | 277 ++ Build/source/texk/web2c/cwebdir/comm-vms.ch | 88 + Build/source/texk/web2c/cwebdir/comm-w2c.ch | 866 ++++ Build/source/texk/web2c/cwebdir/comm-w2c.h | 265 ++ Build/source/texk/web2c/cwebdir/comm-w32.ch | 66 + Build/source/texk/web2c/cwebdir/common.c | 1327 ++++++ Build/source/texk/web2c/cwebdir/common.h | 243 + Build/source/texk/web2c/cwebdir/common.w | 1301 ++++++ Build/source/texk/web2c/cwebdir/ctang-bs.ch | 192 + Build/source/texk/web2c/cwebdir/ctang-man.ch | 22 + Build/source/texk/web2c/cwebdir/ctang-pc.ch | 24 + Build/source/texk/web2c/cwebdir/ctang-ql.ch | 25 + Build/source/texk/web2c/cwebdir/ctang-vms.ch | 35 + Build/source/texk/web2c/cwebdir/ctang-w2c.ch | 481 ++ Build/source/texk/web2c/cwebdir/ctang-w32.ch | 44 + Build/source/texk/web2c/cwebdir/ctangle.c | 1626 +++++++ Build/source/texk/web2c/cwebdir/ctangle.w | 1543 +++++++ Build/source/texk/web2c/cwebdir/ctproofmac.tex | 353 ++ Build/source/texk/web2c/cwebdir/cttwinxmac.tex | 319 ++ Build/source/texk/web2c/cwebdir/ctwill-mini.ch | 1151 +++++ Build/source/texk/web2c/cwebdir/ctwill-w2c.ch | 1996 +++++++++ Build/source/texk/web2c/cwebdir/ctwill.bux | 88 + Build/source/texk/web2c/cwebdir/ctwimac.tex | 476 ++ Build/source/texk/web2c/cwebdir/cweav-bs.ch | 236 + Build/source/texk/web2c/cwebdir/cweav-man.ch | 22 + Build/source/texk/web2c/cwebdir/cweav-pc.ch | 28 + Build/source/texk/web2c/cwebdir/cweav-ql.ch | 32 + Build/source/texk/web2c/cwebdir/cweav-vms.ch | 38 + Build/source/texk/web2c/cwebdir/cweav-w2c.ch | 713 +++ Build/source/texk/web2c/cwebdir/cweav-w32.ch | 34 + Build/source/texk/web2c/cwebdir/cweave.test | 9 + Build/source/texk/web2c/cwebdir/cweave.w | 4696 ++++++++++++++++++++ Build/source/texk/web2c/cwebdir/cweb.1 | 132 + Build/source/texk/web2c/cwebdir/cweb.el | 218 + .../texk/web2c/cwebdir/cwebinputs/amiga_types.w | 109 + .../texk/web2c/cwebdir/cwebinputs/c++1xlib.w | 37 + .../texk/web2c/cwebdir/cwebinputs/cweb_ecma94.w | 44 + .../texk/web2c/cwebdir/cwebinputs/cweb_hp8.w | 47 + .../texk/web2c/cwebdir/cwebinputs/cweb_mac8.w | 53 + .../texk/web2c/cwebdir/cwebinputs/cweb_pc850.w | 50 + .../texk/web2c/cwebdir/cwebinputs/iso_types.w | 119 + Build/source/texk/web2c/cwebdir/cwebmac.tex | 552 +++ Build/source/texk/web2c/cwebdir/cwebman-w2c.ch | 333 ++ Build/source/texk/web2c/cwebdir/cwebman.tex | 1774 ++++++++ Build/source/texk/web2c/cwebdir/examples/Makefile | 57 + Build/source/texk/web2c/cwebdir/examples/README | 55 + Build/source/texk/web2c/cwebdir/examples/extex.ch | 23 + Build/source/texk/web2c/cwebdir/examples/extex.w | 366 ++ Build/source/texk/web2c/cwebdir/examples/kspell.el | 228 + Build/source/texk/web2c/cwebdir/examples/oemacs.el | 176 + Build/source/texk/web2c/cwebdir/examples/oemacs.w | 896 ++++ .../source/texk/web2c/cwebdir/examples/treeprint.w | 248 ++ Build/source/texk/web2c/cwebdir/examples/wc-dos.ch | 8 + Build/source/texk/web2c/cwebdir/examples/wc.w | 254 ++ .../source/texk/web2c/cwebdir/examples/wmer-os2.ch | 21 + .../source/texk/web2c/cwebdir/examples/wmerg-pc.ch | 22 + Build/source/texk/web2c/cwebdir/examples/wmerge.w | 717 +++ .../source/texk/web2c/cwebdir/examples/wordtest.w | 540 +++ .../texk/web2c/cwebdir/examples/xlib_types.w | 92 + .../texk/web2c/cwebdir/examples/xview_types.w | 274 ++ Build/source/texk/web2c/cwebdir/makefile.bs | 60 + Build/source/texk/web2c/cwebdir/po/cweb-tl.pot | 47 + Build/source/texk/web2c/cwebdir/po/cweb.pot | 604 +++ Build/source/texk/web2c/cwebdir/po/de/cweb-tl.po | 49 + Build/source/texk/web2c/cwebdir/po/de/cweb.po | 684 +++ .../source/texk/web2c/cwebdir/po/de/web2c-help.po | 140 + Build/source/texk/web2c/cwebdir/po/it/cweb.po | 679 +++ Build/source/texk/web2c/cwebdir/po/web2c-help.pot | 137 + Build/source/texk/web2c/cwebdir/prod-twill.w | 303 ++ Build/source/texk/web2c/cwebdir/prod.w | 307 ++ Build/source/texk/web2c/cwebdir/readme.ql | 84 + Build/source/texk/web2c/cwebdir/refsort.w | 165 + Build/source/texk/web2c/cwebdir/system.bux | 49 + .../texk/web2c/cwebdir/texinputs/Xcwebmac.tex | 41 + .../texk/web2c/cwebdir/texinputs/cweb_ecma94.sty | 206 + .../texk/web2c/cwebdir/texinputs/cweb_hp8.sty | 184 + .../texk/web2c/cwebdir/texinputs/cweb_mac8.sty | 232 + .../texk/web2c/cwebdir/texinputs/cweb_pc850.sty | 194 + .../texk/web2c/cwebdir/texinputs/dctproofmac.tex | 28 + .../texk/web2c/cwebdir/texinputs/dctwimac.tex | 12 + .../texk/web2c/cwebdir/texinputs/dcwebmac.tex | 105 + .../texk/web2c/cwebdir/texinputs/dcwebstrings.tex | 40 + .../texk/web2c/cwebdir/texinputs/fcwebmac.tex | 135 + .../texk/web2c/cwebdir/texinputs/icwebmac.tex | 156 + .../texk/web2c/cwebdir/texinputs/pdfctwimac.tex | 693 +++ .../web2c/cwebdir/texinputs/pdfwebtocfront.tex | 85 + Build/source/texk/web2c/cwebdir/twinx.w | 460 ++ 97 files changed, 33443 insertions(+) create mode 100644 Build/source/texk/web2c/cwebdir/ChangeLog create mode 100644 Build/source/texk/web2c/cwebdir/Makefile create mode 100644 Build/source/texk/web2c/cwebdir/README create mode 100644 Build/source/texk/web2c/cwebdir/c++lib.w create mode 100644 Build/source/texk/web2c/cwebdir/comm-amiga.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-bs.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-mac.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-man.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-os2.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-pc.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-ql.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-vms.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-w2c.ch create mode 100644 Build/source/texk/web2c/cwebdir/comm-w2c.h create mode 100644 Build/source/texk/web2c/cwebdir/comm-w32.ch create mode 100644 Build/source/texk/web2c/cwebdir/common.c create mode 100644 Build/source/texk/web2c/cwebdir/common.h create mode 100644 Build/source/texk/web2c/cwebdir/common.w create mode 100644 Build/source/texk/web2c/cwebdir/ctang-bs.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctang-man.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctang-pc.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctang-ql.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctang-vms.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctang-w2c.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctang-w32.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctangle.c create mode 100644 Build/source/texk/web2c/cwebdir/ctangle.w create mode 100644 Build/source/texk/web2c/cwebdir/ctproofmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/cttwinxmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/ctwill-mini.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctwill-w2c.ch create mode 100644 Build/source/texk/web2c/cwebdir/ctwill.bux create mode 100644 Build/source/texk/web2c/cwebdir/ctwimac.tex create mode 100644 Build/source/texk/web2c/cwebdir/cweav-bs.ch create mode 100644 Build/source/texk/web2c/cwebdir/cweav-man.ch create mode 100644 Build/source/texk/web2c/cwebdir/cweav-pc.ch create mode 100644 Build/source/texk/web2c/cwebdir/cweav-ql.ch create mode 100644 Build/source/texk/web2c/cwebdir/cweav-vms.ch create mode 100644 Build/source/texk/web2c/cwebdir/cweav-w2c.ch create mode 100644 Build/source/texk/web2c/cwebdir/cweav-w32.ch create mode 100755 Build/source/texk/web2c/cwebdir/cweave.test create mode 100644 Build/source/texk/web2c/cwebdir/cweave.w create mode 100644 Build/source/texk/web2c/cwebdir/cweb.1 create mode 100644 Build/source/texk/web2c/cwebdir/cweb.el create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/amiga_types.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/c++1xlib.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/cweb_ecma94.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/cweb_hp8.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/cweb_mac8.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/cweb_pc850.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebinputs/iso_types.w create mode 100644 Build/source/texk/web2c/cwebdir/cwebmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/cwebman-w2c.ch create mode 100644 Build/source/texk/web2c/cwebdir/cwebman.tex create mode 100644 Build/source/texk/web2c/cwebdir/examples/Makefile create mode 100644 Build/source/texk/web2c/cwebdir/examples/README create mode 100644 Build/source/texk/web2c/cwebdir/examples/extex.ch create mode 100644 Build/source/texk/web2c/cwebdir/examples/extex.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/kspell.el create mode 100644 Build/source/texk/web2c/cwebdir/examples/oemacs.el create mode 100644 Build/source/texk/web2c/cwebdir/examples/oemacs.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/treeprint.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/wc-dos.ch create mode 100644 Build/source/texk/web2c/cwebdir/examples/wc.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/wmer-os2.ch create mode 100644 Build/source/texk/web2c/cwebdir/examples/wmerg-pc.ch create mode 100644 Build/source/texk/web2c/cwebdir/examples/wmerge.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/wordtest.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/xlib_types.w create mode 100644 Build/source/texk/web2c/cwebdir/examples/xview_types.w create mode 100644 Build/source/texk/web2c/cwebdir/makefile.bs create mode 100644 Build/source/texk/web2c/cwebdir/po/cweb-tl.pot create mode 100644 Build/source/texk/web2c/cwebdir/po/cweb.pot create mode 100644 Build/source/texk/web2c/cwebdir/po/de/cweb-tl.po create mode 100644 Build/source/texk/web2c/cwebdir/po/de/cweb.po create mode 100644 Build/source/texk/web2c/cwebdir/po/de/web2c-help.po create mode 100644 Build/source/texk/web2c/cwebdir/po/it/cweb.po create mode 100644 Build/source/texk/web2c/cwebdir/po/web2c-help.pot create mode 100644 Build/source/texk/web2c/cwebdir/prod-twill.w create mode 100644 Build/source/texk/web2c/cwebdir/prod.w create mode 100644 Build/source/texk/web2c/cwebdir/readme.ql create mode 100644 Build/source/texk/web2c/cwebdir/refsort.w create mode 100644 Build/source/texk/web2c/cwebdir/system.bux create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/Xcwebmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/cweb_ecma94.sty create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/cweb_hp8.sty create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/cweb_mac8.sty create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/cweb_pc850.sty create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/dctproofmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/dctwimac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/dcwebmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/dcwebstrings.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/fcwebmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/icwebmac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/pdfctwimac.tex create mode 100644 Build/source/texk/web2c/cwebdir/texinputs/pdfwebtocfront.tex create mode 100644 Build/source/texk/web2c/cwebdir/twinx.w (limited to 'Build/source/texk/web2c/cwebdir') 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 + + * 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 + + * 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 + + * cweave.w: Fix spacing for |#include| in TeX comment. + +2021-02-24 Andreas Scherer + + * common.w, + * ctangle.w, + * cweave.w: Fine print for single '@' characters in TeX text. + +2021-02-24 Andreas Scherer + + * cweave.w: Fix output format when 'tracing @2'. + +2021-02-23 Andreas Scherer + + * cwebman.tex, + * cwebman-w2c.ch: Minor redactions. + +2021-02-23 Andreas Scherer + + * comm-w2c.ch: Simplify documentation. + +2021-02-22 Andreas Scherer + + * 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 + + * 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 + + * 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 + + * cweave.w: Purge unused macro definition. + +2021-02-18 Andreas Scherer + + * ctangle.c, + * ctangle.w, + * cweave.w: Reshuffle a few variables (upstream). + +2021-02-18 Andreas Scherer + + * cweave.w: Fix an 'aspell'ing error and one old macro call. + +2021-02-17 Andreas Scherer + + * cweave.w: Fix 'Illegal hardware instruction' on MacOS. + +2021-02-17 Andreas Scherer + + * Makefile: Main CWEB modules depend on COMMON interface. + +2021-02-16 Andreas Scherer + + * common.c, + * common.h, + * ctangle.c, + * comm-w2c.h: Reshuffle byte_mem pointer. + +2021-02-16 Andreas Scherer + + * comm-w2c.ch, + * common.h: Restore comment from 'cweave.w' (3.64c). + +2021-02-11 Andreas Scherer + + * texinputs/pdfctwimac.tex: Fix bug in color setter. + +2021-02-08 Andreas Scherer + + * comm-w2c.ch, + * common.c, + * common.h, + * common.w, + * ctangle.c, + * ctangle.w, + * cweave.w: Don't repeat yourself. + +2021-02-07 Andreas Scherer + + * comm-w2c.ch: Fix 'reading error'; + CWEB development has moved to another level. + +2021-02-07 Andreas Scherer + + * 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 + + * comm-w2c.ch, + * ctang-w2c.ch, + * ctwill-w2c.ch, + * cweav-w2c.ch: Fix typographic inconsistency. + +2020-07-15 Andreas Scherer + + * comm-w2c.ch, + * comm-w2c.hch, + * ctwill-mini.ch: Clearer exposition re external type definitions. + +2020-07-08 Andreas Scherer + + * cwebman-w2c.ch, + * po/web2c-help.pot, + * po/de/web2c-help.po: Add '-dN' to 'help' message. + +2020-07-08 Andreas Scherer + + * comm-w2c.ch: Add special index entries for Kpathsea values. + +2020-07-08 Andreas Scherer + + * cwebman-w2c.ch: Add links to appendices D, E, F, and G. + +2020-07-05 Andreas Scherer + + * ctwill-mini.ch, + * texinputs/pdfctwimac.tex: Fix two issues with 'ctwill.dvi/pdf'. + +2020-07-02 Andreas Scherer + + * cwebman-w2c.ch: Add links and bookmarks in PDF. + +2020-06-29 Andreas Scherer + + * 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 + + * 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 + + * prod-twill.w: Roll back editorial changes. + +2020-06-21 Andreas Scherer + + * 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 + + * 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 + + * comm-w2c.ch: Clarify triple responsibility. + +2020-06-19 Andreas Scherer + + * texinputs/pdfwebtocfront.tex: Generic 'group title' on the first + page after the table-of-contents. + +2020-06-16 Andreas Scherer + + * texinputs/pdfctimac.tex: Bookmarks for "Names of the sections". + +2020-06-16 Andreas Scherer + + * 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 + + * 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 + + * 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 + + * comm-w2c.ch, + * ctang-w2c.ch, + * ctwill-w2c.ch, + * cweav-w2c.ch: Purge space from 'covernote'. + +2020-06-11 Andreas Scherer + + * cwebman-w2c.ch: Add footnotes for TeX Live extensions. + +2020-06-10 Andreas Scherer + + * ctang-w2c.ch: Add short comments to new material. + +2020-06-10 Andreas Scherer + + * 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 + + * comm-w2c.ch, + * ctang-w2c.ch, + * cweav-w2c.ch, + * ctwill-w2c.ch: Add date to table-of-contents page. + +2020-06-07 Andreas Scherer + + * ctang-w2c.ch: Handle special 'files' as secondary output. + +2020-06-07 Andreas Scherer + + * comm-w2c.ch, + * ctang-w2c.ch, + * cweav-w2c.ch, + * ctwill-w2c.ch: Check accessibility to designated output files. + +2020-06-07 Andreas Scherer + + * 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 + + * comm-w2c.ch: Add index entries for the CWEBINPUTS envvar. + +2020-06-05 Andreas Scherer + + * comm-w2c.ch: Fix newline blunder in case of error. + +2020-06-01 Andreas Scherer + + * texinputs/pdfwebtocfront.tex: Adapt to 'pwebmac.tex 4.5.2'. + +2020-05-31 Andreas Scherer + + * comm-w2c.ch: Sanitize command for PDF outlines. + +2020-05-26 Andreas Scherer + + * texinputs/pdfwebtocfront.tex: Fake headline on page after TOC. + +2020-05-23 Andreas Scherer + + * texinputs/pdfwebtocfront.tex: Add treatment for {pdf,xe}tex.web. + +2020-05-22 Andreas Scherer + + * texinputs/Xcwebmac.tex: Activate alternative assignment operator. + * texinputs/pdfwebtocfront.tex: Add comments to the macro code. + +2020-05-07 Andreas Scherer + + * 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 + + * comm-w2c.ch: Clarify §95 and fix missing type format. + +2020-04-29 Andreas Scherer + + * comm-w2c.ch: Purge irrelevant mention of .web extension. + +2020-04-28 Andreas Scherer + + * comm-w2c.ch: Purge standard headers already in KPathSea. + +2020-04-27 Andreas Scherer + + * 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 + + * cweav-w2c.ch, + * ctwill-w2c.ch: Fix missing hyphen. + +2020-04-14 Andreas Scherer + + * cweav-w2c.ch, + * ctwill-w2c.ch: Fix uppercase spelling for COMMON module. + +2020-04-13 Andreas Scherer + + * ctwill-w2c.ch: Print CTWILL user manual on two pages. + +2020-04-13 Andreas Scherer + + * cweav-w2c.ch, + * ctwill-w2c.ch: Move reference to global variable 'use_language' + from 'main' to section 'Extensions'. + +2020-04-13 Andreas Scherer + + * comm-w2c.h: Add comment for section 6 in CWEB programs. + +2020-04-11 Andreas Scherer + + * comm-w2c.ch, comm-w2c.h: Rearrange 'common variables'. + +2020-03-30 Andreas Scherer + + * 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 + + * ctang-w2c.ch: Fix verbosity bug in ctangle. + +2019-05-29 Andreas Scherer + + * comm-w2c.ch, comm-w2c.h: Minor changes. + +2019-02-16 Andreas Scherer + + * cwebinputs/c++1xlib.w: Add some C++1x class names. + +2019-01-20 Andreas Scherer + + * comm-w2c.ch: Use braced evaluation and save a macro variable. + +2019-01-19 Andreas Scherer + + * comm-w2c.ch: Extended notes about NLS activation. + * po/web2c-help.pot, po/de/web2c-help.po: Fix typos. + +2019-01-18 Andreas Scherer + + * po/cweb.pot, po/de/cweb.po, po/it/cweb.po: + Update NLS references for TP notification. + +2019-01-17 Andreas Scherer + + * 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 + + * comm-w2c.ch: Correct usage of 'kpse_var_expand'; + skip numeric argument of '-d' flag. + +2019-01-15 Andreas Scherer + + * 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 + + 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 + + * 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 + + * 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 + + * 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 + + * ../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 + + * comm-w2c.ch, ctang-w2c.ch, cweav-w2c.ch: Avoid useless + char subscript warnings. + +2014-02-12 Peter Breitenlohner + + * comm-w2c.ch: Handle input lines with CRLF. + +2013-07-02 Peter Breitenlohner + + * comm-w2c.ch: Include system headers after "cpascal.h". + +2013-06-28 Peter Breitenlohner + + * comm-w2c.ch, ctang-w2c.ch, cweav-w2c.ch: Include system + headers after . + +2012-09-05 Akira Kakuto + + * 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 + + * 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 + + * {comm,ctang,cweav}-w2c.ch: Use binary mode for output files. + From Akira Kakuto (W32TeX). + +2011-04-19 Peter Breitenlohner + + Avoid 'differ in signedness' warnings. + * cweav-w2c.ch: cast strcpy() arg collate to 'char *'. + +2010-01-18 Peter Breitenlohner + + * {comm,ctang,cweav}-w2c.ch: Move extern declaration of + versionstring from {ctangle,cweave}.c to cweb.h. + +2009-08-29 Peter Breitenlohner + + * {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 + + * ../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 + + * 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 */ + +@= +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 + +@= +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. +@ @= +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 +@ @= +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@> + +@= +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@> + +@= +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 */ + @@; +@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 */ + @@; +@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 +@^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 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 +@= +{ + if (s-*argv > max_file_name_length-5) + @@; + 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 +@= +{ + if (s-*argv > max_file_name_length-5) + @; + 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 +@ @= +{ + if (strcmp(*argv,"-")!=0) { + if (s-*argv > max_file_name_length-4) + @@; + if (dot_pos==NULL) + sprintf(change_file_name,"%s.ch",*argv); + else strcpy(change_file_name,*argv); + } + found_change=true; +} +@y +@ @= +{ + if (strcmp(*argv,"-")!=0) { + if (s-*argv > max_file_name_length-4) + @; + if (dot_pos==NULL) + sprintf(change_file_name,"%s_ch",*argv); + else strcpy(change_file_name,*argv); + found_change=true; + } +} +@z + + +@x +@ @= +{ + if (s-*argv > max_file_name_length-5) + @@; + 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 +@ @= +{ + if (s-*argv > max_file_name_length-5) + @; + 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 +@ @= +{ +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 +@ @= +{ +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 ) + > 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 /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* 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 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 + @@; +@y + @@; + @@; +@z + +@x + @@; +@y + @@; + @@; +@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 + @@; +@y + @@; + @@; +@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 +@= +{ + for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++) +@y +@= +{ + if (strcmp("-help",*argv)==0 || strcmp("--help",*argv)==0) +@.--help@> + @@; + if (strcmp("-version",*argv)==0 || strcmp("--version",*argv)==0) +@.--version@> + @@; + 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) @@; + 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 +@ @= +{ +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 +@ @= +cb_usage(program==ctangle ? "ctangle" : program==cweave ? "cweave" : "ctwill"); +@.Usage:@> +@z + +@x +@ @= fatal("! Filename too long\n", *argv); +@y +@ @= 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_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_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. + +@= +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] + +@= +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. + +@= +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} + +@= +#if HAVE_GETTEXT +#include /* |@!LC_MESSAGES|, |@!LC_CTYPE| */ +#else +#define setlocale(A,B) "" +#define bindtextdomain(A,B) "" +#define textdomain(A) "" +#endif + +@ @= +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) + +@= +typedef bool boolean; +#define HAVE_BOOLEAN +#include /* include every \Kpathsea/ header; + |@!kpathsea_debug|, |@!const_string|, |@!string| */ +#include /* \&{integer} */ +#include /* |@!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@> + +@= +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. + +@= +#define CWEB +#include "help.h" /* |@!CTANGLEHELP|, |@!CWEAVEHELP|, |@!CTWILLHELP| */ + +@ @= +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). + +@= +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. + +@= +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 + + +@= +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) + +@= +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif +@# +#if HAVE_GETTEXT +#include +#else +#define gettext(A) A +#endif +@# +#include /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* 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} */ + +@= +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)) + +@= +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 */ + +@= +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 */ + +@ @= +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: +@= +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 */ + +@= +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 */ + +@ @= +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@> + +@= +extern int history; /* indicates how bad this run was */ + +@ @= +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? */ + +@= +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? */ + +@= +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: +@= +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 ) + +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 +#include +#include +#include +#include +#include +#include + +/*: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+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(++ilink; +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 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"); +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 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 + +@= +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 /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* 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} */ + +@= +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)) + +@= +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 */ + +@= +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 */ + +@ @= +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: +@= +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 */ + +@= +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 */ + +@ @= +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@> + +@= +extern int history; /* indicates how bad this run was */ + +@ @= +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? */ + +@= +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? */ + +@= +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: +@= +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 +@@/ +@h +@@/ +@@/ +@ + +@ 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|. + +@= +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. + +@= +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) +{ + @@; + @@; + @@; +} + +@* 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@> + +@= +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. + +@= +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; +} + +@ @=@+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}. + +@= +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))) + +@= +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 */ + @@; + @@; + @@; +} + +@ @=@+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). + +@= +while(true) { + change_line++; + if (!input_ln(change_file)) return; + if (limit + } +} + +@ Here we are looking at lines following the \.{@@x}. + +@= +do { + change_line++; + if (!input_ln(change_file)) { + err_print("! Change file ended after @@x"); +@.Change file ended...@> + return; + } +} while (limit==buffer); + +@ @= +{ + 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 + 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]; + @@; + } + @@; + 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++; + } +} + +@ @=@+static void check_change(void); + +@ @= +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]=' '; + @@; + 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@> + +@= +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. + +@= +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) + @@; + if (! changing || include_depth>change_depth) { + @@; + 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 */ + @@; + } + 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@>@= { + 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; +} + +@ @= { + 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(); +} + +@ @= { + 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|. + +@= +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|. + +@= +char *byte_ptr; /* first unused position in |byte_mem| */ +name_pointer name_ptr; /* first unused position in |name_dir| */ + +@ @= +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 */ + +@= +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. + +@= +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 */ + @@; + @@; + if (p==name_ptr) @@; + 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|.$$ + +@= +h=(eight_bits)*i; +while (++i + +@ If the identifier is new, it will be placed in position |p=name_ptr|, +otherwise |p| will point to its existing 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. +@= { + 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 */ + +@= +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 /* 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; + @@; + @@; + @@; +} + +@ 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. + +@= +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 (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. + +@= +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 + 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 \.{@@} should be an acceptable ``abbreviation'' +for \.{@@}. 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 \.{@@} 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; + } + } +} + +@ @=@+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. + +@= +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) @@; + 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@> + +@= +{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 + +@c +int wrap_up(void) { + if (show_progress) new_line; + if (show_stats) + print_stats(); /* print statistics about memory usage */ + @@; + if (history > harmless_message) return EXIT_FAILURE; + else return EXIT_SUCCESS; +} + +@ @= +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. + +@= +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|. + +@= +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)) @@; + 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) @@; + else if (!found_change) @@; + else if (!found_out) @@; + else @@; + } + } + if (!found_web) @@; +} + +@ @=@+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. + +@= +{ + if (s-*argv > max_file_name_length-5) + @@; + 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; +} + +@ @= +{ + if (strcmp(*argv,"-")!=0) { + if (s-*argv > max_file_name_length-4) + @@; + if (dot_pos==NULL) + sprintf(change_file_name,"%s.ch",*argv); + else strcpy(change_file_name,*argv); + } + found_change=true; +} + +@ @= +{ + if (s-*argv > max_file_name_length-5) + @@; + 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!='-') +@= +{ + for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++) + flags[(eight_bits)*dot_pos]=flag_change; +} + +@ @= +{ +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" + ,""); +} + +@ @= fatal("! Filename too long\n", *argv); +@.Filename too long@> + +@** Output. Here is the code that opens the output file: +@^system dependencies@> + +@= +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_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 */ + +@= +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 + +@= +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 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 ) + > 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 /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* 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 +@= +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 +@= +fclose(C_file); C_file=NULL; +@@; +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; + @@; +} +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. + +@= +if((C_file=fopen(C_file_name,"r"))!=NULL) { + @@; + @@; +} else + rename(check_file_name,C_file_name); /* This was the first run */ + +@ @= + 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) @@; + + fclose(C_file); C_file=NULL; + fclose(check_file); check_file=NULL; + +@ We hope that this runs fast on most systems. + +@= +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|. + +@= +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. + +@= +if(0==strcmp("/dev/stdout",output_file_name)) + @@; +else if(0==strcmp("/dev/stderr",output_file_name)) + @@; +else if(0==strcmp("/dev/null",output_file_name)) + @@; +else { /* Hopefully a \\{regular} output file */ + if((C_file=fopen(output_file_name,"r"))!=NULL) { + @@; + @@; + } else + rename(check_file_name,output_file_name); /* This was the first run */ +} + +@ Again, we use a call to |remove| before |rename|. + +@= +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|. + +@={ + @@; + 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; + @@; +} + +@ Copy secondary output to |stderr|. + +@={ + @@; + 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; + @@; +} + +@ No copying necessary, just remove the temporary output file. + +@={ + int comparison=true; + @@; +} + +@ @= +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 + +@= +extern char cb_banner[]; + +@ @= + 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 +#include +#include +#include +#include +#include +#include + +/*: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_linktext_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_texttext_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_bytebyte_start; +k= (cur_val+name_dir+1)->byte_start; +while(j 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');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){ +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 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='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_controltext_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_linktext_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||!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=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 +@@/ +@h +@@/ +@@/ +@@/ +@ + +@ \.{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; + @@; + 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|. + +@= +typedef struct { + eight_bits *tok_start; /* pointer into |tok_mem| */ + sixteen_bits text_link; /* relates replacement texts */ +} text; +typedef text *text_pointer; + +@ @= +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| */ + +@ @= +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 */ + +@ @= +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 */ + +@= +static text_pointer last_unnamed; /* most recent replacement text of unnamed section */ + +@ @= 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 */ +} + +@ @=@+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|. + +@= +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 */ + +@= +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. + +@= +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; + } +} + +@ @= +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_linktext_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 */ + +@= +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 @@; + break; + default: cur_val=a-050000; if (cur_val>0) cur_section=cur_val; + out_char(section_number); + } + } +} + +@ @=@+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. + +@= +{ + 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:
@> + } + 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 */ + +@= +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++; +} + +@ @=@+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 +@= +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. +@= +cur_out_file=end_output_files=output_files+max_files; + +@ @= +{ + for (an_output_file=cur_out_file; + an_output_fileoutput_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; + @@; + @@; + 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: @@; + if (show_happiness) { + if (show_progress) new_line; + fputs("Done.",stdout); + } + } +} + +@ @=@+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. + +@= +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. + +@= + if (!output_defs_seen) + output_defs(); + +@ @= +static boolean output_defs_seen=false; + +@ @= +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_texttext_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 + 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@>@@; + @/@t\4@>@@; + @/@t\4@>@@; + 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; + } +} + +@ @= +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 + +@= +static char translit[128][translit_length]; + +@ @= +{ + int i; + for (i=0;i<128;i++) sprintf(translit[i],"X%02X",(unsigned int)(128+i)); +} + +@ @= +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 + else C_printf("%s",translit[(eight_bits)(*j)-0200]); + j++; + } + out_state=num_or_id; break; + +@ @= +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= +static eight_bits ccode[256]; /* meaning of a char following \.{@@} */ + +@ @= { + 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; + } + } +} + +@ @= +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 `\.{@@*}'. + +@= +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 + +@= +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; + @@; + } + 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=='.') @@; + else if (c=='\'' || c=='"'@| + || ((c=='L' || c=='u' || c=='U')&&(*loc=='\'' || *loc=='"'))@| + || ((c=='u' && *loc=='8')&&(*(loc+1)=='\'' || *(loc+1)=='"'))) + @@; + else if (isalpha(c) || isxalpha(c) || ishigh(c)) + @@; + else if (c=='@@') @@; + 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: @@; + return c; + } +} + +@ @=@+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 + +@= +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; +} + +@ @= { + 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; +} + +@ @= { + 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|. + +@= { + 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. + +@= { + 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); + @@; + case string: @@; + case ord: @@; + 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'}. + +@= + 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; + +@ @= { + char *k; /* pointer 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=='(') + @@; + 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.) + +@=section_text[0]=' '; + +@ @= +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; + @@; + loc++; 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 (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. + +@= { + 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;} + +@= +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) {@@;} + while (true) switch (a=get_next()) { + @@; + 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; +} + +@ @=@+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. + +@= +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);} + +@ @= +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 { + @@; + a=cur_section_name-name_dir; + app_repl((a / 0400)+0250); + app_repl(a % 0400); + @@; 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); + @@; + } + break; +case constant: case string: + @@; +case ord: + @@; +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; + +@ @= { + char *try_loc=loc; + while (*try_loc==' ' && try_loc + /* user who isn't defining a section should put newline after the name, + as explained in the manual */ +} + +@ @= + 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@> + +@= { + 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) { + @@; + if (next_control == definition) { /* \.{@@d} */ + @@; + continue; + } + if (next_control == begin_C) { /* \.{@@c} or \.{@@p} */ + p=name_dir; break; + } + if (next_control == section_name) { /* \.{@@<} or \.{@@(} */ + p=cur_section_name; + @@; + break; + } + return; /* \.{@@\ } or \.{@@*} */ + } + no_where=print_where=false; + @@; +} + +@ @=@+static void scan_section(void); + +@ At the top of this loop, if |next_control==section_name|, the +section name has already been scanned (see |@|). 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. + +@= +while (next_control= { + 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. + +@= +while ((next_control=get_next())=='+'); /* allow optional \.{+=} */ +if (next_control!='=' && next_control!=eq_eq) + continue; + +@ @= +@@; +scan_repl(section_name); /* now |cur_text| points to the replacement text */ +@@; + +@ @= +store_two_bytes((sixteen_bits)(0150000+section_count)); + /* |0150000==0320*0400| */ + +@ @= +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_linktext_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; +} + +@ @=@+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: @@; 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...@> + } + } + } +} + +@ @=@+static void skip_limbo(void); + +@ @= + while(xisspace(*loc)&&loclimit || !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=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\{\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\{\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 +@ @= +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 +@= { +@y +@= {@+ +@z + +Section 70. + +@x +@ @= +@y +@r @ @= +@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\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\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\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\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\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\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 +@ @= +@y +@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: @@; @+break; + case lpar: @@; @+break; + case unop: @@; @+break; + case ubinop: @@; @+break; + case binop: @@; @+break; + case cast: @@; @+break; + case sizeof_like: @@; @+break; + case int_like: @@; @+break; + case public_like: @@; @+break; + case colcol: @@; @+break; + case decl_head: @@; @+break; + case decl: @@; @+break; + case base: @@; @+break; + case struct_like: @@; @+break; + case struct_head: @@; @+break; + case fn_decl: @@; @+break; + case function: @@; @+break; + case lbrace: @@; @+break; + case if_like: @@; @+break; + case else_like: @@; @+break; + case else_head: @@; @+break; + case if_clause: @@; @+break; + case if_head: @@; @+break; + case do_like: @@; @+break; + case case_like: @@; @+break; + case catch_like: @@; @+break; + case tag: @@; @+break; + case stmt: @@; @+break; + case semi: @@; @+break; + case lproc: @@; @+break; + case section_scrap: @@; @+break; + case insert: @@; @+break; + case prelangle: @@; @+break; + case prerangle: @@; @+break; + case langle: @@; @+break; + case template_like: @@; @+break; + case new_like: @@; @+break; + case new_exp: @@; @+break; + case ftemplate: @@; @+break; + case for_like: @@; @+break; + case raw_ubin: @@; @+break; + case const_like: @@; @+break; + case raw_int: @@; @+break; + case operator_like: @@; @+break; + case typedef_like: @@; @+break; + case delete_like: @@; @+break; + case question: @@; @+break; + } + pp++; /* if no match was found, we move to the right */ +} +@y + switch (pp->cat) { + @cat|@>@; + } + pp++; /* if no match was found, we move to the right */ +} + +@ @cat|@>= + case exp: @@; @+break; + case lpar: @@; @+break; + case unop: @@; @+break; + case ubinop: @@; @+break; + case binop: @@; @+break; + case cast: @@; @+break; + case sizeof_like: @@; @+break; + case int_like: @@; @+break; + case public_like: @@; @+break; + case colcol: @@; @+break; + case decl_head: @@; @+break; + case decl: @@; @+break; + case base: @@; @+break; + case struct_like: @@; @+break; + case struct_head: @@; @+break; + case fn_decl: @@; @+break; + case function: @@; @+break; + case lbrace: @@; @+break; + case if_like: @@; @+break; + case else_like: @@; @+break; + case else_head: @@; @+break; + case if_clause: @@; @+break; + case if_head: @@; @+break; + case do_like: @@; @+break; + case case_like: @@; @+break; + case catch_like: @@; @+break; + case tag: @@; @+break; + case stmt: @@; @+break; + case semi: @@; @+break; + case lproc: @@; @+break; + case section_scrap: @@; @+break; + case insert: @@; @+break; + case prelangle: @@; @+break; + case prerangle: @@; @+break; + case langle: @@; @+break; + case template_like: @@; @+break; + case new_like: @@; @+break; + case new_exp: @@; @+break; + case ftemplate: @@; @+break; + case for_like: @@; @+break; + case raw_ubin: @@; @+break; + case const_like: @@; @+break; + case raw_int: @@; @+break; + case operator_like: @@; @+break; + case typedef_like: @@; @+break; + case delete_like: @@; @+break; + case 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 +@ @= +@y +@r @ @= +@z + +Section 168. + +@x +@ @= +@y +@r @ @= +@z + +Section 173. + +@x +@ @= +@y +@r @ @= +@z + +Section 208. + +@x +@ Here's the |squash| procedure, which +@y +@r @ Here's the |squash| procedure, which +@z + +Section 212. + +@x +@ @= +@y +@r @ @= +@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 @ +@y +else {@} +@z + +Section 245. + +@x +@= { +@y +@= +@z + +@x +} +@y +@z + +Section 246. + +@x +@ @= +@y +@r @ @= +@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 +@= do { +@y +@= 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 +@ @= +@y +@r @ @= +@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 +@ +@y +@ + +@ 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 "" \\zip@@>}$$ +will generate a mini-index entry like `\\{printf}, \.{}.'. + +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. + +@= +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 */ + +@= +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; + +@ @= +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|? */ + +@ @= +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; +} + +@ @= +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); + } + @; +} + +@ @= +{@+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); + +@ @= +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) @@; + else if (c==suppress && phase==2) @; + } +} + +@ @= +{ char *first=id_first,*last=id_loc; + while (xisspace(*first)) first++; + while (xisspace(*(last-1))) last--; + if (firststamp=section_count; /* this is what actually suppresses output */ + } +} + +@ @= +{ 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 @; + } + loc=id_loc+2; +} + +@ @= +{ 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=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(); + @; +@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}'. + +@= +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'] + +@= +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 +@ @= +@y +@ @= +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 +@ @=@+static void print_text(text_pointer p); +@y +@ @= +#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=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; + @; + 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. + +@= +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 && **(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 */ + @; +} + +@ @= +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 +@= +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 +@= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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. + +@= +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); + } + } + @; +@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; +@; +section_count=0; format_visible=true; right_start_switch=false; copy_limbo(); +@z + +@x +while (!input_has_ended) @@; +} + +@y +while (!input_has_ended) @@; +} + +@ @= +static FILE *aux_file; +static char aux_file_name[max_file_name_length]; /* name of \.{.aux} file */ + +@ @= +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? */ + +@ @= { + 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 +@= { + 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) @; + finish_C(format_visible); format_visible=true; + doing_format=false; +} + +@ @= +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 +@= { +@y +@= { + 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 +@ @= { + doing_format=true; +@y +@ @= +{ + 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); +} + +@ @= { + 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@> +@; +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. + +@= +{ 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; + } +} + +@ @= +{ 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(' '); + @; + out(' '); out_str(m->tex_part); finish_line(); +} + +@ @=@+static void out_mini(meaning_struct *); + +@ @= +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) { + @@; 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; +@@; +@z + +@x + fputs("Done.",stdout); +@y + fputs(_("Done."),stdout); +@z + +@x +the index section itself. + +@= +static sixteen_bits k_section; /* runs through the sections */ +@y +the index section itself---NOT! +@z + +@x +@ @= { + /* 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=scrap_info_end) overflow("sorting"); +@y + if (sort_ptr>=scrap_info_end) overflow(_("sorting")); +@z + +@x +@ @= +@y +@ We don't format the index completely; the \.{twinx} program does the +rest of the job. + +@= +@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? */ + +@= +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? */ + +@= +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. + +@= +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) @@; + + fclose(tex_file); tex_file=NULL; + fclose(check_file); check_file=NULL; + + @@; +} 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. + +@= +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|. + +@= +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 + +@= +extern char cb_banner[]; + +@ @= + 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 "" \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\{\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 */ + +@= +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 + +@= +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->numxlink=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->numxlink=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; kbyte_start; /* pointers into |byte_mem| */ + out('{'); + for (k=p->byte_start; kxref!=(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 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 ) + > 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 /* definition of |@!isalpha|, |@!isdigit| and so on */ +#include /* definition of |@!bool|, |@!true| and |@!false| */ +#include /* definition of |@!ptrdiff_t| */ +#include /* definition of |@!uint8_t| and |@!uint16_t| */ +#include /* definition of |@!getenv| and |@!exit| */ +#include /* definition of |@!printf| and friends */ +#include /* 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}'. + +@= +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}'. + +@= +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 +@ @=@+static void print_text(text_pointer p); +@y +@ @= +#if 0 +static void print_text(text_pointer p); +#endif +@z + +@x +@= +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 +@= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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 +@ @= +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; +@@; +@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? */ + +@= +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? */ + +@= +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. + +@= +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) @@; + + fclose(tex_file); tex_file=NULL; + fclose(check_file); check_file=NULL; + + @@; +} 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. + +@= +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|. + +@= +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 + +@= +extern char cb_banner[]; + +@ @= + 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 +# Copyright 2009 Peter Breitenlohner +# 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 @@/ +@h +@@/ +@@/ +@@/ +@ + +@ \.{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; + @@; + common_init(); + @@; + if (show_banner) puts(banner); /* print a ``banner line'' */ + @@; + 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. + +@= +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. + +@= +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; + +@ @= +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 + +@= +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) (ailk>=custom) + /* tells if uses of a name are to be indexed */ + +@= +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|. + +@= +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|. + +@= +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| */ + +@ @= +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; +} + +@ @=@+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@> + +@= +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|. + +@= +static eight_bits ccode[256]; /* meaning of a char following \.{@@} */ + +@ @= +{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; +@@; + +@ Users can write +\.{@@2}, \.{@@1}, and \.{@@0} to turn tracing fully on, partly on, +and off, respectively. + +@= +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. + +@= +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) @@; + } + } +} + +@ 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 */ + +@= +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) { + @@; + if (loc>limit && get_line()==false) return new_section; + c=*(loc++); + if (xisdigit(c) || c=='.') @@; + 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)) + @@; + else if (xisalpha(c) || isxalpha(c) || ishigh(c)) + @@; + else if (c=='@@') @@; + else if (xisspace(c)) continue; /* ignore spaces and tabs */ + if (c=='#' && loc==buffer+1) @@; + mistake: @@; + return c; + } +} + +@ @=@+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 */ + +@= +static boolean preprocessing=false; /* are we scanning a preprocessor command? */ + +@ @= { + preprocessing=true; + @@; + 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. + +@= +static boolean sharp_include_line=false; /* are we scanning a \&{\#include} line? */ + +@ @= +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 \.\\. + +@= + 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 + +@= +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; +} + +@ @= { + 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|. + +@= { + 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|. + +@= { + 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. + +@= { + 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: + @@; + case verbatim: @@; + case ord: @@; + 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}. + +@= { + char *k; /* pointer into |section_text| */ + cur_section_char=*(loc-1); + @@; + 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.) + +@=section_text[0]=' '; + +@ @= +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; + @@; + loc++; 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 (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...@> + } +} + +@ @=@+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. + +@= { + 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. + +@= +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) + @@; + changed_section[section_count]=change_exists; + /* the index changes if anything does */ + phase=2; /* prepare for second phase */ + @@; +} + +@ @=@+static void phase_one(void); + +@ @= +{ + 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 */ + } + @@; + @@; + @@; + 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|. + +@= +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=identifier && next_control<=xref_typewriter) { + if (next_control>identifier) @@; + 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_control0) { + 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\,$\.{@@>}. + +@= +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) { + @@; + new_xref(id_lookup(id_first, id_loc,next_control-identifier)); + } + break; + } + if (next_control>=format_code) break; +} + +@ @= +{ + char *src=id_first,*dst=id_first; + while(src= +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|. + +@= +while (next_control<=definition) { /* |format_code| or |definition| */ + if (next_control==definition) { + xref_switch=def_flag; /* implied \.{@@!} */ + next_control=get_next(); + } else @@; + 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. + +@= { + 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->numxlink=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. + +@= +{ + 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|. + +@= +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. + +@= +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 '); mark_harmless; +@.Never defined:
@> + } + 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_check(p->rlink); + } +} + +@ @=@+static void section_check(name_pointer); + +@ @=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. + +@= +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) + +@= +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 (bout_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}'. + +@= +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;} + +@= +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. + +@= +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) @@; + 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. + +@= +{ + 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. + +@= +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 +@.\\\_@> + 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. + +@= +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) @@; + if (phase==2) { + if (ishigh(c)) app_tok(quoted_char); + app_tok(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:@@; +} + +@ @= +if (c=='*' && *loc=='/') { + loc++; + if (bal>1) err_print("! Missing } in comment"); +@.Missing \} in comment@> + goto done; +} + +@ @= +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. + +@= +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 /* \.{@@]} */ + +@= +static char cat_name[256][12]; + +@ @= +{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); +} + +@ @=@+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. + +@= +typedef struct { + eight_bits cat; + eight_bits mathness; + union { + text_pointer Trans; + @@; + } trans_plus; +} scrap; +typedef scrap *scrap_pointer; + +@ @d trans trans_plus.Trans /* translation texts of scraps */ + +@= +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 */ + +@ @= +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: @@; + } + } + update_terminal; +} + +@ @=@+static void print_text(text_pointer p); + +@ @= +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)) + +@= +static int cur_mathness, init_mathness; + +@ @= +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 */ + +@= { + 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: @@; @+break; + case lpar: @@; @+break; + case unop: @@; @+break; + case ubinop: @@; @+break; + case binop: @@; @+break; + case cast: @@; @+break; + case sizeof_like: @@; @+break; + case int_like: @@; @+break; + case public_like: @@; @+break; + case colcol: @@; @+break; + case decl_head: @@; @+break; + case decl: @@; @+break; + case base: @@; @+break; + case struct_like: @@; @+break; + case struct_head: @@; @+break; + case fn_decl: @@; @+break; + case function: @@; @+break; + case lbrace: @@; @+break; + case if_like: @@; @+break; + case else_like: @@; @+break; + case else_head: @@; @+break; + case if_clause: @@; @+break; + case if_head: @@; @+break; + case do_like: @@; @+break; + case case_like: @@; @+break; + case catch_like: @@; @+break; + case tag: @@; @+break; + case stmt: @@; @+break; + case semi: @@; @+break; + case lproc: @@; @+break; + case section_scrap: @@; @+break; + case insert: @@; @+break; + case prelangle: @@; @+break; + case prerangle: @@; @+break; + case langle: @@; @+break; + case template_like: @@; @+break; + case new_like: @@; @+break; + case new_exp: @@; @+break; + case ftemplate: @@; @+break; + case for_like: @@; @+break; + case raw_ubin: @@; @+break; + case const_like: @@; @+break; + case raw_int: @@; @+break; + case operator_like: @@; @+break; + case typedef_like: @@; @+break; + case delete_like: @@; @+break; + case 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 */ + +@= +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 && nxlink; + } + @@; +} + +@ 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|. + +@= + 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|. + +@= +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); + +@ @= +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); +} + +@ @= +if (cat1==exp || cat1==int_like) squash(pp,2,exp,-2,16); + +@ @= +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); +} + +@ @= +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); +} + +@ @= +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); + +@ @= +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); +} + +@ @= +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); + +@ @= +if (cat1==colon) squash(pp,2,tag,-1,29); +else squash(pp,1,int_like,-2,30); + +@ @= +if (cat1==exp||cat1==int_like) { + app(qualifier); squash(pp,2,cat1,-2,31); +}@+else if (cat1==colcol) squash(pp,2,colcol,-1,32); + +@ @= +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); + +@ @= +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); +} + +@ @= +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); + } +} + +@ @= +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); + } +} + +@ @= +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); +} + +@ @= +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); +} + +@ @= +if (cat1==function || cat1==decl || cat1==stmt) { + big_app1(pp); big_app(big_force); big_app1(pp+1); reduce(pp,2,cat1,-1,53); +} + +@ @= +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); +} + +@ @= +if (cat1==exp) { + big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,if_clause,0,57); +} + +@ @= +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); +} + +@ @= +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); +} + +@ @= +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); +} + +@ @= +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); +} + +@ @= +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); +} + +@ @= +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); +} + +@ @= +if (cat1==cast || cat1==exp) { + big_app2(pp); big_app(indent); big_app(indent); reduce(pp,2,fn_decl,0,73); +} + +@ @= +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? */ + +@= +force_lines=true; + +@ @= +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); +} + +@ @= +big_app(' '); big_app1(pp); reduce(pp,1,stmt,-1,77); + +@ @= +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); + } +} + +@ @= +if (cat1==semi) { + big_app2(pp); big_app(force); reduce(pp,2,stmt,-2,81); +} +else squash(pp,1,exp,-2,82); + +@ @= +if (cat1) + squash(pp,2,cat1,0,83); + +@ @= +init_mathness=cur_mathness=yes_math; +app('<'); reduce(pp,1,binop,-2,84); + +@ @= +init_mathness=cur_mathness=yes_math; +app('>'); reduce(pp,1,binop,-2,85); + +@ @= +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); + } +} + +@ @= +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); + +@ @= +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); + +@ @= +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); + +@ @= +if (cat1==prelangle) squash(pp+1,1,langle,1,100); +else squash(pp,1,exp,-2,101); + +@ @= +if (cat1==exp) { + big_app1(pp); big_app(' '); big_app1(pp+1); reduce(pp,2,else_like,-2,102); +} + +@ @= +if (cat1==const_like) { + big_app2(pp); app_str("\\ "); reduce(pp,2,raw_ubin,0,103); +@.\\\ @> +} else squash(pp,1,ubinop,-2,104); + +@ @= +squash(pp,1,int_like,-2,105); + +@ @= +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); + +@ @= +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); + +@ @= +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); +} + +@ @= +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); +} + +@ @= +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 + +@= +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@; + 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@; + pp--; /* we next say |pp++| */ + return; + } + for (i=j; i= +while (true) { + @@; + 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; + @@; +} + +@ 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. + +@= +if (lo_ptrcat=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. + +@= +static int tracing; /* can be used to show parsing details */ + +@ @= +{ 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@; + @@; + @@; +} + +@ @=@+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. + +@= { + @@; + 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 (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==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@; + next_control=get_next(); + if (next_control=='|' || next_control==begin_comment || + next_control==begin_short_comment) return; + } +} + +@ @=@+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; +} + +@ @= +@@; +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: + @@;@+break; + case identifier: app_cur_id(true);@+break; + case TeX_string: + @@;@+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@> @@; + 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; +} + +@ @= +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. + +@= +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@> + +@= +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@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@> + +@= +app_str("\\hbox{"@q}@>); +@^high-bit character handling@> +while (id_first0177) { + 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|. + +@= +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'] + +@= +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@; + 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 */ + +@= 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 */ + +@= +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| */ + +@ @= +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. + +@= +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. + +@= +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 */ + +@= +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: @@; break; + case section_code: @@; 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 ((abig_force) break; + if (a==indent) c++; else if (a==outdent) c--; + else if (a==opt) a=get_output(); + } + @@; + goto reswitch; + case indent: case outdent: case opt: case backup: case break_space: + case force: case big_force: case preproc_line: @@; 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\}}'. + +@= +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. + +@= +if (a +@.\\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 @ + +@ 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}'). + +@= { + b=a; save_mode=cur_mode; c=0; + while (true) { + a=get_output(); + if (a==inserted) continue; + if (a==cancel || a==big_cancel) { + @@; + goto reswitch; /* |cancel| overrides everything */ + } + if ((a!=' ' && abig_force) { + if (save_mode==outer) { + if (out_ptr>out_buf+3 && strncmp(out_ptr-3,"\\Y\\B",4)==0) + goto reswitch; + @@; + 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= + 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. + +@= { + 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}@>); +@.\\.@> + @@; + if (an_output) out_str(@q{@>" }"); + out_str("\\X"); +} + +@ @= +sprint_section_name(scratch,cur_name); +k=scratch; +k_limit=scratch+strlen(scratch); +cur_section_name=cur_name; +while (k@; + 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 { + @@; + save_loc=loc; save_limit=limit; loc=limit+2; limit=j+1; + *limit='|'; output_C(); + loc=save_loc; limit=save_limit; + } } +} + +@ @= +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. + +@= +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)) + @@; + 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; + } +} + +@ @= { + 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) @@; +} + +@ @=@+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@> + +@= +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? */ + +@ @= { + section_count++; + @@; + save_position; + @@; + @@; + @@; + @@; + @@; +} + +@ 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. + +@= +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. + +@= 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|, and +the token memory is in its initial empty state. + +@= +space_checked=false; +while (next_control<=definition) { /* |format_code| or |definition| */ + init_stack; + if (next_control==definition) @@; + else @@; + 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 */ +} + +@ @=@+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 `\.)'. + +@= { + 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 */ + } +} + +@ @= { + 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. + +@= +static name_pointer this_section; /* the current section name, or zero */ + +@ @= +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; + @= +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 */ + +@ @= +if (next_control + 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. + +@= +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'); + @@; + out('.'); +} + +@ @=@+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. + +@= +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 */ + } +} + +@ @= +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) { + @@; finish_line(); finish_line(); + } + out_str("\\inx"); finish_line(); +@.\\inx@> + active_file=idx_file; /* change active file to the index file */ + @@; + @@; + 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 */ + @@; + 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? */ +} + +@ @=@+static void phase_three(void); + +@ Just before the index comes a list of all the changed sections, including +the index section itself. + +@= +static sixteen_bits k_section; /* runs through the 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= +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. + +@= { +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|. + +@= +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 */ + +@= +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| */ + +@ @= +max_sort_ptr=scrap_info; + +@ The desired alphabetic order is specified by the |collate| array; namely, +$|collate|[0]<|collate|[1]<\cdots<|collate|[100]$. + +@= +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. + +@= +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; + } +} + +@ @=@+static void unbucket(eight_bits); + +@ @= +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) + @@; + else @@; +} + +@ @= { + 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); +} + +@ @= { + cur_name=sort_ptr->head; + do { + out_str("\\I"); +@.\\I@> + @@; + @@; + cur_name=blink[cur_name-name_dir]; + } while (cur_name); + --sort_ptr; +} + +@ @= +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\,$\.]'. + +@= +@@; +do { + out_str(", "); cur_val=cur_xref->num; + if (cur_val + 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. +@= +static xref_pointer next_xref, this_xref; + /* pointer variables for rearranging a list */ + +@ @= +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); + } +} + +@ @=@+static void section_print(name_pointer); + +@ @=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 +% +% 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 +% +% 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 +% +% 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 +% +% 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\{\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, `\.{@}' can be abbreviated to `\.{@}' if no other section +name begins with the five letters `\.{Clear}'. Elsewhere +you might use the abbreviation `\.{@}', 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 `\.{@}' would not match +`\.{@}'. + +\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 `\.{@
=}'. 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 `\.{@
}' 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 \.{@
} 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)} \.{@}} \cr +\hbox{\.{...} \.{using} \.{the} \.{algorithm} +\.{in} \.{|@|.}} } +$$ +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(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 \.{@} 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 +\.{} 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 +`\.{@}' 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 +\.{@@;@\#}\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. + +@= +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 */ + @@; + @@; + @@; +} + +@ 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). + +@= +while(true) { + change_line++; + if (!!input_ln(change_file)) return; + if (limit + } +} + +@ Here we are looking at lines following the \.{@@x}. + +@= +do { + change_line++; + if (!!input_ln(change_file)) { + err_print("!! Change file ended after @@x"); +@.Change file ended...@> + return; + } +} while (limit==buffer); + +@ @= +{ + 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}', 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 +#include +#include +extern void exit(); /* system routine that terminates execution */ +@# +@@; +@@; +@# +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) */ +{ + @; + if (strlen(*argv)>=6 && strcmp(*argv+strlen(*argv)-6,"excweb")==0) { + web=1; + @; + } else web=0; + comment=skipping=c=0; + main_cycle: if (c) goto big_switch; + restart: c=get(); + big_switch: switch(c) { + @@; + case EOF: exit(0); + default: goto restart; + } + @; +} + +@ @= +int c; /* one-character look-see buffer */ + +@ @= +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';@+} + +@= +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. + +@= +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|. + +@= +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. + +@= +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. + +@ @= +control_seq_in_word: if (!c) goto continue_word; +goto checkout_word; + +@ @= +case '\\': if (controlseq()) goto control_seq_in_word; +goto main_cycle; + +@ @= +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(); + @; + return 0; +} + +@ @d pair(x,y) (a==x && b==y) + +@= +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. + +@= +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. + +@= +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. + +@= +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}' */ + +@= +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. + +@= +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. + +@= +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] 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 +@@; +@# +Frame frame; /* the base frame where we will live */ +@@; /* additional globals besides |frame| */ +@# +@@; +@# +main(argc,argv) + int argc;@+char *argv[]; /* typical \UNIX/ setup */ +{ + @; + @; + xv_main_loop(frame); + exit(0); +} + +@ Including the header file \.{} also causes other +basic header files like \.{}, \.{}, 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 \.{}, some in +\.{}; the Sun documentation calls for \.{}. 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, +\.{} isn't really needed with Sun's \CEE/, unless certain macros +are used. I'll include \.{} and \.{} anyway, in the +spirit of being obedient to the stated rules. + +@= +#include +#include +#include + +@* 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.) + +@= +{@+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 + +@ 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. + +@= +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.) + +@= +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. + +@= +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); + +@ @= +Tty tty; + +@ @= +#include + +@ 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. + +@= +window=(Xv_window)xv_get(tty,OPENWIN_NTH_VIEW,0); +xv_set(window,WIN_CONSUME_EVENT,LOC_WINENTER,NULL); + +@ @= +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|. + +@= +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 /* 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. + +@= +rv=0; +{@+int k=argc; + while (--k>0) if (strcmp(argv[k],"-rv")==0 || + strcmp(argv[k],"-reverse")==0) rv=1; +} + +@ @= +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.'' + +@= +{ + 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); +} + +@ @= +int char_width, char_height; /* character dimensions in the font */ + +@ @= +#include /* 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. + +@= +@; +xv_init(XV_INIT_ARGC_PTR_ARGV,&argc,argv,NULL); + /* start XViewing; strip and remember the OpenWin arguments */ +@; +@; +@; +@; +@; +@; +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. + +@= +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 + @; + if (id==LOC_WINENTER) @; + if (event_is_button(event)) @; + if (event_is_up(event)) return NOTIFY_DONE; /* key has been released */ + @; + @; + 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. + +@= +{ + 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 \.{}, +clears the |action| code as desired. + +@= +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 \.{}, 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 \.{}. + +@ 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|. + +@= +{@+register int bank='b'; /* |'l'|, |'r'|, |'t'|, or |'b'| */ + register int n; /* function key serial number, |1<=n<=15| */ + if (id>=KEY_LEFT(1)) @@; + else if (id>=256) @@; + else if (id>=128) + @@; + else if (id>0 || + (event_action(event)==0 && event_shiftmask(event)==CTRLMASK)) + goto non_function; + else n=1; /* Help key */ +emit_function_key:@; +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. + +@= +{ + if (id} +but not in the XView reference manual. + +@= +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. + +@= +{ + 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; +} + +@ @= +char buf[]="\030*??\021"; /* |030| and |021| give control-X, control-Q */ + +@ @= +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)}. + +@= +int num_lock_state; +char turnon[]="\370turn-numlock-on\r", turnoff[]="\370turn-numlock-off\r"; +int keyboard; /* file descriptor of \.{/dev/kbd} */ + +@ @= +#include /* definition of |O_RDWR| for |open| */ +#include /* definition of |KIOCGLED| for |ioctl| */ + +@ @d LED_NUM_LOCK 0x1 /* the official definition is in \.{}, + but that header file includes huge gobs of other stuff */ + +@= +{@+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. + +@= +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. + +@= +{@+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; + @; + 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; +} + +@ @= +char mouse_buf[24]="\030"; + +@ XView's event structure includes |event_time(event)|, which has +type |struct timeval|; this data type is declared in \.{}, +which is one of the files included automatically as a result of +including \.{}. +A |timeval| structure consists of two |long| integers, |tv_sec| and |tv_usec|, +denoting clock time in seconds and microseconds, respectively. + +@= +{@+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; +} + +@ @= +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 \.{}; 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 +@@; +@@; +@@; + +@# +main(argc, argv) + int argc; + char **argv; +{ +@<|main| variable declarations@>; +@; +@; +@@; +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 + +@= +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) { + @; + add_tree(rootptr, buf); + } + } +@ @= +#include + +@ Depending what system you're on, you may or may not get a newline in |buf|. +@= + 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; + +@; + + if (*rootptr==NULL) { +@; + 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. + +@= + for (s=p;*s!='\0'&&*s!='/';) s++; + if (*s=='/') { + slashed=1; + *s='\0'; + } else slashed=0; + +@ Node allocation is perfectly standard \dots +@= + *rootptr=(struct tnode *) malloc (sizeof(struct tnode)); + (*rootptr)->left = (*rootptr)->right = NULL; + (*rootptr)->data = malloc (strlen(p)+1); + +@ +@= char *malloc(); + +@ In this simple implementation, we just read from standard input. +@= 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@> + +@= +#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. +@= +char vert=svert; +char horiz=shoriz; +char cross=scross; +char corner=scorner; + +@ With option |"-p"| use the printer character set. +@= +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. + +@= +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\ \ @> " +--"); +@; + 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. +@= + 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. + +@= 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 +@
@/ +@@/ +@@/ +@ + +@ We must include the standard I/O definitions, since we want to send +formatted output to |stdout| and |stderr|. + +@
= +#include + +@ 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 */ + +@= +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. + +@= +main (argc,argv) + int argc; /* the number of arguments on the \UNIX/ command line */ + char **argv; /* the arguments themselves, an array of strings */ +{ + @@; + prog_name=argv[0]; + @; + @; + @; + 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. + +@= +int file_count; /* how many files there are */ +char *which; /* which counts to print */ +int silent=0; /* nonzero if the silent option was selected */ + +@ @= +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. + +@= +argc--; +do@+{ + @; + @; + @; + @; + @; + @; /* 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. + +@= +int fd=0; /* file descriptor, initialized to |stdin| */ + +@ @d READ_ONLY 0 /* read access code for system |open| routine */ + +@= +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(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*/ + +@= +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 */ + +@ @= +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@> + +@= +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. + +@= +while (1) { + @; + 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. + +@= +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|. + +@= +if (!silent) { + wc_print(which, char_count, word_count, line_count); + if (file_count) printf (" %s\n", *argv); /* not |stdin| */ + else printf ("\n"); /* |stdin| */ +} + +@ @= +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. + +@= +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) + +@= +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 +#include /* declaration of |getenv| */ +#include /* definition of |isalpha|, |isdigit| and so on */ +@@; +@@; +@@; +main (ac,av) +int ac; char **av; +{ + argc=ac; argv=av; + @; + @; + reset_input(); + while (get_line()) + put_line(); + fflush(out_file); + check_complete(); + fflush(out_file); + return wrap_up(); +} + +@ @= +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 \.{} and \.{}.) + +@= +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 */ + +@ @= + +@ 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 + +@= +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|. + +@= +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 */ + +@= +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)) + +@= +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. + +@= +void +prime_the_change_buffer() +{ + change_limit=change_buffer; /* this value is used if the change file ends */ + @; + @; + @; +} + +@ 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). + +@= +while(1) { + change_line++; + if (!input_ln(change_file)) return; + if (limit + } +} + +@ Here we are looking at lines following the \.{@@x}. + +@= +do { + change_line++; + if (!input_ln(change_file)) { + err_print("! Change file ended after @@x"); +@.Change file ended...@> + return; + } +} while (limit==buffer); + +@ @= +{ + 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= +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]; + @; + } + @; + 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 (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. + +@= +void +reset_input() +{ + limit=buffer; loc=buffer+1; buffer[0]=' '; + @; + 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@> + +@= +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. + +@= +int get_line() /* inputs the next line */ +{ + restart: + if (changing && include_depth==change_depth) + @; + if (! changing || include_depth>change_depth) { + @; + 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 */ + @; + } + return 1; +} + +void put_line() +{ + char *ptr=buffer; + while (ptr= { + 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; +} + +@ @= { + 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(); +} + +@ @= { + 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|. + +@= +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 + +@= +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|. + +@= +void err_print(); + +@ +@= +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) @@; + 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@> + +@= +{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 + +@= +wrap_up() { + @; + if (history > harmless_message) return(1); + else return(0); +} + +@ @= +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? */ + +@= +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. + +@= +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. + +@= +void scan_args(); + +@ +@= +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=='+') @@; + 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) @@; + else if (!found_change) @@; + else if (!found_out) @@; + else @; + } + } + if (!found_web) @; + 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. + +@= +{ + if (s-*argv > max_file_name_length-5) + @; + 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; +} + +@ @= +{ + if (s-*argv > max_file_name_length-4) + @; + if (dot_pos==NULL) + sprintf(change_file_name,"%s.ch",*argv); + else strcpy(change_file_name,*argv); + found_change=1; +} + +@ @= +{ + if (s-*argv > max_file_name_length-5) + @; + if (dot_pos==NULL) sprintf(out_file_name,"%s.out",*argv); + else strcpy(out_file_name,*argv); + found_out=1; +} + +@ @= +{ + if (**argv=='-') flag_change=0; + else flag_change=1; + for(dot_pos=*argv+1;*dot_pos>'\0';dot_pos++) + flags[*dot_pos]=flag_change; +} + +@ @= +{ + fatal("! Usage: wmerge webfile[.w] [changefile[.ch] [outfile[.out]]]\n","")@; +} + +@ @= fatal("! Filename too long\n", *argv); + +@* Output. Here is the code that opens the output file: +@^system dependencies@> + +@= +FILE *out_file; /* where output goes */ + +@ @= +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 +#include +@# +@@; +int main(argc,argv) + int argc; /* the number of command-line arguments */ + char *argv[]; /* the arguments themselves */ +{ + @; + @; + @; + @; + return 0; +} + +@ @= +typedef unsigned char byte; /* our bytes will range from 0 to 255 */ + +@ @= +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. + +@= +for (c=0;c<256;c++) ord[c]=c; +delta=0; +targc=argc-1;@+targv=(byte**)argv+1; +while (targc && **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) @; +} +@; +for (;targc;targc--,targv++) @; + +@ @= +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; +} + +@ @= +{ + 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$ */ + +@= +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. + +@= +{@+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]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. + +@= +{@+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]left), p=*q; + else q=&(p->right), p=*q; + } + @; + r->rank=current_rank; + *q=r; /* link the new node into the tree */ + @; +} + +@ @= +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.) + +@= +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]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;@+} + +@= +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++; +@keyword| point to it@>; + +@ @= +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. + +@= +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. + +@= +buffer=(byte*)malloc(max_length+1); +if (buffer==NULL) out_of_mem(-5); +while (1) { + @; + if (l) { + @; + @; + found:; + } +} +done:; + +@ @= +u=buffer;@+l=0; +while (l= +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: @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. + +@= +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; + +@ @= +if (targc) { + curfile=(filenode*)calloc(targc,sizeof(filenode)); + if (curfile==NULL) out_of_mem(-7); + for (f=curfile;flink=f+1; + f->link=curfile; /* circular linking */ +} else curfile=NULL; + +@ @= +filenode *curfile; /* current filenode of interest */ +filenode *f; /* temporary register for filenode list processing */ + +@ @= +{ + 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. + +@ @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]; +} +@keyword| and |breakchar| on |stdout|@>@; +word_done:; + +@ @keyword| and |breakchar| on |stdout|@>= +for (u=p->keyword;*u;u++) putchar(*u); +putchar(breakchar); + +@ @= +@curword|, as fast as you can@>; +@; + +@ 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|. + +@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| */ + @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:; + +@ @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; + +@ @= +if (curfile!=NULL) {@+filenode *sentinel=curfile; + for (f=curfile->link;f!=sentinel;f=f->link) + @curwordcurword|@>; +} + +@ @curwordcurword|@>= +{ + *f->endword='\0'; + for (u=f->curword,v=curfile->curword;ord[*u]==ord[*v];u++,v++) ; + if (ord[*u]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 , 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 \n" +"Language-Team: LANGUAGE \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 , 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 \n" +"Language-Team: LANGUAGE \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 , 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 \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 , 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 \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 , 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 \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 , 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 \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 , 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 \n" +"Language-Team: LANGUAGE \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\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|\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\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|\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.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.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 +#include +#include +@# +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) { + @; + @; + @; + } + return 0; /* normal exit */ +} + +@ @= +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'; + +@ @= +n=0; +while (1) { + input_status=fgets(buf,max_size,stdin); + if (input_status==NULL || *buf!='+') break; + x=&items[n]; + @; + @; + if (++n>max_items) abort(-11,"too many lines in group"); +} + +@ @= +{ + for (y=sorted;yentry); + 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. + +@= +if (*(buf+1)!=' ') abort(-3,"missing blank after +"); +@; +if (*p!=' ') abort(-4,"missing blank after alpha"); +if (*(p+1)=='$') @@; +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'; +@entry|@>; +if (p==buf+max_size-1) abort(-10,"entry too long"); +*(q-1)='\0'; + +@ @= +{ + 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"); +} + +@ @= +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. + +@= +{ 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. + +@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 "" \zip@> +@$memcpy "" \zip@> +@$strcat "" \zip@> +@$strcmp "" \zip@> +@$strcpy "" \zip@> +@$strlen "" \zip@> +@$strncmp "" \zip@> +@$strncpy "" \zip@> + +@$BUFSIZ "" \zip@> +@$fclose "" \zip@> +@$feof "" \zip@> +@$fflush "" \zip@> +@$fopen "" \zip@> +@$fprintf "" \zip@> +@$fputs "" \zip@> +@$fread "" \zip@> +@$fwrite "" \zip@> +@$printf "" \zip@> +@$putc "" \zip@> +@$putchar "" \zip@> +@$puts "" \zip@> +@$rename "" \zip@> +@$remove "" \zip@> +@$sprintf "" \zip@> +@$stdout "" \zip@> + +@$getenv "" \zip@> +@$exit "" \zip@> + +@$isalpha "" \zip@> +@$isdigit "" \zip@> +@$islower "" \zip@> +@$isspace "" \zip@> +@$isupper "" \zip@> +@$isxdigit "" \zip@> +@$tolower "" \zip@> +@$toupper "" \zip@> + +@$gettext "" \zip@> +@$textdomain "" \zip@> + +@$bool "" \zip@> +@$false "" \zip@> +@$true "" \zip@> +@$ptrdiff_t "" \zip@> +@$size_t "" \zip@> +@$uint8_t "" \zip@> +@$uint16_t "" \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 +% +% 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\{\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 +#include +#include +#include +@@; +@@; +@@; +@# +int main( + int argc, + char *argv[]) +{ @; + @; + while (--argc) { + f=fopen(*++argv,"r"); + if (!f) + fprintf(stderr,"twinx: Couldn't open file %s for reading!\n",*argv); + else { + @; + 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 { + @; + fclose(f); + } + } + } + @; + return 0; +} + +@ @d buf_size 100 /* input lines won't be this long */ + +@= +FILE *f; +char buf[buf_size]; +char title[buf_size]; +char cur_name[buf_size]; + +@ @= +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. + +@= +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 */ + +@= +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 + +@= +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; +} + +@ @= +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. + +@= +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; + +@ @= +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. + +@= +while (1) {@+register node *cur_node; + if (fgets(buf,buf_size,f)==NULL) break; /* end of file */ + if (strncmp(buf,"\\I",2)==0) { + @; + 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); +} + +@ @= +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'; + @; +} + +@ 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. + +@= +{@+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. + +@= +@; +@; + +@ 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. + +@= +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; + @next|@>; + if (r==&header) break; + s->next=&sentinel; + q=s=r; + @next|@>; + s->next=&sentinel; + @; + t->next=r; + } + if (t==&header) break; +} + +@ @= +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->idid| */ +}@+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. + +@= +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->idid| */ + t->next=p; /* |p->idid| */ + 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). + +@= +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}. + +@= +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}. + +@= +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. + +@= +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. + +@= +{@+register node *x; + printf("\\input cttwinxmac\n"); + for (x=header.next;x!=&header;x=x->next) { + printf("\\I"); + @id| in suitable \TeX\ format@>; + @data.n| in reverse order@>; + } + printf("\\fin\n"); +} + +@ @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:; +} + +@ @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. -- cgit v1.2.3