|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U
Length: 227876 (0x37a24) Types: TextFile Notes: Uncompressed file
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦beba6c409⟧ »unix3.0/Unsupported.tar.Z« └─⟦25c524ae4⟧ └─⟦4b8d507d2⟧ »Unsupported/texware.sh.Z« └─⟦this⟧
# This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. #-----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # Makefile.BSD4_n # Makefile.PYR # Makefile.SUN # Makefile.SYS_V # dvitype.BSD4_n.ch # dvitype.PYR.ch # dvitype.SYS_V.ch # patgen.BSD4_n.ch # patgen.PYR.ch # patgen.SYS_V.ch # pltotf.BSD4_n.ch # pltotf.PYR.ch # pltotf.SYS_V.ch # tangle.BSD4_n.ch # tangle.PYR.ch # tangle.SYS_V.ch # tftopl.BSD4_n.ch # tftopl.PYR.ch # tftopl.SYS_V.ch # weave.BSD4_n.ch # weave.PYR.ch # weave.SYS_V.ch # This archive created: Sat Jul 2 22:28:55 1988 cat << \SHAR_EOF > Makefile.BSD4_n # # Makefile for TeX82 distribution, subdirectory `=TeXware' # version for 4.2 bsd # # This file makes TANGLE, WEAVE, TFtoPL, PLtoTF, DVItype, PATGEN, # from their WEB sources. # # Note: The -J option on the 'pc' commands below is the only way to # 'pc' to use the -J option to the assembler (which makes it # do the sensible thing with branches). This flag is not # documented, which is correct, since 'pc' should really be # using it all of the time... (Grrr..) # # Note: The DVItype program uses an environment variable named # TEXFONTS to figure out where the TFM files are. The default # value for this variable is set in the file ../texpaths.h which # is also used by TeX. # BINDIR=/usr/bin PC = pc PCLIB = PFLAGS= -J -O -w CFLAGS= -O -I.. FIXOTHERS= pxp -O -f .SUFFIXES: .SUFFIXES: .o .p .c .ch .ch.o: -tangle $*.web $*.ch $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(PFLAGS) -c $*.p .ch.p: tangle $*.web $*.ch .p.o: $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(PFLAGS) -c $*.p all: tangle weave tftopl pltotf dvitype patgen install: all mv tangle weave tftopl pltotf dvitype patgen $(BINDIR) tangle: tangle.o tangext.o $(PC) $(PFLAGS) -o tangle tangle.o tangext.o $(PCLIB) tangle.p: tangle.web tangext.o: tangext.c ../h00vars.h weave: weave.o weavext.o $(PC) $(PFLAGS) -o weave weave.o weavext.o $(PCLIB) weave.p: weave.web weavext.o: weavext.c tftopl: tftopl.o $(PC) $(PFLAGS) -o tftopl tftopl.o $(PCLIB) tftopl.p: tftopl.web pltotf: pltotf.o $(PC) $(PFLAGS) -o pltotf pltotf.o $(PCLIB) pltotf.p: pltotf.web dvitype: dvitype.o dvityext.o $(PC) $(PFLAGS) -o dvitype dvitype.o dvityext.o $(PCLIB) dvitype.p: dvitype.web dvityext.o: dvityext.h ../h00vars.h ../texpaths.h patgen: patgen.o $(PC) $(PFLAGS) -o patgen patgen.o $(PCLIB) patgen.p: patgen.web clean: # Don't delete tangle.p; it's needed on new sites to bootstrap rm -f weave.p dvitype.p tftopl.p pltotf.p \ patgen.p rm -f tangle.pool weave.pool dvitype.pool tftopl.pool pltotf.pool \ patgen.pool rm -f tangle.o weave.o dvitype.o tftopl.o pltotf.o \ patgen.o rm -f dvityext.o tangext.o weavext.o SHAR_EOF cat << \SHAR_EOF > Makefile.PYR # # Makefile for TeX82 distribution, subdirectory `=TeXware' # version for 4.2 bsd/Pyramid OSx # # This file makes TANGLE, WEAVE, TFtoPL, PLtoTF, DVItype, PATGEN, # from their WEB sources. # # Note: The DVItype program uses an environment variable named # TEXFONTS to figure out where the TFM files are. The default # value for this variable is set in the file ../texpaths.h which # is also used by TeX. # BINDIR=/usr/bin PC = pascal PCLIB = PFLAGS= -T4/bin/nas CFLAGS= -O -I.. #FIXOTHERS= pxp -O -f #FIXOTHERS= sed 's/others:/otherwise:/g' .SUFFIXES: .SUFFIXES: .o .p .c .ch .ch.o: -tangle $*.web $*.ch $(PC) $(PFLAGS) -c $*.p .ch.p: tangle $*.web $*.ch .p.o: $(PC) $(PFLAGS) -c $*.p all: tangle weave tftopl pltotf dvitype patgen install: all mv tangle weave tftopl pltotf dvitype patgen $(BINDIR) tangle: tangle.o tangext.o $(PC) $(PFLAGS) -o tangle tangle.o tangext.o $(PCLIB) tangle.p: tangle.web tangext.o: tangext.c ../h00vars.h weave: weave.o weavext.o $(PC) $(PFLAGS) -o weave weave.o weavext.o $(PCLIB) weave.p: weave.web weavext.o: weavext.c tftopl: tftopl.o $(PC) $(PFLAGS) -o tftopl tftopl.o $(PCLIB) tftopl.p: tftopl.web pltotf: pltotf.o $(PC) $(PFLAGS) -o pltotf pltotf.o $(PCLIB) pltotf.p: pltotf.web dvitype: dvitype.o dvityext.o $(PC) $(PFLAGS) -o dvitype dvitype.o dvityext.o $(PCLIB) dvitype.p: dvitype.web dvityext.o: dvityext.h ../h00vars.h ../texpaths.h patgen: patgen.o $(PC) $(PFLAGS) -o patgen patgen.o $(PCLIB) patgen.p: patgen.web clean: # Don't delete tangle.p; it's needed on new sites to bootstrap rm -f weave.p dvitype.p tftopl.p pltotf.p \ patgen.p rm -f tangle.pool weave.pool dvitype.pool tftopl.pool pltotf.pool \ patgen.pool rm -f tangle.o weave.o dvitype.o tftopl.o pltotf.o \ patgen.o rm -f dvityext.o tangext.o weavext.o SHAR_EOF cat << \SHAR_EOF > Makefile.SUN # # Makefile for TeX82 distribution, subdirectory `TeXware' # version for 4.2 bsd (Sun version, with no -J flag) # # This file makes TANGLE, WEAVE, TFtoPL, PLtoTF, DVItype, PATGEN, # from their WEB sources. # # # Note: The DVItype program uses an environment variable named # TEXFONTS to figure out where the TFM files are. The default # value for this variable is set in the file ../texpaths.h which # is also used by TeX. # BINDIR=/usr/bin PC = pc PCLIB = PFLAGS= -O -w CFLAGS= -O -I.. # FIXOTHERS= pxp -O -f FIXOTHERS= sed 's/others:/otherwise /g' .SUFFIXES: .SUFFIXES: .o .p .c .ch .ch.o: -tangle $*.web $*.ch $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(PFLAGS) -c $*.p .ch.p: tangle $*.web $*.ch .p.o: $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(PFLAGS) -c $*.p all: tangle weave tftopl pltotf dvitype patgen install: all mv tangle weave tftopl pltotf dvitype patgen $(BINDIR) tangle: tangle.o tangext.o $(PC) $(PFLAGS) -o tangle tangle.o tangext.o $(PCLIB) tangle.p: tangle.web tangext.o: tangext.c ../h00vars.h weave: weave.o weavext.o $(PC) $(PFLAGS) -o weave weave.o weavext.o $(PCLIB) weave.p: weave.web weavext.o: weavext.c tftopl: tftopl.o $(PC) $(PFLAGS) -o tftopl tftopl.o $(PCLIB) tftopl.p: tftopl.web pltotf: pltotf.o $(PC) $(PFLAGS) -o pltotf pltotf.o $(PCLIB) pltotf.p: pltotf.web dvitype: dvitype.o dvityext.o $(PC) $(PFLAGS) -o dvitype dvitype.o dvityext.o $(PCLIB) dvitype.p: dvitype.web dvityext.o: dvityext.h ../h00vars.h ../texpaths.h patgen: patgen.o $(PC) $(PFLAGS) -o patgen patgen.o $(PCLIB) patgen.p: patgen.web clean: # Don't delete tangle.p; it's needed on new sites to bootstrap rm -f weave.p dvitype.p tftopl.p pltotf.p \ patgen.p rm -f tangle.pool weave.pool dvitype.pool tftopl.pool pltotf.pool \ patgen.pool rm -f tangle.o weave.o dvitype.o tftopl.o pltotf.o \ patgen.o rm -f dvityext.o tangext.o weavext.o SHAR_EOF cat << \SHAR_EOF > Makefile.SYS_V # # Makefile for TeX82 distribution, subdirectory `=TeXware' # Version for 3b2 System V UNIX # # This file makes TANGLE, WEAVE, TFtoPL, PLtoTF, DVItype, and PATGEN # from their WEB sources # # Note: The DVItype program uses an environment variable named # TEXFONTS to figure out where the TFM files are. The default # value for this variable is set in the file ../texpaths.h which # is also used by TeX. # #BINDIR=/usr/bin BINDIR=/usr/local PC = pc PCLIB = PFLAGS= -O CFLAGS= -O -I.. # turn off range checking FASTPFLAGS= -Tr $(PFLAGS) FIXOTHERS= pxp -O -f -L100 .SUFFIXES: .SUFFIXES: .o .p .c .ch .ch.o: -tangle $*.web $*.ch $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(PFLAGS) -c $*.p .ch.p: tangle $*.web $*.ch .p.o: $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(PFLAGS) -c $*.p all: tangle weave tftopl pltotf dvitype patgen install: all mv tangle weave tftopl pltotf dvitype patgen $(BINDIR) tangle: tangle.o tangext.o $(PC) $(PFLAGS) -o tangle tangle.o tangext.o $(PCLIB) tangle.p: tangle.web # this program should run extra fast... tangle.o: tangle.p $(FIXOTHERS) $*.p > tmp.p mv tmp.p $*.p $(PC) $(FASTPFLAGS) -c $*.p tangext.o: tangext.c ../h00vars.h weave: weave.o weavext.o $(PC) $(PFLAGS) -o weave weave.o weavext.o $(PCLIB) weave.p: weave.web weavext.o: weavext.c tftopl: tftopl.o $(PC) $(PFLAGS) -o tftopl tftopl.o $(PCLIB) tftopl.p: tftopl.web tftoplext.o: tftoplext.c ../h00vars.h pltotf: pltotf.o pltotfext.o $(PC) $(PFLAGS) -o pltotf pltotf.o pltotfext.o $(PCLIB) pltotf.p: pltotf.web pltotfext.o: pltotfext.c ../h00vars.h dvitype: dvitype.o dvityext.o $(PC) $(PFLAGS) -o dvitype dvitype.o dvityext.o $(PCLIB) dvitype.p: dvitype.web dvityext.o: dvityext.h ../h00vars.h ../texpaths.h patgen: patgen.o $(PC) $(PFLAGS) -o patgen patgen.o $(PCLIB) patgen.p: patgen.web clean: # Don't delete tangle.p; it's needed on new sites to bootstrap rm -f weave.p dvitype.p tftopl.p pltotf.p \ patgen.p rm -f tangle.pool weave.pool dvitype.pool tftopl.pool pltotf.pool \ patgen.pool rm -f tangle.o weave.o dvitype.o tftopl.o pltotf.o \ patgen.o rm -f dvityext.o tangext.o weavext.o pltotfext.o tftoplext.o SHAR_EOF cat << \SHAR_EOF > dvitype.BSD4_n.ch % Change file for the DVItype processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey, CSD.Trickey@SCORE, and modified % by Pavel Curtis, Pavel@Cornell. % History: % ?? (HT) Original version. % 4/4/83 (PC) Merged with Pavel's change file and made to work with the % version 1.0 of DVItype released with version 0.95 of TeX in % February, 1983. % 4/18 (PC) Added changes to module 47 so that it would work the same % when input was a file (or pipe) as with a terminal. % 6/29 (HWT) Brought up to version 1.1 as released with version 0.99 of % TeX, with new change file format % 7/28 (HWT) Brought up to version 2 as released with version 0.999. % Only the banner changes. % 11/21 (HWT) Brought up to version 2.2 as released with version 1.0. % 2/19/84 (HWT) Made it use TEXFONTS environment. % 3/23/84 (HWT) Brought up to version 2.3. % 7/11/84 (HWT) Brought up to version 2.6 as released with version 1.1. % 8/4/84 (RKF) To version 2.7 % 9/3/85 (RKF) To version 2.8 % 12/5/87 (PAM) To version 2.9 % The module numbers used in this file refer to those in the red-covered % listing (Version 2, July 1983) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{DVI$\,$\lowercase{type} changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is DVItype, Version 2.9' {printed when the program starts} @y @d banner=='This is DVItype, Version 2.9 for Berkeley UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Turn off random-access reading %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d random_reading==true {should we skip around in the file?} @y @d random_reading==false {should we skip around in the file?} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [3] Change filenames in program statement; add #include statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(#) @d print_ln(#)==write_ln(#) @p program DVI_type(@!dvi_file,@!output); @y For Berkeley {\mc UNIX}, we need the name |output| for the dialog, so make the output come out on a file called |'dvitype.out'|. @d print(#)==write(dvityout,#) @d print_ln(#)==write_ln(dvityout,#) @p program DVI_type(@!input,@!output); @z @x var @<Globals in the outer block@>@/ @y var @<Globals in the outer block@>@/ @\@=#include "dvityext.h"@>@\ {declarations for external C procedures} @z @x begin print_ln(banner);@/ @y begin setpaths; {read environment, to find TEXFONTS, if there} rewrite(dvityout,'dvitype.out'); {prepare typescript for output} print_ln(banner);@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [5] Increase name_length %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!name_length=50; {a file name shouldn't be longer than this} @y @!name_length=100; {a file name shouldn't be longer than this} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] Change definition of 'byte_file' to correct subrange %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We shall stick to simple \PASCAL\ in this program, for reasons of clarity, even if such simplicity is sometimes unrealistic. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of eight_bits; {files that contain binary data} @y On Berkeley {\mc UNIX}, we have to use |-128..127| for byte files, as explained in the \TeX\ changes. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of -128..127; {files that contain binary data} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [23] Fix up opening the binary files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin reset(dvi_file); cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,cur_name); end; @y On Berkeley {\mc UNIX}, the |eof| testing won't work. We use the external |test_access| procedure, which also does path searching based on the user's environment or the default path. @d read_access_mode=4 {``read'' mode for |test_access|} @d write_access_mode=2 {``write'' mode for |test_access|} @d no_file_path=0 {no path searching should be done} @d font_file_path=3 {path specifier for \.{TFM} files} @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin if argc <> 2 then begin write_ln('Usage: dvitype <dvi-file>'); jump_out; end; argv(1, cur_name); if test_access(read_access_mode,no_file_path) then reset(dvi_file, real_name_of_file) else begin write_ln('DVI file not found'); jump_out; end; cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin if test_access(read_access_mode,font_file_path) then reset(tfm_file,real_name_of_file) else begin write_ln('TFM file not found'); jump_out end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [25] Declare real_name_of_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x |dvi_file|, and |cur_name| is a string variable that will be set to the current font metric file name before |open_tfm_file| is called. @<Glob...@>= @!cur_loc:integer; {where we are about to look, in |dvi_file|} @!cur_name:packed array[1..name_length] of char; {external name, with no lower case letters} @y |dvi_file|, and |cur_name| is a string variable that will be set to the current font metric file name before |open_tfm_file| is called. Under UNIX, we also have a |real_name_of_file| string, that gets set by the external |test_access| procedure after path searching. @<Glob...@>= @!cur_loc:integer; {where we are about to look, in |dvi_file|} @!cur_name,@!real_name_of_file:packed array[1..name_length] of char; {external name} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] Fix read_tfm_word to read bytes properly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_tfm_word; begin read(tfm_file,b0); read(tfm_file,b1); read(tfm_file,b2); read(tfm_file,b3); end; @y @d get_tfm_byte(#) == read(tfm_file,byte); if byte < 0 then # := byte + 256 else # := byte; @p procedure read_tfm_word; var byte : -128..127; begin get_tfm_byte(b0); get_tfm_byte(b1); get_tfm_byte(b2); get_tfm_byte(b3); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [27] Fix up functions to read DVI bytes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(dvi_file) then get_byte:=0 else begin read(dvi_file,b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin read(dvi_file,b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @y @p function get_byte:integer; {returns the next byte, unsigned} var b:-128..127; begin if eof(dvi_file) then get_byte:=0 else begin read(dvi_file,b); incr(cur_loc); if b < 0 then get_byte := b + 256 else get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:-128..127; begin read(dvi_file,b); incr(cur_loc); signed_byte:=b; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,b:integer; begin a := get_byte; b := get_byte; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:integer; begin a := signed_byte; b := get_byte; signed_pair:=a*256+b end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:integer; begin a := get_byte; b := get_byte; c := get_byte; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:integer; begin a := signed_byte; b := get_byte; c := get_byte; signed_trio:=(a*256+b)*256+c end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:integer; begin a := signed_byte; b := get_byte; c := get_byte; d := get_byte; signed_quad:=((a*256+b)*256+c)*256+d end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] Make dvi_length() and move_to_byte() stubs. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function dvi_length:integer; begin set_pos(dvi_file,-1); dvi_length:=cur_pos(dvi_file); end; @# procedure move_to_byte(n:integer); begin set_pos(dvi_file,n); cur_loc:=n; end; @y @p function dvi_length:integer; begin dvi_length:=0; end; @# procedure move_to_byte(n:integer); begin ; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [45] Define term_in and term_out and declare dvityout %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x and |term_out| for terminal output. @^system dependencies@> @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!term_in:text_file; {the terminal, considered as an input file} @!term_out:text_file; {the terminal, considered as an output file} @y and |term_out| for terminal output. @^system dependencies@> @d term_in==input @d term_out==output @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!dvityout:text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [46] Define update_terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [47] Remove call to reset(term_in) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin update_terminal; reset(term_in); @y begin update_terminal; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] Remove call to rewrite(term_out) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin rewrite(term_out); {prepare the terminal for output} @y begin @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [64] Set default_directory_name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d default_directory_name=='TeXfonts:' {change this to the correct name} @d default_directory_name_length=9 {change this to the correct length} @<Glob...@>= @!default_directory:packed array[1..default_directory_name_length] of char; @y Actually, under UNIX the standard area is defined in an external ``texpaths.h'' file. And the user have a path serached for fonts, by setting the TEXFONTS environment variable. @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [65] Remove initialization of now-defunct array %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ @<Set init...@>= default_directory:=default_directory_name; @y @ (No initialization to be done. Keep this module to preserve numbering.) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [66] Fix addition of ".tfm" suffix for portability and keep lowercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The string |cur_name| is supposed to be set to the external name of the \.{TFM} file for the current font. This usually means that we need to prepend the name of the default directory, and to append the suffix `\.{.TFM}'. Furthermore, we change lower case letters to upper case, since |cur_name| is a \PASCAL\ string. @y @ The string |cur_name| is supposed to be set to the external name of the \.{TFM} file for the current font. This usually means that we need to, at most sites, append the suffix ``.tfm''. @z @x if p=0 then begin for k:=1 to default_directory_name_length do cur_name[k]:=default_directory[k]; r:=default_directory_name_length; end else r:=0; @y r:=0; @z @x if (names[k]>="a")and(names[k]<="z") then cur_name[r]:=xchr[names[k]-@'40] else cur_name[r]:=xchr[names[k]]; end; cur_name[r+1]:='.'; cur_name[r+2]:='T'; cur_name[r+3]:='F'; cur_name[r+4]:='M' @y cur_name[r]:=xchr[names[k]]; end; cur_name[r+1]:='.'; cur_name[r+2]:='t'; cur_name[r+3]:='f'; cur_name[r+4]:='m' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [106] Print newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x final_end:end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > dvitype.PYR.ch % Change file for the DVItype processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey, CSD.Trickey@SCORE, and modified % by Pavel Curtis, Pavel@Cornell. % History: % ?? (HT) Original version. % 4/4/83 (PC) Merged with Pavel's change file and made to work with the % version 1.0 of DVItype released with version 0.95 of TeX in % February, 1983. % 4/18 (PC) Added changes to module 47 so that it would work the same % when input was a file (or pipe) as with a terminal. % 6/29 (HWT) Brought up to version 1.1 as released with version 0.99 of % TeX, with new change file format % 7/28 (HWT) Brought up to version 2 as released with version 0.999. % Only the banner changes. % 11/21 (HWT) Brought up to version 2.2 as released with version 1.0. % 2/19/84 (HWT) Made it use TEXFONTS environment. % 3/23/84 (HWT) Brought up to version 2.3. % 7/11/84 (HWT) Brought up to version 2.6 as released with version 1.1. % 8/4/84 (RKF) To version 2.7 % 1/3/86 (PAM) Modified Urban/Pleasant pyramid change file to reflect % change to Version 2.8 (cosmetic) % The module numbers used in this file refer to those in the red-covered % listing (Version 2, July 1983) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{DVI$\,$\lowercase{type} changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is DVItype, Version 2.8' {printed when the program starts} @y @d banner=='This is DVItype, Version 2.8 for Pyramid OSx' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Turn off random-access reading %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d random_reading==true {should we skip around in the file?} @d othercases == others: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @f othercases == else @f endcases == end @y @d random_reading==false {should we skip around in the file?} @d othercases == otherwise: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @f othercases == else @f endcases == end @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [3] Change filenames in program statement; add #include statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(#) @d print_ln(#)==write_ln(#) @p program DVI_type(@!dvi_file,@!output); @y For 4.2bsd {\mc UNIX}, we need the name |output| for the dialog, so make the output come out on a file called |'dvitype.out'|. @d print(#)==write(dvityout,#) @d print_ln(#)==write_ln(dvityout,#) @p program DVI_type(@!input,@!output); @z @x var @<Globals in the outer block@>@/ @y var @<Globals in the outer block@>@/ @\@=#include "dvityext.h"@>@\ {declarations for external C procedures} @z @x begin print_ln(banner);@/ @y begin setpaths; {read environment, to find TEXFONTS, if there} rewrite(dvityout,'dvitype.out'); {prepare typescript for output} print_ln(banner);@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [5] Increase name_length %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!name_length=50; {a file name shouldn't be longer than this} @y @!name_length=100; {a file name shouldn't be longer than this} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] Change definition of 'byte_file' to correct subrange %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We shall stick to simple \PASCAL\ in this program, for reasons of clarity, even if such simplicity is sometimes unrealistic. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of eight_bits; {files that contain binary data} @y On 4.2bsd {\mc UNIX}, we have to use |-128..127| for byte files, as explained in the \TeX\ changes. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of char; {files that contain binary data} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [23] Fix up opening the binary files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin reset(dvi_file); cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,cur_name); end; @y On 4.2bsd {\mc UNIX}, the |eof| testing won't work. We use the external |test_access| procedure, which also does path searching based on the user's environment or the default path. @d read_access_mode=4 {``read'' mode for |test_access|} @d write_access_mode=2 {``write'' mode for |test_access|} @d no_file_path=0 {no path searching should be done} @d font_file_path=3 {path specifier for \.{TFM} files} @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin if argc <> 2 then begin write_ln('Usage: dvitype <dvi-file>'); jump_out; end; argv(1, cur_name); if test_access(read_access_mode,no_file_path) then reset(dvi_file, real_name_of_file) else begin write_ln('DVI file not found'); jump_out; end; cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin if test_access(read_access_mode,font_file_path) then reset(tfm_file,real_name_of_file) else begin write_ln('TFM file not found'); jump_out end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [25] Declare real_name_of_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x |dvi_file|, and |cur_name| is a string variable that will be set to the current font metric file name before |open_tfm_file| is called. @<Glob...@>= @!cur_loc:integer; {where we are about to look, in |dvi_file|} @!cur_name:packed array[1..name_length] of char; {external name, with no lower case letters} @y |dvi_file|, and |cur_name| is a string variable that will be set to the current font metric file name before |open_tfm_file| is called. Under UNIX, we also have a |real_name_of_file| string, that gets set by the external |test_access| procedure after path searching. @<Glob...@>= @!cur_loc:integer; {where we are about to look, in |dvi_file|} @!cur_name,@!real_name_of_file:packed array[1..name_length] of char; {external name} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] Fix read_tfm_word to read bytes properly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_tfm_word; begin read(tfm_file,b0); read(tfm_file,b1); read(tfm_file,b2); read(tfm_file,b3); end; @y @d get_tfm_byte(#) == read(tfm_file,byte); # := ord(byte); @p procedure read_tfm_word; var byte : char; begin get_tfm_byte(b0); get_tfm_byte(b1); get_tfm_byte(b2); get_tfm_byte(b3); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [27] Fix up functions to read DVI bytes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(dvi_file) then get_byte:=0 else begin read(dvi_file,b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin read(dvi_file,b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @y @p function get_byte:integer; {returns the next byte, unsigned} var b:char; begin if eof(dvi_file) then get_byte:=0 else begin read(dvi_file,b); incr(cur_loc); get_byte:=ord(b); end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:char; begin read(dvi_file,b); incr(cur_loc); if ord(b)<128 then signed_byte:=ord(b) @+ else signed_byte:=ord(b)-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:char; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; get_two_bytes:=ord(a)*256+ord(b); end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:char; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; if ord(a)<128 then signed_pair:=ord(a)*256+ord(b) else signed_pair:=(ord(a)-256)*256+ord(b); end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:char; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(ord(a)*256+ord(b))*256+ord(c); end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:char; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; if ord(a)<128 then signed_trio:=(ord(a)*256+ord(b))*256+ord(c) else signed_trio:=((ord(a)-256)*256+ord(b))*256+ord(c); end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:char; i:integer; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d); cur_loc:=cur_loc+4; if ord(a)<128 then signed_quad:=((ord(a)*256+ord(b))*256+ord(c))*256+ord(d) else begin i:=(((ord(a)-256)*256+ord(b))*256+ord(c)); signed_quad:=i*256+ord(d); end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] Make dvi_length() and move_to_byte() stubs. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function dvi_length:integer; begin set_pos(dvi_file,-1); dvi_length:=cur_pos(dvi_file); end; @# procedure move_to_byte(n:integer); begin set_pos(dvi_file,n); cur_loc:=n; end; @y @p function dvi_length:integer; begin dvi_length:=0; end; @# procedure move_to_byte(n:integer); begin ; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [45] Define term_in and term_out and declare dvityout %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x and |term_out| for terminal output. @^system dependencies@> @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!term_in:text_file; {the terminal, considered as an input file} @!term_out:text_file; {the terminal, considered as an output file} @y and |term_out| for terminal output. @^system dependencies@> @d term_in==input @d term_out==output @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!dvityout:text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [46] Define update_terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [47] Remove call to reset(term_in) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin update_terminal; reset(term_in); @y begin update_terminal; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] Remove call to rewrite(term_out) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin rewrite(term_out); {prepare the terminal for output} @y begin @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [64] Set default_directory_name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d default_directory_name=='TeXfonts:' {change this to the correct name} @d default_directory_name_length=9 {change this to the correct length} @<Glob...@>= @!default_directory:packed array[1..default_directory_name_length] of char; @y Actually, under UNIX the standard area is defined in an external ``texpaths.h'' file. And the user have a path serached for fonts, by setting the TEXFONTS environment variable. @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [65] Remove initialization of now-defunct array %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ @<Set init...@>= default_directory:=default_directory_name; @y @ (No initialization to be done. Keep this module to preserve numbering.) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [66] Fix addition of ".tfm" suffix for portability and keep lowercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The string |cur_name| is supposed to be set to the external name of the \.{TFM} file for the current font. This usually means that we need to prepend the name of the default directory, and to append the suffix `\.{.TFM}'. Furthermore, we change lower case letters to upper case, since |cur_name| is a \PASCAL\ string. @y @ The string |cur_name| is supposed to be set to the external name of the \.{TFM} file for the current font. This usually means that we need to, at most sites, append the suffix ``.tfm''. @z @x if p=0 then begin for k:=1 to default_directory_name_length do cur_name[k]:=default_directory[k]; r:=default_directory_name_length; end else r:=0; @y r:=0; @z @x if (names[k]>="a")and(names[k]<="z") then cur_name[r]:=xchr[names[k]-@'40] else cur_name[r]:=xchr[names[k]]; end; cur_name[r+1]:='.'; cur_name[r+2]:='T'; cur_name[r+3]:='F'; cur_name[r+4]:='M' @y cur_name[r]:=xchr[names[k]]; end; cur_name[r+1]:='.'; cur_name[r+2]:='t'; cur_name[r+3]:='f'; cur_name[r+4]:='m' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [106] Print newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x final_end:end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > dvitype.SYS_V.ch % Change file for the DVItype processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey, CSD.Trickey@SCORE, and modified % by Pavel Curtis, Pavel@Cornell. % History: % ?? (HT) Original version. % 4/4/83 (PC) Merged with Pavel's change file and made to work with the % version 1.0 of DVItype released with version 0.95 of TeX in % February, 1983. % 4/18 (PC) Added changes to module 47 so that it would work the same % when input was a file (or pipe) as with a terminal. % 6/29 (HWT) Brought up to version 1.1 as released with version 0.99 of % TeX, with new change file format % 7/28 (HWT) Brought up to version 2 as released with version 0.999. % Only the banner changes. % 11/21 (HWT) Brought up to version 2.2 as released with version 1.0. % 2/19/84 (HWT) Made it use TEXFONTS environment. % 3/23/84 (HWT) Brought up to version 2.3. % 7/11/84 (HWT) Brought up to version 2.6 as released with version 1.1. % 8/4/84 (RKF) To version 2.7 % 1/3/86 (PAM) Modified Urban/Pleasant pyramid change file to reflect % change to Version 2.8 (cosmetic) % 3/27/87 (LKS) Changes for System V UNIX % 12/5/87 (PAM) To version 2.9 % The module numbers used in this file refer to those in the red-covered % listing (Version 2, July 1983) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{DVI$\,$\lowercase{type} changes for System V {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is DVItype, Version 2.9' {printed when the program starts} @y @d banner=='This is DVItype, Version 2.9 for System V UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Turn off random-access reading %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d random_reading==true {should we skip around in the file?} @y @d random_reading==false {should we skip around in the file?} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [3] Change filenames in program statement; add #include statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(#) @d print_ln(#)==write_ln(#) @p program DVI_type(@!dvi_file,@!output); @y For System V {\mc UNIX}, we need the name |output| for the dialog, so make the output come out on a file called |'dvitype.out'|. @d print(#)==write(dvityout,#) @d print_ln(#)==write_ln(dvityout,#) @p program DVI_type(@!input,@!output); @z @x var @<Globals in the outer block@>@/ @y var @<Globals in the outer block@>@/ @\@=#include "dvityext.h"@>@\ {declarations for external C procedures} @z @x begin print_ln(banner);@/ @y begin setpaths; {read environment, to find TEXFONTS, if there} rewrite(dvityout,'dvitype.out'); {prepare typescript for output} print_ln(banner);@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [5] Increase name_length %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!name_length=50; {a file name shouldn't be longer than this} @y @!name_length=100; {a file name shouldn't be longer than this} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] Change definition of 'byte_file' to correct subrange %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We shall stick to simple \PASCAL\ in this program, for reasons of clarity, even if such simplicity is sometimes unrealistic. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of eight_bits; {files that contain binary data} @y On System V {\mc UNIX}, we have to use char for byte files, as explained in the \TeX\ changes. @<Types...@>= @!eight_bits=0..255; {unsigned one-byte quantity} @!byte_file=packed file of char; {files that contain binary data} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [23] Fix up opening the binary files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin reset(dvi_file); cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin reset(tfm_file,cur_name); end; @y On System V {\mc UNIX}, the |eof| testing won't work. We use the external |test_access| procedure, which also does path searching based on the user's environment or the default path. @d read_access_mode=4 {``read'' mode for |test_access|} @d write_access_mode=2 {``write'' mode for |test_access|} @d no_file_path=0 {no path searching should be done} @d font_file_path=3 {path specifier for \.{TFM} files} @p procedure open_dvi_file; {prepares to read packed bytes in |dvi_file|} begin if argc <> 2 then begin write_ln('Usage: dvitype <dvi-file>'); jump_out; end; argv(2, cur_name); if test_access(read_access_mode,no_file_path) then reset(dvi_file, real_name_of_file) else begin write_ln('DVI file not found'); jump_out; end; cur_loc:=0; end; @# procedure open_tfm_file; {prepares to read packed bytes in |tfm_file|} begin if test_access(read_access_mode,font_file_path) then reset(tfm_file,real_name_of_file) else begin write_ln('TFM file not found'); jump_out end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [25] Declare real_name_of_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x |dvi_file|, and |cur_name| is a string variable that will be set to the current font metric file name before |open_tfm_file| is called. @<Glob...@>= @!cur_loc:integer; {where we are about to look, in |dvi_file|} @!cur_name:packed array[1..name_length] of char; {external name, with no lower case letters} @y |dvi_file|, and |cur_name| is a string variable that will be set to the current font metric file name before |open_tfm_file| is called. Under UNIX, we also have a |real_name_of_file| string, that gets set by the external |test_access| procedure after path searching. @<Glob...@>= @!cur_loc:integer; {where we are about to look, in |dvi_file|} @!cur_name,@!real_name_of_file:packed array[1..name_length] of char; {external name} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] Fix read_tfm_word to read bytes properly %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_tfm_word; begin read(tfm_file,b0); read(tfm_file,b1); read(tfm_file,b2); read(tfm_file,b3); end; @y @d tfm_read(#)==begin #:=ord(tfm_file^); get(tfm_file) end @d dvi_read(#)==begin #:=ord(dvi_file^); get(dvi_file) end @p procedure read_tfm_word; begin tfm_read(b0); tfm_read(b1); tfm_read(b2); tfm_read(b3); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [27] Fix up functions to read DVI bytes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(dvi_file) then get_byte:=0 else begin read(dvi_file,b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin read(dvi_file,b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin read(dvi_file,a); read(dvi_file,b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin read(dvi_file,a); read(dvi_file,b); read(dvi_file,c); read(dvi_file,d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @y @p function get_byte:integer; {returns the next byte, unsigned} var b:eight_bits; begin if eof(dvi_file) then get_byte:=0 else begin dvi_read(b); incr(cur_loc); get_byte:=b; end; end; @# function signed_byte:integer; {returns the next byte, signed} var b:eight_bits; begin dvi_read(b); incr(cur_loc); if b<128 then signed_byte:=b @+ else signed_byte:=b-256; end; @# function get_two_bytes:integer; {returns the next two bytes, unsigned} var a,@!b:eight_bits; begin dvi_read(a); dvi_read(b); cur_loc:=cur_loc+2; get_two_bytes:=a*256+b; end; @# function signed_pair:integer; {returns the next two bytes, signed} var a,@!b:eight_bits; begin dvi_read(a); dvi_read(b); cur_loc:=cur_loc+2; if a<128 then signed_pair:=a*256+b else signed_pair:=(a-256)*256+b; end; @# function get_three_bytes:integer; {returns the next three bytes, unsigned} var a,@!b,@!c:eight_bits; begin dvi_read(a); dvi_read(b); dvi_read(c); cur_loc:=cur_loc+3; get_three_bytes:=(a*256+b)*256+c; end; @# function signed_trio:integer; {returns the next three bytes, signed} var a,@!b,@!c:eight_bits; begin dvi_read(a); dvi_read(b); dvi_read(c); cur_loc:=cur_loc+3; if a<128 then signed_trio:=(a*256+b)*256+c else signed_trio:=((a-256)*256+b)*256+c; end; @# function signed_quad:integer; {returns the next four bytes, signed} var a,@!b,@!c,@!d:eight_bits; begin dvi_read(a); dvi_read(b); dvi_read(c); dvi_read(d); cur_loc:=cur_loc+4; if a<128 then signed_quad:=((a*256+b)*256+c)*256+d else signed_quad:=(((a-256)*256+b)*256+c)*256+d; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] Make dvi_length() and move_to_byte() stubs. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function dvi_length:integer; begin set_pos(dvi_file,-1); dvi_length:=cur_pos(dvi_file); end; @# procedure move_to_byte(n:integer); begin set_pos(dvi_file,n); cur_loc:=n; end; @y @p function dvi_length:integer; begin dvi_length:=0; end; @# procedure move_to_byte(n:integer); begin ; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [45] Define term_in and term_out and declare dvityout %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x and |term_out| for terminal output. @^system dependencies@> @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!term_in:text_file; {the terminal, considered as an input file} @!term_out:text_file; {the terminal, considered as an output file} @y and |term_out| for terminal output. @^system dependencies@> @d term_in==input @d term_out==output @<Glob...@>= @!buffer:array[0..terminal_line_length] of ASCII_code; @!dvityout:text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [46] Define update_terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [47] Remove call to reset(term_in) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin update_terminal; reset(term_in); @y begin update_terminal; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] Remove call to rewrite(term_out) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin rewrite(term_out); {prepare the terminal for output} @y begin @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [64] Set default_directory_name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d default_directory_name=='TeXfonts:' {change this to the correct name} @d default_directory_name_length=9 {change this to the correct length} @<Glob...@>= @!default_directory:packed array[1..default_directory_name_length] of char; @y Actually, under UNIX the standard area is defined in an external ``texpaths.h'' file. And the user have a path serached for fonts, by setting the TEXFONTS environment variable. @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [65] Remove initialization of now-defunct array %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ @<Set init...@>= default_directory:=default_directory_name; @y @ (No initialization to be done. Keep this module to preserve numbering.) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [66] Fix addition of ".tfm" suffix for portability and keep lowercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The string |cur_name| is supposed to be set to the external name of the \.{TFM} file for the current font. This usually means that we need to prepend the name of the default directory, and to append the suffix `\.{.TFM}'. Furthermore, we change lower case letters to upper case, since |cur_name| is a \PASCAL\ string. @y @ The string |cur_name| is supposed to be set to the external name of the \.{TFM} file for the current font. This usually means that we need to, at most sites, append the suffix ``.tfm''. @z @x if p=0 then begin for k:=1 to default_directory_name_length do cur_name[k]:=default_directory[k]; r:=default_directory_name_length; end else r:=0; @y r:=0; @z @x if (names[k]>="a")and(names[k]<="z") then cur_name[r]:=xchr[names[k]-@'40] else cur_name[r]:=xchr[names[k]]; end; cur_name[r+1]:='.'; cur_name[r+2]:='T'; cur_name[r+3]:='F'; cur_name[r+4]:='M' @y cur_name[r]:=xchr[names[k]]; end; cur_name[r+1]:='.'; cur_name[r+2]:='t'; cur_name[r+3]:='f'; cur_name[r+4]:='m' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [106] Print newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x final_end:end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > patgen.BSD4_n.ch % Change file for patgen, for use on Berkeley UNIX systems. % This file was created by Howard Trickey, Trickey@SU-Score % History: % 7/1/83 (HWT) Original version, made to work with patgen released with % version 0.99 of TeX in July 1983. It may not work % properly---it is hard to test without more information. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{PATGEN changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change files in program statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p @<Compiler directives@>@/ program PATGEN(@!dictionary,@!patterns,@!output); @y @d std_input==i@&n@&p@&u@&t @d std_output==o@&u@&t@&p@&u@&t @p @<Compiler directives@>@/ program PATGEN(std_input,std_output); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add file opening to initialization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin @<Set up input/output translation tables@>@/ @y begin @<Open files@>@/ @<Set up input/output translation tables@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add f_name declaration %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!dictionary, @!patterns, @!pattmp: file of text_char; @y @!dictionary, @!patterns, @!pattmp, @!outfile: file of text_char; @!f_name: packed array [1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Terminal I/O %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(tty,#) @d print_ln(#)==writeln(tty,#) @d input(#)==read(tty,#) @d input_ln(#)==begin if eoln(tty) then readln(tty); read(tty,#) end @# @y @d print(#)==write(std_output,#) @d print_ln(#)==writeln(std_output,#) @d input(#)==read(std_input,#) @d input_ln(#)==begin if eoln(std_input) then readln(std_input); read(std_input,#) end @# @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Compiler directives %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @y @=(*$C-*)@> {no range check} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change write(...) to write(outfile,...) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if hval[0]>0 then write(hval[0]:1); for d:=1 to pat_len do begin if pat[d]=edge_of_word then write('.') else write(xchr[pat[d]]); if hval[d]>0 then write(hval[d]:1); end; writeln; @y if hval[0]>0 then write(outfile,hval[0]:1); for d:=1 to pat_len do begin if pat[d]=edge_of_word then write(outfile,'.') else write(outfile,xchr[pat[d]]); if hval[d]>0 then write(outfile,hval[d]:1); end; writeln(outfile); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change readln of string into loop %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_word; var c: ascii_code; begin readln(dictionary,buf); @y @d read_to_buf(#)== buf_ptr:=1; while not eoln(#) and (buf_ptr<80) do begin buf[buf_ptr]:=#^; get(#); incr(buf_ptr); end; buf[buf_ptr]:=' '; readln(#) @p procedure read_word; var c: ascii_code; bptr: integer; begin read_to_buf(dictionary); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Use args to get dictionary file name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(dictionary);@/ @y argv(1, f_name); reset(dictionary, f_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Remove file close %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if hyphp then close(pattmp); @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Another readln change and opening using args %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(patterns); while not eof(patterns) do begin readln(patterns,buf); @y argv(2, f_name); reset(patterns, f_name); while not eof(patterns) do begin read_to_buf(patterns); @z @x @* Index. @y @ Use the command line arguments to get the file names. Open the output file here; the others are reset above. @<Open files@>= if argc < 4 then begin error('Usage: patgen <dict-file> <pat-file> <out-file>') end; argv(3, f_name); rewrite(outfile, f_name); @* Index. @z SHAR_EOF cat << \SHAR_EOF > patgen.PYR.ch % Change file for patgen, for use on Berkeley UNIX systems. % This file was created by Howard Trickey, Trickey@SU-Score % History: % 7/1/83 (HWT) Original version, made to work with patgen released with % version 0.99 of TeX in July 1983. It may not work % properly---it is hard to test without more information. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{PATGEN changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change files in program statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p @<Compiler directives@>@/ program PATGEN(@!dictionary,@!patterns,@!output); @y @d std_input==i@&n@&p@&u@&t @d std_output==o@&u@&t@&p@&u@&t @p @<Compiler directives@>@/ program PATGEN(std_input,std_output); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add file opening to initialization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin @<Set up input/output translation tables@>@/ @y begin @<Open files@>@/ @<Set up input/output translation tables@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add f_name declaration %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!dictionary, @!patterns, @!pattmp: file of text_char; @y @!dictionary, @!patterns, @!pattmp, @!outfile: file of text_char; @!f_name: packed array [1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Terminal I/O %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(tty,#) @d print_ln(#)==writeln(tty,#) @d input(#)==read(tty,#) @d input_ln(#)==begin if eoln(tty) then readln(tty); read(tty,#) end @# @y @d print(#)==write(std_output,#) @d print_ln(#)==writeln(std_output,#) @d input(#)==read(std_input,#) @d input_ln(#)==begin if eoln(std_input) then readln(std_input); read(std_input,#) end @# @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Compiler directives %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @y @=(*$C-*)@> {no range check} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change write(...) to write(outfile,...) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if hval[0]>0 then write(hval[0]:1); for d:=1 to pat_len do begin if pat[d]=edge_of_word then write('.') else write(xchr[pat[d]]); if hval[d]>0 then write(hval[d]:1); end; writeln; @y if hval[0]>0 then write(outfile,hval[0]:1); for d:=1 to pat_len do begin if pat[d]=edge_of_word then write(outfile,'.') else write(outfile,xchr[pat[d]]); if hval[d]>0 then write(outfile,hval[d]:1); end; writeln(outfile); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change readln of string into loop %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_word; var c: ascii_code; begin readln(dictionary,buf); @y @d read_to_buf(#)== buf_ptr:=1; while not eoln(#) and (buf_ptr<80) do begin buf[buf_ptr]:=#^; get(#); incr(buf_ptr); end; buf[buf_ptr]:=' '; readln(#) @p procedure read_word; var c: ascii_code; bptr: integer; begin read_to_buf(dictionary); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Use args to get dictionary file name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(dictionary);@/ @y argv(1, f_name); reset(dictionary, f_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Remove file close %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if hyphp then close(pattmp); @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Another readln change and opening using args %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(patterns); while not eof(patterns) do begin readln(patterns,buf); @y argv(2, f_name); reset(patterns, f_name); while not eof(patterns) do begin read_to_buf(patterns); @z @x @* Index. @y @ Use the command line arguments to get the file names. Open the output file here; the others are reset above. @<Open files@>= if argc < 4 then begin error('Usage: patgen <dict-file> <pat-file> <out-file>') end; argv(3, f_name); rewrite(outfile, f_name); @* Index. @z SHAR_EOF cat << \SHAR_EOF > patgen.SYS_V.ch % Change file for patgen, for use on Berkeley UNIX systems. % This file was created by Howard Trickey, Trickey@SU-Score % History: % 7/1/83 (HWT) Original version, made to work with patgen released with % version 0.99 of TeX in July 1983. It may not work % properly---it is hard to test without more information. % 3/27/87 (LKS) Changes for System V UNIX %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{PATGEN changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change files in program statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p @<Compiler directives@>@/ program PATGEN(@!dictionary,@!patterns,@!output); @y @d std_input==i@&n@&p@&u@&t @d std_output==o@&u@&t@&p@&u@&t @p @<Compiler directives@>@/ program PATGEN(std_input,std_output); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add file opening to initialization %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin @<Set up input/output translation tables@>@/ @y begin @<Open files@>@/ @<Set up input/output translation tables@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Add f_name declaration %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!dictionary, @!patterns, @!pattmp: file of text_char; @y @!dictionary, @!patterns, @!pattmp, @!outfile: file of text_char; @!f_name: packed array [1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Terminal I/O %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(tty,#) @d print_ln(#)==writeln(tty,#) @d input(#)==read(tty,#) @d input_ln(#)==begin if eoln(tty) then readln(tty); read(tty,#) end @# @y @d print(#)==write(std_output,#) @d print_ln(#)==writeln(std_output,#) @d input(#)==read(std_input,#) @d input_ln(#)==begin if eoln(std_input) then readln(std_input); read(std_input,#) end @# @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Compiler directives %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @y @=(*$C-*)@> {no range check} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change write(...) to write(outfile,...) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if hval[0]>0 then write(hval[0]:1); for d:=1 to pat_len do begin if pat[d]=edge_of_word then write('.') else write(xchr[pat[d]]); if hval[d]>0 then write(hval[d]:1); end; writeln; @y if hval[0]>0 then write(outfile,hval[0]:1); for d:=1 to pat_len do begin if pat[d]=edge_of_word then write(outfile,'.') else write(outfile,xchr[pat[d]]); if hval[d]>0 then write(outfile,hval[d]:1); end; writeln(outfile); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Change readln of string into loop %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure read_word; var c: ascii_code; begin readln(dictionary,buf); @y @d read_to_buf(#)== buf_ptr:=1; while not eoln(#) and (buf_ptr<80) do begin buf[buf_ptr]:=#^; get(#); incr(buf_ptr); end; buf[buf_ptr]:=' '; readln(#) @p procedure read_word; var c: ascii_code; bptr: integer; begin read_to_buf(dictionary); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Use args to get dictionary file name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(dictionary);@/ @y argv(1, f_name); reset(dictionary, f_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Remove file close %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x if hyphp then close(pattmp); @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Another readln change and opening using args %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(patterns); while not eof(patterns) do begin readln(patterns,buf); @y argv(2, f_name); reset(patterns, f_name); while not eof(patterns) do begin read_to_buf(patterns); @z @x @* Index. @y @ Use the command line arguments to get the file names. Open the output file here; the others are reset above. @<Open files@>= if argc < 4 then begin error('Usage: patgen <dict-file> <pat-file> <out-file>') end; argv(3, f_name); rewrite(outfile, f_name); @* Index. @z SHAR_EOF cat << \SHAR_EOF > pltotf.BSD4_n.ch % Change file for the PLtoTF processor, for use on Berkeley UNIX systems. % This file was created by Pavel Curtis, Pavel@Cornell. % History: % 4/4/83 (PC) Original version, made to work with version 1.2 of PLtoTF. % 4/16 (PC) Brought up to version 1.3 of PLtoTF. % 6/30 (HWT) Revised changefile format for version 1.7 Tangle % 7/28 (HWT) Brought up to version 2 % 11/21 (HWT) Brought up to version 2.1 % 9/3/85 (RKF) Brought up to version 2.3 % The section numbers used in this file refer to those in the red-covered % listing (Version 2) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{PL\lowercase{to}TF changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is PLtoTF, Version 2.3' {printed when the program starts} @y @d banner=='This is PLtoTF, Version 2.3 for Berkeley UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Fix filenames in program statement; add `final_end' label %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program PLtoTF(@!pl_file,@!tfm_file,@!output); @y @d final_end==9999 @p program PLtoTF(@!output); label final_end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Open PL file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(pl_file); @y if argc < 3 then begin print_ln('Usage: pltotf <pl-file> <tfm-file>'); goto final_end; end; argv(1, pl_name); reset(pl_file, pl_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [15] Change type of tfm_file and declare extra TFM-file variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!tfm_file:packed file of 0..255; @y @!tfm_file : packed file of -128..127; @!tmp : 0..255; @!tfm_name, @!pl_name : packed array[1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Open TFM file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ On some systems you may have to do something special to write a packed file of bytes. For example, the following code didn't work when it was first tried at Stanford, because packed files have to be opened with a special switch setting on the \PASCAL\ that was used. @^system dependencies@> @<Set init...@>= rewrite(tfm_file); @y @ On some systems you may have to do something special to write a packed file of bytes. @^system dependencies@> @<Set init...@>= argv(2, tfm_name); rewrite(tfm_file, tfm_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [119] Change TFM-byte output to fix ranges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d out(#)==write(tfm_file,#) @y @d out(#)==begin tmp := #; if tmp > 127 then write(tfm_file, tmp - 256) else write(tfm_file, tmp) end @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [134] Define label `final_end'; print newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > pltotf.PYR.ch % Change file for the PLtoTF processor, for use on Berkeley UNIX systems. % This file was created by Pavel Curtis, Pavel@Cornell. % History: % 4/4/83 (PC) Original version, made to work with version 1.2 of PLtoTF. % 4/16 (PC) Brought up to version 1.3 of PLtoTF. % 6/30 (HWT) Revised changefile format for version 1.7 Tangle % 7/28 (HWT) Brought up to version 2 % 11/21 (HWT) Brought up to version 2.1 % 3/86 (PAM) Cosmetic change to Version 2.3 % The section numbers used in this file refer to those in the red-covered % listing (Version 2) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{PL\lowercase{to}TF changes for Pyramid {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is PLtoTF, Version 2.3' {printed when the program starts} @y @d banner=='This is PLtoTF, Version 2.3 for Pyramid OSx' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Fix filenames in program statement; add `final_end' label %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program PLtoTF(@!pl_file,@!tfm_file,@!output); @y @d final_end==9999 @p program PLtoTF(@!output); label final_end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Open PL file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(pl_file); @y if argc < 3 then begin print_ln('Usage: pltotf <pl-file> <tfm-file>'); goto final_end; end; argv(1, pl_name); reset(pl_file, pl_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [15] Change type of tfm_file and declare extra TFM-file variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!tfm_file:packed file of 0..255; @y @!tfm_file : packed file of char; @!tfm_name, @!pl_name : packed array[1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Open TFM file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ On some systems you may have to do something special to write a packed file of bytes. For example, the following code didn't work when it was first tried at Stanford, because packed files have to be opened with a special switch setting on the \PASCAL\ that was used. @^system dependencies@> @<Set init...@>= rewrite(tfm_file); @y @ On some systems you may have to do something special to write a packed file of bytes. @^system dependencies@> @<Set init...@>= argv(2, tfm_name); rewrite(tfm_file, tfm_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [119] Change TFM-byte output to fix ranges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d out(#)==write(tfm_file,#) @y @d out(#)==write(tfm_file,chr(#)) @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [134] Define label `final_end'; print newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > pltotf.SYS_V.ch % Change file for the PLtoTF processor, for use on Berkeley UNIX systems. % This file was created by Pavel Curtis, Pavel@Cornell. % History: % 4/4/83 (PC) Original version, made to work with version 1.2 of PLtoTF. % 4/16 (PC) Brought up to version 1.3 of PLtoTF. % 6/30 (HWT) Revised changefile format for version 1.7 Tangle % 7/28 (HWT) Brought up to version 2 % 11/21 (HWT) Brought up to version 2.1 % 9/3/85 (RKF) Brought up to version 2.3 % 3/27/87 (LKS) Changes for System V UNIX % The section numbers used in this file refer to those in the red-covered % listing (Version 2) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{PL\lowercase{to}TF changes for System V {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is PLtoTF, Version 2.3' {printed when the program starts} @y @d banner=='This is PLtoTF, Version 2.3 for System V UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Fix filenames in program statement; add `final_end' label %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program PLtoTF(@!pl_file,@!tfm_file,@!output); @y @d final_end==9999 @p program PLtoTF(@!output); label final_end; @z @x var @<Globals in the outer block@>@/ @y var @<Globals in the outer block@>@/ @\ @=#include "pltotfext.h"@> @\@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Open PL file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(pl_file); @y if argc < 3 then begin print_ln('Usage: pltotf <pl-file> <tfm-file>'); goto final_end; end; argv(2, pl_name); reset(pl_file, pl_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [15] Change type of tfm_file and declare extra TFM-file variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!tfm_file:packed file of 0..255; @y @!tfm_file: bytefile; @!tfm_name, @!pl_name : packed array[1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Open TFM file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ On some systems you may have to do something special to write a packed file of bytes. For example, the following code didn't work when it was first tried at Stanford, because packed files have to be opened with a special switch setting on the \PASCAL\ that was used. @^system dependencies@> @<Set init...@>= rewrite(tfm_file); @y @ On some systems you may have to do something special to write a packed file of bytes. @^system dependencies@> @<Set init...@>= argv(3, tfm_name); rewrite(tfm_file, tfm_name); @z @x @!byte=0..255; {unsigned eight-bit quantity} @y @!byte=0..255; {unsigned eight-bit quantity} @!bytefile=packed file of char; @z @x @* The input phase. We're ready now to read and parse the \.{PL} file, storing property values as we go. @<Glob...@>= @!c:byte; {the current character or byte being processed} @y @* The input phase. We're ready now to read and parse the \.{PL} file, storing property values as we go. @<Glob...@>= @!c:byte; {the current character or byte being processed} @!c_idx:byte; {the current character or byte being processed} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [119] Change TFM-byte output to fix ranges %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d out(#)==write(tfm_file,#) @y @d out(#)==bytewrite(tfm_file,#) @z @x for c:=bc to ec do if char_wd[c]>0 then begin temp_width:=memory[char_wd[c]]; @y for c_idx:=bc to ec do if char_wd[c_idx]>0 then begin temp_width:=memory[char_wd[c_idx]]; @z @x for c:=bc to ec do begin out(index[char_wd[c]]); out(index[char_ht[c]]*16+index[char_dp[c]]); out(index[char_ic[c]]*4+char_tag[c]); out(char_remainder[c]); end @y for c_idx:=bc to ec do begin out(index[char_wd[c_idx]]); out(index[char_ht[c_idx]]*16+index[char_dp[c_idx]]); out(index[char_ic[c_idx]]*4+char_tag[c_idx]); out(char_remainder[c_idx]); end @z @x if ne>0 then for c:=0 to ne-1 do begin out(exten[c].b0); out(exten[c].b1); out(exten[c].b2); out(exten[c].b3); end; @y if ne>0 then for c_idx:=0 to ne-1 do begin out(exten[c_idx].b0); out(exten[c_idx].b1); out(exten[c_idx].b2); out(exten[c_idx].b3); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [134] Define label `final_end'; print newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > tangle.BSD4_n.ch % Change file for the TANGLE processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey and Pavel Curtis. % Subsequent small updates (to match Stanford releases) by % Richard Furuta and Pierre MacKay % History: % 10/9/82 (HT) Original version % 11/29 (HT) New version, with conversion to lowercase handled properly % Also, new control sequence: % @=...text...@> Put ...text... verbatim on a line % by itself in the Pascal output. % (argument must fit on one line) % This control sequence facilitates putting #include "gcons.h" % (for example) in files meant for the pc compiler. % Also, changed command line usage, so that the absence of a % change file implies no change file, rather than one with the % same name as the web file, with .ch at the end. % 1/15/83 (HT) Changed to work with version 1.2, which incorporates the % above change (though unbundling the output line breaking), % so mainly had to remove stuff. % 2/17 (HT) Fixed bug that caused 0-9 in identifiers to be converted to % Q-Y on output. % 3/18 (HT) Brought up to work with Version 1.5. Added -r command line % flag to cause a .rpl file to be written with all the lines % of the .web file that were replaced because of the .ch file % (useful for comparing with previous .rpl files, to see if a % change file will still work with a new version of a .web file) % Also, made it write a newline just before exit. % 4/12 (PC) Merged with Pavel's version, including adding a call to exit() % at the end depending upon the value of history. % 4/16 (PC) Brought up to date with version 1.5 released April, 1983. % 6/28 (HWT) Brought up to date with version 1.7 released June, 1983. % With new change file format, the -r option is now unnecessary. % 7/17 (HWT) Brought up to date with version 2.0 released July, 1983. % 11/17 (HWT) Made some I/O use external C procedures, for speedup. % 8/4/84 (RKF) To version 2.6 % 9/3/85 (RKF) To version 2.7 % 12/28/85(PAM) To version 2.8, and increase ww and zz so that METAFONT fits % NOTE: The module numbers refer to the red-covered listing (Version 2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print only changes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{TANGLE changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is TANGLE, Version 2.8' @y @d banner=='This is TANGLE, Version 2.8 for Berkeley UNIX' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] add input and output, remove other files, add ref to scan_args, % [2] and #include external definition for exit(), etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x program TANGLE(@!web_file,@!change_file,@!Pascal_file,@!pool); label end_of_TANGLE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @<Error handling procedures@>@/ @y program TANGLE(@!input,@!output); label end_of_TANGLE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\ @=#include "tangext.h"@> @\@/ @<Error handling procedures@>@/ @<Declaration of |scan_args|@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [4] compiler options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y @=(*$C-*)@> {no range check} @!debug @=(*$C+*)@>@+ gubed {but turn everything on when debugging} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Constants: increase id lengths %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!max_id_length=12; {long identifiers are chopped to this length, which must not exceed |line_length|} @!unambig_length=7; {identifiers must be unique if chopped to this length} {note that 7 is more strict than \PASCAL's 8, but this can be varied} @y @!max_id_length=20; {long identifiers are chopped to this length, which must not exceed |line_length|} @!unambig_length=20; {identifiers must be unique if chopped to this length} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] terminal output: use standard i/o %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @y @d term_out==output @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @z @x @<Globals...@>= @!term_out:text_file; {the terminal as an output file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] init terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. Here is one way to do this on the \PASCAL\ system that was used in \.{TANGLE}'s initial development: @^system dependencies@> @<Set init...@>= rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. @^system dependencies@> @<Set init...@>= {Nothing need be done on Berkeley UNIX} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [22] flush terminal buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] open input files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens the input files. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has already checked that suitable file names have been given; therefore no additional error checking needs to be done. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file); reset(change_file); end; @y @ The following code opens the input files. This happens after the initialize procedure has executed. That will have called the |scan_args| procedure to set up the global variables |web_file_name| and |change_file_name| to the appropriate file names. These globals, and the |scan_args| procedure will be defined at the end where they won't disturb the module numbering. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file,web_file_name); reset(change_file,change_file_name); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] open output files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens |Pascal_file| and |pool|. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has checked that suitable external file names have been given. @^system dependencies@> @<Set init...@>= rewrite(Pascal_file); rewrite(pool); @y @ The following code opens |Pascal_file| and |pool|. Use the |scan_args| procedure to fill the global file names, according to the names given on the command line. @^system dependencies@> @<Set init...@>= scan_args; rewrite(Pascal_file,Pascal_file_name); rewrite(pool,pool_file_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] faster input_ln %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} begin limit:=0; final_limit:=0; if eof(f) then input_ln:=false else begin while not eoln(f) do begin buffer[limit]:=xord[f^]; get(f); incr(limit); if buffer[limit-1]<>" " then final_limit:=limit; if limit=buf_size then begin while not eoln(f) do get(f); decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; end; read_ln(f); limit:=final_limit; input_ln:=true; end; end; @y With Berkeley {\mc UNIX} we call an external C procedure, |line_read|. That routine fills |buffer| from 0 onwards with the |xord|'ed values of the next line, setting |limit| appropriately (ignoring trailing blanks). It will stop if |limit=buf_size|, and the following will cause an error message. Note: for bootstrapping purposes it is all right to use the original form of |input_ln|; it will just run slower. @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} begin limit:=0; if test_eof(f) then input_ln:=false else begin line_read(f); if limit=buf_size then begin decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; input_ln:=true; end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [38] Data Structures: provide for larger |byte_mem| and |tok_mem| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x Extra capacity: @d ww=2 {we multiply the byte capacity by approximately this amount} @d zz=3 {we multiply the token capacity by approximately this amount} @y @d ww=3 {we multiply the byte capacity by approximately this amount} @d zz=4 {we multiply the token capacity by approximately this amount} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [63] Remove conversion to uppercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin if c>="a" then c:=c-@'40; {convert to uppercase} @^uppercase@> @y begin @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [96] faster flush_buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d check_break==if out_ptr>line_length then flush_buffer @p procedure flush_buffer; {writes one line to output file} var k:0..out_buf_size; {index into |out_buf|} @!b:0..out_buf_size; {value of |break_ptr| upon entry} begin b:=break_ptr; if (semi_ptr<>0)and(out_ptr-semi_ptr<=line_length) then break_ptr:=semi_ptr; for k:=1 to break_ptr do write(Pascal_file,xchr[out_buf[k-1]]); @y For Berkeley {\mc UNIX} we use an external C procedure, |line_write|, to write the |xchr|'d version of characters to a file. This improves the speed significantly. @d check_break==if out_ptr>line_length then flush_buffer @p procedure flush_buffer; {writes one line to output file} var k:0..out_buf_size; {index into |out_buf|} @!b:0..out_buf_size; {value of |break_ptr| upon entry} begin b:=break_ptr; if (semi_ptr<>0)and(out_ptr-semi_ptr<=line_length) then break_ptr:=semi_ptr; line_write(Pascal_file,break_ptr); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [105] Accept DIV, div, MOD, and mod %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@| ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) ))or@| @^uppercase@> @y (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@| ((out_contrib[1]="d")and(out_contrib[2]="i")and(out_contrib[3]="v")) or@| ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) or@| ((out_contrib[1]="m")and(out_contrib[2]="o")and(out_contrib[3]="d")) ))or@| @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [110] lowercase ids %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @^uppercase@> if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and (out_buf[out_ptr-1]="V"))or @/ ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and (out_buf[out_ptr-1]="D")) then@/ goto bad_case @y if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and (out_buf[out_ptr-1]="V"))or @/ ((out_buf[out_ptr-3]="d")and(out_buf[out_ptr-2]="i")and (out_buf[out_ptr-1]="v"))or @/ ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and (out_buf[out_ptr-1]="D"))or @/ ((out_buf[out_ptr-3]="m")and(out_buf[out_ptr-2]="o")and (out_buf[out_ptr-1]="d")) then@/ goto bad_case @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [114] lowercase operators (`and', `or', etc.) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x and_sign: begin out_contrib[1]:="A"; out_contrib[2]:="N"; out_contrib[3]:="D"; @^uppercase@> send_out(ident,3); end; not_sign: begin out_contrib[1]:="N"; out_contrib[2]:="O"; out_contrib[3]:="T"; send_out(ident,3); end; set_element_sign: begin out_contrib[1]:="I"; out_contrib[2]:="N"; send_out(ident,2); end; or_sign: begin out_contrib[1]:="O"; out_contrib[2]:="R"; send_out(ident,2); @y and_sign: begin out_contrib[1]:="a"; out_contrib[2]:="n"; out_contrib[3]:="d"; send_out(ident,3); end; not_sign: begin out_contrib[1]:="n"; out_contrib[2]:="o"; out_contrib[3]:="t"; send_out(ident,3); end; set_element_sign: begin out_contrib[1]:="i"; out_contrib[2]:="n"; send_out(ident,2); end; or_sign: begin out_contrib[1]:="o"; out_contrib[2]:="r"; send_out(ident,2); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [116] Remove conversion to uppercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Single-character identifiers represent themselves, while longer ones appear in |byte_mem|. All must be converted to uppercase, with underlines removed. Extremely long identifiers must be chopped. (Some \PASCAL\ compilers work with lowercase letters instead of uppercase. If this module of \.{TANGLE} is changed, it's also necessary to change from uppercase to lowercase in the modules that are listed in the index under ``uppercase''.) @^system dependencies@> @^uppercase@> @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14, #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,# @<Cases related to identifiers@>= "A",up_to("Z"): begin out_contrib[1]:=cur_char; send_out(ident,1); end; "a",up_to("z"): begin out_contrib[1]:=cur_char-@'40; send_out(ident,1); end; identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); if out_contrib[k]>="a" then out_contrib[k]:=out_contrib[k]-@'40 else if out_contrib[k]="_" then decr(k); end; send_out(ident,k); end; @y @ Single-character identifiers represent themselves, while longer ones appear in |byte_mem|. All must be converted to lowercase, with underlines removed. Extremely long identifiers must be chopped. @^system dependencies@> @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14, #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,# @<Cases related to identifiers@>= "A",up_to("Z"), "a",up_to("z"): begin out_contrib[1]:=cur_char; send_out(ident,1); end; identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); if out_contrib[k]="_" then decr(k); end; send_out(ident,k); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [179] make term_in = input %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x any error stop will set |debug_cycle| to zero. @y any error stop will set |debug_cycle| to zero. @d term_in==input @z @x @!term_in:text_file; {the user's terminal as an input file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [180] remove term_in reset %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [182] write newline just before exit; use value of |history| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where it ends. @^system dependencies@> @y We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where it ends. @^system dependencies@> @d UNIXexit==e@&x@&i@&t @z @x @<Print the job |history|@>; @y @<Print the job |history|@>; new_line; if (history <> spotless) and (history <> harmless_message) then UNIXexit(1) else UNIXexit(0); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [188] system dependent changes--the |scan_args| procedure. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make \.{TANGLE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @^system dependencies@> @y @* System-dependent changes. @^system dependencies@> @ The user calls \.{TANGLE} with arguments on the command line. These are either file names or flags (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 full names of those files, as UNIX knows them. There are no flags that affect \.{TANGLE} at the moment. @d max_file_name_length==60 @<Globals...@>= @!web_file_name,@!change_file_name,@!Pascal_file_name,@!pool_file_name: array[1..max_file_name_length] of char; @ The |scan_args| procedure looks at the command line arguments and sets the |file_name| variables accordingly. At least one file name must be present: the \.{WEB} file. It may have an extension, or it may omit it to get |'.web'| added. The \PASCAL\ output file name is formed by replacing the \.{WEB} file name extension by |'.p'|. Similarly, the pool file name is formed using a |'.pool'| extension. 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. @<Declaration of |scan_args|@>= procedure scan_args; var dot_pos,i,a: integer; {indices} c: char; @!fname: array[1..max_file_name_length-5] of char; {temporary argument holder} @!found_web,@!found_change: boolean; {|true| when those file names have been seen} begin found_web:=false; found_change:=false; for a:=1 to argc-1 do begin argv(a,fname); {put argument number |a| into |fname|} if fname[1]<>'-' then begin if not found_web then @<Get |web_file_name|, |Pascal_file_name|, and | pool_file_name| variables from |fname|@> else if not found_change then @<Get |change_file_name| from |fname|@> else @<Print usage error message and quit@>; end else @<Handle flag argument in |fname|@>; end; if not found_web then @<Print usage error message and quit@>; if not found_change then @<Set up null change file@>; end; @ Use all of |fname| for the |web_file_name| if there is a |'.'| in it, otherwise add |'.web'|. The other file names come from adding things after the dot. The |argv| procedure will not put more than |max_file_name_length-5| characters into |fname|, and this leaves enough room in the |file_name| variables to add the extensions. The end of a file name is marked with a |' '|, the convention assumed by the |reset| and |rewrite| procedures. @<Get |web_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin web_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; web_file_name[dot_pos]:='.'; web_file_name[dot_pos+1]:='w'; web_file_name[dot_pos+2]:='e'; web_file_name[dot_pos+3]:='b'; web_file_name[dot_pos+4]:=' '; end; for i:=1 to dot_pos do begin c:=web_file_name[i]; Pascal_file_name[i]:=c; pool_file_name[i]:=c; end; Pascal_file_name[dot_pos+1]:='p'; Pascal_file_name[dot_pos+2]:=' '; pool_file_name[dot_pos+1]:='p'; pool_file_name[dot_pos+2]:='o'; pool_file_name[dot_pos+3]:='o'; pool_file_name[dot_pos+4]:='l'; pool_file_name[dot_pos+5]:=' '; found_web:=true; end @ @<Get |change_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin change_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; change_file_name[dot_pos]:='.'; change_file_name[dot_pos+1]:='c'; change_file_name[dot_pos+2]:='h'; change_file_name[dot_pos+3]:=' '; end; found_change:=true; end @ @<Set up null...@>= begin change_file_name[1]:='/'; change_file_name[2]:='d'; change_file_name[3]:='e'; change_file_name[4]:='v'; change_file_name[5]:='/'; change_file_name[6]:='n'; change_file_name[7]:='u'; change_file_name[8]:='l'; change_file_name[9]:='l'; change_file_name[10]:=' '; end @ There are no flags currently used by \.{TANGLE}, but this module can be used as a hook to introduce flags. @<Handle flag...@>= begin @<Print usage error message and quit@>; end @ @<Print usage error message and quit@>= begin print_nl('! Usage: webfile[.web] [changefile[.ch]]'); error; jump_out; end @z SHAR_EOF cat << \SHAR_EOF > tangle.PYR.ch % Change file for the TANGLE processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey and Pavel Curtis. % History: % 10/9/82 (HT) Original version % 11/29 (HT) New version, with conversion to lowercase handled properly % Also, new control sequence: % @=...text...@> Put ...text... verbatim on a line % by itself in the Pascal output. % (argument must fit on one line) % This control sequence facilitates putting #include "gcons.h" % (for example) in files meant for the pc compiler. % Also, changed command line usage, so that the absence of a % change file implies no change file, rather than one with the % same name as the web file, with .ch at the end. % 1/15/83 (HT) Changed to work with version 1.2, which incorporates the % above change (though unbundling the output line breaking), % so mainly had to remove stuff. % 2/17 (HT) Fixed bug that caused 0-9 in identifiers to be converted to % Q-Y on output. % 3/18 (HT) Brought up to work with Version 1.5. Added -r command line % flag to cause a .rpl file to be written with all the lines % of the .web file that were replaced because of the .ch file % (useful for comparing with previous .rpl files, to see if a % change file will still work with a new version of a .web file) % Also, made it write a newline just before exit. % 4/12 (PC) Merged with Pavel's version, including adding a call to exit() % at the end depending upon the value of history. % 4/16 (PC) Brought up to date with version 1.5 released April, 1983. % 6/28 (HWT) Brought up to date with version 1.7 released June, 1983. % With new change file format, the -r option is now unnecessary. % 7/17 (HWT) Brought up to date with version 2.0 released July, 1983. % 11/17 (HWT) Made some I/O use external C procedures, for speedup. % 8/4/84 (RKF) To version 2.6 % 7/85 (Mike Urban) Cosmetic change for pyramid % 3/86 (P. MacKay) similar cosmetic change for version 2.8 (larger arrays) % NOTE: The module numbers refer to the red-covered listing (Version 2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print only changes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{TANGLE changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is TANGLE, Version 2.8' @y @d banner=='This is TANGLE, Version 2.8 for Pyramid OSx' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] add input and output, remove other files, add ref to scan_args, % [2] and #include external definition for exit(), etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x program TANGLE(@!web_file,@!change_file,@!Pascal_file,@!pool); label end_of_TANGLE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @<Error handling procedures@>@/ @y program TANGLE(@!input,@!output); label end_of_TANGLE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\ @=#include "tangext.h"@> @\@/ @<Error handling procedures@>@/ @<Declaration of |scan_args|@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [4] compiler options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y @=(*$C-*)@> {no range check} @!debug @=(*$C+*)@>@+ gubed {but turn everything on when debugging} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [7] Pyramid groks "otherwise:" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d othercases == others: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @f othercases == else @f endcases == end @y @d othercases == otherwise: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @f othercases == else @f endcases == end @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Constants: increase id lengths %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!max_id_length=12; {long identifiers are chopped to this length, which must not exceed |line_length|} @!unambig_length=7; {identifiers must be unique if chopped to this length} {note that 7 is more strict than \PASCAL's 8, but this can be varied} @y @!max_id_length=20; {long identifiers are chopped to this length, which must not exceed |line_length|} @!unambig_length=20; {identifiers must be unique if chopped to this length} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [12] use text as the type for text_file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!text_file=packed file of text_char; @y @!text_file=text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] terminal output: use standard i/o %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @y @d term_out==output @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @z @x @<Globals...@>= @!term_out:text_file; {the terminal as an output file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] init terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. Here is one way to do this on the \PASCAL\ system that was used in \.{TANGLE}'s initial development: @^system dependencies@> @<Set init...@>= rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. @^system dependencies@> @<Set init...@>= {Nothing need be done on Berkeley UNIX} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [22] flush terminal buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [23] input file types %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Globals...@>= @!web_file:text_file; {primary input} @!change_file:text_file; {updates} @y @<Globals...@>= @!web_file:text; {primary input} @!change_file:text; {updates} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] open input files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens the input files. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has already checked that suitable file names have been given; therefore no additional error checking needs to be done. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file); reset(change_file); end; @y @ The following code opens the input files. This happens after the initialize procedure has executed. That will have called the |scan_args| procedure to set up the global variables |web_file_name| and |change_file_name| to the appropriate file names. These globals, and the |scan_args| procedure will be defined at the end where they won't disturb the module numbering. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file,web_file_name); reset(change_file,change_file_name); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] open output files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens |Pascal_file| and |pool|. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has checked that suitable external file names have been given. @^system dependencies@> @<Set init...@>= rewrite(Pascal_file); rewrite(pool); @y @ The following code opens |Pascal_file| and |pool|. Use the |scan_args| procedure to fill the global file names, according to the names given on the command line. @^system dependencies@> @<Set init...@>= scan_args; rewrite(Pascal_file,Pascal_file_name); rewrite(pool,pool_file_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] input_ln wants a "text" argument now. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} @y @p function input_ln(var f:text):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [63] Remove conversion to uppercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin if c>="a" then c:=c-@'40; {convert to uppercase} @^uppercase@> @y begin @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [105] Accept DIV, div, MOD, and mod %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@| ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) ))or@| @^uppercase@> @y (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@| ((out_contrib[1]="d")and(out_contrib[2]="i")and(out_contrib[3]="v")) or@| ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) or@| ((out_contrib[1]="m")and(out_contrib[2]="o")and(out_contrib[3]="d")) ))or@| @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [110] lowercase ids %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @^uppercase@> if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and (out_buf[out_ptr-1]="V"))or @/ ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and (out_buf[out_ptr-1]="D")) then@/ goto bad_case @y if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and (out_buf[out_ptr-1]="V"))or @/ ((out_buf[out_ptr-3]="d")and(out_buf[out_ptr-2]="i")and (out_buf[out_ptr-1]="v"))or @/ ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and (out_buf[out_ptr-1]="D"))or @/ ((out_buf[out_ptr-3]="m")and(out_buf[out_ptr-2]="o")and (out_buf[out_ptr-1]="d")) then@/ goto bad_case @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [114] lowercase operators (`and', `or', etc.) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x and_sign: begin out_contrib[1]:="A"; out_contrib[2]:="N"; out_contrib[3]:="D"; @^uppercase@> send_out(ident,3); end; not_sign: begin out_contrib[1]:="N"; out_contrib[2]:="O"; out_contrib[3]:="T"; send_out(ident,3); end; set_element_sign: begin out_contrib[1]:="I"; out_contrib[2]:="N"; send_out(ident,2); end; or_sign: begin out_contrib[1]:="O"; out_contrib[2]:="R"; send_out(ident,2); @y and_sign: begin out_contrib[1]:="a"; out_contrib[2]:="n"; out_contrib[3]:="d"; send_out(ident,3); end; not_sign: begin out_contrib[1]:="n"; out_contrib[2]:="o"; out_contrib[3]:="t"; send_out(ident,3); end; set_element_sign: begin out_contrib[1]:="i"; out_contrib[2]:="n"; send_out(ident,2); end; or_sign: begin out_contrib[1]:="o"; out_contrib[2]:="r"; send_out(ident,2); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [116] Remove conversion to uppercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Single-character identifiers represent themselves, while longer ones appear in |byte_mem|. All must be converted to uppercase, with underlines removed. Extremely long identifiers must be chopped. (Some \PASCAL\ compilers work with lowercase letters instead of uppercase. If this module of \.{TANGLE} is changed, it's also necessary to change from uppercase to lowercase in the modules that are listed in the index under ``uppercase''.) @^system dependencies@> @^uppercase@> @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14, #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,# @<Cases related to identifiers@>= "A",up_to("Z"): begin out_contrib[1]:=cur_char; send_out(ident,1); end; "a",up_to("z"): begin out_contrib[1]:=cur_char-@'40; send_out(ident,1); end; identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); if out_contrib[k]>="a" then out_contrib[k]:=out_contrib[k]-@'40 else if out_contrib[k]="_" then decr(k); end; send_out(ident,k); end; @y @ Single-character identifiers represent themselves, while longer ones appear in |byte_mem|. All must be converted to lowercase, with underlines removed. Extremely long identifiers must be chopped. @^system dependencies@> @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14, #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,# @<Cases related to identifiers@>= "A",up_to("Z"), "a",up_to("z"): begin out_contrib[1]:=cur_char; send_out(ident,1); end; identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); if out_contrib[k]="_" then decr(k); end; send_out(ident,k); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [179] make term_in = input %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x any error stop will set |debug_cycle| to zero. @y any error stop will set |debug_cycle| to zero. @d term_in==input @z @x @!term_in:text_file; {the user's terminal as an input file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [180] remove term_in reset %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [182] write newline just before exit; use value of |history| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where it ends. @^system dependencies@> @y We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where it ends. @^system dependencies@> @d UNIXexit==e@&x@&i@&t @z @x @<Print the job |history|@>; @y @<Print the job |history|@>; new_line; if (history <> spotless) and (history <> harmless_message) then UNIXexit(1) else UNIXexit(0); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [188] system dependent changes--the |scan_args| procedure. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make \.{TANGLE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @^system dependencies@> @y @* System-dependent changes. @^system dependencies@> @ The user calls \.{TANGLE} with arguments on the command line. These are either file names or flags (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 full names of those files, as UNIX knows them. There are no flags that affect \.{TANGLE} at the moment. @d max_file_name_length==60 @<Globals...@>= @!web_file_name,@!change_file_name,@!Pascal_file_name,@!pool_file_name: array[1..max_file_name_length] of char; @ The |scan_args| procedure looks at the command line arguments and sets the |file_name| variables accordingly. At least one file name must be present: the \.{WEB} file. It may have an extension, or it may omit it to get |'.web'| added. The \PASCAL\ output file name is formed by replacing the \.{WEB} file name extension by |'.p'|. Similarly, the pool file name is formed using a |'.pool'| extension. 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. @<Declaration of |scan_args|@>= procedure scan_args; var dot_pos,i,a: integer; {indices} c: char; @!fname: array[1..max_file_name_length-5] of char; {temporary argument holder} @!found_web,@!found_change: boolean; {|true| when those file names have been seen} begin found_web:=false; found_change:=false; for a:=1 to argc-1 do begin argv(a,fname); {put argument number |a| into |fname|} if fname[1]<>'-' then begin if not found_web then @<Get |web_file_name|, |Pascal_file_name|, and | pool_file_name| variables from |fname|@> else if not found_change then @<Get |change_file_name| from |fname|@> else @<Print usage error message and quit@>; end else @<Handle flag argument in |fname|@>; end; if not found_web then @<Print usage error message and quit@>; if not found_change then @<Set up null change file@>; end; @ Use all of |fname| for the |web_file_name| if there is a |'.'| in it, otherwise add |'.web'|. The other file names come from adding things after the dot. The |argv| procedure will not put more than |max_file_name_length-5| characters into |fname|, and this leaves enough room in the |file_name| variables to add the extensions. The end of a file name is marked with a |' '|, the convention assumed by the |reset| and |rewrite| procedures. @<Get |web_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin web_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; web_file_name[dot_pos]:='.'; web_file_name[dot_pos+1]:='w'; web_file_name[dot_pos+2]:='e'; web_file_name[dot_pos+3]:='b'; web_file_name[dot_pos+4]:=' '; end; for i:=1 to dot_pos do begin c:=web_file_name[i]; Pascal_file_name[i]:=c; pool_file_name[i]:=c; end; Pascal_file_name[dot_pos+1]:='p'; Pascal_file_name[dot_pos+2]:=' '; pool_file_name[dot_pos+1]:='p'; pool_file_name[dot_pos+2]:='o'; pool_file_name[dot_pos+3]:='o'; pool_file_name[dot_pos+4]:='l'; pool_file_name[dot_pos+5]:=' '; found_web:=true; end @ @<Get |change_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin change_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; change_file_name[dot_pos]:='.'; change_file_name[dot_pos+1]:='c'; change_file_name[dot_pos+2]:='h'; change_file_name[dot_pos+3]:=' '; end; found_change:=true; end @ @<Set up null...@>= begin change_file_name[1]:='/'; change_file_name[2]:='d'; change_file_name[3]:='e'; change_file_name[4]:='v'; change_file_name[5]:='/'; change_file_name[6]:='n'; change_file_name[7]:='u'; change_file_name[8]:='l'; change_file_name[9]:='l'; change_file_name[10]:=' '; end @ There are no flags currently used by \.{TANGLE}, but this module can be used as a hook to introduce flags. @<Handle flag...@>= begin @<Print usage error message and quit@>; end @ @<Print usage error message and quit@>= begin print_nl('! Usage: webfile[.web] [changefile[.ch]]'); error; jump_out; end @z SHAR_EOF cat << \SHAR_EOF > tangle.SYS_V.ch % Change file for the TANGLE processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey and Pavel Curtis. % Subsequent small updates (to match Stanford releases) by % Richard Furuta and Pierre MacKay % History: % 10/9/82 (HT) Original version % 11/29 (HT) New version, with conversion to lowercase handled properly % Also, new control sequence: % @=...text...@> Put ...text... verbatim on a line % by itself in the Pascal output. % (argument must fit on one line) % This control sequence facilitates putting #include "gcons.h" % (for example) in files meant for the pc compiler. % Also, changed command line usage, so that the absence of a % change file implies no change file, rather than one with the % same name as the web file, with .ch at the end. % 1/15/83 (HT) Changed to work with version 1.2, which incorporates the % above change (though unbundling the output line breaking), % so mainly had to remove stuff. % 2/17 (HT) Fixed bug that caused 0-9 in identifiers to be converted to % Q-Y on output. % 3/18 (HT) Brought up to work with Version 1.5. Added -r command line % flag to cause a .rpl file to be written with all the lines % of the .web file that were replaced because of the .ch file % (useful for comparing with previous .rpl files, to see if a % change file will still work with a new version of a .web file) % Also, made it write a newline just before exit. % 4/12 (PC) Merged with Pavel's version, including adding a call to exit() % at the end depending upon the value of history. % 4/16 (PC) Brought up to date with version 1.5 released April, 1983. % 6/28 (HWT) Brought up to date with version 1.7 released June, 1983. % With new change file format, the -r option is now unnecessary. % 7/17 (HWT) Brought up to date with version 2.0 released July, 1983. % 11/17 (HWT) Made some I/O use external C procedures, for speedup. % 8/4/84 (RKF) To version 2.6 % 9/3/85 (RKF) To version 2.7 % 12/28/85(PAM) To version 2.8, and increase ww and zz so that METAFONT fits % 3/27/87 (LKS) Changes for System V UNIX % NOTE: The module numbers refer to the red-covered listing (Version 2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print only changes %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{TANGLE changes for System V {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is TANGLE, Version 2.8' @y @d banner=='This is TANGLE, Version 2.8 for System V UNIX' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] add input and output, remove other files, add ref to scan_args, % [2] and #include external definition for exit(), etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x program TANGLE(@!web_file,@!change_file,@!Pascal_file,@!pool); label end_of_TANGLE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @<Error handling procedures@>@/ @y program TANGLE(@!input,@!output); label end_of_TANGLE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\ @=#include "tangext.h"@> @\@/ @<Error handling procedures@>@/ @<Declaration of |scan_args|@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [4] compiler options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Constants: increase id lengths %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!max_id_length=12; {long identifiers are chopped to this length, which must not exceed |line_length|} @!unambig_length=7; {identifiers must be unique if chopped to this length} {note that 7 is more strict than \PASCAL's 8, but this can be varied} @y @!max_id_length=20; {long identifiers are chopped to this length, which must not exceed |line_length|} @!unambig_length=20; {identifiers must be unique if chopped to this length} @z % ANSII Standard Pascal: writeln only works on text files @x @!text_file=packed file of text_char; @y @!text_file=text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] terminal output: use standard i/o %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @y @d term_out==output @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @z @x @<Globals...@>= @!term_out:text_file; {the terminal as an output file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] init terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. Here is one way to do this on the \PASCAL\ system that was used in \.{TANGLE}'s initial development: @^system dependencies@> @<Set init...@>= rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. @^system dependencies@> @<Set init...@>= {Nothing need be done on System V UNIX} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [22] flush terminal buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] open input files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens the input files. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has already checked that suitable file names have been given; therefore no additional error checking needs to be done. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file); reset(change_file); end; @y @ The following code opens the input files. This happens after the initialize procedure has executed. That will have called the |scan_args| procedure to set up the global variables |web_file_name| and |change_file_name| to the appropriate file names. These globals, and the |scan_args| procedure will be defined at the end where they won't disturb the module numbering. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file,web_file_name); reset(change_file,change_file_name); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] open output files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens |Pascal_file| and |pool|. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has checked that suitable external file names have been given. @^system dependencies@> @<Set init...@>= rewrite(Pascal_file); rewrite(pool); @y @ The following code opens |Pascal_file| and |pool|. Use the |scan_args| procedure to fill the global file names, according to the names given on the command line. @^system dependencies@> @<Set init...@>= scan_args; rewrite(Pascal_file,Pascal_file_name); rewrite(pool,pool_file_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] faster input_ln %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} begin limit:=0; final_limit:=0; if eof(f) then input_ln:=false else begin while not eoln(f) do begin buffer[limit]:=xord[f^]; get(f); incr(limit); if buffer[limit-1]<>" " then final_limit:=limit; if limit=buf_size then begin while not eoln(f) do get(f); decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; end; read_ln(f); limit:=final_limit; input_ln:=true; end; end; @y With System V {\mc UNIX} we call an external C procedure, |line_read|. That routine fills |buffer| from 0 onwards with the |xord|'ed values of the next line, setting |limit| appropriately (ignoring trailing blanks). It will stop if |limit=buf_size|, and the following will cause an error message. Note: for bootstrapping purposes it is all right to use the original form of |input_ln|; it will just run slower. @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} begin limit:=0; if test_eof(f) then input_ln:=false else begin line_read(f); if limit=buf_size then begin decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; input_ln:=true; end; end; @z % eliminate non-local goto for benefit of optimizer @x procedure jump_out; begin goto end_of_TANGLE; end; @y procedure jump_out; begin if string_ptr>128 then @<Finish off the string pool file@>; stat @<Print statistics about memory usage@>;@+tats@;@/ @t\4\4@>{here files should be closed if the operating system requires it} @<Print the job |history|@>; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [38] Data Structures: provide for larger |byte_mem| and |tok_mem| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x Extra capacity: @d ww=2 {we multiply the byte capacity by approximately this amount} @d zz=3 {we multiply the token capacity by approximately this amount} @y @d ww=3 {we multiply the byte capacity by approximately this amount} @d zz=4 {we multiply the token capacity by approximately this amount} @z @x @!string_ptr:name_pointer; {next number to be given to a string of length |<>1|} @y @!string_ptr:name_pointer; {next number to be given to a string of length |<>1|} @!x_string_ptr:name_pointer; {next number to be given to a string of length |<>1|} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [63] Remove conversion to uppercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x begin if c>="a" then c:=c-@'40; {convert to uppercase} @^uppercase@> @y begin @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [96] faster flush_buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d check_break==if out_ptr>line_length then flush_buffer @p procedure flush_buffer; {writes one line to output file} var k:0..out_buf_size; {index into |out_buf|} @!b:0..out_buf_size; {value of |break_ptr| upon entry} begin b:=break_ptr; if (semi_ptr<>0)and(out_ptr-semi_ptr<=line_length) then break_ptr:=semi_ptr; for k:=1 to break_ptr do write(Pascal_file,xchr[out_buf[k-1]]); @y For System V {\mc UNIX} we use an external C procedure, |line_write|, to write the |xchr|'d version of characters to a file. This improves the speed significantly. @d check_break==if out_ptr>line_length then flush_buffer @p procedure flush_buffer; {writes one line to output file} var k:0..out_buf_size; {index into |out_buf|} @!b:0..out_buf_size; {value of |break_ptr| upon entry} begin b:=break_ptr; if (semi_ptr<>0)and(out_ptr-semi_ptr<=line_length) then break_ptr:=semi_ptr; line_write(Pascal_file,break_ptr); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [105] Accept DIV, div, MOD, and mod %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@| ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) ))or@| @^uppercase@> @y (((out_contrib[1]="D")and(out_contrib[2]="I")and(out_contrib[3]="V")) or@| ((out_contrib[1]="d")and(out_contrib[2]="i")and(out_contrib[3]="v")) or@| ((out_contrib[1]="M")and(out_contrib[2]="O")and(out_contrib[3]="D")) or@| ((out_contrib[1]="m")and(out_contrib[2]="o")and(out_contrib[3]="d")) ))or@| @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [110] lowercase ids %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @^uppercase@> if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and (out_buf[out_ptr-1]="V"))or @/ ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and (out_buf[out_ptr-1]="D")) then@/ goto bad_case @y if ((out_buf[out_ptr-3]="D")and(out_buf[out_ptr-2]="I")and (out_buf[out_ptr-1]="V"))or @/ ((out_buf[out_ptr-3]="d")and(out_buf[out_ptr-2]="i")and (out_buf[out_ptr-1]="v"))or @/ ((out_buf[out_ptr-3]="M")and(out_buf[out_ptr-2]="O")and (out_buf[out_ptr-1]="D"))or @/ ((out_buf[out_ptr-3]="m")and(out_buf[out_ptr-2]="o")and (out_buf[out_ptr-1]="d")) then@/ goto bad_case @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [114] lowercase operators (`and', `or', etc.) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x and_sign: begin out_contrib[1]:="A"; out_contrib[2]:="N"; out_contrib[3]:="D"; @^uppercase@> send_out(ident,3); end; not_sign: begin out_contrib[1]:="N"; out_contrib[2]:="O"; out_contrib[3]:="T"; send_out(ident,3); end; set_element_sign: begin out_contrib[1]:="I"; out_contrib[2]:="N"; send_out(ident,2); end; or_sign: begin out_contrib[1]:="O"; out_contrib[2]:="R"; send_out(ident,2); @y and_sign: begin out_contrib[1]:="a"; out_contrib[2]:="n"; out_contrib[3]:="d"; send_out(ident,3); end; not_sign: begin out_contrib[1]:="n"; out_contrib[2]:="o"; out_contrib[3]:="t"; send_out(ident,3); end; set_element_sign: begin out_contrib[1]:="i"; out_contrib[2]:="n"; send_out(ident,2); end; or_sign: begin out_contrib[1]:="o"; out_contrib[2]:="r"; send_out(ident,2); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [116] Remove conversion to uppercase %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Single-character identifiers represent themselves, while longer ones appear in |byte_mem|. All must be converted to uppercase, with underlines removed. Extremely long identifiers must be chopped. (Some \PASCAL\ compilers work with lowercase letters instead of uppercase. If this module of \.{TANGLE} is changed, it's also necessary to change from uppercase to lowercase in the modules that are listed in the index under ``uppercase''.) @^system dependencies@> @^uppercase@> @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14, #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,# @<Cases related to identifiers@>= "A",up_to("Z"): begin out_contrib[1]:=cur_char; send_out(ident,1); end; "a",up_to("z"): begin out_contrib[1]:=cur_char-@'40; send_out(ident,1); end; identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); if out_contrib[k]>="a" then out_contrib[k]:=out_contrib[k]-@'40 else if out_contrib[k]="_" then decr(k); end; send_out(ident,k); end; @y @ Single-character identifiers represent themselves, while longer ones appear in |byte_mem|. All must be converted to lowercase, with underlines removed. Extremely long identifiers must be chopped. @^system dependencies@> @d up_to(#)==#-24,#-23,#-22,#-21,#-20,#-19,#-18,#-17,#-16,#-15,#-14, #-13,#-12,#-11,#-10,#-9,#-8,#-7,#-6,#-5,#-4,#-3,#-2,#-1,# @<Cases related to identifiers@>= "A",up_to("Z"), "a",up_to("z"): begin out_contrib[1]:=cur_char; send_out(ident,1); end; identifier: begin k:=0; j:=byte_start[cur_val]; w:=cur_val mod ww; while (k<max_id_length)and(j<byte_start[cur_val+ww]) do begin incr(k); out_contrib[k]:=byte_mem[w,j]; incr(j); if out_contrib[k]="_" then decr(k); end; send_out(ident,k); end; @z % change loop arrays for ANSII Standard Pascal @x @!loc:0..buf_size; {the next character position to be read from the buffer} @y @!loc:0..buf_size; {the next character position to be read from the buffer} @!x_loc:0..buf_size; {the next character position to be read from the buffer} @z @x begin for loc:=0 to change_limit do buffer[loc]:=change_buffer[loc]; @y begin for x_loc:=0 to change_limit do buffer[x_loc]:=change_buffer[x_loc]; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [179] make term_in = input %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x any error stop will set |debug_cycle| to zero. @y any error stop will set |debug_cycle| to zero. @d term_in==input @z @x @!term_in:text_file; {the user's terminal as an input file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [180] remove term_in reset %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [182] write newline just before exit; use value of |history| %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where it ends. @^system dependencies@> @y We have defined plenty of procedures, and it is time to put the last pieces of the puzzle in place. Here is where \.{TANGLE} starts, and where it ends. @^system dependencies@> @d UNIXexit==e@&x@&i@&t @z @x @<Print the job |history|@>; @y @<Print the job |history|@>; new_line; if (history <> spotless) and (history <> harmless_message) then UNIXexit(1) else UNIXexit(0); @z % Change loop arrays for ANSII Standard Pascal @x for string_ptr:=1 to 9 do begin out_buf[string_ptr]:=pool_check_sum mod 10; pool_check_sum:=pool_check_sum div 10; end; for string_ptr:=9 downto 1 do write(pool,xchr["0"+out_buf[string_ptr]]); @y for x_string_ptr:=1 to 9 do begin out_buf[x_string_ptr]:=pool_check_sum mod 10; pool_check_sum:=pool_check_sum div 10; end; for x_string_ptr:=9 downto 1 do write(pool,xchr["0"+out_buf[x_string_ptr]]); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [188] system dependent changes--the |scan_args| procedure. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make \.{TANGLE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @^system dependencies@> @y @* System-dependent changes. @^system dependencies@> @ The user calls \.{TANGLE} with arguments on the command line. These are either file names or flags (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 full names of those files, as UNIX knows them. There are no flags that affect \.{TANGLE} at the moment. @d max_file_name_length==60 @<Globals...@>= @!web_file_name,@!change_file_name,@!Pascal_file_name,@!pool_file_name: packed array[1..max_file_name_length] of char; @ The |scan_args| procedure looks at the command line arguments and sets the |file_name| variables accordingly. At least one file name must be present: the \.{WEB} file. It may have an extension, or it may omit it to get |'.web'| added. The \PASCAL\ output file name is formed by replacing the \.{WEB} file name extension by |'.p'|. Similarly, the pool file name is formed using a |'.pool'| extension. 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. @<Declaration of |scan_args|@>= procedure scan_args; var dot_pos,i,a: integer; {indices} c: char; @!fname: packed array[1..max_file_name_length-5] of char; {temporary argument holder} @!found_web,@!found_change: boolean; {|true| when those file names have been seen} begin found_web:=false; found_change:=false; for a:=2 to argc do begin argv(a,fname); {put argument number |a| into |fname|} if fname[1]<>'-' then begin if not found_web then @<Get |web_file_name|, |Pascal_file_name|, and | pool_file_name| variables from |fname|@> else if not found_change then @<Get |change_file_name| from |fname|@> else @<Print usage error message and quit@>; end else @<Handle flag argument in |fname|@>; end; if not found_web then @<Print usage error message and quit@>; if not found_change then @<Set up null change file@>; end; @ Use all of |fname| for the |web_file_name| if there is a |'.'| in it, otherwise add |'.web'|. The other file names come from adding things after the dot. The |argv| procedure will not put more than |max_file_name_length-5| characters into |fname|, and this leaves enough room in the |file_name| variables to add the extensions. The end of a file name is marked with a |' '|, the convention assumed by the |reset| and |rewrite| procedures. @<Get |web_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin web_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; web_file_name[dot_pos]:='.'; web_file_name[dot_pos+1]:='w'; web_file_name[dot_pos+2]:='e'; web_file_name[dot_pos+3]:='b'; web_file_name[dot_pos+4]:=' '; end; for i:=1 to dot_pos do begin c:=web_file_name[i]; Pascal_file_name[i]:=c; pool_file_name[i]:=c; end; Pascal_file_name[dot_pos+1]:='p'; Pascal_file_name[dot_pos+2]:=' '; pool_file_name[dot_pos+1]:='p'; pool_file_name[dot_pos+2]:='o'; pool_file_name[dot_pos+3]:='o'; pool_file_name[dot_pos+4]:='l'; pool_file_name[dot_pos+5]:=' '; found_web:=true; end @ @<Get |change_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin change_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; change_file_name[dot_pos]:='.'; change_file_name[dot_pos+1]:='c'; change_file_name[dot_pos+2]:='h'; change_file_name[dot_pos+3]:=' '; end; found_change:=true; end @ @<Set up null...@>= begin change_file_name[1]:='/'; change_file_name[2]:='d'; change_file_name[3]:='e'; change_file_name[4]:='v'; change_file_name[5]:='/'; change_file_name[6]:='n'; change_file_name[7]:='u'; change_file_name[8]:='l'; change_file_name[9]:='l'; change_file_name[10]:=' '; end @ There are no flags currently used by \.{TANGLE}, but this module can be used as a hook to introduce flags. @<Handle flag...@>= begin @<Print usage error message and quit@>; end @ @<Print usage error message and quit@>= begin print_nl('! Usage: webfile[.web] [changefile[.ch]]'); error; jump_out; end @z SHAR_EOF cat << \SHAR_EOF > tftopl.BSD4_n.ch % Change file for the TFtoPL processor, for use on Berkeley UNIX systems. % This file was created by Pavel Curtis, Pavel@Cornell. % History: % 4/4/83 (PC) Original version, made to work with version 1.0 of TFtoPL, % released with version 0.96 of TeX in February, 1983. % 4/16 (PC) Brought up to version 1.0 released with version 0.97 of TeX % in April, 1983. % 6/30 (HWT) Revised changefile format, for use with version 1.7 Tangle. % 7/28 (HWT) Brought up to version 2 % 11/21 (HWT) Brought up to version 2.1 % 3/24/84 (HWT) Brought up to version 2.2 % 7/12/84 (HWT) Brought up to version 2.3 % 9/3/85 (RKF) Brought up to version 2.4 % 3/1/86 (PAM) Cosmetic upgrade to Version 2.5 % The section numbers used in this file refer to those in the red-covered % listing (Version 2, July 1983) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{TF\lowercase{to}PL changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is TFtoPL, Version 2.5' {printed when the program starts} @y @d banner=='This is TFtoPL, Version 2.5 for Berkeley UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Fix files in program statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program TFtoPL(@!tfm_file,@!pl_file,@!output); @y @p program TFtoPL(@!output); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Fix declaration of tfm_file; declare extra TFM-file variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!tfm_file:packed file of 0..255; @y @!tfm_file:packed file of -128..127; {files that contain binary data} @!tfm_name:packed array [1..100] of char; @!tfm_byte:integer; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [7] Open TFM file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ On some systems you may have to do something special to read a packed file of bytes. For example, the following code didn't work when it was first tried at Stanford, because packed files have to be opened with a special switch setting on the \PASCAL\ that was used. @^system dependencies@> @<Set init...@>= reset(tfm_file); @y @ On some systems you may have to do something special to read a packed file of bytes. @<Set init...@>= if argc < 3 then begin print_ln('Usage: tftopl <tfm-file> <pl-file>'); goto final_end; end; argv(1, tfm_name); reset(tfm_file, tfm_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Declare pl_name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!pl_file:text; @y @!pl_file:text; @!pl_name: array[1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [17] Open PL file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ @<Set init...@>= rewrite(pl_file); @y @ @<Set init...@>= argv(2, pl_name); rewrite(pl_file, pl_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] Fix reading of TFM bytes. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Read the whole input file@>= read(tfm_file,tfm[0]); if tfm[0]>127 then abort('The first byte of the input file exceeds 127!'); @.The first byte...@> if eof(tfm_file) then abort('The input file is only one byte long!'); @.The input...one byte long@> read(tfm_file,tfm[1]); lf:=tfm[0]*@'400+tfm[1]; if lf=0 then abort('The file claims to have length zero, but that''s impossible!'); @.The file claims...@> if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!'); @.The file is bigger...@> for tfm_ptr:=2 to 4*lf-1 do begin if eof(tfm_file) then abort('The file has fewer bytes than it claims!'); @.The file has fewer bytes...@> read(tfm_file,tfm[tfm_ptr]); end; if not eof(tfm_file) then begin print_ln('There''s some extra junk at the end of the TFM file,'); @.There's some extra junk...@> print_ln('but I''ll proceed as if it weren''t there.'); end @y @d fget==begin get(tfm_file); tfm_byte:=tfm_file^; if tfm_byte<0 then tfm_byte:=tfm_byte+256; end @d fbyte==tfm_byte @d read_sixteen(#)==begin #:=fbyte; if #>127 then abort; fget; #:=#*@'400+fbyte; end @d store_four_quarters(#)==begin fget; a:=fbyte; qw.b0:=qi(a); fget; b:=fbyte; qw.b1:=qi(b); fget; c:=fbyte; qw.b2:=qi(c); fget; d:=fbyte; qw.b3:=qi(d); #:=qw; end @<Read the whole input file@>= {Prime the pump} tfm_byte:=tfm_file^; if tfm_byte<0 then tfm_byte:=tfm_byte+256; tfm[0]:=fbyte; fget; if tfm[0]>127 then abort('The first byte of the input file exceeds 127!'); @.The first byte...@> if eof(tfm_file) then abort('The input file is only one byte long!'); @.The input...one byte long@> tfm[1]:=fbyte; fget; lf:=tfm[0]*@'400+tfm[1]; if lf=0 then abort('The file claims to have length zero, but that''s impossible!'); @.The file claims...@> if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!'); @.The file is bigger...@> for tfm_ptr:=2 to 4*lf-1 do begin if eof(tfm_file) then abort('The file has fewer bytes than it claims!'); @.The file has fewer bytes...@> tfm[tfm_ptr]:=fbyte; fget; end; if not eof(tfm_file) then begin print_ln('There''s some extra junk at the end of the TFM file,'); @.There's some extra junk...@> print_ln('but I''ll proceed as if it weren''t there.'); end @^system dependencies@>@^Changes for Berkeley {\mc UNIX}@> @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [88] Add printing of newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x final_end:end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > tftopl.PYR.ch % Change file for the TFtoPL processor, for use on Berkeley UNIX systems. % This file was created by Pavel Curtis, Pavel@Cornell. % History: % 4/4/83 (PC) Original version, made to work with version 1.0 of TFtoPL, % released with version 0.96 of TeX in February, 1983. % 4/16 (PC) Brought up to version 1.0 released with version 0.97 of TeX % in April, 1983. % 6/30 (HWT) Revised changefile format, for use with version 1.7 Tangle. % 7/28 (HWT) Brought up to version 2 % 11/21 (HWT) Brought up to version 2.1 % 3/24/84 (HWT) Brought up to version 2.2 % 7/12/84 (HWT) Brought up to version 2.3 % 3/1/86 (PAM) Cosmetic upgrade to Version 2.5 % The section numbers used in this file refer to those in the red-covered % listing (Version 2, July 1983) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{TF\lowercase{to}PL changes for Pyramid {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is TFtoPL, Version 2.5' {printed when the program starts} @y @d banner=='This is TFtoPL, Version 2.5 for Pyramid OSx' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Fix files in program statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program TFtoPL(@!tfm_file,@!pl_file,@!output); @y @p program TFtoPL(@!output); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Fix declaration of tfm_file; declare extra TFM-file variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!tfm_file:packed file of 0..255; @y @!tfm_file:packed file of char; {Only sort of packed bytes on Pyramid?} @!tfm_name:packed array [1..100] of char; @!tfm_byte:integer; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [7] Open TFM file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ On some systems you may have to do something special to read a packed file of bytes. For example, the following code didn't work when it was first tried at Stanford, because packed files have to be opened with a special switch setting on the \PASCAL\ that was used. @^system dependencies@> @<Set init...@>= reset(tfm_file); @y @ On some systems you may have to do something special to read a packed file of bytes. @<Set init...@>= if argc < 3 then begin print_ln('Usage: tftopl <tfm-file> <pl-file>'); goto final_end; end; argv(1, tfm_name); reset(tfm_file, tfm_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Declare pl_name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!pl_file:text; @y @!pl_file:text; @!pl_name: array[1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [17] Open PL file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ @<Set init...@>= rewrite(pl_file); @y @ @<Set init...@>= argv(2, pl_name); rewrite(pl_file, pl_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] Fix reading of TFM bytes. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Read the whole input file@>= read(tfm_file,tfm[0]); if tfm[0]>127 then abort('The first byte of the input file exceeds 127!'); @.The first byte...@> if eof(tfm_file) then abort('The input file is only one byte long!'); @.The input...one byte long@> read(tfm_file,tfm[1]); lf:=tfm[0]*@'400+tfm[1]; if lf=0 then abort('The file claims to have length zero, but that''s impossible!'); @.The file claims...@> if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!'); @.The file is bigger...@> for tfm_ptr:=2 to 4*lf-1 do begin if eof(tfm_file) then abort('The file has fewer bytes than it claims!'); @.The file has fewer bytes...@> read(tfm_file,tfm[tfm_ptr]); end; if not eof(tfm_file) then begin print_ln('There''s some extra junk at the end of the TFM file,'); @.There's some extra junk...@> print_ln('but I''ll proceed as if it weren''t there.'); end @y @d fget==begin get(tfm_file); tfm_byte:=ord(tfm_file^); end @d fbyte==tfm_byte @<Read the whole input file@>= {Prime the pump} tfm_byte:=ord(tfm_file^); tfm[0]:=fbyte; fget; if tfm[0]>127 then abort('The first byte of the input file exceeds 127!'); @.The first byte...@> if eof(tfm_file) then abort('The input file is only one byte long!'); @.The input...one byte long@> tfm[1]:=fbyte; fget; lf:=tfm[0]*@'400+tfm[1]; if lf=0 then abort('The file claims to have length zero, but that''s impossible!'); @.The file claims...@> if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!'); @.The file is bigger...@> for tfm_ptr:=2 to 4*lf-1 do begin if eof(tfm_file) then abort('The file has fewer bytes than it claims!'); @.The file has fewer bytes...@> tfm[tfm_ptr]:=fbyte; fget; end; if not eof(tfm_file) then begin print_ln('There''s some extra junk at the end of the TFM file,'); @.There's some extra junk...@> print_ln('but I''ll proceed as if it weren''t there.'); end @^system dependencies@>@^Changes for Pyramid {\mc UNIX}@> @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [88] Add printing of newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x final_end:end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > tftopl.SYS_V.ch % Change file for the TFtoPL processor, for use on Berkeley UNIX systems. % This file was created by Pavel Curtis, Pavel@Cornell. % History: % 4/4/83 (PC) Original version, made to work with version 1.0 of TFtoPL, % released with version 0.96 of TeX in February, 1983. % 4/16 (PC) Brought up to version 1.0 released with version 0.97 of TeX % in April, 1983. % 6/30 (HWT) Revised changefile format, for use with version 1.7 Tangle. % 7/28 (HWT) Brought up to version 2 % 11/21 (HWT) Brought up to version 2.1 % 3/24/84 (HWT) Brought up to version 2.2 % 7/12/84 (HWT) Brought up to version 2.3 % 9/3/85 (RKF) Brought up to version 2.4 % 3/1/86 (PAM) Cosmetic upgrade to Version 2.5 % 3/27/87 (LKS) Changes for System V UNIX % The section numbers used in this file refer to those in the red-covered % listing (Version 2, July 1983) (same numbers as in blue-covered). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{TF\lowercase{to}PL changes for System V {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner string %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is TFtoPL, Version 2.5' {printed when the program starts} @y @d banner=='This is TFtoPL, Version 2.5 for System V UNIX' {printed when the program starts} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] Fix files in program statement %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p program TFtoPL(@!tfm_file,@!pl_file,@!output); @y @p program TFtoPL(@!output); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [6] Fix declaration of tfm_file; declare extra TFM-file variables %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!tfm_file:packed file of 0..255; @y @!tfm_file:byte_file; {files that contain binary data} @!tfm_name:packed array [1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [7] Open TFM file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ On some systems you may have to do something special to read a packed file of bytes. For example, the following code didn't work when it was first tried at Stanford, because packed files have to be opened with a special switch setting on the \PASCAL\ that was used. @^system dependencies@> @<Set init...@>= reset(tfm_file); @y @ On some systems you may have to do something special to read a packed file of bytes. @<Set init...@>= if argc < 3 then begin print_ln('Usage: tftopl <tfm-file> <pl-file>'); goto final_end; end; argv(2, tfm_name); reset(tfm_file, tfm_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [16] Declare pl_name %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!pl_file:text; @y @!pl_file:text; @!pl_name: packed array[1..100] of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [17] Open PL file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ @<Set init...@>= rewrite(pl_file); @y @ @<Set init...@>= argv(3, pl_name); rewrite(pl_file, pl_name); @z @x @<Types...@>= @y @<Types...@>= @!byte_file=packed file of char; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] Fix reading of TFM bytes. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Read the whole input file@>= read(tfm_file,tfm[0]); if tfm[0]>127 then abort('The first byte of the input file exceeds 127!'); @.The first byte...@> if eof(tfm_file) then abort('The input file is only one byte long!'); @.The input...one byte long@> read(tfm_file,tfm[1]); lf:=tfm[0]*@'400+tfm[1]; if lf=0 then abort('The file claims to have length zero, but that''s impossible!'); @.The file claims...@> if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!'); @.The file is bigger...@> for tfm_ptr:=2 to 4*lf-1 do begin if eof(tfm_file) then abort('The file has fewer bytes than it claims!'); @.The file has fewer bytes...@> read(tfm_file,tfm[tfm_ptr]); end; if not eof(tfm_file) then begin print_ln('There''s some extra junk at the end of the TFM file,'); @.There's some extra junk...@> print_ln('but I''ll proceed as if it weren''t there.'); end @y @d fread(#)==begin #:=ord(tfm_file^); get(tfm_file) end @<Read the whole input file@>= fread(tfm[0]); if tfm[0]>127 then abort('The first byte of the input file exceeds 127!'); @.The first byte...@> if eof(tfm_file) then abort('The input file is only one byte long!'); @.The input...one byte long@> fread(tfm[1]); lf:=tfm[0]*@'400+tfm[1]; if lf=0 then abort('The file claims to have length zero, but that''s impossible!'); @.The file claims...@> if 4*lf-1>tfm_size then abort('The file is bigger than I can handle!'); @.The file is bigger...@> for tfm_ptr:=2 to 4*lf-1 do begin if eof(tfm_file) then abort('The file has fewer bytes than it claims!'); @.The file has fewer bytes...@> fread(tfm[tfm_ptr]); end; if not eof(tfm_file) then begin print_ln('There''s some extra junk at the end of the TFM file,'); @.There's some extra junk...@> print_ln('but I''ll proceed as if it weren''t there.'); end @^system dependencies@>@^Changes for System V {\mc UNIX}@> @z @x @!i:0..@'77777; {an index to words of a subfile} @!c,@!r:byte; {random characters} @y @!i,@!i_idx:0..@'77777; {an index to words of a subfile} @!c,@!r,@!r_idx:byte; {random characters} @z @x active:=false; sort_ptr:=1; for i:=0 to nl-1 do begin @<Output any labels for step $i$@>; @y active:=false; sort_ptr:=1; for i_idx:=0 to nl-1 do begin i:=i_idx; @<Output any labels for step $i$@>; @z @x if ne>0 then for c:=0 to ne-1 do for r:=0 to 3 do begin k:=4*(exten_base+c)+r; if (tfm[k]>0)or(r=3) then @y if ne>0 then for c:=0 to ne-1 do for r_idx:=0 to 3 do begin k:=4*(exten_base+c)+r_idx; if (tfm[k]>0)or(r_idx=3) then @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [88] Add printing of newline at end of program %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x final_end:end. @y final_end: print_ln(' '); end. @z SHAR_EOF cat << \SHAR_EOF > weave.BSD4_n.ch % Change file for the WEAVE processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey and Pavel Curtis. % History: % 11/29/82 HWT Original version. This modifies weave to allow a new % control sequence: % @=...text...@> Put ...text... verbatim on a line % by itself in the Pascal output. % (argument must fit on one line) % This control sequence facilitates putting #include "gcons.h" % (for example) in files meant for the pc compiler. % Also, there is a command line option, -c, which means that % only the modules affected by the change file are to generate % TeX output. (All the limbo stuff still goes to the output % file, as does the index and table of contents.) % % 2/12/83 HWT Brought up for use with version 1.3. Uses Knuth's new % control sequences for verbatim Pascal (as above, without % the "on one line" part), and the force_line (@\) primitive. % Also, he added stuff to keep track of changed modules, and % output enough information that macros can choose only to % print changed modules. This isn't as efficient as my % implementation because I avoided outputting the text for % non-changed modules altogether, but this feature won't be % used too often (just for TeX and TeXware), so Knuth's % solution is accepted. % The change file changes that used % to implement these features have been removed. % There is a -x flag to cause WEAVE to omit cross referencing % of identifiers, and index and T.of.C. processing. % This, too, is unnecessary, for one could simply redefine some % WEB macros to avoid the printing, but there are only a couple % of easy changes, so they have been made. % % 2/18 HWT Increased stack size to 400 (not for TeX-related programs). % % 3/18 HWT Brought up for Version 1.5. Made it print newline at end of % run. % % 4/13 PC Merged with Pavel's version, including adding a call to % exit() at the end of the program, based upon the value of % `history'. % 4/16 PC Brought up to version 1.5 released with TeX 0.97 in April 1983 % 6/29 HWT Brought up to version 1.7 released with TeX 0.99 in June 1983, % introducing a new change file format % 7/17 HWT Brought up to version 2.0 released with TeX 0.999 in July 1983 % 7/29 HWT Brought up to version 2.1 % 11/17 HWT Brought up to version 2.4 released with TeX 1.0. Made % changes to use C routines for I/O, for speedup. % 1/31 HWT Brought up to version 2.6 % 12/28/85 PAM Brought up to version 2.8 (like 2.7, version number only) % 3/6/87 PAM Brought up to version 2.9 (like 2.8, version number only) % NOTE: The module numbers refer to the red-covered listing (Version 2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{WEAVE changes for Berkeley {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is WEAVE, Version 2.9' @y @d banner=='This is WEAVE, Version 2.9 for Berkeley UNIX' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] add input and output, remove other files, add ref to scan_args, % [2] and #include external definition for exit(), etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x program WEAVE(@!web_file,@!change_file,@!tex_file); label end_of_WEAVE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @<Error handling procedures@>@/ @y program WEAVE(@!input,@!output); label end_of_WEAVE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\ @=#include "tangext.h"@> @\@/ @<Error handling procedures@>@/ @<|scan_args| procedure@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [4] compiler options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y @=(*$C-*)@> {no range check} @!debug @=(*$C+*)@>@+ gubed {but turn everything on when debugging} @\ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Constants: Make stack_size=400 instead of 200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!stack_size=200; {number of simultaneous output levels} @y @!stack_size=400; {number of simultaneous output levels} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] terminal output: use standard i/o %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @y @d term_out==output @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @z @x @<Globals...@>= @!term_out:text_file; {the terminal as an output file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] init terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. Here is one way to do this on the \PASCAL\ system that was used in \.{TANGLE}'s initial development: @^system dependencies@> @<Set init...@>= rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. @^system dependencies@> @<Set init...@>= ; {nothing need be done} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [22] flush terminal buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] open input files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens the input files. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has already checked that suitable file names have been given; therefore no additional error checking needs to be done. We will see below that \.{WEAVE} reads through the entire input twice. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file); reset(change_file); end; @y @ The following code opens the input files. This is called after |scan_args| has filled the file name variables appropriately. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file,web_file_name); reset(change_file,change_file_name); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] opening tex file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens |tex_file|. Since this file was listed in the program header, we assume that the \PASCAL\ runtime system has checked that a suitable external file name has been given. @^system dependencies@> @<Set init...@>= rewrite(tex_file); @y @ The following code opens |tex_file|. The |scan_args| procedure is used to set up |tex_file_name| as required. @^system dependencies@> @<Set init...@>= scan_args; rewrite(tex_file,tex_file_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] faster input_ln %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} begin limit:=0; final_limit:=0; if eof(f) then input_ln:=false else begin while not eoln(f) do begin buffer[limit]:=xord[f^]; get(f); incr(limit); if buffer[limit-1]<>" " then final_limit:=limit; if limit=buf_size then begin while not eoln(f) do get(f); decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; end; read_ln(f); limit:=final_limit; input_ln:=true; end; end; @y With Berkeley {\mc UNIX} we call an external C procedure, |line_read|. That routine fills |buffer| from 0 onwards with the |xord|'ed values of the next line, setting |limit| appropriately (ignoring trailing blanks). It will stop if |limit=buf_size|, and the following will cause an error message. Note: for bootstrapping purposes it is all right to use the original form of |input_ln|; it will just run slower. @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} begin limit:=0; if test_eof(f) then input_ln:=false else begin line_read(f); if limit=buf_size then begin decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; input_ln:=true; end; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] don't enter xrefs if no_xref set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d append_xref(#)==if xref_ptr=max_refs then overflow('cross reference') else begin incr(xref_ptr); num(xref_ptr):=#; end @p procedure new_xref(@!p:name_pointer); label exit; var q:xref_number; {pointer to previous cross reference} @!m,@!n: sixteen_bits; {new and previous cross-reference value} begin if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and @y If the user has sent the |no_xref| flag (the -x option of the command line), then it is unnecessary to keep track of cross references for identifers. If one were careful, one could probably make more changes around module 100 to avoid a lot of identifier looking up. @d append_xref(#)==if xref_ptr=max_refs then overflow('cross reference') else begin incr(xref_ptr); num(xref_ptr):=#; end @p procedure new_xref(@!p:name_pointer); label exit; var q:xref_number; {pointer to previous cross-reference} @!m,@!n: sixteen_bits; {new and previous cross-reference value} begin if no_xref then return; if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [122] faster flush_buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x done: for k:=1 to j do write(tex_file,xchr[out_buf[k]]); @y done: linewrite(tex_file,j); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [239] omit index and module names if no_xref set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Phase III: Output the cross-reference index@>= @y If the user has set the |no_xref| flag (the -x option on the command line), just finish off the page, omitting the index, module name list, and table of contents. @<Phase III: Output the cross-reference index@>= if no_xref then begin finish_line; out("\"); out5("v")("f")("i")("l")("l"); out4("\")("e")("n")("d"); finish_line; end else begin @z @x print('Done.'); @y end; print('Done.'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [258] term_in == input, when debugging %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x any error stop will set |debug_cycle| to zero. @y any error stop will set |debug_cycle| to zero. @d term_in==input @z @x @!term_in:text_file; {the user's terminal as an input file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [259] Take out reset(term_in) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [261] print newline at end of run and exit based upon value of history %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure Phase_I; @y @d UNIXexit==e@&x@&i@&t @p procedure Phase_I; @z @x end. @y new_line; if (history <> spotless) and (history <> harmless_message) then UNIXexit(1) else UNIXexit(0); end. @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [264] system dependent changes--the scan_args procedure %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make \.{WEAVE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @^system dependencies@> @y @* System-dependent changes. The user calls \.{WEAVE} with arguments on the command line. These are either file names or flags (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 full names of those files, as UNIX knows them. The only flag that affects weave is |'-x'| whose status is kept in |no_xref|. @d max_file_name_length==60 @<Globals...@>= @!web_file_name,@!change_file_name,@!tex_file_name: array[1..max_file_name_length] of char; @!no_xref:boolean; @ The |scan_args| procedure looks at the command line arguments and sets the |file_name| variables accordingly. At least one file name must be present: the \.{WEB} file. It may have an extension, or it may omit it to get |'.web'| added. The \TeX\ output file name is formed by replacing the \.{WEB} file name extension by |'.tex'|. 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. An argument beginning with a minus sign is a flag. Any letters following the minus sign may cause global flag variables to be set. Currently, an |x| means that the cross referencing information---the index, the module name list, and the table of contents---is to be suppressed. @<|scan_args|...@>= procedure scan_args; var dot_pos,i,a: integer; {indices} @!fname: array[1..max_file_name_length-5] of char; {temporary argument holder} @!found_web,@!found_change: boolean; {|true| when those file names have been seen} begin found_web:=false; found_change:=false; no_xref:=false; for a:=1 to argc-1 do begin argv(a,fname); {put argument number |a| into |fname|} if fname[1]<>'-' then begin if not found_web then @<Get |web_file_name|, |pascal_file_name|, and | pool_file_name| variables from |fname|@> else if not found_change then @<Get |change_file_name| from |fname|@> else @<Print usage error message and quit@>; end else @<Handle flag argument in |fname|@>; end; if not found_web then @<Print usage error message and quit@>; if not found_change then @<Set up null change file@>; end; @ Use all of |fname| for the |web_file_name| if there is a |'.'| in it, otherwise add |'.web'|. The other file names come from adding things after the dot. The |argv| procedure will not put more than |max_file_name_length-5| characters into |fname|, and this leaves enough room in the |file_name| variables to add the extensions. The end of a file name is marked with a |' '|, the convention assumed by the |reset| and |rewrite| procedures. @<Get |web_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin web_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; web_file_name[dot_pos]:='.'; web_file_name[dot_pos+1]:='w'; web_file_name[dot_pos+2]:='e'; web_file_name[dot_pos+3]:='b'; web_file_name[dot_pos+4]:=' '; end; for i:=1 to dot_pos do begin tex_file_name[i]:=web_file_name[i]; end; tex_file_name[dot_pos+1]:='t'; tex_file_name[dot_pos+2]:='e'; tex_file_name[dot_pos+3]:='x'; tex_file_name[dot_pos+4]:=' '; found_web:=true; end @ @<Get |change_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin change_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; change_file_name[dot_pos]:='.'; change_file_name[dot_pos+1]:='c'; change_file_name[dot_pos+2]:='h'; change_file_name[dot_pos+3]:=' '; end; found_change:=true; end @ @<Set up null...@>= begin change_file_name[1]:='/'; change_file_name[2]:='d'; change_file_name[3]:='e'; change_file_name[4]:='v'; change_file_name[5]:='/'; change_file_name[6]:='n'; change_file_name[7]:='u'; change_file_name[8]:='l'; change_file_name[9]:='l'; change_file_name[10]:=' '; end @ @<Handle flag...@>= begin i:=2; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin if fname[i]='x' then no_xref:=true; incr(i); end; end @ @<Print usage error message and quit@>= begin print_nl('! Usage: weave webfile[.web] [changefile[.ch]] [-x]'); error; jump_out; end @z SHAR_EOF cat << \SHAR_EOF > weave.PYR.ch % Change file for the WEAVE processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey and Pavel Curtis. % History: % 11/29/82 HWT Original version. This modifies weave to allow a new % control sequence: % @=...text...@> Put ...text... verbatim on a line % by itself in the Pascal output. % (argument must fit on one line) % This control sequence facilitates putting #include "gcons.h" % (for example) in files meant for the pc compiler. % Also, there is a command line option, -c, which means that % only the modules affected by the change file are to generate % TeX output. (All the limbo stuff still goes to the output % file, as does the index and table of contents.) % % 2/12/83 HWT Brought up for use with version 1.3. Uses Knuth's new % control sequences for verbatim Pascal (as above, without % the "on one line" part), and the force_line (@\) primitive. % Also, he added stuff to keep track of changed modules, and % output enough information that macros can choose only to % print changed modules. This isn't as efficient as my % implementation because I avoided outputting the text for % non-changed modules altogether, but this feature won't be % used too often (just for TeX and TeXware), so Knuth's % solution is accepted. % The change file changes that used % to implement these features have been removed. % There is a -x flag to cause WEAVE to omit cross referencing % of identifiers, and index and T.of.C. processing. % This, too, is unnecessary, for one could simply redefine some % WEB macros to avoid the printing, but there are only a couple % of easy changes, so they have been made. % % 2/18 HWT Increased stack size to 400 (not for TeX-related programs). % % 3/18 HWT Brought up for Version 1.5. Made it print newline at end of % run. % % 4/13 PC Merged with Pavel's version, including adding a call to % exit() at the end of the program, based upon the value of % `history'. % 4/16 PC Brought up to version 1.5 released with TeX 0.97 in April 1983 % 6/29 HWT Brought up to version 1.7 released with TeX 0.99 in June 1983, % introducing a new change file format % 7/17 HWT Brought up to version 2.0 released with TeX 0.999 in July 1983 % 7/29 HWT Brought up to version 2.1 % 11/17 HWT Brought up to version 2.4 released with TeX 1.0. Made % changes to use C routines for I/O, for speedup. % 1/31 HWT Brought up to version 2.6 % 7/12/85 MPU Fixes for Pyramid's compiler % 1/3/86 PAM Cosmetic change for Version 2.8 % 3/6/87 PAM Cosmetic change for Version 2.9 % NOTE: The module numbers refer to the red-covered listing (Version 2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{WEAVE changes for Pyramid {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is WEAVE, Version 2.9' @y @d banner=='This is WEAVE, Version 2.9 for Pyramid OSx' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] add input and output, remove other files, add ref to scan_args, % [2] and #include external definition for exit(), etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x program WEAVE(@!web_file,@!change_file,@!tex_file); label end_of_WEAVE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @<Error handling procedures@>@/ @y program WEAVE(@!input,@!output); label end_of_WEAVE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\ @=#include "tangext.h"@> @\@/ @<Error handling procedures@>@/ @<|scan_args| procedure@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [4] compiler options %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @{@&$C-,A+,D-@} {no range check, catch arithmetic overflow, no debug overhead} @!debug @{@&$C+,D+@}@+ gubed {but turn everything on when debugging} @y @=(*$C-*)@> {no range check} @!debug @=(*$C+*)@>@+ gubed {but turn everything on when debugging} @\ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [7] Compiler: Pyramid uses "otherwise" not "others" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d othercases == others: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @y @d othercases == otherwise: {default for cases not listed explicitly} @d endcases == @+end {follows the default case in an extended |case| statement} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Constants: Make stack_size=400 instead of 200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!stack_size=200; {number of simultaneous output levels} @y @!stack_size=400; {number of simultaneous output levels} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [13] File type %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d text_char == char {the data type of characters in text files} @d first_text_char=0 {ordinal number of the smallest element of |text_char|} @d last_text_char=127 {ordinal number of the largest element of |text_char|} @<Types...@>= @!text_file=packed file of text_char; @y @d text_char == char {the data type of characters in text files} @d first_text_char=0 {ordinal number of the smallest element of |text_char|} @d last_text_char=127 {ordinal number of the largest element of |text_char|} @<Types...@>= @!text_file=text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] terminal output: use standard i/o %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @y @d term_out==output @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @z @x @<Globals...@>= @!term_out:text_file; {the terminal as an output file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] init terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. Here is one way to do this on the \PASCAL\ system that was used in \.{TANGLE}'s initial development: @^system dependencies@> @<Set init...@>= rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. @^system dependencies@> @<Set init...@>= ; {nothing need be done} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [22] flush terminal buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] open input files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens the input files. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has already checked that suitable file names have been given; therefore no additional error checking needs to be done. We will see below that \.{WEAVE} reads through the entire input twice. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file); reset(change_file); end; @y @ The following code opens the input files. This is called after |scan_args| has filled the file name variables appropriately. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file,web_file_name); reset(change_file,change_file_name); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] opening tex file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The main output goes to |tex_file|. @<Globals...@>= @!tex_file: text_file; @ The following code opens |tex_file|. Since this file was listed in the program header, we assume that the \PASCAL\ runtime system has checked that a suitable external file name has been given. @^system dependencies@> @<Set init...@>= rewrite(tex_file); @y @ The main output goes to |tex_file|. @<Globals...@>= @!tex_file: text_file; @ The following code opens |tex_file|. The |scan_args| procedure is used to set up |tex_file_name| as required. @^system dependencies@> @<Set init...@>= scan_args; rewrite(tex_file,tex_file_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] don't enter xrefs if no_xref set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d append_xref(#)==if xref_ptr=max_refs then overflow('cross reference') else begin incr(xref_ptr); num(xref_ptr):=#; end @p procedure new_xref(@!p:name_pointer); label exit; var q:xref_number; {pointer to previous cross reference} @!m,@!n: sixteen_bits; {new and previous cross-reference value} begin if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and @y If the user has sent the |no_xref| flag (the -x option of the command line), then it is unnecessary to keep track of cross references for identifers. If one were careful, one could probably make more changes around module 100 to avoid a lot of identifier looking up. @d append_xref(#)==if xref_ptr=max_refs then overflow('cross reference') else begin incr(xref_ptr); num(xref_ptr):=#; end @p procedure new_xref(@!p:name_pointer); label exit; var q:xref_number; {pointer to previous cross-reference} @!m,@!n: sixteen_bits; {new and previous cross-reference value} begin if no_xref then return; if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [239] omit index and module names if no_xref set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Phase III: Output the cross-reference index@>= @y If the user has set the |no_xref| flag (the -x option on the command line), just finish off the page, omitting the index, module name list, and table of contents. @<Phase III: Output the cross-reference index@>= if no_xref then begin finish_line; out("\"); out5("v")("f")("i")("l")("l"); out4("\")("e")("n")("d"); finish_line; end else begin @z @x print('Done.'); @y end; print('Done.'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [258] term_in == input, when debugging %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x any error stop will set |debug_cycle| to zero. @y any error stop will set |debug_cycle| to zero. @d term_in==input @z @x @!term_in:text_file; {the user's terminal as an input file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [259] Take out reset(term_in) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [261] print newline at end of run and exit based upon value of history %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure Phase_I; @y @d UNIXexit==e@&x@&i@&t @p procedure Phase_I; @z @x end. @y new_line; if (history <> spotless) and (history <> harmless_message) then UNIXexit(1) else UNIXexit(0); end. @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [264] system dependent changes--the scan_args procedure %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make \.{WEAVE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @^system dependencies@> @y @* System-dependent changes. The user calls \.{WEAVE} with arguments on the command line. These are either file names or flags (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 full names of those files, as UNIX knows them. The only flag that affects weave is |'-x'| whose status is kept in |no_xref|. @d max_file_name_length==60 @<Globals...@>= @!web_file_name,@!change_file_name,@!tex_file_name: array[1..max_file_name_length] of char; @!no_xref:boolean; @ The |scan_args| procedure looks at the command line arguments and sets the |file_name| variables accordingly. At least one file name must be present: the \.{WEB} file. It may have an extension, or it may omit it to get |'.web'| added. The \TeX\ output file name is formed by replacing the \.{WEB} file name extension by |'.tex'|. 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. An argument beginning with a minus sign is a flag. Any letters following the minus sign may cause global flag variables to be set. Currently, an |x| means that the cross referencing information---the index, the module name list, and the table of contents---is to be suppressed. @<|scan_args|...@>= procedure scan_args; var dot_pos,i,a: integer; {indices} @!fname: array[1..max_file_name_length-5] of char; {temporary argument holder} @!found_web,@!found_change: boolean; {|true| when those file names have been seen} begin found_web:=false; found_change:=false; no_xref:=false; for a:=1 to argc-1 do begin argv(a,fname); {put argument number |a| into |fname|} if fname[1]<>'-' then begin if not found_web then @<Get |web_file_name|, |pascal_file_name|, and | pool_file_name| variables from |fname|@> else if not found_change then @<Get |change_file_name| from |fname|@> else @<Print usage error message and quit@>; end else @<Handle flag argument in |fname|@>; end; if not found_web then @<Print usage error message and quit@>; if not found_change then @<Set up null change file@>; end; @ Use all of |fname| for the |web_file_name| if there is a |'.'| in it, otherwise add |'.web'|. The other file names come from adding things after the dot. The |argv| procedure will not put more than |max_file_name_length-5| characters into |fname|, and this leaves enough room in the |file_name| variables to add the extensions. The end of a file name is marked with a |' '|, the convention assumed by the |reset| and |rewrite| procedures. @<Get |web_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin web_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; web_file_name[dot_pos]:='.'; web_file_name[dot_pos+1]:='w'; web_file_name[dot_pos+2]:='e'; web_file_name[dot_pos+3]:='b'; web_file_name[dot_pos+4]:=' '; end; for i:=1 to dot_pos do begin tex_file_name[i]:=web_file_name[i]; end; tex_file_name[dot_pos+1]:='t'; tex_file_name[dot_pos+2]:='e'; tex_file_name[dot_pos+3]:='x'; tex_file_name[dot_pos+4]:=' '; found_web:=true; end @ @<Get |change_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin change_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; change_file_name[dot_pos]:='.'; change_file_name[dot_pos+1]:='c'; change_file_name[dot_pos+2]:='h'; change_file_name[dot_pos+3]:=' '; end; found_change:=true; end @ @<Set up null...@>= begin change_file_name[1]:='/'; change_file_name[2]:='d'; change_file_name[3]:='e'; change_file_name[4]:='v'; change_file_name[5]:='/'; change_file_name[6]:='n'; change_file_name[7]:='u'; change_file_name[8]:='l'; change_file_name[9]:='l'; change_file_name[10]:=' '; end @ @<Handle flag...@>= begin i:=2; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin if fname[i]='x' then no_xref:=true; incr(i); end; end @ @<Print usage error message and quit@>= begin print_nl('! Usage: weave webfile[.web] [changefile[.ch]] [-x]'); error; jump_out; end @z SHAR_EOF cat << \SHAR_EOF > weave.SYS_V.ch % Change file for the WEAVE processor, for use on Berkeley UNIX systems. % This file was created by Howard Trickey and Pavel Curtis. % History: % 11/29/82 HWT Original version. This modifies weave to allow a new % control sequence: % @=...text...@> Put ...text... verbatim on a line % by itself in the Pascal output. % (argument must fit on one line) % This control sequence facilitates putting #include "gcons.h" % (for example) in files meant for the pc compiler. % Also, there is a command line option, -c, which means that % only the modules affected by the change file are to generate % TeX output. (All the limbo stuff still goes to the output % file, as does the index and table of contents.) % % 2/12/83 HWT Brought up for use with version 1.3. Uses Knuth's new % control sequences for verbatim Pascal (as above, without % the "on one line" part), and the force_line (@\) primitive. % Also, he added stuff to keep track of changed modules, and % output enough information that macros can choose only to % print changed modules. This isn't as efficient as my % implementation because I avoided outputting the text for % non-changed modules altogether, but this feature won't be % used too often (just for TeX and TeXware), so Knuth's % solution is accepted. % The change file changes that used % to implement these features have been removed. % There is a -x flag to cause WEAVE to omit cross referencing % of identifiers, and index and T.of.C. processing. % This, too, is unnecessary, for one could simply redefine some % WEB macros to avoid the printing, but there are only a couple % of easy changes, so they have been made. % % 2/18 HWT Increased stack size to 400 (not for TeX-related programs). % % 3/18 HWT Brought up for Version 1.5. Made it print newline at end of % run. % % 4/13 PC Merged with Pavel's version, including adding a call to % exit() at the end of the program, based upon the value of % `history'. % 4/16 PC Brought up to version 1.5 released with TeX 0.97 in April 1983 % 6/29 HWT Brought up to version 1.7 released with TeX 0.99 in June 1983, % introducing a new change file format % 7/17 HWT Brought up to version 2.0 released with TeX 0.999 in July 1983 % 7/29 HWT Brought up to version 2.1 % 11/17 HWT Brought up to version 2.4 released with TeX 1.0. Made % changes to use C routines for I/O, for speedup. % 1/31 HWT Brought up to version 2.6 % 7/12/85 MPU Fixes for Pyramid's compiler % 1/3/86 PAM Cosmetic change for Version 2.8 % 3/27/87 LKS Changes for System V UNIX % 4/19/86 PAM Cosmetic change for Version 2.9 % NOTE: The module numbers refer to the red-covered listing (Version 2). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [0] WEAVE: print changes only %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x \pageno=\contentspagenumber \advance\pageno by 1 @y \pageno=\contentspagenumber \advance\pageno by 1 \let\maybe=\iffalse \def\title{WEAVE changes for System V {\mc UNIX}} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [1] Change banner message %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d banner=='This is WEAVE, Version 2.9' @y @d banner=='This is WEAVE, Version 2.9 for System V UNIX' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [2] add input and output, remove other files, add ref to scan_args, % [2] and #include external definition for exit(), etc. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x program WEAVE(@!web_file,@!change_file,@!tex_file); label end_of_WEAVE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @<Error handling procedures@>@/ @y program WEAVE(@!input,@!output); label end_of_WEAVE; {go here to finish} const @<Constants in the outer block@>@/ type @<Types in the outer block@>@/ var @<Globals in the outer block@>@/ @\ @=#include "tangext.h"@> @\@/ @<Error handling procedures@>@/ @<|scan_args| procedure@>@/ @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [8] Constants: Make stack_size=400 instead of 200 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @!stack_size=200; {number of simultaneous output levels} @y @!stack_size=400; {number of simultaneous output levels} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [13] File type %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d text_char == char {the data type of characters in text files} @d first_text_char=0 {ordinal number of the smallest element of |text_char|} @d last_text_char=127 {ordinal number of the largest element of |text_char|} @<Types...@>= @!text_file=packed file of text_char; @y @d text_char == char {the data type of characters in text files} @d first_text_char=0 {ordinal number of the smallest element of |text_char|} @d last_text_char=127 {ordinal number of the largest element of |text_char|} @<Types...@>= @!text_file=text; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [20] terminal output: use standard i/o %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @y @d term_out==output @d print(#)==write(term_out,#) {`|print|' means write on the terminal} @z @x @<Globals...@>= @!term_out:text_file; {the terminal as an output file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [21] init terminal %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. Here is one way to do this on the \PASCAL\ system that was used in \.{TANGLE}'s initial development: @^system dependencies@> @<Set init...@>= rewrite(term_out,'TTY:'); {send |term_out| output to the terminal} @y @ Different systems have different ways of specifying that the output on a certain file will appear on the user's terminal. @^system dependencies@> @<Set init...@>= ; {nothing need be done} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [22] flush terminal buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d update_terminal == break(term_out) {empty the terminal output buffer} @y @d update_terminal == flush(term_out) {empty the terminal output buffer} @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [24] open input files %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The following code opens the input files. Since these files were listed in the program header, we assume that the \PASCAL\ runtime system has already checked that suitable file names have been given; therefore no additional error checking needs to be done. We will see below that \.{WEAVE} reads through the entire input twice. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file); reset(change_file); end; @y @ The following code opens the input files. This is called after |scan_args| has filled the file name variables appropriately. @^system dependencies@> @p procedure open_input; {prepare to read |web_file| and |change_file|} begin reset(web_file,web_file_name); reset(change_file,change_file_name); end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [26] opening tex file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @ The main output goes to |tex_file|. @<Globals...@>= @!tex_file: text_file; @ The following code opens |tex_file|. Since this file was listed in the program header, we assume that the \PASCAL\ runtime system has checked that a suitable external file name has been given. @^system dependencies@> @<Set init...@>= rewrite(tex_file); @y @ The main output goes to |tex_file|. @<Globals...@>= @!tex_file: text_file; @ The following code opens |tex_file|. The |scan_args| procedure is used to set up |tex_file_name| as required. @^system dependencies@> @<Set init...@>= scan_args; rewrite(tex_file,tex_file_name); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [28] faster input_ln %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} var final_limit:0..buf_size; {|limit| without trailing blanks} begin limit:=0; final_limit:=0; if eof(f) then input_ln:=false else begin while not eoln(f) do begin buffer[limit]:=xord[f^]; get(f); incr(limit); if buffer[limit-1]<>" " then final_limit:=limit; if limit=buf_size then begin while not eoln(f) do get(f); decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; end; read_ln(f); limit:=final_limit; input_ln:=true; end; end; @y With System V {\mc UNIX} we call an external C procedure, |line_read|. That routine fills |buffer| from 0 onwards with the |xord|'ed values of the next line, setting |limit| appropriately (ignoring trailing blanks). It will stop if |limit=buf_size|, and the following will cause an error message. Note: for bootstrapping purposes it is all right to use the original form of |input_ln|; it will just run slower. @p function input_ln(var f:text_file):boolean; {inputs a line or returns |false|} begin limit:=0; if test_eof(f) then input_ln:=false else begin line_read(f); if limit=buf_size then begin decr(limit); {keep |buffer[buf_size]| empty} print_nl('! Input line too long'); loc:=0; error; @.Input line too long@> end; input_ln:=true; end; end; @z @x procedure jump_out; begin goto end_of_WEAVE; end; @y procedure jump_out; begin stat @<Print statistics about memory usage@>;@+tats@;@/ @t\4\4@>{here files should be closed if the operating system requires it} @<Print the job |history|@>; end; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [50] don't enter xrefs if no_xref set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @d append_xref(#)==if xref_ptr=max_refs then overflow('cross reference') else begin incr(xref_ptr); num(xref_ptr):=#; end @p procedure new_xref(@!p:name_pointer); label exit; var q:xref_number; {pointer to previous cross reference} @!m,@!n: sixteen_bits; {new and previous cross-reference value} begin if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and @y If the user has sent the |no_xref| flag (the -x option of the command line), then it is unnecessary to keep track of cross references for identifers. If one were careful, one could probably make more changes around module 100 to avoid a lot of identifier looking up. @d append_xref(#)==if xref_ptr=max_refs then overflow('cross reference') else begin incr(xref_ptr); num(xref_ptr):=#; end @p procedure new_xref(@!p:name_pointer); label exit; var q:xref_number; {pointer to previous cross-reference} @!m,@!n: sixteen_bits; {new and previous cross-reference value} begin if no_xref then return; if (reserved(p)or(byte_start[p]+1=byte_start[p+ww]))and @z @x @!loc:0..long_buf_size; {the next character position to be read from the buffer} @y @!loc:0..long_buf_size; {the next character position to be read from the buffer} @!x_loc:0..long_buf_size; {the next character position to be read from the buffer} @z @x begin for loc:=0 to change_limit do buffer[loc]:=change_buffer[loc]; @y begin for x_loc:=0 to change_limit do buffer[x_loc]:=change_buffer[x_loc]; @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [122] faster flush_buffer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x done: for k:=1 to j do write(tex_file,xchr[out_buf[k]]); @y done: linewrite(tex_file,j); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [239] omit index and module names if no_xref set %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @<Phase III: Output the cross-reference index@>= @y If the user has set the |no_xref| flag (the -x option on the command line), just finish off the page, omitting the index, module name list, and table of contents. @<Phase III: Output the cross-reference index@>= if no_xref then begin finish_line; out("\"); out5("v")("f")("i")("l")("l"); out4("\")("e")("n")("d"); finish_line; end else begin @z @x print('Done.'); @y end; print('Done.'); @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [258] term_in == input, when debugging %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x any error stop will set |debug_cycle| to zero. @y any error stop will set |debug_cycle| to zero. @d term_in==input @z @x @!term_in:text_file; {the user's terminal as an input file} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [259] Take out reset(term_in) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x reset(term_in,'TTY:','/I'); {open |term_in| as the terminal, don't do a |get|} @y @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [261] print newline at end of run and exit based upon value of history %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @p procedure Phase_I; @y @d UNIXexit==e@&x@&i@&t @p procedure Phase_I; @z @x end. @y new_line; if (history <> spotless) and (history <> harmless_message) then UNIXexit(1) else UNIXexit(0); end. @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % [264] system dependent changes--the scan_args procedure %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @x @* System-dependent changes. This module should be replaced, if necessary, by changes to the program that are necessary to make \.{WEAVE} work at a particular installation. It is usually best to design your change file so that all changes to previous modules preserve the module numbering; then everybody's version will be consistent with the printed program. More extensive changes, which introduce new modules, can be inserted here; then only the index itself will get a new module number. @^system dependencies@> @y @* System-dependent changes. The user calls \.{WEAVE} with arguments on the command line. These are either file names or flags (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 full names of those files, as UNIX knows them. The only flag that affects weave is |'-x'| whose status is kept in |no_xref|. @d max_file_name_length==60 @<Globals...@>= @!web_file_name,@!change_file_name,@!tex_file_name: packed array[1..max_file_name_length] of char; @!no_xref:boolean; @ The |scan_args| procedure looks at the command line arguments and sets the |file_name| variables accordingly. At least one file name must be present: the \.{WEB} file. It may have an extension, or it may omit it to get |'.web'| added. The \TeX\ output file name is formed by replacing the \.{WEB} file name extension by |'.tex'|. 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. An argument beginning with a minus sign is a flag. Any letters following the minus sign may cause global flag variables to be set. Currently, an |x| means that the cross referencing information---the index, the module name list, and the table of contents---is to be suppressed. @<|scan_args|...@>= procedure scan_args; var dot_pos,i,a: integer; {indices} @!fname: packed array[1..max_file_name_length-5] of char; {temporary argument holder} @!found_web,@!found_change: boolean; {|true| when those file names have been seen} begin found_web:=false; found_change:=false; no_xref:=false; for a:=2 to argc do begin argv(a,fname); {put argument number |a| into |fname|} if fname[1]<>'-' then begin if not found_web then @<Get |web_file_name|, |pascal_file_name|, and | pool_file_name| variables from |fname|@> else if not found_change then @<Get |change_file_name| from |fname|@> else @<Print usage error message and quit@>; end else @<Handle flag argument in |fname|@>; end; if not found_web then @<Print usage error message and quit@>; if not found_change then @<Set up null change file@>; end; @ Use all of |fname| for the |web_file_name| if there is a |'.'| in it, otherwise add |'.web'|. The other file names come from adding things after the dot. The |argv| procedure will not put more than |max_file_name_length-5| characters into |fname|, and this leaves enough room in the |file_name| variables to add the extensions. The end of a file name is marked with a |' '|, the convention assumed by the |reset| and |rewrite| procedures. @<Get |web_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin web_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; web_file_name[dot_pos]:='.'; web_file_name[dot_pos+1]:='w'; web_file_name[dot_pos+2]:='e'; web_file_name[dot_pos+3]:='b'; web_file_name[dot_pos+4]:=' '; end; for i:=1 to dot_pos do begin tex_file_name[i]:=web_file_name[i]; end; tex_file_name[dot_pos+1]:='t'; tex_file_name[dot_pos+2]:='e'; tex_file_name[dot_pos+3]:='x'; tex_file_name[dot_pos+4]:=' '; found_web:=true; end @ @<Get |change_file_name|...@>= begin dot_pos:=-1; i:=1; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin change_file_name[i]:=fname[i]; if fname[i]='.' then dot_pos:=i; incr(i); end; if dot_pos=-1 then begin dot_pos:=i; change_file_name[dot_pos]:='.'; change_file_name[dot_pos+1]:='c'; change_file_name[dot_pos+2]:='h'; change_file_name[dot_pos+3]:=' '; end; found_change:=true; end @ @<Set up null...@>= begin change_file_name[1]:='/'; change_file_name[2]:='d'; change_file_name[3]:='e'; change_file_name[4]:='v'; change_file_name[5]:='/'; change_file_name[6]:='n'; change_file_name[7]:='u'; change_file_name[8]:='l'; change_file_name[9]:='l'; change_file_name[10]:=' '; end @ @<Handle flag...@>= begin i:=2; while (fname[i]<>' ') and (i<=max_file_name_length-5) do begin if fname[i]='x' then no_xref:=true; incr(i); end; end @ @<Print usage error message and quit@>= begin print_nl('! Usage: weave webfile[.web] [changefile[.ch]] [-x]'); error; jump_out; end @z SHAR_EOF # End of shell archive exit 0