This change file is for the VAX/VMS vesion of TeX. Original version by David Fuchs Copyright 1983 David Fuchs Changes by Brian {Hamilton Kelly} Copyright 1989 Brian Hamilton Kelly Changes by Don Hosek Copyright 1990 Don Hosek DO NOT MODIFY THIS FILE. If you must make changes, use a different name and alter the banner string so that it no longer has PD VMS in it. This file may be freely distributed only if it is unmodified. --Character Reference------------------------------------------------- Upper case letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ Lower case letters: abcdefghijklmnopqrstuvwxyz Digits: 0123456789 Square, curly, angle braces, parentheses: [] {} <> () Backslash, slash, vertical bar: \ / | Punctuation: . ? ! , : ; Underscore, hyphen, equals sign: _ - = Quotes--right left double: ' ` " "at", "number" "dollar", "percent", "and": @ # $ % & "hat", "star", "plus", "tilde": ^ * + ~ ----------------------------------------------------------------------- 10-JUN-1988 BHK/CNK Make TeX issue VAX/VMS exit status for use with LSEdit. 22-JUN-1988 BHK Extend save_size to 2000 (from 600). 21-NOV-1988 CNK Set |last_text_char| = 255 (from 127). See TeXhax vol. 88, no. 100 29-NOV-1988 thru 6-DEC-1988 BHK Provide .CLD command-line interface for TeX, etc. 6-DEC-1988 BHK Provide .DIA (diagnostics) file output for use with LSEdit 9-DEC-1988 BHK Call Language-sensitive Editor when user interacts with `E' 17-FEB-1989 CNK Surround the above change with 'LSEdit' 'tidESL' delimiters like 'init' and 'tini'. 20-APR-1989 BHK Build with larger hash table space, to permit more command names. 25-APR-1989 BHK Build with larger save and font tables, for Mainz compatibility 4-MAY-1989 BHK Tidy up use of temp_file after prompting for different file name. 24-AUG-1989 BHK (V2.991-1) Revised for TeX V2.991 Use $TRNLNM instead of $TRNLOG 25-AUG-1989 BHK General tidying up to improve WEAVEability. 29-AUG-1989 BHK Remove buggy definition of \\ from limbo material. Use LIB$FIND_IMAGE_SYMBOL instead of linking with LSESHR. 30-AUG-1989 BHK (V2.991-2) Invoke other (callable) editors, or command procedure 12-SEP-1989 BHK (V2.991-3) Cleanup the nauseous interface to |Edit| 14-SEP-1989 BHK (V2.991-4) Use VAX/VMS dynamic strings and string descriptors for |Edit| 19-SEP-1989 BHK (V2.991-5) Support for TECO 25-SEP-1989 BHK (V2.991-6) Use $CRELNM to pass command file to TECO$EDIT 26-SEP-1989 BHK (V2.991-7) Remove the byte-alignment for |str_pool|; was actually WORSE! 26-SEP-1989 BHK (V2.991-8) Make |wake_up_terminal| into procedure, thus saving 8kB in .PAS file! Cured \TeX's annoying habit of outputing empty records to the terminal even though running in batchmode. This now prevents yards of empty lines in a true batch job .LOG file. 27-SEP-1989 BHK (V2.991-9) Capture exit status of subprocess spawned by LIB$SPAWN 28-SEP-1989 BHK (V2.991-10) 19-OCT-1989 CNK (V2.991-11) Fix bug which causedthe "Entering \batchmode..." message to be deferred until the image exit. 6-NOV-1989 BHK (V2.992 [beta test of V3]) Updated for this major revision of TeX 13-NOV-1989 BHK Minor cosmetic revisions. Replace some occurrences of so(...) on left of equation/assignment by si(...) on the right. 14-NOV-1989 BHK Don't bother to lowercase |command_line|; users need to quote multiple parameters anyway. Correct DEK's booboo when indexing \badness primitive 13-DEC-1989 BHK Added DEK's changes (bugfix 339 - see TeXhax V89 #110) (V2.993-0) 10-JAN-1990 BHK Updated for definitive v2.993 of tex.web (dated 8-Jan at 6am PST) 5-APR-1990 BHK Updated for canonical v3 of TeX.web [This would be PD VMS 3.0] 21-APR-1990 thru 27-APR-1990 Don Hosek Assorted changes to BHK's original to form PD VMS 3.1: -modified formatting of history to conform to other HMC TeX change files. -changed format of banner line to include PD VMS version number; added brief notes on history of change file. -re-incorporated BigTeX changes into main change file: 64-bit TeX is still TeX according to DEK, and if there is a serious problem with memory usage, the TeX installer can simply change mem_max. (Brian's TEX-BIGTEX.CH file sometimes reduced the capacity of TeX!) -All instances of a logical name called TEX$something have been changed to TEX_something. -Changed the definition of aux_buf (sec 130) from 133 to size_input_line (defined in sec 11). -Having TeX continue after editing is WRONG!. See p. 32 of the TeXbook, item 9 if you don't believe me. The changes for section 84 have been fixed accordingly. -Removed test of ready_already; BHK's trick deals with it, _but_ why bother? We don't preload in a fashion that it's ever true! -Split line in section 1394 which was over 80 characters. -Have editor selected by /EDITOR qualifier in CLD file. The default value will be TEX_EDIT. (two-pronged advantage: (1) user can, if they want actually use /EDITOR qualifier, and (2) if installer insists on breaking the rules, he can change to TEX$EDIT (or what I think would be classy, MAIL$EDIT) with little difficulty. -Added qualifiers /TEXINPUTS and /TEXFONTS specifying the name of the logicals to be used for the inputs search path and fonts search path. This is only used by INITEX since these names are read from the pool file by TeX. (As an interesting aside, this qualifier could conceivably be used to have different inputs and fonts search paths for different formats. I'm not sure that this would be useful but eliminating the LaTeX directories from the plain search path might speed things up a little in opening files.) -Added qualifier /TEXFORMATS with similar function to /TEXINPUTS and /TEXFONTS. This qualifier is used by both IniTeX and TeX (now wouldn't this be a silly idea: put the name of the format area into the format file :-). This actually has a neat application: suppose you have both TeX and smallTeX running; you define verbs for SMALLTEX, SMALLINITEX, SMALLLATEX, etc. and make a set of format files. Now the kludgey solution is to rename the format files to things like SMALLPLAIN.FMT &c, but I don't like kludges. A better plan is to define SMALL_TEX_FORMATS to be TEX_ROOT:[SMALLFORMATS] and then in all of the verb definitions put the default for TEXFORMATS as SMALL_TEX_FORMATS. Classy, eh? -Integrated INITeX and TeX into a single executable by defining init==if init_flag begin and tini==end; and changing behaviour of /INIT flag (incidentally, can't the INITIALIZE problem be dealt with by saying INIT :== INITIALIZE?). All conditionals (there are three) are outside the main loop, so the only problem would be with the bigger executable. INITeX is 10% larger than TeX (25K difference). Big deal. Since DCL insists on command verbs being unique in the first four letters (what kind of stupid restriction is that? Are they trying to pack identifiers into words? Wotta bunch of losers) INITEX should be defined with INITEX :== TEX/INIT/NOFORMAT (BHK's original let you get away with TEX/INIT, but required two executables.) This annoyance will go away in a future release of VMS (perhaps 5.4) -Minor change to handling of /EDITOR qual. If it ends with a ':', it is treated as a logical, otherwise it's treated as a literal. Also added the possibility of specifying /NOEDITOR (I use this under DECwindows since I have the file already called up in a DW EVE window.) -Allow TeX to print characters in the range x'a0'-x'fe' without using ^^ notation. -Added character table to beginning of change file to assist those who get it via e-mail in detecting errors in gateways etc. -Included TEX.CLD into the change file (my experience with CMS TeX was that front-end EXECs were frequently not distributed with the change file; including them inside the change file guaranteed (1) that someone receiving a copy would have a copy of the EXEC and (2) if the EXEC they received had been modified at all, they could compare it against the original in the change file--the same considerations should apply for VMS TeX and CLDs). -Changed definition of pool_name so that it uses value from /TEXFORMATS -Added fix for active definition of E so that TeX.WEB will WEAVE. 28-APR-1990 Don Hosek v3.1a (this was necessary due to the fact that some defective change files may have found their way out under the label 3.1; in general, I will be using a letter after the version number to indicate bug fixes). Changed the way that we handle setting the value for TEXINPUTS and TEXFONTS. We (obviously) cannot let INITEX write them into the format file, because that technique is highly dependent on the string pool mechanism (exercise for "real" TeXhackers: add a mechanism for allowing strings set at run time to be communicated between INITEX and TeX). Anyway, the fix for this is deliriously simple; figuring out the problem, on the other hand, took 1h40m of banging my head against my VAXstation. All we need to do is move the initialization of the appropriate strings into the main program loop at an appropriate location. 23-AUG-1990 Documentation changes. Fixed dropped-E bug, also fixed header in the WEAVE output. 30-AUG-1990 Don Hosek v3.2. Added /[NO]CONTINUE option to control whether TeX continues after a response of E at the error prompt; added /[NO]JOBNAME_SYMBOL=n option for controlling whether the specified DCL symbol is created at completion of the TeX run. Minor documentation changes. 30-MAY-1991 Piet Tutelaers. Incremented: trie_size 65000, max_quarterword 511 and trie_op_size 1500 (last really necessary?) ------Cut here for TeX.CLD------------------------------------------------- ! This is TEX.CLD as of 30-AUG-1990 ! ! CLD for TeX. ! Based loosely on Brian Hamilton Kelly's TeX.CLD ! ! Note that for easy configuration of a TeX system, all logical names etc. ! used by TeX are defined here. Thus, if, for example, you would like to ! be able to have your input path defined by TEXINPUTS rather than ! TEX_INPUTS, you can simply change the value for the /TEXINPUTS qualifier. ! The last few definitions in the verb are of this nature and are not ! expected to be used by the end user. The default logical names used here ! are: ! ! TEX_EDIT (name for editor to be invoked at error prompt ! with E response) ! TEX_FORMATS (input path for FMT files) ! TEX_FONTS (input path for TeX fonts) ! TEX_INPUTS (input path for TeX files) ! ! The last two are only used by INITEX (TeX gets their values from the FMT ! file). ! ! Also, on completion, TeX creates a DCL symbol whose name is specified by ! the /JOBNAME_SYMBOL qualifier. The default name is TEX_JOBNAME. ! ! INSTALLING TeX. ! To install TeX from scratch, you should first run TANGLE to generate the ! Pascal file tex.pas. (IMPORTANT NOTE: This implementation of TeX uses ! one executable for both TeX and IniTeX!) After tex.pas has been generated, ! it should then be compiled and linked using the commands ! PASCAL/CHECK=(OVERFLOW,BOUNDS) TEX ! LINK TEX ! The COM file COMPILE_TEX.COM has been provided to do all three steps in ! one fell swoop. (Since there is only one linear path of dependencies ! in the generation of TEX.EXE, it was not felt to be necessary to provide ! an MMS file to generate TeX). ! Once TeX has been compiled and linked, you should edit this file to ! insure that each image portion of the defined verbs points at the location ! where you will be keeping TEX.EXE (usually tex_root:[exe]). TEX.CLD should ! then be installed in your system DCL tables. ! ! In older versions of VMS TeX, the initialization file (usually texdefs.com) ! would have definitions along the lines of: ! TEX == "$TEX_EXE:tex" ! LATEX == "$TEX_EXE:tex &lplain" ! etc. All of these should be removed and replaced with the single ! definition ! INITEX == "TEX/INIT/NOFORMAT" ! (Note that we cannot define INITEX as a verb since that would wipe out the ! VMS INITIALIZE command. I've heard rumors that this will be fixes in a future ! version of VMS.) ! ! One other important thing to note: if you type TeX commands on the command ! line rather than simply a file name, you will need to enclose the argument ! in quotes. e.g., ! TEX FOO ! works in bothe the new and old versions of TeX, but ! TEX "foo \bye" ! is necessary in the new version of TeX (the old one required there to be ! NO quotes). ! ! ADDING A NEW PRELOADED FORMAT ! To add a new preloaded format, use an editor to copy the definition for the ! verb TEX; replace the name TEX with the name of the new preloaded TEX version ! (e.g., LATEX, SLITEX, etc.) and change the default value for the FORMAT ! qualifier to point to the appropriate format file. ! define verb TEX image "TEX_root:[EXE]TEX" parameter P1, label=COMMAND_LINE, value(default="") qualifier FORMAT, placement=global, negatable, default, value(default="TEX_FORMATS:PLAIN") qualifier INIT, batch, negatable, placement=global qualifier BATCH, batch, negatable, placement=global qualifier DVI_FILE, label=OUTPUT, default, placement=global, negatable, value(required,type=$FILE) qualifier LOG_FILE, placement=global, default, negatable, value(required,type=$FILE) qualifier DIAGNOSTICS, placement=global, negatable, value(type=$FILE) qualifier EDITOR, placement=global, default, negatable, value(default="TEX_EDIT:") qualifier TEXINPUTS, placement=global, default, nonnegatable, value(default="TEX_INPUTS:") qualifier TEXFORMATS, placement=global, default, nonnegatable, value(default="TEX_FORMATS:") qualifier TEXFONTS, placement=global, default, nonnegatable, value(default="TEX_FONTS:") qualifier CONTINUE, placement=global, negatable qualifier JOBNAME_SYMBOL placement=global, default, value(default="TEX_JOBNAME") define verb LATEX image "TEX_root:[EXE]TEX" parameter P1, label=COMMAND_LINE, value(default="") qualifier FORMAT, placement=global, negatable, default, value(default="TEX_FORMATS:LPLAIN") qualifier INIT, batch, negatable, placement=global qualifier BATCH, batch, negatable, placement=global qualifier DVI_FILE, label=OUTPUT, default, placement=global, negatable, value(required,type=$FILE) qualifier LOG_FILE, placement=global, default, negatable, value(required,type=$FILE) qualifier DIAGNOSTICS, placement=global, negatable, value(type=$FILE) qualifier EDITOR, placement=global, default, negatable, value(default="TEX_EDIT:") qualifier TEXINPUTS, placement=global, default, nonnegatable, value(default="TEX_INPUTS:") qualifier TEXFORMATS, placement=global, default, nonnegatable, value(default="TEX_FORMATS:") qualifier TEXFONTS, placement=global, default, nonnegatable, value(default="TEX_FONTS:") qualifier CONTINUE, placement=global, negatable qualifier JOBNAME_SYMBOL placement=global, default, value(default="TEX_JOBNAME") define verb SLITEX image "TEX_root:[EXE]TEX" parameter P1, label=COMMAND_LINE, value(default="") qualifier FORMAT, placement=global, negatable, default, value(default="TEX_FORMATS:SPLAIN") qualifier INIT, batch, negatable, placement=global qualifier BATCH, batch, negatable, placement=global qualifier DVI_FILE, label=OUTPUT, default, placement=global, negatable, value(required,type=$FILE) qualifier LOG_FILE, placement=global, default, negatable, value(required,type=$FILE) qualifier DIAGNOSTICS, placement=global, negatable, value(type=$FILE) qualifier EDITOR, placement=global, default, negatable, value(default="TEX_EDIT:") qualifier TEXINPUTS, placement=global, default, nonnegatable, value(default="TEX_INPUTS:") qualifier TEXFORMATS, placement=global, default, nonnegatable, value(default="TEX_FORMATS:") qualifier TEXFONTS, placement=global, default, nonnegatable, value(default="TEX_FONTS:") qualifier CONTINUE, placement=global, negatable qualifier JOBNAME_SYMBOL placement=global, default, value(default="TEX_JOBNAME") define verb AMSTEX image "TEX_root:[EXE]TEX" parameter P1, label=COMMAND_LINE, value(default="") qualifier FORMAT, placement=global, negatable, default, value(default="TEX_FORMATS:AMSTEX") qualifier INIT, batch, negatable, placement=global qualifier BATCH, batch, negatable, placement=global qualifier DVI_FILE, label=OUTPUT, default, placement=global, negatable, value(required,type=$FILE) qualifier LOG_FILE, placement=global, default, negatable, value(required,type=$FILE) qualifier DIAGNOSTICS, placement=global, negatable, value(type=$FILE) qualifier EDITOR, placement=global, default, negatable, value(default="TEX_EDIT:") qualifier TEXINPUTS, placement=global, default, nonnegatable, value(default="TEX_INPUTS:") qualifier TEXFORMATS, placement=global, default, nonnegatable, value(default="TEX_FORMATS:") qualifier TEXFONTS, placement=global, default, nonnegatable, value(default="TEX_FONTS:") qualifier CONTINUE, placement=global, negatable qualifier JOBNAME_SYMBOL placement=global, default, value(default="TEX_JOBNAME") define verb TEXSIS image "TEX_root:[EXE]TEX" parameter P1, label=COMMAND_LINE, value(default="") qualifier FORMAT, placement=global, negatable, default, value(default="TEX_FORMATS:TEXSIS") qualifier INIT, batch, negatable, placement=global qualifier BATCH, batch, negatable, placement=global qualifier DVI_FILE, label=OUTPUT, default, placement=global, negatable, value(required,type=$FILE) qualifier LOG_FILE, placement=global, default, negatable, value(required,type=$FILE) qualifier DIAGNOSTICS, placement=global, negatable, value(type=$FILE) qualifier EDITOR, placement=global, default, negatable, value(default="TEX_EDIT:") qualifier TEXINPUTS, placement=global, default, nonnegatable, value(default="TEX_INPUTS:") qualifier TEXFORMATS, placement=global, default, nonnegatable, value(default="TEX_FORMATS:") qualifier TEXFONTS, placement=global, default, nonnegatable, value(default="TEX_FONTS:") qualifier CONTINUE, placement=global, negatable qualifier JOBNAME_SYMBOL placement=global, default, value(default="TEX_JOBNAME") ------End of TeX.CLD------------------------------------------------------- {Section 0} <<<<>>>> >>>>>Modified 30-AUG-1990 by DAH>>>>> @x \pageno=3 @y \pageno=3 \let\maybe=\iffalse \def\title{\TeX\ 3.1 [PD VMS 3.3/DECUS]} \def\LaTeX{{\rm L\kern-.3em\raise.33ex\hbox{\sc A}\kern-.15em\TeX}} @z {Section 2} <<<<>>>> <<<<>>>> >>>>>Modified 30-AUG-1990 by DAH>>>>> @x @d banner=='This is TeX, Version 3.14' {printed when \TeX\ starts} @y This change file is the result of a long odyssey of change files beginning with the original change files created in 1984 by David Fuchs; many people have made significant contributions since then, the most notable of whom have been Brian Hamilton Kelly, Niel Kempson, and Adrian Clark @d banner=='This is TeX, Version 3.14 [PD VMS 3.4/DECUS]' @z <<<<>>>> {Section 4} @x procedure initialize; {this procedure gets things started properly} @y @t\4@>@@/ procedure initialize; {this procedure gets things started properly} @z <<<<>>>> {Section 7} @x @d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging} @d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging} @y @d debug==@{ @d gubed==@t\2@>@} @z <<<<>>>> {Section 7} @x @d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering usage statistics} @d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering usage statistics} @y @d stat== @d tats==@t\2@> @z <<<<>>>> <<<<>>>> <<<<>>>> <<<<>>>> {Section 8} @x Parts of the program that are needed in (1) but not in (2) are delimited by the codewords `$|init|\ldots|tini|$'. @d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version} @d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version} @y Parts of the program that are needed in (1) but not in (2) are delimited by the codewords `$|init|\ldots|tini|$'. @d init==if init_flag then begin @d tini==end; @z <<<<>>>> <<<<>>>> {Section 9} @x compiler directives== starlet and vax reserved words @ If the first character of a \PASCAL\ comment is a dollar sign, \ph\ treats the comment as a list of ``compiler directives'' that will affect the translation of this program into machine language. The directives shown below specify full checking and inclusion of the \PASCAL\ debugger when \TeX\ is being debugged, but they cause range checking and other redundant code to be eliminated when the production system is being generated. Arithmetic overflow will be detected in all cases. @^system dependencies@> @^Overflow in arithmetic@> @= @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y @ When the \PASCAL\ program generated as a result of `tangling' the \.{WEB} with the change file is compiled under VAX/VMS, command line qualifiers should be included to specify full checking and inclusion of debugger symbol records whilst \TeX\ is being debugged, but eliminate range checking and other redundant code when the production system is being generated. Arithmetic overflow should be detected in all cases. @^system dependencies@> @^Overflow in arithmetic@> Under VAX/VMS, we arrange to `inherit' the descriptions of standard system services and named constants from the precompiled \PASCAL\ environment held in |'SYS$LIBRARY:STARLET.PEN'|---we do \&{not} specify whether or not any specific level of run-time checks shall be included, because any such attribute applied within the source code cannot be overridden by a command line qualifier when \TeX\ is compiled. This library does not include \&{all} the library routines that are used by \TeX82 under VAX/VMS, so other routines are declared as required using \PASCAL's syntax for |extern| routines. @fextern==forward @= @/@=[inherit('sys$library:starlet')]@>@\ {allows us to use system symbols and routines} @z {Section 10} @x @d othercases == others: {default for cases not listed explicitly} @y Fortunately for us, VAX-\PASCAL\ \&{does} support this default mechanism. @d othercases == otherwise {default for cases not listed explicitly} @z {Section 11} >>>>>Modified 26-MAY-1990 by DAH : fix handling of |pool_name|>>>>> <<<<>>>> <<<<>>>> @x [1] compile-time constants @^system dependencies@> @= @!mem_max=30000; {greatest index in \TeX's internal |mem| array; must be strictly less than |max_halfword|; must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|} @!mem_min=0; {smallest index in \TeX's internal |mem| array; must be |min_halfword| or more; must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|} @!buf_size=500; {maximum number of characters simultaneously present in current lines of open files and in control sequences between \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|} @!error_line=72; {width of context lines on terminal error messages} @!half_error_line=42; {width of first lines of contexts in terminal error messages; should be between 30 and |error_line-15|} @!max_print_line=79; {width of longest text lines output; should be at least 60} @!stack_size=200; {maximum number of simultaneous input sources} @!max_in_open=6; {maximum number of input files and error insertions that can be going on simultaneously} @!font_max=75; {maximum internal font number; must not exceed |max_quarterword| and must be at most |font_base+256|} @!font_mem_size=20000; {number of words of |font_info| for all fonts} @!param_size=60; {maximum number of simultaneous macro parameters} @!nest_size=40; {maximum number of semantic levels simultaneously active} @!max_strings=3000; {maximum number of strings; must not exceed |max_halfword|} @!string_vacancies=8000; {the minimum number of characters that should be available for the user's control sequences and font names, after \TeX's own error messages are stored} @!pool_size=32000; {maximum number of characters in strings, including all error messages and help texts, and the names of all fonts and control sequences; must exceed |string_vacancies| by the total length of \TeX's own strings, which is currently about 23000} @!save_size=600; {space for saving values outside of current group; must be at most |max_halfword|} @!trie_size=8000; {space for hyphenation patterns; should be larger for \.{INITEX} than it is in production versions of \TeX} @!trie_op_size=500; {space for ``opcodes'' in the hyphenation patterns} @!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} @!file_name_size=40; {file names shouldn't be longer than this} @!pool_name='TeXformats:TEX.POOL '; {string of length |file_name_size|; tells where the string pool appears} @y Since a number of arrays of |file_name_size| are used in this program to receive the full file specification of files when they are opened, it is necessary to extend this constant to 255, which is the maximum possible size that VAX/RMS can @.RMS@> @^Record Management Services@> return. It is not necessary, however, to pad out |pool_name| to this size (which would in any case prove ``difficult'' in WEB, because VAX-\PASCAL\ automatically pads short strings with spaces when assigned into longer variables. Furthermore, because the area where the pool file resides is specified at run time, we need to make |pool_name| into a variable which will be set shortly after we determine the value of the name of the format area. @^system dependencies@> @d pool_name_length=8 @= @!mem_max=327144; {greatest index in \TeX's internal |mem| array; must be strictly less than |max_halfword|; must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|} @!mem_min=0; {smallest index in \TeX's internal |mem| array; must be |min_halfword| or more; must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|} @!buf_size=2000; {maximum number of characters simultaneously present in current lines of open files and in control sequences between \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|} @!size_input_line=133; {maximum size of an input line} @!error_line=79; {width of context lines on terminal error messages} @!half_error_line=50; {width of first lines of contexts in terminal error messages; should be between 30 and |error_line-15|} @!max_print_line=79; {width of longest text lines output; should be at least 60} @!stack_size=200; {maximum number of simultaneous input sources} @!max_in_open=6; {maximum number of input files and error insertions that can be going on simultaneously} @!font_max=150; {maximum internal font number; must not exceed |max_quarterword| and must be at most |font_base+256|} @!font_mem_size=50000; {number of words of |font_info| for all fonts} @!param_size=60; {maximum number of simultaneous macro parameters} @!nest_size=40; {maximum number of semantic levels simultaneously active} @!max_strings=5400; {maximum number of strings; must not exceed |max_halfword|} @!string_vacancies=26000; {the minimum number of characters that should be available for the user's control sequences and font names, after \TeX's own error messages are stored} @!pool_size=65500; {maximum number of characters in strings, including all error messages and help texts, and the names of all fonts and control sequences; must exceed |string_vacancies| by the total length of \TeX's own strings, which is currently about 22500} @!save_size=1500; {space for saving values outside of current group; must be at most |max_halfword|} @!trie_size=65000; {space for hyphenation patterns; should be larger for \.{INITEX} than it is in production versions of \TeX} @# @!trie_op_size=1500; {space for ``opcodes'' in the hyphenation patterns} @!dvi_buf_size=1024; {size of the output buffer; must be a multiple of 8} @!VAX_block_length=512; {must be half |dvi_buf_size| on VAX/VMS} @!file_name_size=255; {file names shouldn't be longer than this} @# @!pool_f_name='TEX.POOL'; {string \&{not} of length |file_name_size|; tells the name of the string pool} @z {Section 12} <<<<>>>> @x [1] Tangle-time constants @d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX}; must not be less than |mem_min|} @d mem_top==30000 {largest index in the |mem| array dumped by \.{INITEX}; must be substantially larger than |mem_bot| and not greater than |mem_max|} @d font_base=0 {smallest internal font number; must not be less than |min_quarterword|} @d hash_size=2100 {maximum number of control sequences; it should be at most about |(mem_max-mem_min)/10|} @d hash_prime=1777 {a prime number equal to about 85\pct! of |hash_size|} @d hyph_size=307 {another prime; the number of \.{\\hyphenation} exceptions} @y @d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX}; must not be less than |mem_min|} @d mem_top==327144 {largest index in the |mem| array dumped by \.{INITEX}; must be substantially larger than |mem_bot| and not greater than |mem_max|} @d font_base=0 {smallest internal font number; must not be less than |min_quarterword|} @d hash_size=5000 {maximum number of control sequences; it should be at most about |(mem_max-mem_min)/10|} @d hash_prime=4253 {a prime number equal to about 85\pct! of |hash_size|} @d hyph_size=503 {another prime; the number of \.{\\hyphenation} exceptions} @z {Section 23} <<<<>>>> @x [2] System-dependent character set changes: @^character set dependencies@> @^system dependencies@> @= for i:=0 to @'37 do xchr[i]:=' '; for i:=@'177 to @'377 do xchr[i]:=' '; @y @^character set dependencies@> @^system dependencies@> The code shown here is intended to be used on VAX/VMS systems, and at other installations where only the printable ASCII set, plus |carriage_return|, |tab|, and |form_feed| will show up in text files. All |line_feed| and |null| characters are skipped. We also permit characters taken from columns 10--15 of the extended ISO character set; macro packages can then utilize these character codes for multilingual support. @d form_feed=@'14 {ASCII code used at end of a page} @d tab=@'11 @= xchr[0]:=' '; for i:=1 to @'37 do xchr[i]:=chr(i); xchr[form_feed]:=chr(form_feed); xchr[tab]:=chr(tab); for i:=@'177 to @'237 do xchr[i]:=' '; for i:=@'240 to @'377 do xchr[i]:=chr(i); @z {Section 25} <<<<>>>> @x The program actually makes use also of a third kind of file, called a |word_file|, when dumping and reloading base information for its own initialization. We shall define a word file later; but it will be possible for us to specify simple operations on word files before they are defined. @y The program actually makes use also of a third kind of file, called a |word_file|, when dumping and reloading base information for its own initialization. We shall define a word file later; but it will be possible for us to specify simple operations on word files before they are defined. Since the \.{WEB} already uses the name |text| for its own purposes, we have to define a macro to permit access to this VAX-\PASCAL\ file type identifier. @d VAX_text==@= text @> @z {Section 25} @x [3] alpha files are text and byte files are blocks @!alpha_file=packed file of text_char; {files that contain textual data} @!byte_file=packed file of eight_bits; {files that contain binary data} @y @!alpha_file=VAX_text; {files that contain textual data} @!byte_block=packed array [0..VAX_block_length-1] of eight_bits; @!byte_file=packed file of byte_block; {files that contain binary data} @z {Section 26} @x <<<<>>>> implement \TeX\ can open a file whose external name is specified by |name_of_file|. @^system dependencies@> @= @!name_of_file:packed array[1..file_name_size] of char;@;@/ {on some systems this may be a \&{record} variable} @!name_length:0..file_name_size;@/{this many characters are actually relevant in |name_of_file| (the rest are blank)} @y implement \TeX\ can open a file whose external name is specified by |name_of_file|. Any VAX-\PASCAL\ defaults may be supplied in |default_name|; this is used to expand partial file specifications given on such qualifiers as \.{/LOG}, in combination with other parts taken from the file specification of the \.{.TeX} file. @^system dependencies@> @= @!name_of_file, @!default_name:packed array[1..file_name_size] of char;@;@/ {on some systems this may be a \&{record} variable} @!name_length, @!deflt_length : file_size;@/ {this many characters are actually relevant in |name_of_file| (the rest are blank)} @z {Section 27} @x <<<<>>>> @ The \ph\ compiler with which the present version of \TeX\ was prepared has extended the rules of \PASCAL\ in a very convenient way. To open file~|f|, we can write $$\vbox{\halign{#\hfil\qquad&#\hfil\cr |reset(f,@t\\{name}@>,'/O')|&for input;\cr |rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$ The `\\{name}' parameter, which is of type `{\bf packed array $[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of the external file that is being opened for input or output. Blank spaces that might appear in \\{name} are ignored. The `\.{/O}' parameter tells the operating system not to issue its own error messages if something goes wrong. If a file of the specified name cannot be found, or if such a file cannot be opened for some other reason (e.g., someone may already be trying to write the same file), we will have |@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows \TeX\ to undertake appropriate corrective action. @:PASCAL H}{\ph@> @^system dependencies@> \TeX's file-opening procedures return |false| if no file identified by |name_of_file| could be opened. @d reset_OK(#)==erstat(#)=0 @d rewrite_OK(#)==erstat(#)=0 @p function a_open_in(var f:alpha_file):boolean; @y @ Under VAX-\PASCAL, we can open files with names that are not known at compile time through use of the VAX-specific procedure |open|, which takes too many varied parameters to describe here: for example, the third parameter controls whether a new file shall be generated, or can enforce that an existing file cannot possibly be altered. @^system dependencies@> However, one in particular deserves special mention: the |user_action| parameter when included causes execution of a user-supplied routine which can manipulate the data structures used by RMS (Record Management Services) and thus @.RMS@> @^Record Management Services@> permit finer control over the actions undertaken during the opening or creation of files. All file manipulation procedures in VAX-\PASCAL\ (including |open|/|close|, |read|/|write|, etc.)\ can take an optional parameter which specifies whether or no the program shall continue execution after an error. Since we code to detect such errors, we nearly always make use of this facility. \TeX's file-opening procedures return |false| if no file identified by |name_of_file| could be opened: note that VAX-\PASCAL's |status| function returns zero if the previous file operation was successfully completed, |-1| if |eof| would be |true|, and a positive integer if any error was detected. When a |new| file is opened, we specify that it shall be deleted when the program exits; this ensures that output files are correctly discarded if \TeX\ is interrupted in its work. Later, when the files are closed, we can arrange to keep the files instead. VAX-\PASCAL's |open| procedure also allows us to specify a `default' file specification, which is used to supply defaults for those parts of the specification of the file being created that have not otherwise been provided by the user. Whenever a |word_file| is opened, the variable |fmt_count| is reset to zero to ensure that the first byte of the VAX block is that first accessed. @d VAX_user_action==@=user_action@> @# @d VAX_new==@= new @> @d VAX_readonly==@= readonly @> @# @d VAX_default==@= default @> @# @d VAX_disposition_delete==@=disposition:=delete@> @d VAX_ignore_error==@=error:=continue@> @p function a_open_in(var f:alpha_file):boolean; @z {Section 27} @x [3] file opening begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f); @y begin open(f,name_of_file,VAX_readonly,VAX_user_action:=user_reset, VAX_ignore_error); if status(f)>0 then a_open_in:=false else begin reset(f,VAX_ignore_error); a_open_in:=status(f)<=0; end; @z {Section 27} @x <<<<>>>> begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f); @y begin open(f,name_of_file,VAX_new,16383,VAX_disposition_delete, VAX_default:=default_name, VAX_user_action:=user_rewrite,VAX_ignore_error); if status(f)>0 then a_open_out:=false else begin linelimit(f,maxint); rewrite(f,VAX_ignore_error); a_open_out:=status(f)<=0; end; @z {Section 27} @x begin reset(f,name_of_file,'/O'); b_open_in:=reset_OK(f); @y begin open(f,name_of_file,VAX_readonly,VAX_user_action:=user_reset, VAX_ignore_error); if status(f)>0 then b_open_in:=false else begin reset(f,VAX_ignore_error); b_open_in:=status(f)<=0; end; @z {Section 27} @x begin rewrite(f,name_of_file,'/O'); b_open_out:=rewrite_OK(f); @y begin open(f,name_of_file,VAX_new,VAX_disposition_delete, VAX_default:=default_name, VAX_user_action:=user_rewrite,VAX_ignore_error); if status(f)>0 then b_open_out:=false else begin rewrite(f,VAX_ignore_error); b_open_out:=status(f)<=0; end; @z {Section 27} @x begin reset(f,name_of_file,'/O'); w_open_in:=reset_OK(f); @y begin open(f,name_of_file,VAX_readonly,VAX_user_action:=user_reset, VAX_ignore_error); if status(f)>0 then w_open_in:=false else begin reset(f,VAX_ignore_error); w_open_in:=status(f)<=0; end; fmt_count:=0; @z {Section 27} @x begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f); @y begin open(f,name_of_file,VAX_new,VAX_disposition_delete, VAX_user_action:=user_rewrite,VAX_ignore_error); if status(f)>0 then w_open_out:=false else begin rewrite(f,VAX_ignore_error); w_open_out:=status(f)<=0; end; fmt_count:=0; @z <<<<>>>> {Section 28} @x @ Files can be closed with the \ph\ routine `|close(f)|', which @^system dependencies@> should be used when all input or output with respect to |f| has been completed. This makes |f| available to be opened again, if desired; and if |f| was used for output, the |close| operation makes the corresponding external file appear on the user's area, ready to be read. These procedures should not generate error messages if a file is being closed before it has been successfully opened. @p procedure a_close(var f:alpha_file); {close a text file} begin close(f); @y @ Files can be closed with the VAX-\PASCAL\ routine |close(f,disposition,error)|, which @^system dependencies@> should be used when all input or output with respect to |f| has been completed. This makes |f| available to be opened again, if desired; and if |f| was used for output, the |close| operation can make the corresponding external file appear in the user's directory, ready to be read: this depends upon the value of the |disposition| parameter, which can (\\{inter alia}) control whether the file is kept or discarded. If this parameter is not specified, then disposition of the file is determined by the corresponding parameter of the |open| routine. It is through this mechanism that we are able to ensure that all output files are discarded if the operation of \TeX\ is aborted by the user, and yet are kept if the program terminates correctly. These procedures should not generate error messages if a file is being closed before it has been successfully opened; the |error| parameter is used here to ensure that any such errors do not cause run-time failures. @d VAX_disposition_save==@=disposition:=save@> @p procedure a_close(var f:alpha_file); {close a text file} begin close(f,VAX_disposition_save,VAX_ignore_error); @z {Section 28} @x begin close(f); @y begin close(f,VAX_disposition_save,VAX_ignore_error); @z {Section 28} @x begin close(f); @y begin close(f,VAX_disposition_save,VAX_ignore_error); @z {Section 30} >>>DAH changed size of aux_buf from 133 to size_input_line. @x [3] read into auxiliary buffer first representing the beginning and ending of a line of text. @= @y representing the beginning and ending of a line of text. On VAX/VMS, we will read the lines first into an auxiliary buffer, in order to save the running time of procedure-call overhead. We have to be very careful to handle lines longer than the arbitrarily chosen length of the |aux_buf|. This buffer is declared using a VAX-\PASCAL\ extension for variable length strings, namely the |varying| array type. Such arrays actually appear as if they were a record declared with two fields, thus: |varying [max_size] of = record length: 0..max_size; body: packed array [1..max_size] of|. @d VAX_length(#)==#.@=length@> @d VAX_body(#)==#.@=body@> @f varying==array @= @!aux_buf:varying [buf_size] of char; {where the characters go first} @z {Section 31} <<<<>>>> @x [3] ditto of characters at once, if such routines are available. The following code uses standard \PASCAL\ to illustrate what needs to be done, but finer tuning is often possible at well-developed \PASCAL\ sites. @^inner loop@> @p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean; {inputs the next line or returns |false|} var last_nonblank:0..buf_size; {|last| with trailing blanks removed} begin if bypass_eoln then if not eof(f) then get(f); {input the first character of the line into |f^|} last:=first; {cf.\ Matthew 19\thinspace:\thinspace30} if eof(f) then input_ln:=false else begin last_nonblank:=first; while not eoln(f) do begin if last>=max_buf_stack then begin max_buf_stack:=last+1; if max_buf_stack=buf_size then @; end; buffer[last]:=xord[f^]; get(f); incr(last); if buffer[last-1]<>" " then last_nonblank:=last; end; last:=last_nonblank; input_ln:=true; end; end; @y of characters at once, if such routines are available. The following code uses VAX-\PASCAL\ extensions, such as |varying| strings to perform input of larger amounts of characters with a single input instruction. @^inner loop@> Under VAX-\PASCAL, it is not necessary to take special action to |bypass_eoln|, since the terminator character will be included in those read into the |aux_buf|. @p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean; {inputs the next line or returns |false|} label found; var @!len:integer; {length of line input} @!k:0..buf_size; {index into |buffer|} begin last:=first; {cf.\ Matthew 19\thinspace:\thinspace30} if status(f)<>0 then input_ln:=false else begin while not eoln(f) do begin read(f,aux_buf,VAX_ignore_error); len:=VAX_length(aux_buf); if last+len>=max_buf_stack then begin if last+len; end; for k:=last to last+len-1 do buffer[k]:=xord[aux_buf[k-last+1]]; last:=last+len; end; found: if last>first then if buffer[last-1]=" " then begin decr(last); goto found; end; input_ln:=true; read_ln(f,VAX_ignore_error); end; end; @z <<<<>>>> {Section 33} @x [3] terminal file opening @ Here is how to open the terminal files in \ph. The `\.{/I}' switch suppresses the first |get|. @^system dependencies@> @d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input} @d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output} @y @ Here is how to open the terminal files under VAX/VMS. @^system dependencies@> The standard input and output proces-permanent files \.{SYS\$INPUT} and \.{SYS\$OUTPUT} @.SYS{\$}INPUT@> @.SYS{\$}OUTPUT@> are opened, and the addresses of the associated |FAB| and |RAB| noted so that special actions (such as flushing the input buffer) can be coded. Output occurs without any implicit carriage-control: this permits the output buffer to be flushed to the terminal without terminating the line of output; it is necessary to output the carriage-return, line-feed character pair explicitly when the line is to be terminated. @d VAX_sys_input==@= 'SYS$INPUT' @> @d VAX_sys_output==@= 'SYS$OUTPUT' @> @d VAX_PAS_FAB==@= PAS$FAB@> @d VAX_PAS_RAB==@= PAS$RAB@> @d VAX_carriage_control==@= carriage_control @> @d VAX_none==@= none @> @# @d t_open_in==begin open(term_in,VAX_sys_input); reset(term_in); in_FAB:=VAX_PAS_FAB(term_in); in_RAB:=VAX_PAS_RAB(term_in); end {open the terminal for text input} @d t_open_out==begin open(term_out,VAX_sys_output,VAX_carriage_control:=VAX_none); linelimit(term_out,maxint); rewrite(term_out); out_FAB:=VAX_PAS_FAB(term_out); out_RAB:=VAX_PAS_RAB(term_out); end {open the terminal for text output} @z <<<<>>>> {Section 34} @x [3] terminal hacks: clear and update these operations can be specified in \ph: @^system dependencies@> @d update_terminal == break(term_out) {empty the terminal output buffer} @d clear_terminal == break_in(term_in,true) {clear the terminal input buffer} @d wake_up_terminal == do_nothing {cancel the user's cancellation of output} @y these operations can be specified in VAX/VMS Pascal, through manipulation of the data structures maintained in the |RAB| (Record Access Block) @^Record Access Block@> by RMS. @^RMS@> @^Record Management Services@> Since |wake_up_terminal| is only called just before output of an error message, there's no significant overhead in its being a procedure, and this saves 8k bytes of \PASCAL\ source compared with having it as a \.{WEB} definition. @^system dependencies@> To prevent spurious empty writes to the terminal in |batch_mode|, we apply a condition to |update_terminal|. @d VAX_RAB_purge_typeahead== @=RAB$V_PTA@> @d VAX_RAB_cancel_ctrlO== @=RAB$V_CCO@> @# @d update_terminal == if odd(selector) then write_ln(term_out) {empty the terminal output buffer} @d clear_terminal == in_RAB^.VAX_RAB_purge_typeahead:=true {clear the terminal input buffer} @.PTA@> @d crlf == chr(13),chr(10) @# @= procedure wake_up_terminal; begin out_RAB^.VAX_RAB_cancel_ctrlO:=true; write_ln(term_out); out_RAB^.VAX_RAB_cancel_ctrlO:=false; end; {cancel the user's cancellation of output} @.CCO@> @z <<<<>>>> <<<<>>>> {Section 37} @x [3] terminal initialization @ The following program does the required initialization without retrieving a possible command line. It should be clear how to modify this routine to deal with command lines, if the system permits them. @^system dependencies@> @p function init_terminal:boolean; {gets the terminal input started} label exit; begin t_open_in; loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal; @.**@> if not input_ln(term_in,true) then {this shouldn't happen} begin write_ln(term_out); write(term_out,'! End of file on the terminal... why?'); @.End of file on the terminal@> init_terminal:=false; return; end; loc:=first; while (loc @.LIB{\$}GET_FOREIGN@> @^system dependencies@> Since any command line passed to \TeX\ from DCL via \.{LIB\$GET\_FOREIGN} will have been ``up-cased'', we convert everything to lower-case, so that any \TeX\ commands therein can be recognized; of course, any such commands which are named with upper-case letters will be ``ruined'', but we can't have everything! Such conversion does not occur if we are using the full command line interpreter interface, since with that it is only possible to pass commands consisting of more than one word by enclosing the whole string in `\.{\char'042}' quotation marks, and this mechanism can thus preserve the correct case on input. @d VAX_lib_get_foreign==@= lib$get_foreign@> @d VAX_cli_present==@= cli$present@> @d VAX_cli_get_value==@= cli$get_value@> @p function init_terminal:boolean; {gets the terminal input started} label exit; var command_line: packed array[1..300] of char; @!len: sixteen_bits; @!i: integer; begin t_open_in; if cmd_line_present then VAX_cli_get_value('COMMAND_LINE',command_line,len) else VAX_lib_get_foreign(command_line,,len); i:=1; while (i<=len) and (command_line[i]=' ') do incr(i); if i<=len then begin loc:=first; last:=first; while i<=len do begin buffer[last]:=xord[command_line[i]]; if cmd_line_present then if (buffer[last]>="A") and (buffer[last]<="Z") then buffer[last]:=buffer[last]+"a"-"A"; incr(last); incr(i); end; init_terminal:=true; return; end; loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal; @.**@> if not input_ln(term_in,true) then {this shouldn't happen} begin write(term_out,crlf); write_ln(term_out,'! End of file on the terminal... why?',crlf); @.End of file on the terminal@> init_terminal:=false; return; end; loc:=first; while (loc>>>>Added 25-May-1990 DAH--declare all init functions>>>>> @x @p @!init function get_strings_started:boolean; {initializes the string pool, but returns |false| if something goes wrong} label done,exit; var k,@!l:0..255; {small indices or counters} @!m,@!n:text_char; {characters input from |pool_file|} @!g:str_number; {garbage} @!a:integer; {accumulator for check sum} @!c:boolean; {check sum has been checked} begin pool_ptr:=0; str_ptr:=0; str_start[0]:=0; @; @; exit:end; tini @y @p function get_strings_started:boolean; {initializes the string pool, but returns |false| if something goes wrong} label done,exit; var k,@!l:0..255; {small indices or counters} @!m,@!n:text_char; {characters input from |pool_file|} @!g:str_number; {garbage} @!a:integer; {accumulator for check sum} @!c:boolean; {check sum has been checked} begin pool_ptr:=0; str_ptr:=0; str_start[0]:=0; @; @; exit:end; @z {Section 49} >>>>>Added 26-May-1990 DAH--print ASCII characters in [x'a0',x'fe']. @x Unprintable characters of codes 128--255 are, similarly, rendered \.{\^\^80}--\.{\^\^ff}. @y Unprintable characters of codes 128--159 and 255 are, similarly, rendered \.{\^\^80}--\.{\^\^9f} and \.{\^\^ff}. We will print characters in the range 160--254. @z {Section 49} >>>>>Added 26-May-1990 DAH--print ASCII characters in [x'a0',x'fe']. @x (k<" ")or(k>"~") @y (k<" ")or((k>"~")and (k<160))or(k=255) @z {Section 50} >>>>>Added 25-May-1990 DAH--declare all init functions>>>>> @x @!init @!pool_file:alpha_file; {the string-pool file output by \.{TANGLE}} tini @y @!pool_file:alpha_file; {the string-pool file output by \.{TANGLE}} @z {Section 51} @x [4] bad_pool needs real crlf @ @d bad_pool(#)==begin wake_up_terminal; write_ln(term_out,#); @y @ As noted before, it is not necessary for the string |pool_name| to have the same length as the |array name_of_file|, because VAX-\PASCAL\ automatically pads such shorter strings with spaces when an assignment is made into a longer string variable. @d bad_pool(#)==begin wake_up_terminal; write_ln(term_out,#,crlf); @z {Section 56}<<<<>>>> @x [5] real crlf for terminal by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section. @^system dependencies@> @d wterm(#)==write(term_out,#) @d wterm_ln(#)==write_ln(term_out,#) @d wterm_cr==write_ln(term_out) @d wlog(#)==write(log_file,#) @d wlog_ln(#)==write_ln(log_file,#) @d wlog_cr==write_ln(log_file) @y by changing |wterm|, |wterm_ln|, and |wterm_cr| in this section. @^system dependencies@> We also introduce here analogous macros for writing to the |diag_file|, which is used to generate diagnostic messages for use in conjunction with DEC's Language-sensitive editor (LSEdit). @^Language-sensitive editor@> @^LSE@> Yet another set of macros is concerned with writing to |temp_file|, which is a purely internal file, used to concatenate the various elements of \TeX's error messages for use in diagnostic and other files. @d wterm(#)==write(term_out,#) @d wterm_ln(#)==write_ln(term_out,#,crlf) @d wterm_cr==write_ln(term_out,crlf) @d wlog(#)==if log_qual then write(log_file,#) @d wlog_ln(#)==if log_qual then write_ln(log_file,#) @d wlog_cr==if log_qual then write_ln(log_file) @d wdiag(#)==if diag_qual then write(diag_file,#) @d wdiag_ln(#)==if diag_qual then write_ln(diag_file,#) @d wdiag_cr==if diag_qual then write_ln(diag_file) @d wtemp(#)==write(temp_file,#) @d wtemp_ln(#)==write_ln(temp_file,#) @d wtemp_cr==write_ln(temp_file) @= procedure diag_char( s : integer ); var ch : char; begin ch := xchr[s]; wdiag(ch); if ch='"' then wdiag(ch) end; @# procedure temp_char( s : integer); var ch : char; begin ch := xchr[s]; wtemp(ch); if ch='"' then wtemp(ch) end; @# procedure print_diag( s : integer); var j : pool_pointer; begin j:=str_start[s]; while j < str_start[s+1] do begin diag_char(so(str_pool[j])); incr(j) end; end; @z {Section 58} @x <<<<>>>> @ The |print_char| procedure sends one character to the desired destination, using the |xchr| array to map it into an external character compatible with |input_ln|. All printing comes through |print_ln| or |print_char|. @= procedure print_char(@!s:ASCII_code); {prints a single character} label exit; begin if @ then if selector= procedure print_char(@!s:ASCII_code); {prints a single character} label exit; begin if @ then if selector; case selector of term_and_log: begin wterm(xchr[s]); wlog(xchr[s]); incr(term_offset); incr(file_offset); if term_offset=max_print_line then begin wterm_cr; term_offset:=0; end; if file_offset=max_print_line then begin wlog_cr; file_offset:=0; end; end; log_only: begin wlog(xchr[s]); incr(file_offset); if file_offset=max_print_line then print_ln; end; term_only: begin wterm(xchr[s]); incr(term_offset); if term_offset=max_print_line then print_ln; end; no_print: do_nothing; pseudo: if tally} @y in_RAB^.VAX_RAB_purge_typeahead:=false; {turn off purging of typeahead} @.PTA@> term_offset:=0; {the user's line ended with \<\rm return>} @z {Section 73} @x @ The global variable |interaction| has four settings, representing increasing amounts of user interaction: @y @ The global variable |interaction| has four settings, representing increasing amounts of user interaction: This version of \TeX\ can generate a diagnostics file for use with the \.{REVIEW} mode of DEC's Language-sensitive editor (LSEdit). @^Language-sensitive editor@> So whenever \TeX\ starts to generate an error message, we arrange for the text which is sent to the terminal and/or the transcript file to be copied also into our |temp_file|. @z {Section 73} @x <<<<>>>> @d print_err(#)==begin if interaction=error_stop_mode then wake_up_terminal; print_nl("! "); print(#); end @= @!interaction:batch_mode..error_stop_mode; {current level of interaction} @y @d print_err(#)==begin if interaction=error_stop_mode then wake_up_terminal; print_nl("! "); copy_err:=save_it; rewrite(temp_file); print(#); {Other |print|s will add to |temp_file|} end @= @!interaction:batch_mode..error_stop_mode; {current level of interaction} @z {Section 82} @x <<<<>>>> @ Here now is the general |error| routine. @y @ Here now is the general |error| routine, which completes output of the error message. @z {Section 82} @x <<<<>>>> begin if history; @y begin if history; show_context; if interaction=error_stop_mode then @; @z {Section 84} >>>>>Modified 24-MAY-1990 by DAH>>>>> <<<<>>>> @x <<<<>>>> @ It is desirable to provide an `\.E' option here that gives the user an easy way to return from \TeX\ to the system editor, with the offending line ready to be edited. But such an extension requires some system wizardry, so the present implementation simply types out the name of the file that should be edited and the relevant line number. @^system dependencies@> @y @ It is desirable to provide an `\.E' option here that gives the user an easy way to return from \TeX\ to the system editor, with the offending line ready to be edited. This version of \TeX\ invokes callable versions of various DEC editors, depending upon the value of the \.{/EDITOR} switch (normally set to \.{TEX\_EDIT}), @./EDITOR@> @.TEX_EDIT@> including \.{EDT}, \.{TPU}, DEC's Language-sensitive editor (LSEdit), and even @^EDT@> @^TPU@> @^Language-sensitive editor@> @^LSE@> \.{TECO}. @^TECO@> Other editors may be run in a sub-process by setting \.{/EDITOR} to any DCL command, including activating a command procedure. In addition, if the \.{/CONTINUE} qualifier is present on the command line, @./CONTINUE@> \TeX will continue processing after returning from the editor. @^system dependencies@> @z {Section 84} >>>>>Modified 30-JUN-1990 by DAH>>>>> @x <<<<>>>> "E": if base_ptr>0 then begin print_nl("You want to edit file "); @.You want to edit file x@> print(input_stack[base_ptr].name_field); print(" at line "); print_int(line); interaction:=scroll_mode; jump_out; end; @y "E": if base_ptr>0 then begin if edit_file(input_stack[base_ptr],line) then begin if continue_qual then begin show_context; goto continue; end else begin interaction:=scroll_mode; jump_out; end end else begin print_nl("You want to edit file "); @.You want to edit file x@> print(input_stack[base_ptr].name_field); print(" at line "); print_int(line); interaction:=scroll_mode; jump_out; end end; @z {Section 86} <<<<>>>> @x @= begin error_count:=0; interaction:=batch_mode+c-"Q"; print("OK, entering "); case c of "Q":begin print_esc("batchmode"); decr(selector); end; "R":print_esc("nonstopmode"); "S":print_esc("scrollmode"); end; {there are no other cases} print("..."); print_ln; update_terminal; return; end @y @= begin error_count:=0; interaction:=batch_mode+c-"Q"; print("OK, entering "); case c of "Q":print_esc("batchmode"); "R":print_esc("nonstopmode"); "S":print_esc("scrollmode"); end; {there are no other cases} print("..."); print_ln; update_terminal; if c = "Q" then decr (selector); return; end @z {Section 96} @x @ Users occasionally want to interrupt \TeX\ while it's running. If the \PASCAL\ runtime system allows this, one can implement a routine that sets the global variable |interrupt| to some nonzero value when such an interrupt is signalled. Otherwise there is probably at least a way to make |interrupt| nonzero using the \PASCAL\ debugger. @^system dependencies@> @^debugging@> @y @ Users occasionally want to interrupt \TeX\ while it's running. By using a VAX system service, we can declare an Asynchronous System Trap (AST) handler which will be called when the user types \.{Ctrl-C}. The AST handler then sets the global variable |interrupt| to some nonzero value when such an interrupt is signalled. @^system dependencies@> Since this variable may be changed at any time, we must prevent the compiler from applying optimizations to the code related to this variable (for example, it would not do for it to be held in a machine register), so we give it the VAX-\PASCAL\ `attribute' \.{volatile}, which is defined at this point. We also define a couple of other attributes that may be applied to affect the placement of variables under VAX-\PASCAL. Assuming that it's possible to assign an I/O channel to device \.{SYS\$COMMAND}, @.SYS{\$}COMMAND@> which should be the case provided the program is being run interactively, then the Control-C handler is declared by a call of the \.{\$QIOW} system service. @.{\$}QIOW@> Some parameters for this system service have to passed by the `immediate' parameter-passing mechanism; we take this opportunity to define all the means used in \TeX\ to override VAX-\PASCAL's default parameter-passing mechanisms. @d VAX_volatile==@= volatile @> @d VAX_aligned==@= aligned @> @d VAX_static==@= static @> @# @d VAX_immed==@= %immed @> @d VAX_stdescr==@= %stdescr @> @d VAX_ref==@= %ref @> @# @d VAX_io_setmode==@= io$_setmode @> @d VAX_iom_ctrlcast==@= io$m_ctrlcast @> @# @d VAX_qiow==@= $qiow@> @d VAX_assign==@= $assign@> @# @z {Section 96} @x [6] interrupts @d check_interrupt==begin if interrupt<>0 then pause_for_instructions; end @= @!interrupt:integer; {should \TeX\ pause for instructions?} @y @d check_interrupt==begin if interrupt<>0 then pause_for_instructions; end @d enable_control_C== VAX_qiow(,tt_chan,VAX_io_setmode+VAX_iom_ctrlcast,,,, VAX_immed ctrlc_rout,,VAX_immed 3,,,); @= @!interrupt:[VAX_volatile]integer; {should \TeX\ pause for instruction?} @z {Section 97} @x interrupt:=0; OK_to_interrupt:=true; @y interrupt:=0; OK_to_interrupt:=true; if VAX_assign('SYS$COMMAND',tt_chan,,)=VAX_ss_normal then enable_control_C; @z {Section 109} @x [7] double precision reals @d set_glue_ratio_zero(#) == #:=0.0 {store the representation of zero ratio} @d set_glue_ratio_one(#) == #:=1.0 {store the representation of unit ratio} @d float(#) == # {convert from |glue_ratio| to type |real|} @d unfloat(#) == # {convert from |real| to type |glue_ratio|} @d float_constant(#) == #.0 {convert |integer| constant to |real|} @= @!glue_ratio=real; {one-word representation of a glue expansion factor} @y On VAX/VMS, we use some hackery to cause floating point numbers stored in |mem| to be |single|, but other |real| variables and expressions are done as |double| length reals. @d set_glue_ratio_zero(#) == #:=0.0 {store the representation of zero ratio} @d set_glue_ratio_one(#) == #:=1.0 {store the representation of unit ratio} @d real == double {use double precision reals for computation} @d float(#) == dble(#) {convert from |glue_ratio| to type |real|} {FIX ME} @d unfloat(#) == sngl(1.0@&D0 * #) {convert from |real| to type |glue_ratio|} @d float_constant(#) == #.0@&D0 {convert |integer| constant to |real|} @= @!glue_ratio=r@&e@&a@&l; {one-word representation of a glue expansion factor} @z A trie_size of 8000 is to small to load patterns for dutch, german and english. For the german patterns we need also more than 255 ops, so the max_quarterword is incremented as is done with bigtex on UNIX machines. @x [1] We need bigger max_quarterword @d max_quarterword=255 {largest allowable value in a |quarterword|} @y @d max_quarterword=511 {largest allowable value in a |quarterword|} @z {Section 110} <<<<: BIGTeX changes to match Adrian's>>>>> @x @d max_halfword==65535 {largest allowable value in a |halfword|} @y @d max_halfword==327144+1 {largest allowable value in a |halfword|} @z {Section 111} <<<<: BIGTeX changes to match Adrian's>>>>> @x if (min_halfword>0)or(max_halfword<32767) then bad:=12; @y if (min_halfword>0)or(max_halfword<327144) then bad:=12; @z {Section 112} @x @d qi(#)==#+min_quarterword {to put an |eight_bits| item into a quarterword} @d qo(#)==#-min_quarterword {to take an |eight_bits| item out of a quarterword} @d hi(#)==#+min_halfword {to put a sixteen-bit item into a halfword} @d ho(#)==#-min_halfword {to take a sixteen-bit item from a halfword} @y @d qi(#)==# @d qo(#)==# @d hi(#)==# @d ho(#)==# @z {Section 113} @x [8] block up word files @!word_file = file of memory_word; @y @!word_block = packed array [0..VAX_block_length-1] of memory_word; @!word_file = packed file of word_block; @z {Section 131} >>>>>Added 25-May-1990 DAH--declare all init functions>>>>> @x @p @!init procedure sort_avail; {sorts the available variable-size nodes by location} var p,@!q,@!r: pointer; {indices into |mem|} @!old_rover:pointer; {initial |rover| setting} begin p:=get_node(@'10000000000); {merge adjacent free areas} p:=rlink(rover); rlink(rover):=max_halfword; old_rover:=rover; while p<>old_rover do @; p:=rover; while rlink(p)<>max_halfword do begin llink(rlink(p)):=p; p:=rlink(p); end; rlink(p):=rover; llink(rover):=p; end; tini @y @p procedure sort_avail; {sorts the available variable-size nodes by location} var p,@!q,@!r: pointer; {indices into |mem|} @!old_rover:pointer; {initial |rover| setting} begin p:=get_node(@'10000000000); {merge adjacent free areas} p:=rlink(rover); rlink(rover):=max_halfword; old_rover:=rover; while p<>old_rover do @; p:=rover; while rlink(p)<>max_halfword do begin llink(rlink(p)):=p; p:=rlink(p); end; rlink(p):=rover; llink(rover):=p; end; @z {Section 186} @x [12] check glue ratio for REALness arbitrary random value. The following code assumes that a properly formed nonzero |real| number has absolute value $2^{20}$ or more when it is regarded as an integer; this precaution was adequate to prevent floating point underflow on the author's computer. @y arbitrary random value. The following code uses the VAX/VMS predeclared routine |undefined|, which returns |true| if its argument is not a properly constituted |real| number. @d VAX_undefined==@= undefined@> @z {Section 186} @x if abs(mem[p+glue_offset].int)<@'4000000 then print("?.?") @y if VAX_undefined(mem[p+glue_offset].gr) then print("?.?") @z {Section 232} @x [17] Special form_feed initialization: cat_code("\"):=escape; cat_code("%"):=comment; @y cat_code("\"):=escape; cat_code("%"):=comment; cat_code(form_feed):=car_ret; @z {Section 241} @x [17] date/time Since standard \PASCAL\ cannot provide such information, something special is needed. The program here simply specifies July 4, 1776, at noon; but users probably want a better approximation to the truth. @p procedure fix_date_and_time; begin time:=12*60; {minutes since midnight} day:=4; {fourth day of the month} month:=7; {seventh month of the year} year:=1776; {Anno Domini} @y The requisite information is obtained through a call of the \.{\$NUMTIM} system @.{\$}NUMTIM@> service. @d VAX_numtim==@= $numtim@> @p procedure fix_date_and_time; var t:array[1..7] of signed_halfword; {raw year, month, day and time} begin VAX_numtim(t); year:=t[1]; month:=t[2]; day:=t[3]; time:=t[4]*60+t[5]; {minutes since midnight} @z {Section 264} >>>>>Added 25-May-1990 DAH--declare all init functions>>>>> @x @p @!init procedure primitive(@!s:str_number;@!c:quarterword;@!o:halfword); var k:pool_pointer; {index into |str_pool|} @!j:small_number; {index into |buffer|} @!l:small_number; {length of the string} begin if s<256 then cur_val:=s+single_base else begin k:=str_start[s]; l:=str_start[s+1]-k; {we will move |s| into the (empty) |buffer|} for j:=0 to l-1 do buffer[j]:=so(str_pool[k+j]); cur_val:=id_lookup(0,l); {|no_new_control_sequence| is |false|} flush_string; text(cur_val):=s; {we don't want to have the string twice} end; eq_level(cur_val):=level_one; eq_type(cur_val):=c; equiv(cur_val):=o; end; tini @y @p procedure primitive(@!s:str_number;@!c:quarterword;@!o:halfword); var k:pool_pointer; {index into |str_pool|} @!j:small_number; {index into |buffer|} @!l:small_number; {length of the string} begin if s<256 then cur_val:=s+single_base else begin k:=str_start[s]; l:=str_start[s+1]-k; {we will move |s| into the (empty) |buffer|} for j:=0 to l-1 do buffer[j]:=so(str_pool[k+j]); cur_val:=id_lookup(0,l); {|no_new_control_sequence| is |false|} flush_string; text(cur_val):=s; {we don't want to have the string twice} end; eq_level(cur_val):=level_one; eq_type(cur_val):=c; equiv(cur_val):=o; end; @z {Section 311} @x <<<<>>>> @@/ begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input; {store current state} @y @@/ begin base_ptr:=input_ptr; input_stack[base_ptr]:=cur_input; {store current state} @; @z {Section 311} @x <<<<>>>> done: cur_input:=input_stack[input_ptr]; {restore original state} end; @y done: cur_input:=input_stack[input_ptr]; {restore original state} @; end; @z {Section 313} @x <<<<>>>> @= if name<=17 then if terminal_input then if base_ptr=0 then print_nl("<*>") else print_nl(" ") else begin print_nl(" print_char(">"); end else begin print_nl("l."); print_int(line); end; @y @= if name<=17 then begin @; if terminal_input then if base_ptr=0 then print_nl("<*>") else print_nl(" ") else begin print_nl(" print_char(">"); end; @; end else begin print_nl("l."); print_int(line); @; end; @z {Section 314} @x <<<<>>>> @ @= case token_type of parameter: print_nl(" "); u_template,v_template: print_nl("