diff options
Diffstat (limited to 'obsolete/systems/sisisi/unix/SiTeX3.14')
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/LIESMICH.EXPERTE | 184 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/MANIFEST | 20 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/Makefile | 200 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/README.EXPERT | 155 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/coerce.h | 890 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/ctex.ch | 1877 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/install | 59 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/makefile | 280 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/sitex.web.gz | bin | 0 -> 323486 bytes | |||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/sitex3.ch | 2827 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/tangle.ch | 687 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/tex6.c | 2492 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/texd.h | 485 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/web2c.c | 334 | ||||
-rw-r--r-- | obsolete/systems/sisisi/unix/SiTeX3.14/web2c.h | 93 |
15 files changed, 10583 insertions, 0 deletions
diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/LIESMICH.EXPERTE b/obsolete/systems/sisisi/unix/SiTeX3.14/LIESMICH.EXPERTE new file mode 100644 index 0000000000..ea97b1f343 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/LIESMICH.EXPERTE @@ -0,0 +1,184 @@ + + + TeX mit SISISI-Silbentrennung + ============================= + + Technische Dokumentation fuer Fortgeschrittene + ============================================== + + +(Hinweis: Dieses File enthaelt nur technische Information. Wenn Sie nur SiTeX +installieren wollen, ohne sich fuer die Probleme und Hintergruende zu +interessieren, brauchen Sie dieses File nicht zu lesen. Wenn allerdings bei +der normalen Installation etwas schiefgehen sollte, kann Ihnen die in diesem +File enthaltene Information vielleicht weiterhelfen.) + +0) Grundsaetzliches. +-------------------- + +Die SISISI Silbentrennung ist ein WEB-Changefile (sitex3.ch), das gewoehnlich +in tex.web hineingetangle'd wird. Fuer die UNIX-Version von TeX wurde +allerdings ein web2c Konverter geschrieben, der das von tangle erzeugte tex.p +in C-Code konvertieren soll. Dieser Konverter kann mit den in sitex3.ch +verwendeten Standard-Pascal Befehlen nicht umgehen, z.B. koennen keine +statisch geschachtelten Prozeduren verarbeitet werden. + +Es war also notwendig, sitex3.ch so zu aendern, dass es von dem web2c +Konverter verarbeitet werden kann. Ausserdem hat der web2c Konverter einige +Eigenheiten (sprich Fehler :-), die es notwendig machen, den entstehenden +C-Code einer Nachbearbeitung (sprich Korrektur) zu unterwerfen. Diese +Aufgaben wurden im Rahmen eines Informatikpraktikums von den Studenten +Hans-Juergen Szoldatics und Florian Zwerina geloest. + +1) Einbinden von SISISI in TeX. +------------------------------- + +Das erste Problem entsteht dadurch, dass tangle nur ein einzelnes Changefile +in ein .web Masterfile einbinden kann. In der C/UNIX Version ist es +allerdings notwendig, zuerst sitex3.ch in tex.web einzubinden, und dann +zusaetzlich noch ctex.ch. Diese Aufgabe kann mit tangle alleine nicht geloest +werden. Es gibt allerdings ein Programm namens TIE, das dazu verwendet werden +kann, mehrere Changefiles in ein Masterfile einzubinden, und das in einer C +Version auf + + ftp.th-darmstadt.de [130.83.55.75] + directory pub/programming/literate-programming/Tools + file tie-<version>.tar.Z + +zur Verfuegung steht. + +(Ich bin Klaus Guntermann fuer diese Information zu grossem Dank verpflichtet). + +Um Ihnen das Leben zu erleichtern, finden Sie tie-2.4.tar.Z gemeinsam mit den +anderen SISISI-Files in diesem Verzeichnis. Um Ihnen das Leben noch leichter +zu machen, finden Sie auch ein sitex.web, das nichts anderes ist als tex.web +(Version 3.14) mit sitex3.ch hineingetie'd. Falls Sie allerdings vorhaben +sollten, eine andere (neuere oder aeltere) Version von TeX zu verwenden, +muessen Sie zuerst tie.c uebersetzen und das ebenfalls in diesem Verzeichnis +vorhandene sitex3.ch in Ihr tex.web hineintie-en, um ein neues sitex.web zu +erhalten. (Wenn Sie das `install' Skript verwenden wollen, muessen Sie nachher +sitex.web compress-en, oder das `install' Skript entsprechend aendern.) + +2) Die Konversion von TeX (mit SISISI) nach C. +---------------------------------------------- + +Sobald Sie Ihr original tex.web durch sitex.web ersetzt haben (wobei Sie +sitex.web in tex.web umbenennen muessen), koennen Sie ein `make' starten, +genau wie bei der normalen Installation von TeX. Allerdings sind noch einige +kleine Vorarbeiten notwendig, die Ihnen das `install' Skript abnimmt, die Sie +aber bei haendischer Installation selbst tun muessen. + +Zunaechst einmal sind die internen Tabellen von tangle und web2c zu klein +fuer SiTeX, und muessen vergroessert werden. Dazu gibt es neue Versionen von +tangle.ch und web2c.c und web2c.h, die in ihre entsprechenden Verzeichnisse +kopiert werden muessen (naemlich nach TEXSRC/web und TEXSRC/web2c). Ausserdem +muessen einige Definitionen in ctex.ch geaendert werden, und deshalb wird +auch dieses File mitgeliefert. Ausserdem gibt es noch neue Versionen der +Makefiles, da 1) zwei neue Format-Files erzeugt werden muessen und 2) nicht +mehr nur tex[0-8].c ensteht, sondern auch tex9.c. + +3) Jetzt beginnt der Aerger. +---------------------------- + +tex.web wird von tangle in tex.p konvertiert (mit ctex.ch als Changefile), +und tex.p dann von einem Skript namens `convert' unter Verwendung von web2c +in mehrere .c und .h Files umgewandelt. Dann versucht sich der C-Compiler an +dem Resultat, und damit beginnen die Schwierigkeiten. Aus irgendwelchen +unerfindlichen Gruenden wird '] ] )' von web2c in ') ] ]' umgewandelt, was +natuerlich den obligaten Syntaxfehler erzeugt. Ausserdem wird ein Array, das +in Pascal als Wertparameter an eine Prozedur uebergeben wird, automatisch zu +einem Var-Parameter, da der Arrayname in C ja eigentlich nur ein Zeiger auf +das erste Element des Arrays ist. In Pascal wird - wie es sich fuer einen +Wertparameter gehoert - eine Kopie des gesamten Arrays erzeugt und diese dann +an die Prozedur uebergeben. In C wird eine Kopie des Zeigers erzeugt und +diese dann uebergeben. Was passiert, wenn dann das Array innerhalb der +Prozedur modifiziert wird, kann man sich denken (in Pascal ist nur die lokale +Kopie betroffen, in C ...). Aus diesem Grund muss explizit ein temporaeres +Array in der Prozedur definiert werden, das den Wert des Parameters speichert +und beim Verlassen der Prozedur wieder herstellt. Natuerlich muss die +Zuweisung, die in Pascal ja auch fuer Arrays funktioniert, in C durch ein +`memcpy' ersetzt werden. + +Ein weiterer Fehler wird durch die schlechte Konvertierung der Ein-/Ausgabe +Anweisungen von Pascal erzeugt. Bei der Umwandlung von write() in fprintf() +geht die Feldbreite verloren (write(x:4) wird zu printf("%d",x) anstelle von +printf("%4d",x)). Ebenso gibt es Probleme bei der Eingabe, wenn +selbstdefinierte Datentypen verwendet werden. Dadurch kommt es zu einem +Fehler beim Abspeichern bzw. Einlesen der Hashtabelle, die im File hf3 +abgespeichert wird. + +Wieder ein anderes Problem entsteht durch die trickreiche Umsetzung von +Prozedurdeklarationen und -aufrufen. Um die Unterscheidung von Wert- und +Variablenparametern so transparent wie moeglich zu machen, werden alle +Funktionen (im C-Code) umbenannt und stattdessen Makros definiert, die den +Adressoperator auf alle Var-Parameter anwenden und damit die (jetzt +umbenannte) Funktion aufrufen. Vorteil: Am Funktionsaufruf aendert sich gar +nichts, nur wird statt der Funktion jetzt eben der Makro `aufgerufen', der +dann fuer die richtige Uebergabe der Parameter sorgt. Leider tut web2c zuviel +des Guten und erzeugt in den Makros auch noch Typecasts, damit die Parameter +auch nur ja den richtigen Typ haben. Und GNU C vertraegt es leider nicht, +wenn Casts auf Array-Typen vorgenommen werden, was in SiTeX nun halt einmal +vorkommt. Deshalb muessen alle Casts, die Array-Typen spezifizieren, aus +coerce.h entfernt werden (dort sind alle Makros und Funktionsprototypen +definert). + +Um Ihnen diese Korrekturen abzunehmen, stehen die Files tex6.c, coerce.h und +texd.h in bereits korrigierter Form zur Verfuegung, und muessen nach +TEXSRC/tex kopiert werden, sobald `make' zum ersten Mal mit der Fehlermeldung +`cast specifies array type' abbricht (wenn vorher ein anderer Fehler +auftritt, ist etwas schiefgegangen !). Wenn Sie das `install' Skript +verwenden, geschieht dies automatisch. Dann wird einfach wieder das `make' neu +gestartet. Das Problem dabei ist, dass web2c eigentlich nur ein einziges +grosses C-File erzeugt, das dann nachtraeglich in die einzelnen Files +aufgespaltet wird, und dass keine Garantie dafuer besteht, dass das tex6.c, +das Sie erhalten, genauso aussieht wie jenes, das bei mir enstanden ist und +in dem ich die Fehler korrigiert habe. Sollten sich (was aber eher +unwahrscheinlich ist) im weiteren Verlauf des `make' wieder Fehler ergeben, +und zwar dass Symbole nicht bzw. doppelt deklariert wurden, ist genau dieser +Fall eingetreten. Verstaendigen Sie mich dann bitte umgehend. Ansonsten +sollten Sie aber jetzt ohne weitere Probleme initex und virtex in Ihrem +TEXSRC/tex Verzeichnis erhalten. + +4) Die Installation des fertigen SiTeX. +--------------------------------------- + +Nachdem also nun initex und virtex erfolgreich erstellt wurden, muessen Sie +noch die Format-Files erzeugen und alles in den entsprechenden Verzeichnissen +installieren. Die Format-Files werden vom `install' Skript automatisch +erzeugt, aber wenn Sie es haendisch tun wollen/muessen, sehen Sie am besten +im Makefile in Ihrem SISISIDIR nach, wie man Format-Files erzeugt. Wenn Sie +das `install' Skript verwendet haben, finden Sie neben sitex.fmt und +silatex.fmt in TEXSRC/tex auch noch ein File namens sitex.pool und ein File +namens hf3. Wenn Sie allerdings `install' nicht verwendet haben, heisst +sitex.pool noch tex.pool und muss erst umbenannt werden. Das hf3 File wird +automatisch generiert, sobald Sie das erste Format-File erzeugen. + +Sie sollten nun zuerst hf3 in ein Verzeichnis in Ihrem TEXINPUTS Pfad kopieren, +und sitex.pool in das TEXPOOLDIR. Dann kommen sitex.fmt und silatex.fmt in +das TEXFORMATS Verzeichnis, und in dem selben Verzeichnis erzeugen Sie auch +einen Link namens siplain.fmt auf sitex.fmt. + +Jetzt muessen Sie sich entscheiden, ob Sie Ihr altes TeX/LaTeX behalten +wollen oder nicht. Falls Sie auch weiterhin fremdsprachige Texte bearbeiten +wollen, sollten Sie das neue initex und virtex unter neuem Namen (z.B. +siinitex und sivirtex) in ein Verzeichnis in Ihrem Standard-Suchpfad +kopieren, und Links namens sitex und silatex auf sivirtex erzeugen, in dem +selben Verzeichnis. + +Falls Sie das alte TeX nicht mehr wollen, kopieren Sie einfach das neue +virtex ueber das alte, und ebenso das neue initex ueber das alte initex, und +stellen Sie die sitex und silatex Links her. Die alten Links, tex, latex, +slitex etc. koennen Sie entfernen. + +5) Bugs, Probleme etc. +---------------------- + +Der Installationsprozess wurde auf einem 486 PC mit Interactive Unix SVR3.2 +und auf einer HP 9000/705 mit HP-UX 8.07 getestet. Auf beiden Maschinen sind +die Resultate, die silatex liefert, identisch. Allerdings hatte ich bis jetzt +keine Gelegenheit, silatex auf anderen Systemen, speziell BSD und AIX, zu +testen. Deshalb muss silatex noch immer als Beta Version betrachtet werden, +und alle Fehlermeldungen, Kommentare, (Verbesserungs-)Vorschlaege und +Berichte ueber erfolgreiche Inbetriebnahme sind willkommen. + +Schicken Sie bitte EMail an heinz@eiunix.tuwien.ac.at . diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/MANIFEST b/obsolete/systems/sisisi/unix/SiTeX3.14/MANIFEST new file mode 100644 index 0000000000..765509e138 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/MANIFEST @@ -0,0 +1,20 @@ +Dieses Verzeichnis enthaelt: +============================ + +LIESMICH Installationsanleitung auf Deutsch +LIESMICH.EXPERTE Technische Beschreibung von SiTeX +MANIFEST Dieses File +Makefile Ersetzt Makefile in TEXSRC/tex +README Installationsanleitung auf Englisch +README.EXPERT Technische Beschreibung von SiTeX (Engl.) +coerce.h Korrigierte Version, kommt nach TEXSRC/tex +ctex.ch ditto +install Installationsskript +makefile Ersetzt makefile in TEXSRC +sitex.web.Z TeX mit SISISI hineingetie'd +sitex3.ch Changefile mit dem SISISI-Algorithmus +tangle.ch Kommt nach TEXSRC/web +tex6.c Korrigierte Version, kommt nach TEXSRC/tex +texd.h Korrigierte Version, kommt nach TEXSRC/tex +web2c.c Kommt nach TEXSRC/web2c +web2c.h ditto diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/Makefile b/obsolete/systems/sisisi/unix/SiTeX3.14/Makefile new file mode 100644 index 0000000000..92d1e062cc --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/Makefile @@ -0,0 +1,200 @@ +# This file makes TeX in its various incarnations. +# +# The file ../common/texmf.h uses the symbol `TeX' to define certain +# things that are different for TeX and Metafont, hence the addition to +# CFLAGS. + +SITEDIR=.. +CC=gcc +OPT=-O +CFLAGS=$(OPT) -I$(SITEDIR) -DTeX +LDFLAGS= +LOADLIBES= +SHELL=/bin/sh +LN=ln + +# The formats we know how to make. +# +formats=amstex.fmt etex.fmt latex.fmt slitex.fmt tex.fmt \ +texinfo.fmt picplus.fmt + + +makeargs=SITEDIR="$(SITEDIR)" CC="$(CC)" OPT="$(OPT)" \ + LDFLAGS="$(LDFLAGS)" LOADLIBES="$(LOADLIBES)" + +.SUFFIXES: +.SUFFIXES: .o .c +.c.o: + $(CC) $(CFLAGS) -c $*.c + +# Routines used everywhere. +# +commondefines=../common/common.defines ../common/texmf.defines +commonh=../common/extra.h ../common/common.h +commono=../common/alloca.o ../common/extra.o + +# Routines used in both TeX and Metafont. +# +extrac=../common/texmf.c +extrah=../common/texmf.h ../common/endian.h +extrao=texmf.o + +# Routines used in TeX, Metafont, and BibTeX. +# +fileioc=../common/fileio.c +fileioh=../common/fileio.h +fileioo=fileio.o + +# We don't add `$(commono)' here, since it doesn't depend on anything in +# this directory, and we write a dependency for `$(objs)' below. +# +objs=$(fileioo) tex0.o tex1.o tex2.o tex3.o tex4.o tex5.o tex6.o tex7.o tex8.o tex9.o +iobjs=iextra.o initex.o $(objs) +vobjs=tex-extra.o itex.o $(objs) + + +default: all + +all: initex virtex +triptrap: triptex + +initex: stamp-convert $(iobjs) $(commono) + $(CC) -o initex $(LDFLAGS) $(iobjs) $(commono) $(LOADLIBES) + +virtex: stamp-convert $(vobjs) $(commono) + $(CC) -o virtex $(LDFLAGS) $(vobjs) $(commono) $(LOADLIBES) + +run-trip: + rm -f trip.tex + -$(LN) TeXtrip/trip.tex . + ../texware/pltotf TeXtrip/trip.pl trip.tfm + -$(SHELL) -c '. ./tripenv; \ + ./triptex < TeXtrip/trip1.in > /dev/null 2>&1' + -diff TeXtrip/tripin.log trip.log + -$(SHELL) -c '. ./tripenv; \ + ./triptex < TeXtrip/trip2.in > trip.fot' + -diff TeXtrip/trip.log trip.log + -diff TeXtrip/trip.fot trip.fot + $(SHELL) -c '. ./tripenv; \ + ../texware/dvitype trip.dvi < TeXtrip/dvitype.in > trip.typ' + -diff TeXtrip/trip.typ trip.typ + + +# Make format files automatically. +# +fmts: $(formats) + +amstex.fmt: tex.fmt + ./initex \&./tex amstex \\dump + +etex.fmt: tex.fmt + touch eplain.aux # Makes cross-reference warnings work right. + ./initex \&./tex eplain \\dump + mv eplain.fmt etex.fmt + mv eplain.log etex.log + +# Until LaTeX and SLiTeX are updated, we must use a hacked version, that +# sets the new parameters to reasonable values. +# +latex.fmt: + ./initex lplain \\dump + mv lplain.fmt latex.fmt + mv lplain.log latex.log + +picplus.fmt: tex.fmt + ./initex \&./tex picplus \\dump + +slitex.fmt: + ./initex splain \\dump + mv splain.fmt slitex.fmt + mv splain.log slitex.log + +tex.fmt: + ./initex plain \\dump + mv plain.fmt tex.fmt + mv plain.log tex.log + +sitex.fmt: + ./initex siplain \\dump + mv siplain.fmt sitex.fmt + mv siplain.log sitex.log + +silatex.fmt: + ./initex silplain \\dump + mv silplain.fmt silatex.fmt + mv silplain.log silatex.log + +# texinfo changes the escape character from `\' to `@'. +# +texinfo.fmt: tex.fmt + ./initex \&./tex texinfo @dump + + +# The `ini_to_trip' script changes texd.h, instead of the change file, so +# retangling is not necessary. After changing constants, making a +# triptex means making an initex. +# +triptex: stamp-trip $(iobjs) $(commono) + make $(makeargs) initex + mv initex triptex + +stamp-trip: stamp-convert + rm -f *.o + $(SHELL) ./ini_to_trip texd.h + touch stamp-trip + +# tangle produces tex.p and tex.pool. +# +tex.p: tex.web ctex.ch + ../web/tangle tex.web ctex.ch + +# The convert script produces tex[0-8].c, itex.c, coerce.h, and texd.h. +# The (hand-coded) memory.h is included in one of tex?.c files; it isn't +# really necessary to `convert' again if it changes, only to recompile +# those files, but describing that relationship is ugly to do. +# (Furthermore, memory.h is stable.) +# +stamp-convert: tex.p memory.h fixcoerce.h $(commondefines) + $(SHELL) ./convert + touch stamp-convert + +# The (hand-coded) file $(extrac) and the (generated) file itex.c have +# #ifdefs for INITEX, so we compile them differently. +# +iextra.o: $(extrac) texd.h $(extrah) $(commonh) + $(CC) $(CFLAGS) -I. -DINITEX -DINI -c $(extrac) + mv $(extrao) iextra.o + +initex.o: itex.c texd.h $(extrah) $(commonh) + $(CC) $(CFLAGS) -DINITEX -c itex.c && mv itex.o initex.o + +$(objs): stamp-convert texd.h +tex-extra.o: $(extrac) texd.h + rm -f tex-extra.c + $(LN) $(extrac) tex-extra.c + $(CC) $(CFLAGS) -I. -c tex-extra.c + +$(fileioo): $(fileioc) $(fileioh) + $(CC) $(CFLAGS) -I. -c $(fileioc) + +tex0.o: tex0.c +tex1.o: tex1.c +tex2.o: tex2.c +tex3.o: tex3.c +tex4.o: tex4.c +tex5.o: tex5.c +tex6.o: tex6.c +tex7.o: tex7.c +tex8.o: tex8.c +tex9.o: tex9.c + + +clean: + rm -f stamp-* *.o triptex initex virtex + rm -f texd.h coerce.h *.log *.fmt *.aux + rm -f 8terminal.tex trip.* tripos.tex dvitype.out + rm -f tex-extra.c + +veryclean: clean + rm -f tex?.c itex.c tex.p tex.pool texput.* + rm -f \#*\# *~ *.bak *.ckp core diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/README.EXPERT b/obsolete/systems/sisisi/unix/SiTeX3.14/README.EXPERT new file mode 100644 index 0000000000..0cd8f15ec3 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/README.EXPERT @@ -0,0 +1,155 @@ + + + TeX with SISISI-Hyphenation + =========================== + + Technical Guide for Expert Users + ================================ + + +(Note: This file contains technical information only. You don't have to read +it, unless you are *really* interested in the problems of porting SISISI to +UNIX, or unless somthing went wrong with the normal installation process.) + +0) Motivation. +-------------- + +The SISISI-Hyphenation comes as a WEB-changefile (sitex3.ch), which is +usually tangle'd into tex.web. The problem with the C version of TeX is that +the folks who wrote the web2c converter considered only a WEB-specific subset +of PASCAL, but sitex3.ch makes full use of standard PASCAL constructs. For +example, the web2c converter can't handle statically nested procedures, which +SISISI uses quite extensively. + +Therefore, for the C version of TeX, it was necessary to modify sitex3.ch to +allow conversion with web2c, and, since web2c shows some strange and +inexplicable behaviour (read: bugs :-), it is also necessary to modify the C +files that are generated by the converter. This was performed by students of +computer science Hans-J"urgen Szoldatics and Florian Zwerina. + +1) Incorporating SISISI into TeX. +--------------------------------- + +The first problem is that tangle takes a .web and a single .ch file, and +generates a .p file. But in the C version, we have two changefiles, sitex3.ch +and ctex.ch, and we first have to tangle tex.web with sitex3.ch, and the +resulting file with ctex.ch, which is not possible. Fortunately, there's a +program called TIE, which can be used to incorporate many changefiles into a +.web master file, and which is available in a C version from + + ftp.th-darmstadt.de [130.83.55.75] + directory pub/programming/literate-programming/Tools + file tie-<version>.tar.Z + +(Thanks to Klaus Guntermann for providing this information). + +For convenience, tie-2.4.tar.Z is included in this distribution. Also for +convenience, this distribution contains a file called sitex.web, which is +the original tex.web (version 3.14) with sitex3.ch tie'd into it. In case you +want to install a newer (or maybe an older) version of TeX, you will have to +compile tie.c and tie sitex3.ch into your tex.web, thus creating your own +sitex.web. + + +2) Converting tex.web (with SISISI) into a C program. +----------------------------------------------------- + +As soon as tex.web has been replaced with sitex.web, you can start `make', +just as with the normal installation of TeX. There are some differences, +however: SiTeX uses up all the namespace in tangle and in web2c, and you have +to increase the symbol tables in these programs. That's the reason why +tangle.ch and web2c.? are provided and copied to their appropriate places +by `install'. Some definitions in ctex.ch have to be changed, and so this +file is also provided. Finally, the makefiles have to be changed to take into +account the 9th C-file generated by the conversion process and the SISISI +format files. + +3) Now the problems start. +-------------------------- + +As soon as tex.web has been tangle'd into tex.p and tex.p been converted into +several .c and .h files, the bugs in web2c strike. For some strange reason, +the sequence '] ] )' is twisted into ') ] ]', with the obvious result of a C +syntax error. Also, the pass-by-value mechanism of PASCAL turns into +pass-by-reference as soon as arrays are used as actual parameters. This +comes from the fact that an array variable in C is the same as a pointer to +the first array element. Therefore, instead of a copy of the entire array +(which is what happens in PASCAL), only the pointer to the first element +is passed to the function. Guess what happens when the array is modified +inside the function... As a consequence, a temporary array has to be +introduced into the function which stores a copy of the original parameter +and restores it at the end of the function. Needless to say, the PASCAL +assignment for arrays has to be converted manually into a C `memcpy' library +call. + +Another bug is web2c's handling of input/output. PASCAL's write() is not +properly translated into C's fprintf(), when a field width is specified. That +is, write(x:4) is translated into printf("%d",x), but really should be +printf("%4d",x). Similar problems arise with the conversion of read() into +fscanf(), when non-standard data types are used. This causes SISISI's hash +table to be written to file hf3 in wrong format, and to be read back into +memory in a wrong way. + +Other problems arise from the nifty mechanism web2c employs for the handling +of PASCAL's VAR-parameters. The PASCAL functions and procedures are renamed +and introduced C macros with the names of the original functions and +procedures, which apply the C address operator (&) to the arguments that +are pass-by-ref, and subsequently call the now renamed function. Unfortunately, +web2c does too much of the good and also generates type casts for the +function parameters to ensure proper data types, which causes GNU C to +complain about `cast specifies array type', when casts to array types are +attempted. It is therefore necessary to remove these casts from coerce.h, +where macros and function prototypes are defined. + +For convenience, the files tex6.c, coerce.h and texd.h (with all bugs removed) +are provided and can be copied into TEXSRC/tex as soon as the `make' stops +for the first time (usually with the aforementioned complaint about casts to +array types), replacing the buggy files. The `install' script does this for +you. The danger here is that your tex6.c is not necessarily the same as my +tex6.c (i.e. the tex6.c I got out of my converter and applied the necessary +bug fixes to). If this should be the case, the compilation will again +terminate with an error, either that some symbols are declared twice or that +some symbols are missing. If this should happen, please contact me +immediately. If no such errors occur, compilation should terminate normally +and you should get initex and virtex. + +4) Installing SiTeX on your system. +----------------------------------- + +After initex and virtex have been successfully generated, it's now time to +install the program and format files on your system. To get sitex.fmt and +silatex.fmt, look into SISISIDIR/Makefile how these files are generated. The +`install' script performs this step automatically, so if you used `install' to +create SiTeX, you will already have the SISISI format files. You will find +all these files in your TEXDIR, along with a file named sitex.pool and a file +named hf3. + +First, you should copy hf3 to your TEXINPUTS directory (more precisely: +into a directory contained in the TEXINPUTS path), and sitex.pool to the +TEXPOOL dir. Then copy sitex.fmt and silatex.fmt into TEXFORMATS, and +create a link to sitex.fmt named siplain.fmt in the same directory. + +Now you have to decide whether you want to retain TeX with the original +hyphenation algorithm (virtex, tex and latex). If not, simply remove the old +virtex and initex and all the links to it (such as tex, latex, slitex, glatex +etc.) and copy the new initex and virtex into a directory holding your +executables. Then create links to the now new virtex with names sitex and +silatex. + +If you want to keep the original TeX, you have to copy initex and virtex into +your standard search path under different names, preferably siinitex and +sivirtex, and create the sitex and silatex links. Note however, that you can't +use silatex for non-German documents, as the hyphenation algorithm is designed +for the German language only. So if you want to work with German and English +documents, you have to retain the original TeX. + +5) Troubleshooting. +------------------- + +I have tested the installation process on a 486 PC running Interactive SVR3.2, +and on an HP 9000/705 running HP-UX 8.07. silatex gives the same results on +both machines. I had no opportunity, however, to make and test silatex on other +systems, especially not BSD systems and AIX. SiTeX has therefore to be regarded +as being still in its beta version, and any bug reports, comments, critics or +praise (no, seriously ! If you have successfully installed SiTeX please let +me know too !) are welcome. Send EMail to heinz@eiunix.tuwien.ac.at . diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/coerce.h b/obsolete/systems/sisisi/unix/SiTeX3.14/coerce.h new file mode 100644 index 0000000000..f7672fe2ab --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/coerce.h @@ -0,0 +1,890 @@ +void initialize(); +#define initialize_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void println(); +#define println_regmem +void zprintchar(); +#define printchar(s) zprintchar((ASCIIcode) (s)) +#define printchar_regmem register memoryword *eqtb=zeqtb; +void zprint(); +#define print(s) zprint((integer) (s)) +#define print_regmem register memoryword *eqtb=zeqtb; +void zslowprint(); +#define slowprint(s) zslowprint((integer) (s)) +#define slowprint_regmem register memoryword *eqtb=zeqtb; +void zprintnl(); +#define printnl(s) zprintnl((strnumber) (s)) +#define printnl_regmem +void zprintesc(); +#define printesc(s) zprintesc((strnumber) (s)) +#define printesc_regmem register memoryword *eqtb=zeqtb; +void zprintthedigs(); +#define printthedigs(k) zprintthedigs((eightbits) (k)) +#define printthedigs_regmem +void zprintint(); +#define printint(n) zprintint((integer) (n)) +#define printint_regmem +void zprintcs(); +#define printcs(p) zprintcs((integer) (p)) +#define printcs_regmem register memoryword *eqtb=zeqtb; +void zsprintcs(); +#define sprintcs(p) zsprintcs((halfword) (p)) +#define sprintcs_regmem +void zprintfilename(); +#define printfilename(n, a, e) zprintfilename((integer) (n), (integer) (a), (integer) (e)) +#define printfilename_regmem +void zprintsize(); +#define printsize(s) zprintsize((integer) (s)) +#define printsize_regmem +void zprintwritewhatsit(); +#define printwritewhatsit(s, p) zprintwritewhatsit((strnumber) (s), (halfword) (p)) +#define printwritewhatsit_regmem register memoryword *mem=zmem; +void jumpout(); +#define jumpout_regmem +void error(); +#define error_regmem +void zfatalerror(); +#define fatalerror(s) zfatalerror((strnumber) (s)) +#define fatalerror_regmem +void zoverflow(); +#define overflow(s, n) zoverflow((strnumber) (s), (integer) (n)) +#define overflow_regmem +void zconfusion(); +#define confusion(s) zconfusion((strnumber) (s)) +#define confusion_regmem +boolean initterminal(); +#define initterminal_regmem +strnumber makestring(); +#define makestring_regmem +boolean zstreqbuf(); +#define streqbuf(s, k) zstreqbuf((strnumber) (s), (integer) (k)) +#define streqbuf_regmem +boolean zstreqstr(); +#define streqstr(s, t) zstreqstr((strnumber) (s), (strnumber) (t)) +#define streqstr_regmem +boolean getstringsstarted(); +#define getstringsstarted_regmem +void zprinttwo(); +#define printtwo(n) zprinttwo((integer) (n)) +#define printtwo_regmem +void zprinthex(); +#define printhex(n) zprinthex((integer) (n)) +#define printhex_regmem +void zprintromanint(); +#define printromanint(n) zprintromanint((integer) (n)) +#define printromanint_regmem +void printcurrentstring(); +#define printcurrentstring_regmem +void terminput(); +#define terminput_regmem +void zinterror(); +#define interror(n) zinterror((integer) (n)) +#define interror_regmem +void normalizeselector(); +#define normalizeselector_regmem +void pauseforinstructions(); +#define pauseforinstructions_regmem +integer zhalf(); +#define half(x) zhalf((integer) (x)) +#define half_regmem +scaled zrounddecimals(); +#define rounddecimals(k) zrounddecimals((smallnumber) (k)) +#define rounddecimals_regmem +void zprintscaled(); +#define printscaled(s) zprintscaled((scaled) (s)) +#define printscaled_regmem +scaled zmultandadd(); +#define multandadd(n, x, y, maxanswer) zmultandadd((integer) (n), (scaled) (x), (scaled) (y), (scaled) (maxanswer)) +#define multandadd_regmem +scaled zxovern(); +#define xovern(x, n) zxovern((scaled) (x), (integer) (n)) +#define xovern_regmem +scaled zxnoverd(); +#define xnoverd(x, n, d) zxnoverd((scaled) (x), (integer) (n), (integer) (d)) +#define xnoverd_regmem +halfword zbadness(); +#define badness(t, s) zbadness((scaled) (t), (scaled) (s)) +#define badness_regmem +void zprintword(); +#define printword(w) zprintword((memoryword) (w)) +#define printword_regmem +void zshowtokenlist(); +#define showtokenlist(p, q, l) zshowtokenlist((integer) (p), (integer) (q), (integer) (l)) +#define showtokenlist_regmem register memoryword *mem=zmem; +void runaway(); +#define runaway_regmem register memoryword *mem=zmem; +halfword getavail(); +#define getavail_regmem register memoryword *mem=zmem; +void zflushlist(); +#define flushlist(p) zflushlist((halfword) (p)) +#define flushlist_regmem register memoryword *mem=zmem; +halfword zgetnode(); +#define getnode(s) zgetnode((integer) (s)) +#define getnode_regmem register memoryword *mem=zmem; +void zfreenode(); +#define freenode(p, s) zfreenode((halfword) (p), (halfword) (s)) +#define freenode_regmem register memoryword *mem=zmem; +void sortavail(); +#define sortavail_regmem register memoryword *mem=zmem; +halfword newnullbox(); +#define newnullbox_regmem register memoryword *mem=zmem; +halfword newrule(); +#define newrule_regmem register memoryword *mem=zmem; +halfword znewligature(); +#define newligature(f, c, q) znewligature((quarterword) (f), (quarterword) (c), (halfword) (q)) +#define newligature_regmem register memoryword *mem=zmem; +halfword znewligitem(); +#define newligitem(c) znewligitem((quarterword) (c)) +#define newligitem_regmem register memoryword *mem=zmem; +halfword newdisc(); +#define newdisc_regmem register memoryword *mem=zmem; +halfword znewmath(); +#define newmath(w, s) znewmath((scaled) (w), (smallnumber) (s)) +#define newmath_regmem register memoryword *mem=zmem; +halfword znewspec(); +#define newspec(p) znewspec((halfword) (p)) +#define newspec_regmem register memoryword *mem=zmem; +halfword znewparamglue(); +#define newparamglue(n) znewparamglue((smallnumber) (n)) +#define newparamglue_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword znewglue(); +#define newglue(q) znewglue((halfword) (q)) +#define newglue_regmem register memoryword *mem=zmem; +halfword znewskipparam(); +#define newskipparam(n) znewskipparam((smallnumber) (n)) +#define newskipparam_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword znewkern(); +#define newkern(w) znewkern((scaled) (w)) +#define newkern_regmem register memoryword *mem=zmem; +halfword znewpenalty(); +#define newpenalty(m) znewpenalty((integer) (m)) +#define newpenalty_regmem register memoryword *mem=zmem; +void zcheckmem(); +#define checkmem(printlocs) zcheckmem((boolean) (printlocs)) +#define checkmem_regmem register memoryword *mem=zmem; +void zsearchmem(); +#define searchmem(p) zsearchmem((halfword) (p)) +#define searchmem_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zshortdisplay(); +#define shortdisplay(p) zshortdisplay((integer) (p)) +#define shortdisplay_regmem register memoryword *mem=zmem; +void zprintfontandchar(); +#define printfontandchar(p) zprintfontandchar((integer) (p)) +#define printfontandchar_regmem register memoryword *mem=zmem; +void zprintmark(); +#define printmark(p) zprintmark((integer) (p)) +#define printmark_regmem register memoryword *mem=zmem; +void zprintruledimen(); +#define printruledimen(d) zprintruledimen((scaled) (d)) +#define printruledimen_regmem +void zprintglue(); +#define printglue(d, order, s) zprintglue((scaled) (d), (integer) (order), (strnumber) (s)) +#define printglue_regmem +void zprintspec(); +#define printspec(p, s) zprintspec((integer) (p), (strnumber) (s)) +#define printspec_regmem register memoryword *mem=zmem; +void zprintfamandchar(); +#define printfamandchar(p) zprintfamandchar((halfword) (p)) +#define printfamandchar_regmem register memoryword *mem=zmem; +void zprintdelimiter(); +#define printdelimiter(p) zprintdelimiter((halfword) (p)) +#define printdelimiter_regmem register memoryword *mem=zmem; +void zprintsubsidiarydata(); +#define printsubsidiarydata(p, c) zprintsubsidiarydata((halfword) (p), (ASCIIcode) (c)) +#define printsubsidiarydata_regmem register memoryword *mem=zmem; +void zprintstyle(); +#define printstyle(c) zprintstyle((integer) (c)) +#define printstyle_regmem +void zprintskipparam(); +#define printskipparam(n) zprintskipparam((integer) (n)) +#define printskipparam_regmem +void zshownodelist(); +#define shownodelist(p) zshownodelist((integer) (p)) +#define shownodelist_regmem register memoryword *mem=zmem; +void zshowbox(); +#define showbox(p) zshowbox((halfword) (p)) +#define showbox_regmem register memoryword *eqtb=zeqtb; +void zdeletetokenref(); +#define deletetokenref(p) zdeletetokenref((halfword) (p)) +#define deletetokenref_regmem register memoryword *mem=zmem; +void zdeleteglueref(); +#define deleteglueref(p) zdeleteglueref((halfword) (p)) +#define deleteglueref_regmem register memoryword *mem=zmem; +void zflushnodelist(); +#define flushnodelist(p) zflushnodelist((halfword) (p)) +#define flushnodelist_regmem register memoryword *mem=zmem; +halfword zcopynodelist(); +#define copynodelist(p) zcopynodelist((halfword) (p)) +#define copynodelist_regmem register memoryword *mem=zmem; +void zprintmode(); +#define printmode(m) zprintmode((integer) (m)) +#define printmode_regmem +void pushnest(); +#define pushnest_regmem +void popnest(); +#define popnest_regmem register memoryword *mem=zmem; +void showactivities(); +#define showactivities_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zprintparam(); +#define printparam(n) zprintparam((integer) (n)) +#define printparam_regmem +void begindiagnostic(); +#define begindiagnostic_regmem register memoryword *eqtb=zeqtb; +void zenddiagnostic(); +#define enddiagnostic(blankline) zenddiagnostic((boolean) (blankline)) +#define enddiagnostic_regmem +void zprintlengthparam(); +#define printlengthparam(n) zprintlengthparam((integer) (n)) +#define printlengthparam_regmem +void zprintcmdchr(); +#define printcmdchr(cmd, chrcode) zprintcmdchr((quarterword) (cmd), (halfword) (chrcode)) +#define printcmdchr_regmem +void zshoweqtb(); +#define showeqtb(n) zshoweqtb((halfword) (n)) +#define showeqtb_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword zidlookup(); +#define idlookup(j, l) zidlookup((integer) (j), (integer) (l)) +#define idlookup_regmem +void zprimitive(); +#define primitive(s, c, o) zprimitive((strnumber) (s), (quarterword) (c), (halfword) (o)) +#define primitive_regmem register memoryword *eqtb=zeqtb; +void znewsavelevel(); +#define newsavelevel(c) znewsavelevel((groupcode) (c)) +#define newsavelevel_regmem +void zeqdestroy(); +#define eqdestroy(w) zeqdestroy((memoryword) (w)) +#define eqdestroy_regmem register memoryword *mem=zmem; +void zeqsave(); +#define eqsave(p, l) zeqsave((halfword) (p), (quarterword) (l)) +#define eqsave_regmem register memoryword *eqtb=zeqtb; +void zeqdefine(); +#define eqdefine(p, t, e) zeqdefine((halfword) (p), (quarterword) (t), (halfword) (e)) +#define eqdefine_regmem register memoryword *eqtb=zeqtb; +void zeqworddefine(); +#define eqworddefine(p, w) zeqworddefine((halfword) (p), (integer) (w)) +#define eqworddefine_regmem register memoryword *eqtb=zeqtb; +void zgeqdefine(); +#define geqdefine(p, t, e) zgeqdefine((halfword) (p), (quarterword) (t), (halfword) (e)) +#define geqdefine_regmem register memoryword *eqtb=zeqtb; +void zgeqworddefine(); +#define geqworddefine(p, w) zgeqworddefine((halfword) (p), (integer) (w)) +#define geqworddefine_regmem register memoryword *eqtb=zeqtb; +void zsaveforafter(); +#define saveforafter(t) zsaveforafter((halfword) (t)) +#define saveforafter_regmem +void zrestoretrace(); +#define restoretrace(p, s) zrestoretrace((halfword) (p), (strnumber) (s)) +#define restoretrace_regmem +void unsave(); +#define unsave_regmem register memoryword *eqtb=zeqtb; +void preparemag(); +#define preparemag_regmem register memoryword *eqtb=zeqtb; +void ztokenshow(); +#define tokenshow(p) ztokenshow((halfword) (p)) +#define tokenshow_regmem register memoryword *mem=zmem; +void printmeaning(); +#define printmeaning_regmem +void showcurcmdchr(); +#define showcurcmdchr_regmem +void showcontext(); +#define showcontext_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zbegintokenlist(); +#define begintokenlist(p, t) zbegintokenlist((halfword) (p), (quarterword) (t)) +#define begintokenlist_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void endtokenlist(); +#define endtokenlist_regmem +void backinput(); +#define backinput_regmem register memoryword *mem=zmem; +void backerror(); +#define backerror_regmem +void inserror(); +#define inserror_regmem +void beginfilereading(); +#define beginfilereading_regmem +void endfilereading(); +#define endfilereading_regmem +void clearforerrorprompt(); +#define clearforerrorprompt_regmem +void checkoutervalidity(); +#define checkoutervalidity_regmem register memoryword *mem=zmem; +void getnext(); +#define getnext_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void firmuptheline(); +#define firmuptheline_regmem register memoryword *eqtb=zeqtb; +void gettoken(); +#define gettoken_regmem +void macrocall(); +#define macrocall_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void insertrelax(); +#define insertrelax_regmem +void expand(); +#define expand_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void getxtoken(); +#define getxtoken_regmem +void xtoken(); +#define xtoken_regmem +void scanleftbrace(); +#define scanleftbrace_regmem +void scanoptionalequals(); +#define scanoptionalequals_regmem +boolean zscankeyword(); +#define scankeyword(s) zscankeyword((strnumber) (s)) +#define scankeyword_regmem register memoryword *mem=zmem; +void muerror(); +#define muerror_regmem +void scaneightbitint(); +#define scaneightbitint_regmem +void scancharnum(); +#define scancharnum_regmem +void scanfourbitint(); +#define scanfourbitint_regmem +void scanfifteenbitint(); +#define scanfifteenbitint_regmem +void scantwentysevenbitint(); +#define scantwentysevenbitint_regmem +void scanfontident(); +#define scanfontident_regmem register memoryword *eqtb=zeqtb; +void zfindfontdimen(); +#define findfontdimen(writing) zfindfontdimen((boolean) (writing)) +#define findfontdimen_regmem +void zscansomethinginternal(); +#define scansomethinginternal(level, negative) zscansomethinginternal((smallnumber) (level), (boolean) (negative)) +#define scansomethinginternal_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void scanint(); +#define scanint_regmem +void zscandimen(); +#define scandimen(mu, inf, shortcut) zscandimen((boolean) (mu), (boolean) (inf), (boolean) (shortcut)) +#define scandimen_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zscanglue(); +#define scanglue(level) zscanglue((smallnumber) (level)) +#define scanglue_regmem register memoryword *mem=zmem; +halfword scanrulespec(); +#define scanrulespec_regmem register memoryword *mem=zmem; +halfword zstrtoks(); +#define strtoks(b) zstrtoks((poolpointer) (b)) +#define strtoks_regmem register memoryword *mem=zmem; +halfword thetoks(); +#define thetoks_regmem register memoryword *mem=zmem; +void insthetoks(); +#define insthetoks_regmem register memoryword *mem=zmem; +void convtoks(); +#define convtoks_regmem register memoryword *mem=zmem; +halfword zscantoks(); +#define scantoks(macrodef, xpand) zscantoks((boolean) (macrodef), (boolean) (xpand)) +#define scantoks_regmem register memoryword *mem=zmem; +void zreadtoks(); +#define readtoks(n, r) zreadtoks((integer) (n), (halfword) (r)) +#define readtoks_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void passtext(); +#define passtext_regmem +void zchangeiflimit(); +#define changeiflimit(l, p) zchangeiflimit((smallnumber) (l), (halfword) (p)) +#define changeiflimit_regmem register memoryword *mem=zmem; +void conditional(); +#define conditional_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void beginname(); +#define beginname_regmem +boolean zmorename(); +#define morename(c) zmorename((ASCIIcode) (c)) +#define morename_regmem +void endname(); +#define endname_regmem +void zpackfilename(); +#define packfilename(n, a, e) zpackfilename((strnumber) (n), (strnumber) (a), (strnumber) (e)) +#define packfilename_regmem +void zpackbufferedname(); +#define packbufferedname(n, a, b) zpackbufferedname((smallnumber) (n), (integer) (a), (integer) (b)) +#define packbufferedname_regmem +strnumber makenamestring(); +#define makenamestring_regmem +strnumber zamakenamestring(); +#define amakenamestring(f) zamakenamestring((alphafile *) &(f)) +#define amakenamestring_regmem +strnumber zbmakenamestring(); +#define bmakenamestring(f) zbmakenamestring((bytefile *) &(f)) +#define bmakenamestring_regmem +strnumber zwmakenamestring(); +#define wmakenamestring(f) zwmakenamestring((wordfile *) &(f)) +#define wmakenamestring_regmem +void scanfilename(); +#define scanfilename_regmem +void zpackjobname(); +#define packjobname(s) zpackjobname((strnumber) (s)) +#define packjobname_regmem +void zpromptfilename(); +#define promptfilename(s, e) zpromptfilename((strnumber) (s), (strnumber) (e)) +#define promptfilename_regmem +void openlogfile(); +#define openlogfile_regmem register memoryword *eqtb=zeqtb; +void startinput(); +#define startinput_regmem register memoryword *eqtb=zeqtb; +internalfontnumber zreadfontinfo(); +#define readfontinfo(u, nom, aire, s) zreadfontinfo((halfword) (u), (strnumber) (nom), (strnumber) (aire), (scaled) (s)) +#define readfontinfo_regmem register memoryword *eqtb=zeqtb; +void zcharwarning(); +#define charwarning(f, c) zcharwarning((internalfontnumber) (f), (eightbits) (c)) +#define charwarning_regmem register memoryword *eqtb=zeqtb; +halfword znewcharacter(); +#define newcharacter(f, c) znewcharacter((internalfontnumber) (f), (eightbits) (c)) +#define newcharacter_regmem register memoryword *mem=zmem; +void dviswap(); +#define dviswap_regmem +void zdvifour(); +#define dvifour(x) zdvifour((integer) (x)) +#define dvifour_regmem +void zdvipop(); +#define dvipop(l) zdvipop((integer) (l)) +#define dvipop_regmem +void zdvifontdef(); +#define dvifontdef(f) zdvifontdef((internalfontnumber) (f)) +#define dvifontdef_regmem +void zmovement(); +#define movement(w, o) zmovement((scaled) (w), (eightbits) (o)) +#define movement_regmem register memoryword *mem=zmem; +void zprunemovements(); +#define prunemovements(l) zprunemovements((integer) (l)) +#define prunemovements_regmem register memoryword *mem=zmem; +void zspecialout(); +#define specialout(p) zspecialout((halfword) (p)) +#define specialout_regmem register memoryword *mem=zmem; +void zwriteout(); +#define writeout(p) zwriteout((halfword) (p)) +#define writeout_regmem register memoryword *mem=zmem; +void zoutwhat(); +#define outwhat(p) zoutwhat((halfword) (p)) +#define outwhat_regmem register memoryword *mem=zmem; +void hlistout(); +#define hlistout_regmem register memoryword *mem=zmem; +void vlistout(); +#define vlistout_regmem register memoryword *mem=zmem; +void zshipout(); +#define shipout(p) zshipout((halfword) (p)) +#define shipout_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zscanspec(); +#define scanspec(c, threecodes) zscanspec((groupcode) (c), (boolean) (threecodes)) +#define scanspec_regmem +halfword zhpack(); +#define hpack(p, w, m) zhpack((halfword) (p), (scaled) (w), (smallnumber) (m)) +#define hpack_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword zvpackage(); +#define vpackage(p, h, m, l) zvpackage((halfword) (p), (scaled) (h), (smallnumber) (m), (scaled) (l)) +#define vpackage_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zappendtovlist(); +#define appendtovlist(b) zappendtovlist((halfword) (b)) +#define appendtovlist_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword newnoad(); +#define newnoad_regmem register memoryword *mem=zmem; +halfword znewstyle(); +#define newstyle(s) znewstyle((smallnumber) (s)) +#define newstyle_regmem register memoryword *mem=zmem; +halfword newchoice(); +#define newchoice_regmem register memoryword *mem=zmem; +void showinfo(); +#define showinfo_regmem register memoryword *mem=zmem; +halfword zfractionrule(); +#define fractionrule(t) zfractionrule((scaled) (t)) +#define fractionrule_regmem register memoryword *mem=zmem; +halfword zoverbar(); +#define overbar(b, k, t) zoverbar((halfword) (b), (scaled) (k), (scaled) (t)) +#define overbar_regmem register memoryword *mem=zmem; +halfword zcharbox(); +#define charbox(f, c) zcharbox((internalfontnumber) (f), (quarterword) (c)) +#define charbox_regmem register memoryword *mem=zmem; +void zstackintobox(); +#define stackintobox(b, f, c) zstackintobox((halfword) (b), (internalfontnumber) (f), (quarterword) (c)) +#define stackintobox_regmem register memoryword *mem=zmem; +scaled zheightplusdepth(); +#define heightplusdepth(f, c) zheightplusdepth((internalfontnumber) (f), (quarterword) (c)) +#define heightplusdepth_regmem +halfword zvardelimiter(); +#define vardelimiter(d, s, v) zvardelimiter((halfword) (d), (smallnumber) (s), (scaled) (v)) +#define vardelimiter_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword zrebox(); +#define rebox(b, w) zrebox((halfword) (b), (scaled) (w)) +#define rebox_regmem register memoryword *mem=zmem; +halfword zmathglue(); +#define mathglue(g, m) zmathglue((halfword) (g), (scaled) (m)) +#define mathglue_regmem register memoryword *mem=zmem; +void zmathkern(); +#define mathkern(p, m) zmathkern((halfword) (p), (scaled) (m)) +#define mathkern_regmem register memoryword *mem=zmem; +void flushmath(); +#define flushmath_regmem register memoryword *mem=zmem; +halfword zcleanbox(); +#define cleanbox(p, s) zcleanbox((halfword) (p), (smallnumber) (s)) +#define cleanbox_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zfetch(); +#define fetch(a) zfetch((halfword) (a)) +#define fetch_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zmakeover(); +#define makeover(q) zmakeover((halfword) (q)) +#define makeover_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zmakeunder(); +#define makeunder(q) zmakeunder((halfword) (q)) +#define makeunder_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zmakevcenter(); +#define makevcenter(q) zmakevcenter((halfword) (q)) +#define makevcenter_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zmakeradical(); +#define makeradical(q) zmakeradical((halfword) (q)) +#define makeradical_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zmakemathaccent(); +#define makemathaccent(q) zmakemathaccent((halfword) (q)) +#define makemathaccent_regmem register memoryword *mem=zmem; +void zmakefraction(); +#define makefraction(q) zmakefraction((halfword) (q)) +#define makefraction_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +scaled zmakeop(); +#define makeop(q) zmakeop((halfword) (q)) +#define makeop_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zmakeord(); +#define makeord(q) zmakeord((halfword) (q)) +#define makeord_regmem register memoryword *mem=zmem; +void zmakescripts(); +#define makescripts(q, delta) zmakescripts((halfword) (q), (scaled) (delta)) +#define makescripts_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +smallnumber zmakeleftright(); +#define makeleftright(q, style, maxd, maxh) zmakeleftright((halfword) (q), (smallnumber) (style), (scaled) (maxd), (scaled) (maxh)) +#define makeleftright_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void mlisttohlist(); +#define mlisttohlist_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void pushalignment(); +#define pushalignment_regmem register memoryword *mem=zmem; +void popalignment(); +#define popalignment_regmem register memoryword *mem=zmem; +void getpreambletoken(); +#define getpreambletoken_regmem register memoryword *eqtb=zeqtb; +void initalign(); +#define initalign_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zinitspan(); +#define initspan(p) zinitspan((halfword) (p)) +#define initspan_regmem +void initrow(); +#define initrow_regmem register memoryword *mem=zmem; +void initcol(); +#define initcol_regmem register memoryword *mem=zmem; +boolean fincol(); +#define fincol_regmem register memoryword *mem=zmem; +void finrow(); +#define finrow_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void finalign(); +#define finalign_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void alignpeek(); +#define alignpeek_regmem +halfword zfiniteshrink(); +#define finiteshrink(p) zfiniteshrink((halfword) (p)) +#define finiteshrink_regmem register memoryword *mem=zmem; +void ztrybreak(); +#define trybreak(pi, breaktype) ztrybreak((integer) (pi), (smallnumber) (breaktype)) +#define trybreak_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zpostlinebreak(); +#define postlinebreak(finalwidowpenalty) zpostlinebreak((integer) (finalwidowpenalty)) +#define postlinebreak_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +smallnumber zreconstitute(); +#define reconstitute(j, n, bchar, hchar) zreconstitute((smallnumber) (j), (smallnumber) (n), (halfword) (bchar), (halfword) (hchar)) +#define reconstitute_regmem register memoryword *mem=zmem; +void zhashfunk(); +#define hashfunk(w, anfang, ende, v, ind, k) zhashfunk( (w), (integer) (anfang), (integer) (ende), (v), (ind), (k)) +#define hashfunk_regmem +void zunpackinfo(); +#define unpackinfo(b, iausnahme, iuntrennbar, ierste, izweite, iendung, ivorsilbe, istamm, iehervor, istammallein) zunpackinfo((infobyte) (b), (boolean *) &(iausnahme), (boolean *) &(iuntrennbar), (integer *) &(ierste), (integer *) &(izweite), (boolean *) &(iendung), (boolean *) &(ivorsilbe), (boolean *) &(istamm), (boolean *) &(iehervor), (boolean *) &(istammallein)) +#define unpackinfo_regmem +void zunpackentry(); +#define unpackentry(h, etabv, etabb, efrei, ewiederfrei) zunpackentry( (h), (verdschlue *) &(etabv), (infobyte *) &(etabb), (boolean *) &(efrei), (boolean *) &(ewiederfrei)) +#define unpackentry_regmem +void zhashsuch(); +#define hashsuch(v, ind, k, iausnahme, iuntrennbar, ierste, izweite, iendung, ivorsilbe, istamm, iehervor, istammallein, g) zhashsuch((verdschlue) (v), (integer) (ind), (integer) (k), (boolean *) &(iausnahme), (boolean *) &(iuntrennbar), (integer *) &(ierste), (integer *) &(izweite), (boolean *) &(iendung), (boolean *) &(ivorsilbe), (boolean *) &(istamm), (boolean *) &(iehervor), (boolean *) &(istammallein), (boolean *) &(g)) +#define hashsuch_regmem +void zhashload(); +#define hashload(status) zhashload((integer *) &(status)) +#define hashload_regmem +void inittrennen(); +#define inittrennen_regmem +void zpackinfo(); +#define packinfo(i, b) zpackinfo((i), (infobyte *) &(b)) +#define packinfo_regmem +void zpackentry(); +#define packentry(e, h) zpackentry((e), (h)) +#define packentry_regmem +void zhashetr(); +#define hashetr(w, laenge, i, g) zhashetr( (w), (integer) (laenge), (i), (boolean *) &(g)) +#define hashetr_regmem +void hashempty(); +#define hashempty_regmem +void zhashsave(); +#define hashsave(status) zhashsave((integer *) &(status)) +#define hashsave_regmem +integer hashsize(); +#define hashsize_regmem +void zzahl(); +#define zahl(line, i, ende, j) zzahl( (line), (integer *) &(i), (integer) (ende), (integer *) &(j)) +#define zahl_regmem +void zinfobau(); +#define infobau(line, anfang, ende, informausnahme, informuntrennbar, informerste, informzweite, informendung, informvorsilbe, informstamm, informehervor, informstammallein, g) zinfobau( (line), (integer) (anfang), (integer) (ende), (boolean *) &(informausnahme), (boolean *) &(informuntrennbar), (integer *) &(informerste), (integer *) &(informzweite), (boolean *) &(informendung), (boolean *) &(informvorsilbe), (boolean *) &(informstamm), (boolean *) &(informehervor), (boolean *) &(informstammallein), (boolean *) &(g)) +#define infobau_regmem +void zeintragen(); +#define eintragen(line, l) zeintragen( (line), (integer) (l)) +#define eintragen_regmem +void znaechsterbst(); +#define naechsterbst(i, tr, dudstop, b, w) znaechsterbst((integer *) &(i), (tr), (dudstop), (buchstabe *) &(b), (w)) +#define naechsterbst_regmem +void zduden(); +#define duden(tr, w, tr1, dudtr, dud, dudstop, laenge, ok, zerlegungen) zduden( (tr), (w), (tr1), (dudtr), (dud), (dudstop), (integer) (laenge), (boolean *) &(ok), (integer *) &(zerlegungen)) +#define duden_regmem +void ztrennen(); +#define trennen(zustand, anfang, spv, ok1, tr, dudtr, zerlegungen, dud, v, ind, k, dudstop, w, tr1, laenge) ztrennen((integer) (zustand), (integer) (anfang), (spv), (boolean *) &(ok1), (tr), (dudtr), (integer *) &(zerlegungen), (dud), (v), (ind), (k), (dudstop), (w), (tr1), (integer) (laenge)) +#define trennen_regmem +void zabteilen(); +#define abteilen(w, tr1, laenge, ok, zerlegungen) zabteilen( (w), (tr1), (integer) (laenge), (boolean *) &(ok), (integer *) &(zerlegungen)) +#define abteilen_regmem +boolean zisdirtyumlaut(); +#define isdirtyumlaut(p) zisdirtyumlaut((halfword) (p)) +#define isdirtyumlaut_regmem register memoryword *mem=zmem; +integer zgetcharof(); +#define getcharof(s) zgetcharof((halfword) (s)) +#define getcharof_regmem register memoryword *mem=zmem; +integer zgetfontof(); +#define getfontof(s) zgetfontof((halfword) (s)) +#define getfontof_regmem register memoryword *mem=zmem; +void hyphenate(); +#define hyphenate_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +trieopcode znewtrieop(); +#define newtrieop(d, n, v) znewtrieop((smallnumber) (d), (smallnumber) (n), (trieopcode) (v)) +#define newtrieop_regmem +triepointer ztrienode(); +#define trienode(p) ztrienode((triepointer) (p)) +#define trienode_regmem +triepointer zcompresstrie(); +#define compresstrie(p) zcompresstrie((triepointer) (p)) +#define compresstrie_regmem +void zfirstfit(); +#define firstfit(p) zfirstfit((triepointer) (p)) +#define firstfit_regmem +void ztriepack(); +#define triepack(p) ztriepack((triepointer) (p)) +#define triepack_regmem +void ztriefix(); +#define triefix(p) ztriefix((triepointer) (p)) +#define triefix_regmem +void newpatterns(); +#define newpatterns_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void inittrie(); +#define inittrie_regmem +void zlinebreak(); +#define linebreak(finalwidowpenalty) zlinebreak((integer) (finalwidowpenalty)) +#define linebreak_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void newhyphexceptions(); +#define newhyphexceptions_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +halfword zprunepagetop(); +#define prunepagetop(p) zprunepagetop((halfword) (p)) +#define prunepagetop_regmem register memoryword *mem=zmem; +halfword zvertbreak(); +#define vertbreak(p, h, d) zvertbreak((halfword) (p), (scaled) (h), (scaled) (d)) +#define vertbreak_regmem register memoryword *mem=zmem; +halfword zvsplit(); +#define vsplit(n, h) zvsplit((eightbits) (n), (scaled) (h)) +#define vsplit_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void printtotals(); +#define printtotals_regmem +void zfreezepagespecs(); +#define freezepagespecs(s) zfreezepagespecs((smallnumber) (s)) +#define freezepagespecs_regmem register memoryword *eqtb=zeqtb; +void zboxerror(); +#define boxerror(n) zboxerror((eightbits) (n)) +#define boxerror_regmem register memoryword *eqtb=zeqtb; +void zensurevbox(); +#define ensurevbox(n) zensurevbox((eightbits) (n)) +#define ensurevbox_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zfireup(); +#define fireup(c) zfireup((halfword) (c)) +#define fireup_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void buildpage(); +#define buildpage_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void appspace(); +#define appspace_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void insertdollarsign(); +#define insertdollarsign_regmem +void youcant(); +#define youcant_regmem +void reportillegalcase(); +#define reportillegalcase_regmem +boolean privileged(); +#define privileged_regmem +boolean itsallover(); +#define itsallover_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void appendglue(); +#define appendglue_regmem register memoryword *mem=zmem; +void appendkern(); +#define appendkern_regmem register memoryword *mem=zmem; +void offsave(); +#define offsave_regmem register memoryword *mem=zmem; +void extrarightbrace(); +#define extrarightbrace_regmem +void normalparagraph(); +#define normalparagraph_regmem register memoryword *eqtb=zeqtb; +void zboxend(); +#define boxend(boxcontext) zboxend((integer) (boxcontext)) +#define boxend_regmem register memoryword *mem=zmem; +void zbeginbox(); +#define beginbox(boxcontext) zbeginbox((integer) (boxcontext)) +#define beginbox_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zscanbox(); +#define scanbox(boxcontext) zscanbox((integer) (boxcontext)) +#define scanbox_regmem +void zpackage(); +#define package(c) zpackage((smallnumber) (c)) +#define package_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +smallnumber znormmin(); +#define normmin(h) znormmin((integer) (h)) +#define normmin_regmem +void znewgraf(); +#define newgraf(indented) znewgraf((boolean) (indented)) +#define newgraf_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void indentinhmode(); +#define indentinhmode_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void headforvmode(); +#define headforvmode_regmem +void endgraf(); +#define endgraf_regmem register memoryword *eqtb=zeqtb; +void begininsertoradjust(); +#define begininsertoradjust_regmem +void makemark(); +#define makemark_regmem register memoryword *mem=zmem; +void appendpenalty(); +#define appendpenalty_regmem register memoryword *mem=zmem; +void deletelast(); +#define deletelast_regmem register memoryword *mem=zmem; +void unpackage(); +#define unpackage_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void appenditaliccorrection(); +#define appenditaliccorrection_regmem register memoryword *mem=zmem; +void appenddiscretionary(); +#define appenddiscretionary_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void builddiscretionary(); +#define builddiscretionary_regmem register memoryword *mem=zmem; +void makeaccent(); +#define makeaccent_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void alignerror(); +#define alignerror_regmem +void noalignerror(); +#define noalignerror_regmem +void omiterror(); +#define omiterror_regmem +void doendv(); +#define doendv_regmem +void cserror(); +#define cserror_regmem +void zpushmath(); +#define pushmath(c) zpushmath((groupcode) (c)) +#define pushmath_regmem +void initmath(); +#define initmath_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void starteqno(); +#define starteqno_regmem register memoryword *eqtb=zeqtb; +void zscanmath(); +#define scanmath(p) zscanmath((halfword) (p)) +#define scanmath_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void zsetmathchar(); +#define setmathchar(c) zsetmathchar((integer) (c)) +#define setmathchar_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void mathlimitswitch(); +#define mathlimitswitch_regmem register memoryword *mem=zmem; +void zscandelimiter(); +#define scandelimiter(p, r) zscandelimiter((halfword) (p), (boolean) (r)) +#define scandelimiter_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void mathradical(); +#define mathradical_regmem register memoryword *mem=zmem; +void mathac(); +#define mathac_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void appendchoices(); +#define appendchoices_regmem register memoryword *mem=zmem; +halfword zfinmlist(); +#define finmlist(p) zfinmlist((halfword) (p)) +#define finmlist_regmem register memoryword *mem=zmem; +void buildchoices(); +#define buildchoices_regmem register memoryword *mem=zmem; +void subsup(); +#define subsup_regmem register memoryword *mem=zmem; +void mathfraction(); +#define mathfraction_regmem register memoryword *mem=zmem; +void mathleftright(); +#define mathleftright_regmem register memoryword *mem=zmem; +void aftermath(); +#define aftermath_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void resumeafterdisplay(); +#define resumeafterdisplay_regmem +void getrtoken(); +#define getrtoken_regmem +void trapzeroglue(); +#define trapzeroglue_regmem register memoryword *mem=zmem; +void zdoregistercommand(); +#define doregistercommand(a) zdoregistercommand((smallnumber) (a)) +#define doregistercommand_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void alteraux(); +#define alteraux_regmem +void alterprevgraf(); +#define alterprevgraf_regmem +void alterpagesofar(); +#define alterpagesofar_regmem +void alterinteger(); +#define alterinteger_regmem +void alterboxdimen(); +#define alterboxdimen_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void znewfont(); +#define newfont(a) znewfont((smallnumber) (a)) +#define newfont_regmem register memoryword *eqtb=zeqtb; +void newinteraction(); +#define newinteraction_regmem +void prefixedcommand(); +#define prefixedcommand_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void doassignments(); +#define doassignments_regmem +void openorclosein(); +#define openorclosein_regmem +void issuemessage(); +#define issuemessage_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void shiftcase(); +#define shiftcase_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void showwhatever(); +#define showwhatever_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void storefmtfile(); +#define storefmtfile_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void znewwhatsit(); +#define newwhatsit(s, w) znewwhatsit((smallnumber) (s), (smallnumber) (w)) +#define newwhatsit_regmem register memoryword *mem=zmem; +void znewwritewhatsit(); +#define newwritewhatsit(w) znewwritewhatsit((smallnumber) (w)) +#define newwritewhatsit_regmem register memoryword *mem=zmem; +void doextension(); +#define doextension_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void fixlanguage(); +#define fixlanguage_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void handlerightbrace(); +#define handlerightbrace_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void maincontrol(); +#define maincontrol_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void giveerrhelp(); +#define giveerrhelp_regmem register memoryword *eqtb=zeqtb; +boolean openfmtfile(); +#define openfmtfile_regmem +boolean loadfmtfile(); +#define loadfmtfile_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void closefilesandterminate(); +#define closefilesandterminate_regmem register memoryword *eqtb=zeqtb; +void finalcleanup(); +#define finalcleanup_regmem register memoryword *mem=zmem; +void initprim(); +#define initprim_regmem register memoryword *eqtb=zeqtb; +void debughelp(); +#define debughelp_regmem register memoryword *mem=zmem, *eqtb=zeqtb; +void texbody(); +#define texbody_regmem register memoryword *eqtb=zeqtb; +/* + * The C compiler ignores most unnecessary casts (i.e., casts of something + * to its own type). However, for structures, it doesn't. Therefore, + * we have to redefine these two macros so that they don't try to cast + * the argument (a memoryword) as a memoryword. + */ +#undef eqdestroy +#define eqdestroy(x) zeqdestroy(x) +#undef printword +#define printword(x) zprintword(x) diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/ctex.ch b/obsolete/systems/sisisi/unix/SiTeX3.14/ctex.ch new file mode 100644 index 0000000000..0219aedbf2 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/ctex.ch @@ -0,0 +1,1877 @@ +% Change file for TeX in C, derived from various other change files. +% By Tim Morgan, UC Irvine ICS Department, and many others. +% +% +% Modification history: +% (05/28/86) ETM Started with TeX 2.0 +% (06/03/87) ETM Brought up to TeX 2.2 +% (09/26/87) ETM Brought up to TeX 2.3 +% (10/01/87) ETM Brought up to TeX 2.5 +% (12/21/87) ETM Brought up to TeX 2.7 +% (01/14/88) ETM Brought up to TeX 2.9 +% (02/20/88) PAM Revised format and module numbers +% (03/01/88) ETM Eliminated some unused variables and unnecesary tests +% (05/09/88) ETM Added yet another casting bug fix +% (06/21/88) ETM Brought up to TeX version 2.93 +% (12/11/88) ETM Brought up to TeX version 2.94 +% (01/12/89) PAM Brought up to TeX version 2.95 +% (02/14/89) ETM Brought up to TeX version 2.96 +% (03/10/89) ETM Brought up to TeX version 2.98 +% (07/06/89) ETM Brought up to TeX version 2.991 +% (11/30/89) KB To version 2.992 (8-bit). +% (01/10/90) SR To version 2.993. +% (03/27/90) KY To version 3.0. +% (more recent changes in ../ChangeLog.W2C) +% +% The module numbers in this change file refer to the published text in +% TeX: The Program, Volume B of Computers&Typesetting, 1986. + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [0] WEAVE: print changes only. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + \def\?##1]{\hbox to 1in{\hfil##1.\ }} + } +@y + \def\?##1]{\hbox{Changes to \hbox to 1em{\hfil##1}.\ }} + } +\let\maybe=\iffalse +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.2] banner (changed to show trie extension version) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d banner=='This is TeX, Version 3.14 (+SISISI 1.0)' +@y +@d banner=='This is TeX, C Version 3.14t3 (+SISISI 1.0)' {printed when \TeX\ starts} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.4] program header +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +Actually the heading shown here is not quite normal: The |program| line +does not mention any |output| file, because \ph\ would ask the \TeX\ user +to specify a file name if |output| were specified here. +@^system dependencies@> + +@d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:} +@f mtype==type {`\&{mtype}' will be equivalent to `\&{type}'} +@f type==true {but `|type|' will not be treated as a reserved word} + +@p @t\4@>@<Compiler directives@>@/ +program TEX; {all file names are defined dynamically} +label @<Labels in the outer block@>@/ +@y + +@d mtype==t@&y@&p@&e {this is a \.{WEB} coding trick:} +@f mtype==type {`\&{mtype}' will be equivalent to `\&{type}'} +@f type==true {but `|type|' will not be treated as a reserved word} + +@p @t\4@>@<Compiler directives@>@/ +program TEX; {all file names are defined dynamically} +@z + +@x +@<Labels in the out...@>= +start_of_TEX@t\hskip-2pt@>, end_of_TEX@t\hskip-2pt@>,@,final_end; + {key control points} +@y +@<Labels in the outer block@>= +start_of_TEX@t\hskip-2pt@>, end_of_TEX@t\hskip-2pt@>,@,final_end; + {key control points} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.7] debug..gubed, stat..tats +% Here we change these WEB symbols, which are used much as #ifdef's +% are in C, into something which will get translated into actual #ifdef's. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging} +@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging} +@y +@d debug==ifdef('DEBUG') +@d gubed==endif('DEBUG') +@z +@x +@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering + usage statistics} +@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering + usage statistics} +@y +@d stat==ifdef('STAT') +@d tats==endif('STAT') +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.8] Same, for `init..tini'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version} +@d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version} +@y +@d init==ifdef('INITEX') +@d tini==endif('INITEX') +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.9] Turn off all compiler directives. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@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 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.11] Compile-time constants: some enlarged, dvi_buf_size 16K for +% BSD I/O, file_name_size becomes FILENAMESIZE. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@<Constants...@>= +@!mem_max=30000; {greatest index in \TeX's internal |mem| array; + must be strictly less than |max_halfword|; + must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|} +@!mem_min=0; {smallest index in \TeX's internal |mem| array; + must be |min_halfword| or more; + must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|} +@!buf_size=500; {maximum number of characters simultaneously present in + current lines of open files and in control sequences between + \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|} +@!error_line=72; {width of context lines on terminal error messages} +@!half_error_line=42; {width of first lines of contexts in terminal + error messages; should be between 30 and |error_line-15|} +@!max_print_line=79; {width of longest text lines output; should be at least 60} +@!stack_size=200; {maximum number of simultaneous input sources} +@!max_in_open=6; {maximum number of input files and error insertions that + can be going on simultaneously} +@!font_max=75; {maximum internal font number; must not exceed |max_quarterword| + and must be at most |font_base+256|} +@!font_mem_size=20000; {number of words of |font_info| for all fonts} +@!param_size=60; {maximum number of simultaneous macro parameters} +@!nest_size=40; {maximum number of semantic levels simultaneously active} +@!max_strings=3000; {maximum number of strings; must not exceed |max_halfword|} +@!string_vacancies=8000; {the minimum number of characters that should be + available for the user's control sequences and font names, + after \TeX's own error messages are stored} +@!pool_size=32000; {maximum number of characters in strings, including all + error messages and help texts, and the names of all fonts and + control sequences; must exceed |string_vacancies| by the total + length of \TeX's own strings, which is currently about 23000} +@!save_size=600; {space for saving values outside of current group; must be + at most |max_halfword|} +@!trie_size=8000; {space for hyphenation patterns; should be larger for + \.{INITEX} than it is in production versions of \TeX} +@!trie_op_size=500; {space for ``opcodes'' in the hyphenation patterns} +@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} +@!file_name_size=40; {file names shouldn't be longer than this} +@!pool_name='TeXformats:SITEX3.POOL '; + {string of length |file_name_size|; tells where the string pool appears} +@y +@d file_name_size == FILENAMESIZE {Get value from \.{site.h}.} +@<Constants...@>= +@!mem_max=262140; {greatest index in \TeX's internal |mem| array; + must be strictly less than |max_halfword|; + must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|} +@!mem_min=0; {smallest index in \TeX's internal |mem| array; + must be |min_halfword| or more; + must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|} +@!buf_size=3000; {maximum number of characters simultaneously present in + current lines of open files and in control sequences between + \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|} +@!error_line=79; {width of context lines on terminal error messages} +@!half_error_line=50; {width of first lines of contexts in terminal + error messages; should be between 30 and |error_line-15|} +@!max_print_line=79; {width of longest text lines output; should be at least 60} +@!stack_size=300; {maximum number of simultaneous input sources} +@!max_in_open=15; {maximum number of input files and error insertions that + can be going on simultaneously} +@!font_max=255; {maximum internal font number; must not exceed |max_quarterword| + and must be at most |font_base+256|} +@!font_mem_size=72000; {number of words of |font_info| for all fonts} +@!param_size=60; {maximum number of simultaneous macro parameters} +@!nest_size=40; {maximum number of semantic levels simultaneously active} +@!max_strings=7500; {maximum number of strings; must not exceed |max_halfword|} +@!string_vacancies=74000; {the minimum number of characters that should be + available for the user's control sequences and font names, + after \TeX's own error messages are stored} +@!pool_size=100000; {maximum number of characters in strings, including all + error messages and help texts, and the names of all fonts and + control sequences; must exceed |string_vacancies| by the total + length of \TeX's own strings, which is currently about 23000} +@!save_size=4000; {space for saving values outside of current group; must be + at most |max_halfword|} +@!trie_size=24000; {space for hyphenation patterns; should be larger for + \.{INITEX} than it is in production versions of \TeX} +@!trie_op_size=750; {space for ``opcodes'' in the hyphenation patterns} +@!neg_trie_op_size=-750; {for lower trie_op_hash array bound} +@!min_trie_op=0; {first possible trie op code for any language} +@!max_trie_op=500; {largest possible trie op code for any language} +@!dvi_buf_size=16384; {size of the output buffer; must be a multiple of 8} +@!pool_name='sitex.pool'; + {string of length |file_name_size|; tells where the string pool appears} +@!mem_top=262140; {largest index in the |mem| array dumped by \.{INITEX}; + must be substantially larger than |mem_bot| + and not greater than |mem_max|} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.12] Sensitive compile-time constants. For C we change mem_base and +% hi_mem_base to reflect our use of 0-origin vs pc's use of +% negative-origin. Despite the fact that it is a ``sensitive'' +% constants, we're going to make mem_top a #define in the C code for +% readability and ease of modification (it's up above), since to needs +% to be changed for the trip test. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX}; + must not be less than |mem_min|} +@d mem_top==30000 {largest index in the |mem| array dumped by \.{INITEX}; + must be substantially larger than |mem_bot| + and not greater than |mem_max|} +@d font_base=0 {smallest internal font number; must not be less + than |min_quarterword|} +@d hash_size=2100 {maximum number of control sequences; it should be at most + about |(mem_max-mem_min)/10|} +@d hash_prime=1777 {a prime number equal to about 85\pct! of |hash_size|} +@d hyph_size=307 {another prime; the number of \.{\\hyphenation} exceptions} +@y +@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX}; + must not be less than |mem_min|} +@d font_base=0 {smallest internal font number; must not be less + than |min_quarterword|} +@d hash_size=9500 {maximum number of control sequences; it should be at most + about |(mem_max-mem_min)/10|} +@d hash_prime=7919 {a prime number equal to about 85\pct! of |hash_size|} +@d hyph_size=607 {another prime; the number of \.{\\hyphenation} exceptions} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.16] Use C macros for `incr' and `decr'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d incr(#) == #:=#+1 {increase a variable by unity} +@d decr(#) == #:=#-1 {decrease a variable by unity} +@y +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [??] The text_char type is used as an array index into xord. The +% default type `char' produces signed integers, which are bad array +% indices in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d text_char == char {the data type of characters in text files} +@y +@d text_char == ASCII_code {the data type of characters in text files} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [2.23] Allow any character as input. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +for i:=0 to @'37 do xchr[i]:=' '; +for i:=@'177 to @'377 do xchr[i]:=' '; +@y +for i:=0 to @'37 do xchr[i]:=chr(i); +for i:=@'177 to @'377 do xchr[i]:=chr(i); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.25] Remove file types we don't need. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +The program actually makes use also of a third kind of file, called a +|word_file|, when dumping and reloading base information for its own +initialization. We shall define a word file later; but it will be possible +for us to specify simple operations on word files before they are defined. + +@y +I/O in C is done using standard I/O. We will define the path numbers +in an include file for C which are used in searching for files to be +read. We'll define all the file types in C also. +@z + +@x +@!alpha_file=packed file of text_char; {files that contain textual data} +@!byte_file=packed file of eight_bits; {files that contain binary data} +@y +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.27] Do file opening in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ The \ph\ compiler with which the present version of \TeX\ was prepared has +extended the rules of \PASCAL\ in a very convenient way. To open file~|f|, +we can write +$$\vbox{\halign{#\hfil\qquad&#\hfil\cr +|reset(f,@t\\{name}@>,'/O')|&for input;\cr +|rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$ +The `\\{name}' parameter, which is of type `{\bf packed array +$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of +the external file that is being opened for input or output. +Blank spaces that might appear in \\{name} are ignored. + +The `\.{/O}' parameter tells the operating system not to issue its own +error messages if something goes wrong. If a file of the specified name +cannot be found, or if such a file cannot be opened for some other reason +(e.g., someone may already be trying to write the same file), we will have +|@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows +\TeX\ to undertake appropriate corrective action. +@:PASCAL H}{\ph@> +@^system dependencies@> + +\TeX's file-opening procedures return |false| if no file identified by +|name_of_file| could be opened. + +@d reset_OK(#)==erstat(#)=0 +@d rewrite_OK(#)==erstat(#)=0 + +@p function a_open_in(var f:alpha_file):boolean; + {open a text file for input} +begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f); +end; +@# +function a_open_out(var f:alpha_file):boolean; + {open a text file for output} +begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f); +end; +@# +function b_open_in(var f:byte_file):boolean; + {open a binary file for input} +begin reset(f,name_of_file,'/O'); b_open_in:=reset_OK(f); +end; +@# +function b_open_out(var f:byte_file):boolean; + {open a binary file for output} +begin rewrite(f,name_of_file,'/O'); b_open_out:=rewrite_OK(f); +end; +@# +function w_open_in(var f:word_file):boolean; + {open a word file for input} +begin reset(f,name_of_file,'/O'); w_open_in:=reset_OK(f); +end; +@# +function w_open_out(var f:word_file):boolean; + {open a word file for output} +begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f); +end; +@y +@ All of the file opening functions are defined in C. +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.28] Do file closing in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ Files can be closed with the \ph\ routine `|close(f)|', which +@^system dependencies@> +should be used when all input or output with respect to |f| has been completed. +This makes |f| available to be opened again, if desired; and if |f| was used for +output, the |close| operation makes the corresponding external file appear +on the user's area, ready to be read. + +These procedures should not generate error messages if a file is +being closed before it has been successfully opened. + +@p procedure a_close(var f:alpha_file); {close a text file} +begin close(f); +end; +@# +procedure b_close(var f:byte_file); {close a binary file} +begin close(f); +end; +@# +procedure w_close(var f:word_file); {close a word file} +begin close(f); +end; +@y +@ And all the file closing routines as well. +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.31] Do `input_ln' in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@p function input_ln(var f:alpha_file;@!bypass_eoln:boolean):boolean; + {inputs the next line or returns |false|} +var last_nonblank:0..buf_size; {|last| with trailing blanks removed} +begin if bypass_eoln then if not eof(f) then get(f); + {input the first character of the line into |f^|} +last:=first; {cf.\ Matthew 19\thinspace:\thinspace30} +if eof(f) then input_ln:=false +else begin last_nonblank:=first; + while not eoln(f) do + begin if last>=max_buf_stack then + begin max_buf_stack:=last+1; + if max_buf_stack=buf_size then + @<Report overflow of the input buffer, and abort@>; + end; + buffer[last]:=xord[f^]; get(f); incr(last); + if buffer[last-1]<>" " then last_nonblank:=last; + end; + last:=last_nonblank; input_ln:=true; + end; +end; +@y +We define |input_ln| in C, for efficiency. +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.32] `term_in' and `term_out' are standard input and output. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@<Glob...@>= +@!term_in:alpha_file; {the terminal as an input file} +@!term_out:alpha_file; {the terminal as an output file} +@y +@d term_in==stdin {the terminal as an input file} +@d term_out==stdout {the terminal as an output file} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.33] We don't need to open terminal files. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ Here is how to open the terminal files +in \ph. The `\.{/I}' switch suppresses the first |get|. +@^system dependencies@> + +@d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input} +@d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output} +@y +@ Here is how to open the terminal files. |t_open_out| does nothing. +|t_open_in|, on the other hand, does the work of ``rescanning,'' or getting +any command line arguments the user has provided. It's defined in C. + +@d t_open_out == {output already open for text output} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.34] Flushing output. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +these operations can be specified in \ph: +@^system dependencies@> + +@d update_terminal == break(term_out) {empty the terminal output buffer} +@d clear_terminal == break_in(term_in,true) {clear the terminal input buffer} +@y +these operations can be specified with {\mc UNIX}. |update_terminal| +does an |fflush| (via the macro |flush|). |clear_terminal| is redefined +to do nothing, since the user should control the terminal. +@^system dependencies@> + +@d update_terminal == flush (term_out) +@d clear_terminal == do_nothing +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.37] Reading the command line. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ The following program does the required initialization +without retrieving a possible command line. +It should be clear how to modify this routine to deal with command lines, +if the system permits them. +@^system dependencies@> + +@p function init_terminal:boolean; {gets the terminal input started} +label exit; +begin t_open_in; +loop@+begin wake_up_terminal; write(term_out,'**'); update_terminal; +@.**@> + if not input_ln(term_in,true) then {this shouldn't happen} + begin write_ln(term_out); + write(term_out,'! End of file on the terminal... why?'); +@.End of file on the terminal@> + init_terminal:=false; return; + end; + loc:=first; + while (loc<last)and(buffer[loc]=" ") do incr(loc); + if loc<last then + begin init_terminal:=true; + return; {return unless the line was all blank} + end; + write_ln(term_out,'Please type the name of your input file.'); + end; +exit:end; +@y +@ The following program does the required initialization. +Iff anything has been specified on the command line, then |t_open_in| +will return with |last > first|. +@^system dependencies@> + +@p +function init_terminal:boolean; {gets the terminal input started} +label exit; +begin + t_open_in; + if last > first then begin + loc := first; + while (loc < last) and (buffer[loc]=' ') do + incr(loc); + if loc < last then begin + init_terminal := true; + goto exit; + end; + end; + loop@+begin + wake_up_terminal; write(term_out, '**'); update_terminal; +@.**@> + if not input_ln(term_in,true) then begin {this shouldn't happen} + write_ln(term_out); + write(term_out, '! End of file on the terminal... why?'); +@.End of file on the terminal@> + init_terminal:=false; + return; + end; + + loc:=first; + while (loc<last)and(buffer[loc]=" ") do + incr(loc); + + if loc<last then begin + init_terminal:=true; + return; {return unless the line was all blank} + end; + write_ln(term_out, 'Please type the name of your input file.'); + end; +exit: +end; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [4.51] Open the pool file using a path, and can't do string +% assignments directly. (`strcpy' and `strlen' work here because +% `pool_name' is a constant string, and thus ends in a null and doesn't +% start with a space.) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +name_of_file:=pool_name; {we needn't set |name_length|} +if a_open_in(pool_file) then +@y +vstrcpy (name_of_file+1, pool_name); {copy the string} +name_of_file[0] := ' '; +name_of_file[strlen (pool_name)+1] := ' '; +if a_open_in (pool_file, TEX_POOL_PATH) then +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [4.51,52,53] Make `TEX.POOL' lowercase in messages, and change how +% it's read. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +else bad_pool('! I can''t read SITEX3.POOL.'); +@y +else begin + {Like |bad_pool|, but must not close file if we never opened it} + wake_up_terminal; write_ln(term_out, '! I can''t read sitex.pool.'); + get_strings_started:= false; return; +end +@z +@x +begin if eof(pool_file) then bad_pool('! TEX.POOL has no check sum.'); +@.TEX.POOL has no check sum@> +read(pool_file,m,n); {read two digits of string length} +@y +begin if eof(pool_file) then bad_pool('! sitex.pool has no check sum.'); +@.TEX.POOL has no check sum@> +read(pool_file,m); read(pool_file,n); {read two digits of string length} +@z +@x + bad_pool('! TEX.POOL line doesn''t begin with two digits.'); +@y + bad_pool('! sitex.pool line doesn''t begin with two digits.'); +@z +@x + bad_pool('! TEX.POOL check sum doesn''t have nine digits.'); +@y + bad_pool('! sitex.pool check sum doesn''t have nine digits.'); +@z +@x +done: if a<>@$ then bad_pool('! TEX.POOL doesn''t match; TANGLE me again.'); +@y +done: if a<>@$ then bad_pool('! sitex.pool doesn''t match; tangle me again.'); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [5.61] Eliminate the misleading message ``(no format preloaded)''. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if format_ident=0 then wterm_ln(' (no format preloaded)') +else begin print(format_ident); print_ln; + end; +@y +if format_ident>0 then print(format_ident); +print_ln; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [6.81] Eliminate nonlocal goto, since C doesn't have them. +% Plus, it's nicer just to do an exit with the appropriate status code +% under Unix. We call it `uexit' because there's a WEB symbol called +% `exit' already. We use a C macro to change `uexit' back to `exit'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@<Error hand...@>= +procedure jump_out; +begin goto end_of_TEX; +end; +@y +@d do_final_end==begin + update_terminal; + ready_already:=0; + if (history <> spotless) and (history <> warning_issued) then + uexit(1) + else + uexit(0); + end +@<Error hand...@>= +procedure jump_out; +begin +close_files_and_terminate; +do_final_end; +end; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [6.84] Implement the switch-to-editor option. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +line ready to be edited. But such an extension requires some system +wizardry, so the present implementation simply types out the name of the +file that should be +edited and the relevant line number. +@^system dependencies@> + +There is a secret `\.D' option available when the debugging routines haven't +been commented~out. +@^debugging@> +@y +line ready to be edited. +We do this by calling the external procedure |call_edit| with a pointer to +the filename, its length, and the line number. +However, here we just set up the variables that will be used as arguments, +since we don't want to do the switch-to-editor until after TeX has closed +its files. +@^system dependencies@> + +There is a secret `\.D' option available when the debugging routines haven't +been commented~out. +@^debugging@> +@d edit_file==input_stack[base_ptr] +@z +@x +"E": if base_ptr>0 then + begin print_nl("You want to edit file "); +@.You want to edit file x@> + print(input_stack[base_ptr].name_field); + print(" at line "); print_int(line); + interaction:=scroll_mode; jump_out; +@y +"E": if base_ptr>0 then + begin + edit_name_start:=str_start[edit_file.name_field]; + edit_name_length:=str_start[edit_file.name_field+1] - + str_start[edit_file.name_field]; + edit_line:=line; + jump_out; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [7.109] Define glue_ratio in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!glue_ratio=real; {one-word representation of a glue expansion factor} +@y +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [8.110] Make it easy to build a bigger TeX. (Nothing is changed in +% the basic version.) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d min_quarterword=0 {smallest allowable value in a |quarterword|} +@d max_quarterword=255 {largest allowable value in a |quarterword|} +@d min_halfword==0 {smallest allowable value in a |halfword|} +@d max_halfword==65535 {largest allowable value in a |halfword|} +@y +@d min_quarterword=0 {smallest allowable value in a |quarterword|} +@d max_quarterword=255 {largest allowable value in a |quarterword|} +@d min_halfword==0 {smallest allowable value in a |halfword|} +@d max_halfword==262143 {largest allowable value in a |halfword|} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [8.112] Efficiency. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +The inner loop of \TeX\ will run faster with respect to compilers +that don't optimize expressions like `|x+0|' and `|x-0|', if these +macros are simplified in the obvious way when |min_quarterword=0|. +@^inner loop@>@^system dependencies@> + +@d qi(#)==#+min_quarterword + {to put an |eight_bits| item into a quarterword} +@d qo(#)==#-min_quarterword + {to take an |eight_bits| item out of a quarterword} +@d hi(#)==#+min_halfword + {to put a sixteen-bit item into a halfword} +@d ho(#)==#-min_halfword + {to take a sixteen-bit item from a halfword} +@y +The inner loop of \TeX\ will run faster with respect to compilers +that don't optimize expressions like `|x+0|' and `|x-0|', if these +macros are simplified in the obvious way when |min_quarterword=0|. +So they have been simplified here in the obvious way. +@^inner loop@>@^system dependencies@> + +@d qi(#)==# {to put an |eight_bits| item into a quarterword} +@d qo(#)==# {to take an |eight_bits| item from a quarterword} +@d hi(#)==# {to put a sixteen-bit item into a halfword} +@d ho(#)==# {to take a sixteen-bit item from a halfword} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [8.113] Put the memory structure into an include file, since it's too +% hard to translate automatically. Also, remove the `word_file' type. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!quarterword = min_quarterword..max_quarterword; {1/4 of a word} +@!halfword=min_halfword..max_halfword; {1/2 of a word} +@!two_choices = 1..2; {used when there are two variants in a record} +@!four_choices = 1..4; {used when there are four variants in a record} +@!two_halves = packed record@;@/ + @!rh:halfword; + case two_choices of + 1: (@!lh:halfword); + 2: (@!b0:quarterword; @!b1:quarterword); + end; +@!four_quarters = packed record@;@/ + @!b0:quarterword; + @!b1:quarterword; + @!b2:quarterword; + @!b3:quarterword; + end; +@!memory_word = record@;@/ + case four_choices of + 1: (@!int:integer); + 2: (@!gr:glue_ratio); + 3: (@!hh:two_halves); + 4: (@!qqqq:four_quarters); + end; +@!word_file = file of memory_word; +@y +@!quarterword=min_quarterword..max_quarterword; +@!halfword=min_halfword..max_halfword; +@!two_choices = 1..2; {used when there are two variants in a record} +@!four_choices = 1..4; {used when there are four variants in a record} +@=#include "memory.h";@> +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [9.116] Change `mem' to `zmem', so we can define mem to be a register +% pointer to the memory array for speed. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!mem : array[mem_min..mem_max] of memory_word; {the big dynamic storage area} +@y +@!zmem : array[mem_min..mem_max] of memory_word; {the big dynamic storage area} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [9.127] Fix casting problem in C. +% There are several of these. They come from the rules C uses for +% comparing signed and unsigned quantities. Just doing the comparison +% can result in incorrect evaluation wrt the way Pascal would do it. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if r>p+1 then @<Allocate from the top of node |p| and |goto found|@>; +@y +if r>toint(p+1) then @<Allocate from the top of node |p| and |goto found|@>; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [11.165] Fix the word `free' so that it doesn't conflict with the +% standard C library routine of the same name. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +been included. (You may want to decrease the size of |mem| while you +@^debugging@> +are debugging.) +@y +been included. (You may want to decrease the size of |mem| while you +@^debugging@> +are debugging.) + +@d free==free_arr +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [12.174,176] Eliminate some unsigned comparisons to zero. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + begin if (font(p)<font_base)or(font(p)>font_max) then + print_char("*") +@y + begin if (font(p)>font_max) then + print_char("*") +@z + +@x +@p procedure print_font_and_char(@!p:integer); {prints |char_node| data} +begin if p>mem_end then print_esc("CLOBBERED.") +else begin if (font(p)<font_base)or(font(p)>font_max) then print_char("*") +@y +@p procedure print_font_and_char(@!p:integer); {prints |char_node| data} +begin if p>mem_end then print_esc("CLOBBERED.") +else begin if (font(p)>font_max) then print_char("*") +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [12.186] Don't worry about strange floating point values. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + if glue_sign(p)=shrinking then print("- "); + if abs(mem[p+glue_offset].int)<@'4000000 then print("?.?") + else if abs(g)>float_constant(20000) then +@y + if glue_sign(p)=shrinking then print("- "); + { The Unix |pc| folks removed this restriction with a remark that + invalid bit patterns were vanishingly improbable, so we follow + their example without really understanding it. + |if abs(mem[p+glue_offset].int)<@'4000000 then print('?.?')| + |else| } + if fabs(g)>float_constant(20000) then +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [17.241] Do `fix_date_and_time' in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ The following procedure, which is called just before \TeX\ initializes its +input and output, establishes the initial values of the date and time. +@^system dependencies@> +Since standard \PASCAL\ cannot provide such information, something special +is needed. The program here simply specifies July 4, 1776, at noon; but +users probably want a better approximation to the truth. + +@p procedure fix_date_and_time; +begin time:=12*60; {minutes since midnight} +day:=4; {fourth day of the month} +month:=7; {seventh month of the year} +year:=1776; {Anno Domini} +end; +@y +@ The following procedure, which is called just before \TeX\ initializes its +input and output, establishes the initial values of the date and time. +It calls a macro-defined |date_and_time| routine. |date_and_time| +in turn is a C macro, which calls |get_date_and_time|, passing +it the addresses of the day, month, etc., so they can be set by the +routine. |get_date_and_time| also sets up interrupt catching if that +is conditionally compiled in the C code. +@^system dependencies@> + +@d fix_date_and_time==date_and_time(time,day,month,year) +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [17.253] Change eqtb to zeqtb. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!eqtb:array[active_base..eqtb_size] of memory_word; +@y +@!zeqtb:array[active_base..eqtb_size] of memory_word; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [18.262] Remove more unsigned comparisons to zero. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +else if (text(p)<0)or(text(p)>=str_ptr) then print_esc("NONEXISTENT.") +@y +else if (text(p)>=str_ptr) then print_esc("NONEXISTENT.") +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.513] Area and extension rules for filenames. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ The file names we shall deal with for illustrative purposes have the +following structure: If the name contains `\.>' or `\.:', the file area +consists of all characters up to and including the final such character; +otherwise the file area is null. If the remaining file name contains +`\..', the file extension consists of all such characters from the first +remaining `\..' to the end, otherwise the file extension is null. +@^system dependencies@> + +We can scan such file names easily by using two global variables that keep track +of the occurrences of area and extension delimiters: + +@<Glob...@>= +@!area_delimiter:pool_pointer; {the most recent `\.>' or `\.:', if any} +@!ext_delimiter:pool_pointer; {the relevant `\..', if any} +@y +@ The file names we shall deal with for illustrative purposes have the +following structure: If the name contains `\./', the file area +consists of all characters up to and including the final such character; +otherwise the file area is null. If the remaining file name contains +`\..', the file extension consists of all such characters from the last +`\..' to the end, otherwise the file extension is null. +@^system dependencies@> + +We can scan such file names easily by using two global variables that keep +track of the occurrences of area and extension delimiters: + +@<Glob...@>= +@!area_delimiter:pool_pointer; {the most recent `\./', if any} +@!ext_delimiter:pool_pointer; {the most recent `\..', if any} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.514] TeX area directories. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d TEX_area=="TeXinputs:" +@.TeXinputs@> +@d TEX_font_area=="TeXfonts:" +@.TeXfonts@> +@y +In C, the default paths are specified in a separate +file, \.{site.h}. The file opening procedures do path searching +based either on those default paths, or on paths given by the user +in environment variables. +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.516] more_name +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +else begin str_room(1); append_char(c); {contribute |c| to the current string} + if (c=">")or(c=":") then + begin area_delimiter:=cur_length; ext_delimiter:=0; + end + else if (c=".")and(ext_delimiter=0) then ext_delimiter:=cur_length; +@y +else begin str_room(1); append_char(c); {contribute |c| to the current string} + if (c="/") then + begin area_delimiter:=cur_length; ext_delimiter:=0; + end + else if c="." then ext_delimiter:=cur_length; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.520] The default format. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d format_default_length=20 {length of the |TEX_format_default| string} +@d format_area_length=11 {length of its area part} +@d format_ext_length=4 {length of its `\.{.fmt}' part} +@y +Under {\mc UNIX} we don't give the area part, instead depending +on the path searching that will happen during file opening. Also, the +length will be set in the main program. + +@d format_area_length=0 {length of its area part} +@d format_ext_length=4 {length of its `\.{.fmt}' part} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.521] Where `plain.fmt' is. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!TEX_format_default:packed array[1..format_default_length] of char; + +@ @<Set init...@>= +TEX_format_default:='TeXformats:plain.fmt'; +@y +@!format_default_length: integer; +@!TEX_format_default: c_char_pointer; + +@ We set the name of the default format file and the length of that name +in C, instead of Pascal, since we want them to depend on the name of the +program. +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.524] Format file opening: only try once, with path searching. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + pack_buffered_name(0,loc,j-1); {try first without the system file area} + if w_open_in(fmt_file) then goto found; + pack_buffered_name(format_area_length,loc,j-1); + {now try the system format file area} + if w_open_in(fmt_file) then goto found; +@y + pack_buffered_name(0,loc,j-1); + if w_open_in(fmt_file) then goto found; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% (still [29.524]) replace `PLAIN' in error messages with `default'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + wterm_ln('Sorry, I can''t find that format;',' will try PLAIN.'); +@y + wterm_ln('Sorry, I can''t find that format;',' will try the default.'); +@z +@x + wterm_ln('I can''t find the PLAIN format file!'); +@.I can't find PLAIN...@> +@y + wterm_ln('I can''t find the default format file!'); +@.I can't find default format...@> +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.534] Adjust for C string conventions. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!months:packed array [1..36] of char; {abbreviations of month names} +@y +@!months:c_char_pointer; +@z + +@x +months:='JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'; +@y +months := ' JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC'; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.537] Use a path when calling a_open_in to do a \input; also, try +% to open the file with and without the `.tex' extension, regardless of +% whether the file already has an extension. This allows filenames like +% `foo' and `foo.bar.tex', as well as `foo.tex' and `foo.bar'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if cur_ext="" then cur_ext:=".tex"; +pack_cur_name; +loop@+ begin begin_file_reading; {set up |cur_file| and new level of input} + if a_open_in(cur_file) then goto done; + if cur_area="" then + begin pack_file_name(cur_name,TEX_area,cur_ext); + if a_open_in(cur_file) then goto done; + end; +@y +pack_cur_name; {Try without |".tex"|.} +loop@+begin + begin_file_reading; {set up |cur_file| and new level of input} + if a_open_in (cur_file, TEX_INPUT_PATH) then goto done; + pack_cur_name; {Try adding |".tex"|, even if we already have an extension.} + if name_length < file_name_size + 5 {Don't overflow the array.} + then begin + name_of_file[name_length + 1] := "."; + name_of_file[name_length + 2] := "t"; + name_of_file[name_length + 3] := "e"; + name_of_file[name_length + 4] := "x"; + name_length := name_length + 4; + end; + if a_open_in (cur_file, TEX_INPUT_PATH) then goto done; +@z + +% Knuth should fix this bug. +@x +if term_offset+length(name)>max_print_line-2 then print_ln +@y +if term_offset+length(name)>max_print_line-3 then print_ln +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.537] Get rid of return of filename to string pool. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if name=str_ptr-1 then {we can conserve string pool space now} + begin flush_string; name:=cur_name; + end; +@y +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [30.563] Fix TFM file opening. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +file_opened:=false; +if aire="" then pack_file_name(nom,TEX_font_area,".tfm") +else pack_file_name(nom,aire,".tfm"); +if not b_open_in(tfm_file) then abort; +file_opened:=true +@y +file_opened:=false; +pack_file_name(nom,aire,".tfm"); +if not b_open_in(tfm_file) then abort; +file_opened:=true +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [30.564] Reading the tfm file. As a special case, whenever we open a +% tfm file, we read its first byte into `tfm_temp' right away. TeX +% looks at `fbyte' before calling `fget', so it ends up seeing every +% byte. This is Pascal-like I/O. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d fget==get(tfm_file) +@d fbyte==tfm_file^ +@y +@d fget==tfm_temp:=getc(tfm_file) +@d fbyte==tfm_temp +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [32.597] We only want `eof' on the TFM file to be true if we +% previously had EOF, not if we're at EOF now. This is like `feof', and +% unlike our implementation of `eof' elsewhere. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if eof(tfm_file) then abort; +@y +if feof(tfm_file) then abort; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [32.597] write_dvi +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@p procedure write_dvi(@!a,@!b:dvi_index); +var k:dvi_index; +begin for k:=a to b do write(dvi_file,dvi_buf[k]); +end; +@y +In C, we use a macro to call |fwrite| or |write| directly, writing all +the bytes to be written in one shot. Much better even than writing four +bytes at a time. +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [38.859] Fix a casting/expression evaluation problem. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if abs(fit_class-fitness(r))>1 then d:=d+adj_demerits; +@y +if abs(toint(fit_class)-toint(fitness(r)))>1 then d:=d+adj_demerits; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [39.875] Another casting problem. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +repeat if type(r)<>delta_node then + begin line_diff:=line_number(r)-best_line; +@y +repeat if type(r)<>delta_node then + begin line_diff:=toint(line_number(r))-toint(best_line); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [42.920,921,923,924] Allow larger hyphenation tries. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +Comparatively few different number sequences $n_0\ldots n_k$ actually occur, +since most of the |n|'s are generally zero. Therefore the number sequences +are encoded in such a way that |trie_op|$(z_k)$ is only one byte long. +If |trie_op(@t$z_k$@>)<>min_quarterword|, when $p_1\ldots p_k$ has matched +the letters in |hc[(l-k+1)..l@,]| of language |t|, +we perform all of the required operations +for this pattern by carrying out the following little program: Set +|v:=trie_op(@t$z_k$@>)|. Then set |v:=v+op_start[t]|, +|hyf[l-hyf_distance[v]]:=@tmax@>(hyf[l-hyf_distance[v]], hyf_num[v])|, +and |v:=hyf_next[v]|; repeat, if necessary, until |v=min_quarterword|. +@y +The theory that comparatively few different number sequences $n_0\ldots n_k$ +actually occur, since most of the |n|'s are generally zero, seems to fail +at least for the large German hyphenation patterns. +Therefore the number sequences cannot any longer be encoded in such a way +that |trie_op|$(z_k)$ is only one byte long. +We have introduced a new constant |max_trie_op| for the maximum allowable +hyphenation operation code value; |max_trie_op| might be different for +\TeX\ and \.{INITEX} and must not exceed |max_halfword|. +An opcode will occupy a halfword if |max_trie_op| exceeds |max_quarterword| +or a quarterword otherwise. +@^system dependencies@> +If |trie_op(@t$z_k$@>)<>min_trie_op|, when $p_1\ldots p_k$ has matched +the letters in |hc[(l-k+1)..l@,]| of language |t|, +we perform all of the required operations +for this pattern by carrying out the following little program: Set +|v:=trie_op(@t$z_k$@>)|. Then set |v:=v+op_start[t]|, +|hyf[l-hyf_distance[v]]:=@tmax@>(hyf[l-hyf_distance[v]], hyf_num[v])|, +and |v:=hyf_next[v]|; repeat, if necessary, until |v=min_trie_op|. +@z +@x +@!trie_pointer=0..trie_size; {an index into |trie|} +@y +@!trie_opcode=min_trie_op..max_trie_op; {a trie opcode} +@!trie_pointer=0..trie_size; {an index into |trie|} +@z +@x +@ @d trie_link(#)==trie[#].rh {``downward'' link in a trie} +@d trie_char(#)==trie[#].b1 {character matched at this trie location} +@d trie_op(#)==trie[#].b0 {program for hyphenation at this trie location} +@y +@ For more than 255 trie op codes, the three fields |trie_link|, |trie_char|, +and |trie_op| will no longer fit into one memory word; thus using web2c +we define |trie| as three array instead of an array of records. +The variant will be implented by reusing the opcode field later on with +another macro. +@d trie_link(#)==trie_trl[#] {``downward'' link in a trie} +@d trie_char(#)==trie_trc[#] {character matched at this trie location} +@d trie_op(#)==trie_tro[#] {program for hyphenation at this trie location} +@z +@x +@!trie:array[trie_pointer] of two_halves; {|trie_link|, |trie_char|, |trie_op|} +@y +@!trie_trl:array[trie_pointer] of halfword; {|trie_link|} +@!trie_tro:array[trie_pointer] of halfword; {|trie_op| and |trie_link|} +@!trie_trc:array[trie_pointer] of quarterword; {|trie_char|} +@z +%@x +% begin if trie_op(z)<>min_quarterword then +%@y +% begin if trie_op(z)<>min_trie_op then +%@z +%@x +%until v=min_quarterword; +%@y +%until v=min_trie_op; +%@z +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.943] Larger tries, also in documentation parts. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +|hyf_next[@t$v^\prime$@>]=min_quarterword|. +@y +|hyf_next[@t$v^\prime$@>]=min_trie_op|. +@z +@x +$$\hbox{|@t$v^\prime$@>:=new_trie_op(0,1,min_quarterword)|,\qquad +@y +$$\hbox{|@t$v^\prime$@>:=new_trie_op(0,1,min_trie_op)|,\qquad +@z +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.?] Hack around the negative lower bound here. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +The hash table is called |trie_op_hash|, and the number of entries it contains +is |trie_op_ptr|. + +@<Glob...@>= +@!init@! trie_op_hash:array[-trie_op_size..trie_op_size] of 0..trie_op_size; +@y +The hash table is called |trie_op_hash|, and the number of entries it contains +is |trie_op_ptr|. + +@<Glob...@>= +@!init@! trie_op_hash:array[neg_trie_op_size..trie_op_size] of 0..trie_op_size; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.943,944] Larger hyphenation tries. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!trie_used:array[ASCII_code] of quarterword; +@y +@!trie_used:array[ASCII_code] of trie_opcode; +@z +@x +@!trie_op_val:array[1..trie_op_size] of quarterword; +@y +@!trie_op_val:array[1..trie_op_size] of trie_opcode; +@z +@x +tini +@y +tini@; +@!max_op_used:trie_opcode; {largest opcode used for any language} +@!small_op:boolean; {flag used while dumping or undumping} +@z +@x +|new_trie_op| could return |min_quarterword| (thereby simply ignoring +@y +|new_trie_op| could return |min_trie_op| (thereby simply ignoring +@z +@x +function new_trie_op(@!d,@!n:small_number;@!v:quarterword):quarterword; +label exit; +var h:-trie_op_size..trie_op_size; {trial hash location} +@!u:quarterword; {trial op code} +@y +function new_trie_op(@!d,@!n:small_number;@!v:trie_opcode):trie_opcode; +label exit; +var h:neg_trie_op_size..trie_op_size; {trial hash location} +@!u:trie_opcode; {trial op code} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.944] Another casting problem. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +begin h:=abs(n+313*d+361*v+1009*cur_lang) mod (trie_op_size+trie_op_size) +@y +begin h:=abs(toint(n)+313*toint(d)+361*toint(v)+1009*toint(cur_lang)) + mod (trie_op_size+trie_op_size) +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.944,945,946] And larger tries again. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + if u=max_quarterword then + overflow("pattern memory ops per language", + max_quarterword-min_quarterword); + incr(trie_op_ptr); incr(u); trie_used[cur_lang]:=u; +@y + if u=max_trie_op then + overflow("pattern memory ops per language", + max_trie_op-min_trie_op); + incr(trie_op_ptr); incr(u); trie_used[cur_lang]:=u; + if u>max_op_used then max_op_used:=u; +@z +@x +op_start[0]:=-min_quarterword; +@y +op_start[0]:=-min_trie_op; +@z +@x +for k:=0 to 255 do trie_used[k]:=min_quarterword; +@y +for k:=0 to 255 do trie_used[k]:=min_trie_op; +@z +@x +trie_op_ptr:=0; +@y +max_op_used:=min_trie_op; +trie_op_ptr:=0; +@z +@x +@t\hskip10pt@>@!trie_o:packed array[trie_pointer] of quarterword; +@y +@t\hskip10pt@>@!trie_o:packed array[trie_pointer] of trie_opcode; +@z +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.947] And another. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +begin h:=abs(trie_c[p]+1009*trie_o[p]+@| + 2718*trie_l[p]+3142*trie_r[p]) mod trie_size; +@y +begin h:=abs(toint(trie_c[p])+1009*toint(trie_o[p])+@| + 2718*toint(trie_l[p])+3142*toint(trie_r[p])) mod trie_size; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [43.950,958,960,963] Larger tries. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d trie_back(#)==trie[#].lh {backward links in |trie| holes} +@y +@d trie_back(#)==trie_tro[#] {use the opcode field now for backward links} +@z +@x +@<Move the data into |trie|@>= +h.rh:=0; h.b0:=min_quarterword; h.b1:=min_quarterword; {|trie_link:=0|, + |trie_op:=min_quarterword|, |trie_char:=qi(0)|} +if trie_root=0 then {no patterns were given} + begin for r:=0 to 256 do trie[r]:=h; +@y +@d clear_trie == {clear |trie[r]|} + begin trie_link(r):=0; + trie_op(r):=min_trie_op; + trie_char(r):=min_quarterword; {|trie_char:=qi(0)|} + end +@<Move the data into |trie|@>= +if trie_root=0 then {no patterns were given} + begin for r:=0 to 256 do clear_trie; +@z +@x + repeat s:=trie_link(r); trie[r]:=h; r:=s; +@y + repeat s:=trie_link(r); clear_trie; r:=s; +@z +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [49.1275] Same stuff as for \input, this time for \openin. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + if cur_ext="" then cur_ext:=".tex"; + pack_cur_name; + if a_open_in(read_file[n]) then read_open[n]:=just_open; +@y + pack_cur_name; + if a_open_in (read_file[n], TEX_INPUT_PATH) + then read_open[n] := just_open + else begin + pack_cur_name; + if name_length < file_name_size + 5 {Don't overflow the array.} + then begin + name_of_file[name_length + 1] := "."; + name_of_file[name_length + 2] := "t"; + name_of_file[name_length + 3] := "e"; + name_of_file[name_length + 4] := "x"; + name_length := name_length + 4; + end; + if a_open_in (read_file[n], TEX_INPUT_PATH) + then read_open[n] := just_open; + end; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.1302] Eliminate now-unused variable `w' in `store_fmt_file'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!x: integer; {something to dump} +@!w: four_quarters; {four ASCII codes} +@y +@!x: integer; {something to dump} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.1303] Ditto, for `load_fmt_file'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!x: integer; {something undumped} +@!w: four_quarters; {four ASCII codes} +@y +@!x: integer; {something undumped} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.??] Do reading and writing of `fmt_file' in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d dump_wd(#)==begin fmt_file^:=#; put(fmt_file);@+end +@d dump_int(#)==begin fmt_file^.int:=#; put(fmt_file);@+end +@d dump_hh(#)==begin fmt_file^.hh:=#; put(fmt_file);@+end +@d dump_qqqq(#)==begin fmt_file^.qqqq:=#; put(fmt_file);@+end +@y +@z + +@x +@d undump_wd(#)==begin get(fmt_file); #:=fmt_file^;@+end +@d undump_int(#)==begin get(fmt_file); #:=fmt_file^.int;@+end +@d undump_hh(#)==begin get(fmt_file); #:=fmt_file^.hh;@+end +@d undump_qqqq(#)==begin get(fmt_file); #:=fmt_file^.qqqq;@+end +@y +@z + +@x +x:=fmt_file^.int; +@y +undump_int(x); {This reads the first word of the \.{.fmt} file} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [??] Make dumping/undumping more efficient. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +for k:=0 to str_ptr do dump_int(str_start[k]); +k:=0; +while k+4<pool_ptr do + begin dump_four_ASCII; k:=k+4; + end; +k:=pool_ptr-4; dump_four_ASCII; +@y +dump_things(str_start[0], str_ptr+1); +dump_things(str_pool[0], pool_ptr); +@z + +@x +for k:=0 to str_ptr do undump(0)(pool_ptr)(str_start[k]); +k:=0; +while k+4<pool_ptr do + begin undump_four_ASCII; k:=k+4; + end; +k:=pool_ptr-4; undump_four_ASCII; +@y +undump_things(str_start[0], str_ptr+1); +undump_things(str_pool[0], pool_ptr); +@z + +@x +repeat for k:=p to q+1 do dump_wd(mem[k]); +x:=x+q+2-p; var_used:=var_used+q-p; +p:=q+node_size(q); q:=rlink(q); +until q=rover; +var_used:=var_used+lo_mem_max-p; dyn_used:=mem_end+1-hi_mem_min;@/ +for k:=p to lo_mem_max do dump_wd(mem[k]); +x:=x+lo_mem_max+1-p; +dump_int(hi_mem_min); dump_int(avail); +for k:=hi_mem_min to mem_end do dump_wd(mem[k]); +@y +repeat + dump_things(mem[p], q+2-p); +x:=x+q+2-p; var_used:=var_used+q-p; +p:=q+node_size(q); q:=rlink(q); +until q=rover; +var_used:=var_used+lo_mem_max-p; dyn_used:=mem_end+1-hi_mem_min;@/ +dump_things(mem[p], lo_mem_max+1-p); +x:=x+lo_mem_max+1-p; +dump_int(hi_mem_min); dump_int(avail); +dump_things(mem[hi_mem_min], mem_end+1-hi_mem_min); +@z + +@x +repeat for k:=p to q+1 do undump_wd(mem[k]); +p:=q+node_size(q); +if (p>lo_mem_max)or((q>=rlink(q))and(rlink(q)<>rover)) then goto bad_fmt; +q:=rlink(q); +until q=rover; +for k:=p to lo_mem_max do undump_wd(mem[k]); +@y +repeat + undump_things(mem[p], q+2-p); +p:=q+node_size(q); +if (p>lo_mem_max)or((q>=rlink(q))and(rlink(q)<>rover)) then goto bad_fmt; +q:=rlink(q); +until q=rover; +undump_things(mem[p], lo_mem_max+1-p); +@z + +@x +for k:=hi_mem_min to mem_end do undump_wd(mem[k]); +@y +undump_things(mem[hi_mem_min], mem_end+1-hi_mem_min); +@z + +@x +while k<l do + begin dump_wd(eqtb[k]); incr(k); + end; +@y +dump_things(eqtb[k], l-k); +@z + +@x +while k<l do + begin dump_wd(eqtb[k]); incr(k); + end; +@y +dump_things(eqtb[k], l-k); +@z + +@x +for j:=k to k+x-1 do undump_wd(eqtb[j]); +@y +undump_things(eqtb[k], x); +@z + +@x +for p:=hash_used+1 to undefined_control_sequence-1 do dump_hh(hash[p]); +@y +dump_things(hash[hash_used+1], undefined_control_sequence-1-hash_used); +@z + +@x +for p:=hash_used+1 to undefined_control_sequence-1 do undump_hh(hash[p]); +@y +undump_things(hash[hash_used+1], undefined_control_sequence-1-hash_used); +@z + +@x +for k:=0 to fmem_ptr-1 do dump_wd(font_info[k]); +dump_int(font_ptr); +for k:=null_font to font_ptr do + @<Dump the array info for internal font number |k|@>; +@y +@<Dump the array info for internal font number |k|@>; +@z + +@x +for k:=0 to fmem_ptr-1 do undump_wd(font_info[k]); +undump_size(font_base)(font_max)('font max')(font_ptr); +for k:=null_font to font_ptr do + @<Undump the array info for internal font number |k|@> +@y +@<Undump the array info for internal font number |k|@>; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.1322] Writing font info (almost at end of dump stuff). +% Knuth's code writes all the information relevant to a single font +% in the same section of the fmt file. But it's a lot faster to +% write the arrays of information out, one whole array at a time. +% So that's the way we handle dumping and undumping font info. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ @<Dump the array info for internal font number |k|@>= +begin dump_qqqq(font_check[k]); +dump_int(font_size[k]); +dump_int(font_dsize[k]); +dump_int(font_params[k]);@/ +dump_int(hyphen_char[k]); +dump_int(skew_char[k]);@/ +dump_int(font_name[k]); +dump_int(font_area[k]);@/ +dump_int(font_bc[k]); +dump_int(font_ec[k]);@/ +dump_int(char_base[k]); +dump_int(width_base[k]); +dump_int(height_base[k]);@/ +dump_int(depth_base[k]); +dump_int(italic_base[k]); +dump_int(lig_kern_base[k]);@/ +dump_int(kern_base[k]); +dump_int(exten_base[k]); +dump_int(param_base[k]);@/ +dump_int(font_glue[k]);@/ +dump_int(bchar_label[k]); +dump_int(font_bchar[k]); +dump_int(font_false_bchar[k]);@/ +print_nl("\font"); print_esc(font_id_text(k)); print_char("="); +print_file_name(font_name[k],font_area[k],""); +if font_size[k]<>font_dsize[k] then + begin print(" at "); print_scaled(font_size[k]); print("pt"); + end; +end +@y +@ @<Dump the array info for internal font number |k|@>= +begin dump_things(font_info[0], fmem_ptr); +dump_int(font_ptr); +dump_things(font_check[null_font], font_ptr+1-null_font); +dump_things(font_size[null_font], font_ptr+1-null_font); +dump_things(font_dsize[null_font], font_ptr+1-null_font); +dump_things(font_params[null_font], font_ptr+1-null_font); +dump_things(hyphen_char[null_font], font_ptr+1-null_font); +dump_things(skew_char[null_font], font_ptr+1-null_font); +dump_things(font_name[null_font], font_ptr+1-null_font); +dump_things(font_area[null_font], font_ptr+1-null_font); +dump_things(font_bc[null_font], font_ptr+1-null_font); +dump_things(font_ec[null_font], font_ptr+1-null_font); +dump_things(char_base[null_font], font_ptr+1-null_font); +dump_things(width_base[null_font], font_ptr+1-null_font); +dump_things(height_base[null_font], font_ptr+1-null_font); +dump_things(depth_base[null_font], font_ptr+1-null_font); +dump_things(italic_base[null_font], font_ptr+1-null_font); +dump_things(lig_kern_base[null_font], font_ptr+1-null_font); +dump_things(kern_base[null_font], font_ptr+1-null_font); +dump_things(exten_base[null_font], font_ptr+1-null_font); +dump_things(param_base[null_font], font_ptr+1-null_font); +dump_things(font_glue[null_font], font_ptr+1-null_font); +dump_things(bchar_label[null_font], font_ptr+1-null_font); +dump_things(font_bchar[null_font], font_ptr+1-null_font); +dump_things(font_false_bchar[null_font], font_ptr+1-null_font); +for k:=null_font to font_ptr do begin + print_nl("\font"); print_esc(font_id_text(k)); print_char("="); + print_file_name(font_name[k],font_area[k],""); + if font_size[k]<>font_dsize[k] then begin + print(" at "); print_scaled(font_size[k]); print("pt"); + end; +end; +end +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.1322] Reading font info for C (nearly done with undump stuff). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ @<Undump the array info for internal font number |k|@>= +begin undump_qqqq(font_check[k]);@/ +undump_int(font_size[k]); +undump_int(font_dsize[k]); +undump(min_halfword)(max_halfword)(font_params[k]);@/ +undump_int(hyphen_char[k]); +undump_int(skew_char[k]);@/ +undump(0)(str_ptr)(font_name[k]); +undump(0)(str_ptr)(font_area[k]);@/ +undump(0)(255)(font_bc[k]); +undump(0)(255)(font_ec[k]);@/ +undump_int(char_base[k]); +undump_int(width_base[k]); +undump_int(height_base[k]);@/ +undump_int(depth_base[k]); +undump_int(italic_base[k]); +undump_int(lig_kern_base[k]);@/ +undump_int(kern_base[k]); +undump_int(exten_base[k]); +undump_int(param_base[k]);@/ +undump(min_halfword)(lo_mem_max)(font_glue[k]);@/ +undump(0)(font_mem_size)(bchar_label[k]); +undump(min_quarterword)(non_char)(font_bchar[k]); +undump(min_quarterword)(non_char)(font_false_bchar[k]); +end +@y +@ The way this is done in C makes the reference to +the internal font number meaningless, but putting the code +here preserves the association with the WEB modules. + +@<Undump the array info for internal font number |k|@>= +begin undump_things(font_info[0], fmem_ptr); +undump_size(font_base)(font_max)('font max')(font_ptr); +undump_things(font_check[null_font], font_ptr+1-null_font); +undump_things(font_size[null_font], font_ptr+1-null_font); +undump_things(font_dsize[null_font], font_ptr+1-null_font); +undump_things(font_params[null_font], font_ptr+1-null_font); +undump_things(hyphen_char[null_font], font_ptr+1-null_font); +undump_things(skew_char[null_font], font_ptr+1-null_font); +undump_things(font_name[null_font], font_ptr+1-null_font); +undump_things(font_area[null_font], font_ptr+1-null_font); +undump_things(font_bc[null_font], font_ptr+1-null_font); +undump_things(font_ec[null_font], font_ptr+1-null_font); +undump_things(char_base[null_font], font_ptr+1-null_font); +undump_things(width_base[null_font], font_ptr+1-null_font); +undump_things(height_base[null_font], font_ptr+1-null_font); +undump_things(depth_base[null_font], font_ptr+1-null_font); +undump_things(italic_base[null_font], font_ptr+1-null_font); +undump_things(lig_kern_base[null_font], font_ptr+1-null_font); +undump_things(kern_base[null_font], font_ptr+1-null_font); +undump_things(exten_base[null_font], font_ptr+1-null_font); +undump_things(param_base[null_font], font_ptr+1-null_font); +undump_things(font_glue[null_font], font_ptr+1-null_font); +undump_things(bchar_label[null_font], font_ptr+1-null_font); +undump_things(font_bchar[null_font], font_ptr+1-null_font); +undump_things(font_false_bchar[null_font], font_ptr+1-null_font); +end +@z + +% The hyphenation patterns. +% +@x +for k:=0 to trie_max do dump_hh(trie[k]); +dump_int(trie_op_ptr); +for k:=1 to trie_op_ptr do + begin dump_int(hyf_distance[k]); + dump_int(hyf_num[k]); + dump_int(hyf_next[k]); + end; +@y +dump_things(trie_trl[0], trie_max+1); +dump_things(trie_tro[0], trie_max+1); +dump_things(trie_trc[0], trie_max+1); +dump_int(trie_op_ptr); +dump_things(hyf_distance[1], trie_op_ptr); +dump_things(hyf_num[1], trie_op_ptr); +dump_things(hyf_next[1], trie_op_ptr); +@z + +@x +for k:=0 to j do undump_hh(trie[k]); +undump_size(0)(trie_op_size)('trie op size')(j); @+init trie_op_ptr:=j;@+tini +for k:=1 to j do + begin undump(0)(63)(hyf_distance[k]); {a |small_number|} + undump(0)(63)(hyf_num[k]); + undump(min_quarterword)(max_quarterword)(hyf_next[k]); + end; +@y +undump_things(trie_trl[0], j+1); +undump_things(trie_tro[0], j+1); +undump_things(trie_trc[0], j+1); +undump_size(0)(trie_op_size)('trie op size')(j); @+init trie_op_ptr:=j;@+tini +undump_things(hyf_distance[1], j); +undump_things(hyf_num[1], j); +undump_things(hyf_next[1], j); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.1327] As with TFM files, `eof' here means `have we previously +% encountered the end-of-file', not `are we at the end of the file'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +if (x<>69069)or eof(fmt_file) then goto bad_fmt +@y +if (x<>69069)or feof(fmt_file) then goto bad_fmt +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [50.1328] Eliminate possibly wrong word `preloaded' from format_idents. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +print(" (preloaded format="); print(job_name); print_char(" "); +@y +print(" (format="); print(job_name); print_char(" "); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [51.1332] `uexit' argument depends on `history'; add call to +% set_paths; make the main program a procedure, so that uses of `eqtb' +% will work. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@p begin @!{|start_here|} +@y +@p procedure tex_body; +begin @!{|start_here|} +@z + +@x +t_open_out; {open the terminal for output} +@y +t_open_out; {open the terminal for output} +{get default file paths from the environment} +set_paths (TEX_FORMAT_PATH_BIT + TEX_INPUT_PATH_BIT + TEX_POOL_PATH_BIT + + TFM_FILE_PATH_BIT); +@z + +@x +end_of_TEX: close_files_and_terminate; +final_end: ready_already:=0; +end. +@y +close_files_and_terminate; +final_end: do_final_end; +end {|tex_body|}; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [51.1333] Print new line before termination; switch to editor if +% necessary. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + print(log_name); print_char("."); + end; + end; +@y + print(log_name); print_char("."); + end; + end; +print_ln; +if (edit_name_start<>0) and (interaction>batch_mode) then + call_edit(str_pool,edit_name_start,edit_name_length,edit_line); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [52.1338] Core-dump in debugging mode on 0 input. Under Unix, it's +% not possible to switch into the debugger while a program is running. +% The best approximation is to do a core dump, then run the debugger on +% it later. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + begin goto breakpoint;@\ {go to every label at least once} + breakpoint: m:=0; @{'BREAKPOINT'@}@\ + end +@y + dump_core {Do something to cause a core dump} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [54.1376] Add editor-switch variables to globals. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +This section should be replaced, if necessary, by any special +modifications of the program +that are necessary to make \TeX\ work at a particular installation. +It is usually best to design your change file so that all changes to +previous sections preserve the section numbering; then everybody's version +will be consistent with the published program. More extensive changes, +which introduce new sections, can be inserted here; then only the index +itself will get a new section number. +@^system dependencies@> +@y +Here is a temporary integer, used as a holder during reading and writing of +TFM files, and a temporary memory_word, used in reading/writing format +files. +Also, the variables used to hold ``switch-to-editor'' information. +@^<system dependencies@> + +@<Glob...@>= +@!edit_name_start: pool_pointer; +@!edit_name_length,@!edit_line,@!tfm_temp: integer; + +@ The |edit_name_start| will be set to point into |str_pool| somewhere after +its beginning if \TeX\ is supposed to switch to an editor on exit. + +@<Set init...@>= +edit_name_start:=0; +@z diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/install b/obsolete/systems/sisisi/unix/SiTeX3.14/install new file mode 100644 index 0000000000..42018ad32e --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/install @@ -0,0 +1,59 @@ +#!/bin/sh + +TEXSRC="/users/heinz/src/tex/TeX3.14" +TEXDIR=$TEXSRC/tex +WEBDIR=$TEXSRC/web +WEB2CDIR=$TEXSRC/web2c +SISISIDIR="/users/heinz/src/tex/sisisi" + +echo +echo "Do not forget to copy the files *.sty and *.tex" +echo "from $SISISIDIR to your TEXINPUTS-Directory." +echo +echo "Press 'q' to interrupt this installation and do it now, <cr> to continue" +read x +if [ "$x" = "q" ] +then + exit +fi + +cd $TEXSRC + +( cd $SISISIDIR; uncompress <sitex.web.Z >$TEXDIR/tex.web;\ + cp web2c* $WEB2CDIR; \ + cp tangle.ch $WEBDIR; cp makefile $TEXSRC; cp Makefile ctex.ch $TEXDIR ) + +make "CC=gcc" TeX +if [ ! -f $TEXDIR/stamp-convert ] +then + echo "*** SISISI: tex.p not converted. Something's gone wrong. Stop." 1>&2 + exit 1 +fi + +( cd $SISISIDIR; cp tex6.c texd.h coerce.h $TEXDIR ) + +make "CC=gcc" TeX +if [ ! -f $TEXDIR/virtex ] +then + echo "*** SISISI: make failed. Stop." 1>&2 + exit 2 +fi + +( cd $TEXDIR; mv tex.pool sitex.pool ) + +make formats +if [ ! -f $TEXSRC/stamp-formats ] +then + echo "*** SISISI: make formats failed. Stop." 1>&2 + exit 2 +fi + +echo +echo "SISISI has been successfully compiled, and the format files have been" +echo "generated. Now follow the guidelines from the README file for further" +echo "installation. Do not forget to copy $TEXDIR/sitex.pool" +echo "to your TEXPOOL-Directory, and $TEXDIR/hf3 to your" +echo "TEXINPUTS-Directory." +echo + +exit 0 diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/makefile b/obsolete/systems/sisisi/unix/SiTeX3.14/makefile new file mode 100644 index 0000000000..c72607bcef --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/makefile @@ -0,0 +1,280 @@ +# Overall Makefile for making TeX, Metafont, and friends, using WEB to C. + + +# TeX 3.14 + Metafont 2.7 + web2c b. +# +version=5.84b + +# Directory that site.h is in relative to subdirectories, i.e., `..' +# means the directory containing this Makefile. +SITEDIR=.. + +# Default C compiler. +CC=gcc + +# Default flags to give the C compiler. (Don't define CFLAGS directly.) +OPT=-O + +# Default flags to give to the loader. +LDFLAGS= + +# Default libraries with which to link (libraries for the Metafont +# support are specified separately). +LOADLIBES= + +# Make sure we use the sh. If your sh is broken, you might try bash, +# the GNU replacement. +SHELL=/bin/sh + +# The yacc program to use on web2c/web2c.yacc. +YACC=bison -y + +# The lex program to use on web2c/web2c.lex. +LEX=lex +# -ll for lex, -lfl for flex. +LEXLIB=-ll + +# Need -D_POSIX_SOURCE here, perhaps, if on a POSIX system. +LEXCFLAGS= + +# How to make a link. +LN=ln -s + +# Support libraries for Metafont. +x10lib=-lX +x11lib=-lXt -lX11 +sunlib=-lsuntool -lsunwindow -lpixrect + +# This line should select the libraries that match what you said in site.h. +wlibs=$(x11lib) + +# These lines define the format and base files that `make fmts' and +# `make bases' will try to make, and `make install' will try to install. +# See README.W2C for a brief description of each of these formats. +formats=sitex.fmt silatex.fmt +# etex.fmt \ +# amstex.fmt amslatex.fmt picplus.fmt texinfo.fmt +bases=mf.base cmmf.base + +# The name of the file that defines your local devices, for use with +# Metafont. (Only relevant during `make bases'.) I urge you to get the +# file `modes.mf', which defines all known modes, plus useful +# definitions for all fonts. It's available from ftp.cs.umb.edu +# [192.12.26.23] as pub/tex/modes.mf, among other places. +localmodes=modes + +# You may need INSTALL=cp on system V, if you don't have GNU install. +# Or you can install the programs by hand. +# $(fileinstall) is used for the format and base files, man files, and +# other non-executables, and $(programinstall) is used for +# the executables. +INSTALL=install -g tex -c +fileinstall=$(INSTALL) -m 664 +proginstall=$(INSTALL) -m 775 -s + +# These pathnames are used to customize the manual pages with local +# directory names; some of them are used in `make install'. They should +# match the system directories in the paths defined in `./site.h'. +bindir=/usr/local/bin +manext=l +mandir=/usr/man/man$(manext) + +texlibdir=/usr/local/lib/tex +texpooldir=$(texlibdir) +texinputdir=$(texlibdir)/inputs +texfontdir=$(texlibdir)/fonts +formatdir=$(texlibdir)/formats + +mflibdir=/usr/local/lib/mf +mfpooldir=$(mflibdir) +mfinputdir=$(mflibdir)/inputs +basedir=$(mflibdir)/bases + +# Where the Computer Modern sources are. +# (The man pages claim that you have installed the standard utility +# sources, like `grayf.mf' and `expr.mf', somewhere in $(mfinputdir).) +cmsources=/usr/local/src/other/TeX+MF/typefaces/cm + +default: all + + +# Stuff below here probably doesn't need to be changed. +# +alldirs=web tex mf texware mfware fontutil bibtex dviutil +triptrapdirs=tex texware mf mfware + +makeargs=SITEDIR="$(SITEDIR)" CC="$(CC)" OPT="$(OPT)" \ +SHELL="$(SHELL)" LDFLAGS="$(LDFLAGS)" LOADLIBES="$(LOADLIBES)" wlibs="$(wlibs)" + +web2c=web2c +web2cprograms=$(web2c)/web2c $(web2c)/regfix $(web2c)/splitup \ + $(web2c)/fixwrites +commonsources=common/alloca.c common/extra.c common/main.c common/endian.c + +triptrap: stamp-tangle stamp-common + for name in $(triptrapdirs); \ + do \ + (cd $${name}; make $(makeargs) LN="$(LN)" triptrap); \ + done + +run-triptrap: run-trip run-trap + +clean-triptrap: + cd tex; make veryclean + cd mf; make veryclean + +all: stamp-web2c stamp-common + for name in $(alldirs); \ + do \ + (cd $${name}; echo $${name}; make $(makeargs) all); \ + done + +TeX: stamp-web2c stamp-tangle stamp-common + cd tex; make $(makeargs) all + +BibTeX: stamp-web2c stamp-tangle stamp-common + cd bibtex; make $(makeargs) all + +run-trip: + cd tex; make run-trip + +MF: stamp-web2c stamp-tangle stamp-common + cd mf; make $(makeargs) all + +run-trap: + cd mf; make run-trap + + +# The targets below must be up to date for anything to be made. +# + +stamp-web2c: + cd $(web2c); \ + make $(makeargs) YACC="$(YACC)" LEX="$(LEX)" LEXLIB="$(LEXLIB)" all + touch stamp-web2c + +stamp-common: $(commonsources) + cd common; make $(makeargs) all + touch stamp-common + +stamp-tangle: stamp-web2c stamp-common + cd web; make $(makeargs) tangle + touch stamp-tangle + + +manpages: + cd man; make SITEDIR=$(SITEDIR) \ + bindir=$(bindir) texlibdir=$(texlibdir) \ + texpooldir=$(texpooldir) formatdir=$(formatdir) \ + texinputdir=$(texinputdir) texfontdir=$(texfontdir) \ + mflibdir=$(mflibdir) mfpooldir=$(mfpooldir) \ + basedir=$(basedir) mfinputdir=$(mfinputdir) \ + cmsources=$(cmsources) \ + all + +bases: stamp-bases +stamp-bases: + cd mf; MFPOOL=.; export MFPOOL; \ + make bases="$(bases)" localmodes="$(localmodes)" bases + touch stamp-bases + +formats: stamp-formats +stamp-formats: + cd tex; TEXPOOL=.; export TEXPOOL; make formats="$(formats)" fmts + touch stamp-formats + + +# Installation targets. +# +install-manpages: + cd man; make mandir=$(mandir) INSTALL="$(fileinstall)" \ + SITEDIR="$(SITEDIR)" manext=$(manext) install + +install: + if test -d $(bindir); then exit 0; else mkdir $(bindir); fi + $(proginstall) tex/initex $(bindir)/initex + $(proginstall) tex/virtex $(bindir)/virtex + $(proginstall) mf/inimf $(bindir)/inimf + $(proginstall) mf/virmf $(bindir)/virmf + $(proginstall) web/tangle $(bindir)/tangle + $(proginstall) web/weave $(bindir)/weave + $(proginstall) texware/dvitype $(bindir)/dvitype + $(proginstall) texware/pltotf $(bindir)/pltotf + $(proginstall) texware/tftopl $(bindir)/tftopl + $(proginstall) mfware/gftodvi $(bindir)/gftodvi + $(proginstall) mfware/gftopk $(bindir)/gftopk + $(proginstall) mfware/gftype $(bindir)/gftype + $(proginstall) mfware/mft $(bindir)/mft + $(proginstall) fontutil/pktogf $(bindir)/pktogf + $(proginstall) fontutil/pktype $(bindir)/pktype + $(proginstall) fontutil/vftovp $(bindir)/vftovp + $(proginstall) fontutil/vptovf $(bindir)/vptovf + $(proginstall) bibtex/bibtex $(bindir)/bibtex + $(proginstall) dviutil/dvicopy $(bindir)/dvicopy + if test -d $(texpooldir); then exit 0; else mkdir $(texpooldir); fi + -if test -s tex/tex.pool; \ + then (cd tex; $(fileinstall) tex.pool $(texpooldir) ); fi + if test -d $(mfpooldir); then exit 0; else mkdir $(mfpooldir); fi + -if test -s mf/mf.pool; \ + then (cd mf; $(fileinstall) mf.pool $(mfpooldir) ); fi + +install-formats: stamp-formats + if test -d $(formatdir); then exit 0; else -mkdir $(formatdir); fi + for f in $(formats); \ + do \ + rm -f $(bindir)/`basename $$f .fmt`; \ + ln $(bindir)/virtex $(bindir)/`basename $$f .fmt`; \ + $(fileinstall) tex/$$f $(formatdir); \ + done + cd $(formatdir); rm -f plain.fmt; ln tex.fmt plain.fmt + +install-bases: stamp-bases + if test -d $(basedir); then exit 0; else -mkdir $(basedir); fi + for f in $(bases); \ + do \ + rm -f $(bindir)/`basename $$f .base`; \ + ln $(bindir)/virmf $(bindir)/`basename $$f .base`; \ + $(fileinstall) mf/$$f $(basedir); \ + done + cd $(basedir); rm -f plain.base; ln mf.base plain.base + + +# Need GNU tar for this. +# +web2c-dist: web/tangleboot.pas + @echo -n "check -linet;tangleboot" + @echo "big{tex,mf.ch; trie change" + mv ChangeLog ChangeLog.W2C + cd ..; \ + find src-$(version) \! -name '*.web' -type f -print > /tmp/files; \ + tar czfT web2c-$(version).tar.Z /tmp/files; \ + ls -ld web* + mv ChangeLog.W2C ChangeLog + +web-dist: web/tangleboot.pas + cd ..; \ + find src-$(version) -name '*.web' -print > /tmp/webfest; \ + tar czfT web-$(version).tar.Z /tmp/webfest; \ + ls -ld web* + +web/tangleboot.pas: + cd web; make tangle.p; cp tangle.p tangleboot.pas; make veryclean + +clean: + rm -f stamp-* + for name in web2c common $(alldirs); \ + do \ + (cd $${name}; make clean); \ + done + +veryclean: + rm -f stamp-* + for name in web2c common man $(alldirs); \ + do \ + (cd $${name}; make veryclean); \ + done + rm -f \#*\# *~ *.bak *.ckp core + +.PHONY: default triptrap run-triptrap clean-triptrap all TeX run-trip \ + MF run-trap manpages bases formats install-manpages install \ + install-formats install-bases web2c-dist web-dist clean veryclean diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/sitex.web.gz b/obsolete/systems/sisisi/unix/SiTeX3.14/sitex.web.gz Binary files differnew file mode 100644 index 0000000000..13fb851bfe --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/sitex.web.gz diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/sitex3.ch b/obsolete/systems/sisisi/unix/SiTeX3.14/sitex3.ch new file mode 100644 index 0000000000..048d9433cb --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/sitex3.ch @@ -0,0 +1,2827 @@ +========================================================================= + +SI_TEX.CHA Change file for SISISI-hyphenation in TeX 3.1 16.7.1991 + (c) for SISISI-hyphenation: Wilhelm Barth, Heinrich Nirschl + (c) for TeX changes: Heini Hofstaedter, Harald Mueller + + additional changes until 10. October 1991 HH +========================================================================= + +This is the change file for inclusion of SISISI into TeX V.3.14. + +There are three main changes in this file (which are of course quite +intermingled): + + 1) the replacement of Liang's hyphenation by SISISI. + + 2) the change of the interface of the actual hyphenation + to the post-hyphenation and the line-break algorithm. + + This change is necessary because in original TeX, only the + information "hyphen - no hyphen" can be transmitted to the + line break algorithm because of two "bottlenecks": + + 1. Hyphenation --> Post-Hyphenation: Here a hyphen at position i + is marked by the 1-bit information odd(hyf[i]). + 2. Post-Hyphenation --> Line-Breaking: Here a hyphen is marked + by the existence of a discretionary node. + + From SISISI, there must be more information flowing to the + line-break algorithm: + + a. Is a hyphen a main hyphen or a "nebenhyphen"? To this end, + a change is made such that a penalty node is allowed as + the first node in the prebreak list of a discretionary + node. This penalty node contains the penalty associated with + this specific hyphen. For "nebenhyphens", this value is set + by an additional primitive "\nebenhyphenpenalty". + Instead of the hyf-array, an array hyfpen is used that + contains the actual penalties; the old "if odd(hyf[i])" now + is converted ti "if hyfpen[i] <> inf_penalty". + + b. A hyphen may be more complicated than a single -: ck-hyphens + and triple-consonant-hyphens may be present. To include these, + another array hyf_disc is introduced that contains ready-made + discretionary nodes for such hyphens. + + At first, we simply wanted to include these discretionary + during the post-hyphenation into the new node list. But then + Heini felt that the impossiblity of ligatures with parts of such + a discretionary node was not acceptable; therefore he introdiced + the "x-mechanism" (characterized by many variables starting with + "x") and changed the reconstitute function so that more than the + single hyphen_char could be introduced into the reconstitution + process. + + 3) "Dirty" changes for the hyphenation of words with umlauts. + These changes are necessary because the umlauts in TeX are not + (necessarily) real characters, but something else (see definition + of umlauts in plain.tex or german.tex). + Ordinarily, the hyphenation only accepts sequences of letters, + ligatures (which are expanded to their single characters), and + so-called "implicit kerns". An umlaut, however, is usually + represented as a letter character and another character consisting + of two dots ("dieresis character"), which are connected by + explicit kerns (not implicite ones!). Therefore, words containing + umlauts are not hyphenable words in TeX, which is not acceptable + for german texts. + + Therefore, we devised a "bypass" for umlauts as follows: An umlaut + is now represented as a special discretionary node (so-called + "dirty umlaut") as follows: + \discretionary{\kern4321sp m\kern<code>sp\kern<back>sp\kern-1em}% + {}% + {<umlaut>} + where the 4321sp is a "marker" for the "dirty umlaut", the "m" + letter is used to derive the font of the umlaut, <code> is + the font number that should be associated with this umlaut (the + font numbers of the umlauts are given below); and <back> is used + to cancel the preceding kerns, i.e.\ <back> = - (4321 + <code>). + + In other words, the prebreak list contains the information that + this is an umlaut (albeit a "dirty" one) and some more + information needed for the hyphenation, the postbreak list is + empty, and the main list contains the umlaut proper. By a + special if-statement in the line-break algorithm, a hyphenation + at a discretionary node of this format is suppressed, so that + always the umlaut of the main list is printed. + The font numbers for the lowercase umlauts (which are given + in the second \kern node) must be: + ae 228 + oe 246 + ue 252 + The codes for the uppercase umlauts can be chosen arbitrarily. + + In order to get the hyphenation for these "dirty umlauts" + running, one must include lccode assignments of the form + \lccode<code>=<lccode> + for each of the new letters (see example below). + + A typical declaration of the "dirty umlauts" runs like this: + +%%%%%%%%%%%%%%%%%%%%% declaration of dirty umlauts %%%%%%%%%%%%%%%%%%%%%% +\def\A"{\discretionary{\kern 4321sp m\kern 196sp\kern-4517sp\kern-1em}{}{\"A}} +\def\a"{\discretionary{\kern 4321sp m\kern 228sp\kern-4549sp\kern-1em}{}{\"a}} +\def\O"{\discretionary{\kern 4321sp m\kern 214sp\kern-4535sp\kern-1em}{}{\"O}} +\def\o"{\discretionary{\kern 4321sp m\kern 246sp\kern-4567sp\kern-1em}{}{\"o}} +\def\U"{\discretionary{\kern 4321sp m\kern 220sp\kern-4541sp\kern-1em}{}{\"U}} +\def\u"{\discretionary{\kern 4321sp m\kern 252sp\kern-4573sp\kern-1em}{}{\"u}} +\lccode196=228 % uppercase umlaut A +\lccode214=246 % uppercase umlaut O +\lccode220=252 % uppercase umlaut U +\lccode228=228 % uppercase umlaut a +\lccode246=246 % uppercase umlaut o +\lccode252=252 % uppercase umlaut u +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +When (if?) one day N.Schwarz's DC/EC fonts arrive, the changes of the +third kind can be eliminated. How long this will take ... well, wait and +see. +But when they arrive, it's not longer possible to choose the codes for +uppercase umlauts arbitrarily. The codes for uppercase umlauts will +then be those, shown in the example above. + +========================================================================= + +At first, we add a control sequence \SISISI. +@x +\def\PASCAL{Pascal} +@y +\def\SISISI{{\sl SISISI}} +\def\PASCAL{Pascal} + +\let\maybe=\iffalse % print only changed modules +@z + +------------------------------------------------------------------------- + +@x +@d banner=='This is TeX, Version 3.14' {printed when \TeX\ starts} +@y +@d banner=='This is TeX, Version 3.14 (+SISISI 1.0)' +@z + +------------------------------------------------------------------------- + +A number of procedures of SISISI are declared after the TeX program. As +these procedures are used in the hyphenation, of course, they must be +declared as `forward'. + In web2c gibt es keine forward's !!!! +%@x +%procedure initialize; {this procedure gets things started properly} +%@y +%@<forward declarations@> +%procedure initialize; {this procedure gets things started properly} +%@z + +------------------------------------------------------------------------- +%@x +%@d pool_name_length=8 +%@y +%@d pool_name_length=11 +% {number of characters of ``pool_f_name''} +%@z +%see the following change of the pool file name "pool_f_name" +------------------------------------------------------------------------- + +@x +@!pool_name='TeXformats:TEX.POOL '; +@y +@!pool_name='TeXformats:SITEX3.POOL '; +@z + +------------------------------------------------------------------------- + +@x +else bad_pool('! I can''t read TEX.POOL.') +@.I can't read TEX.POOL@> +@y +else bad_pool('! I can''t read SITEX3.POOL.'); +@.I can't read TEX.POOL@> +@z +========================================================================= + +To have all messages, coming from SI_TEX, displayed on screen +and written to the log-file simultanously, we make the following, +additional definitions. + temp nicht mehr vorhanden, in log ve„ndert. +@x +@d wlog_ln(#)==write_ln(log_file,#) +@d wlog_cr==write_ln(log_file) +@y +@d wlog_ln(#)==write_ln(log_file,#) +@d wlog_cr==write_ln(log_file) + +@d si_put(#) == @+ begin + if (file_offset<>0)or(term_offset<>0) then print_ln; + if selector<>log_only then wterm(#); + if (selector=log_only)or(selector=term_and_log) then + wlog(#); + end +@d si_put_ln(#) == @+ begin + if (file_offset<>0)or(term_offset<>0) then print_ln; + if selector<>log_only then wterm_ln(#); + if (selector=log_only)or(selector=term_and_log) then + wlog_ln(#); + end +@d si_put_cr == print_ln + + +@d dbg_put(#) == {} +@d dbg_put_ln(#) == {} +@d dbg_put_cr == {} +@z +========================================================================= + +We add a new primitive \nebenhyphenpenalty for setting the penalty of a +minor hyphen: + +@x +@d int_pars=55 {total number of integer parameters} +@d count_base=int_base+int_pars {256 user \.{\\count} registers} +@y +@d neben_hyphen_penalty_code=55 {penalty for break after neben-hyphen} +@d si_debug_code=56 {value is treated as an set of active debugging sections} +@d supress_debug_mark_code=57 {same as above; if a section number is set, then + the output of the section number and the debugging output banner + of this section is supressed} +@d int_pars=58 {total number of integer parameters} +@d count_base=int_base+int_pars {256 user \.{\\count} registers} +@z +------------------------------------------------------------------------- +@x +@<Assign the values |depth_threshold:=show_box_depth|...@>= +@y +@d neben_hyphen_penalty==int_par(neben_hyphen_penalty_code) +@d si_debug(#) == if odd(int_par(si_debug_code) div #) then begin + if not odd(int_par(supress_debug_mark_code)div #) then + begin + si_put_cr; + si_put_ln(' <* debugging output section #',#:#,' *>'); + end; {marking supression} + { dig_count entfernt !!! } +@d gubed_si == end +@f si_debug == begin +@f gubed_si == end +@f gubed == nil + + +@<Assign the values |depth_threshold:=show_box_depth|...@>= +@z +------------------------------------------------------------------------- +@x +othercases print("[unknown integer parameter!]") +@y +neben_hyphen_penalty_code:print_esc("nebenhyphenpenalty"); +si_debug_code:print_esc("sidebug"); +supress_debug_mark_code:print_esc("supressdebugmark"); +othercases print("[unknown integer parameter!]") +@z +------------------------------------------------------------------------- +@x +@ @<Cases of |print_cmd_chr|...@>= +@y +primitive("nebenhyphenpenalty",assign_int,int_base+neben_hyphen_penalty_code);@/ +@!@:neben_hyphen_penalty_}{\.{\\nebenhyphenpenalty} primitive@> +primitive("sidebug",assign_int,int_base+si_debug_code); +primitive("supressdebugmark",assign_int,int_base+supress_debug_mark_code); +@ @<Cases of |print_cmd_chr|...@>= +@z + +========================================================================= + +As now hyphens may have different penalties, we must somehow associate +a penalty with a discretionary node. We do this by allowing a penalty +node as the first node in the prebreak list of a discretionary node. + +The following changes are in two case statements that check the nodes +in the sublists of a discretionary node; we add an empty case for +penalty nodes (two more case statements follow a little bit later). + +@x + othercases confusion("disc1") +@y + penalty_node: ; + othercases confusion("disc1") +@z +------------------------------------------------------------------------- +@x + othercases confusion("disc2") +@y + penalty_node: ; + othercases confusion("disc2") +@z + +========================================================================= + +MAIN CHANGE 2) + +The following change is in the line-break section, where try_break is +given the penalty stored in the penalty node. This change is the reason +for all other changes concerning penalties. Moreover, in this change +a line break is suppressed if the discretionary node is actually +a "dirty umlaut" (via "if not is_dirty_umlaut(cur_p) then ... try_break"). + +@x +begin s:=pre_break(cur_p); disc_width:=0; +if s=null then try_break(ex_hyphen_penalty,hyphenated) +else begin repeat @<Add the width of node |s| to |disc_width|@>; + s:=link(s); + until s=null; + act_width:=act_width+disc_width; + try_break(hyphen_penalty,hyphenated); + act_width:=act_width-disc_width; + end; +r:=replace_count(cur_p); s:=link(cur_p); +while r>0 do + begin @<Add the width of node |s| to |act_width|@>; + decr(r); s:=link(s); + end; +prev_p:=cur_p; cur_p:=s; goto done5; +end + +@y +begin + s:=pre_break(cur_p); disc_width:=0; + if s=null then try_break(ex_hyphen_penalty,hyphenated) + else if (type(s)=penalty_node) and (link(s)=null) then begin + flush_node_list(s); s := null; + try_break(ex_hyphen_penalty,hyphenated); end + else if not is_dirty_umlaut(cur_p) then begin + if type(s)=penalty_node then s:=link(s); + repeat @<Add the width of node |s| to |disc_width|@>; + s:=link(s); + until s=null; + act_width:=act_width+disc_width; + if type(pre_break(cur_p))=penalty_node then begin + try_break(penalty(pre_break(cur_p)),hyphenated) end + else begin try_break(hyphen_penalty,hyphenated); end; + act_width:=act_width-disc_width; + end; + r:=replace_count(cur_p); s:=link(cur_p); + while r>0 do begin + @<Add the width of node |s| to |act_width|@>; + decr(r); s:=link(s); + end; + prev_p:=cur_p; cur_p:=s; goto done5; +end + +@z + +========================================================================= + +Two more case statements. + +@x + othercases confusion("disc3") +@y + penalty_node: ; + othercases confusion("disc3") +@z + +------------------------------------------------------------------------- + +@x + othercases confusion("disc4") +@y + penalty_node: ; + othercases confusion("disc4") +@z + +========================================================================= + +There's a little problem, converting a device independent (``.dvi'') +to a post script file (``.ps''). I think that this program part could +cause this problem. so let's see... + +!a <-- = --> @x With this, i want to try to reproduce this error. + Because, after i had inserted this change, that error didn`t occur + again! +@<Modify the end of the line...@>= +q:=cur_break(cur_p); disc_break:=false; post_disc_break:=false; +if q<>null then {|q| cannot be a |char_node|} + if type(q)=glue_node then + begin delete_glue_ref(glue_ptr(q)); + glue_ptr(q):=right_skip; + subtype(q):=right_skip_code+1; add_glue_ref(right_skip); + goto done; + end + else begin if type(q)=disc_node then + @<Change discretionary to compulsory and set + |disc_break:=true|@> + else if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0; + end +else begin q:=temp_head; + while link(q)<>null do q:=link(q); + end; +@<Put the \(r)\.{\\rightskip} glue after node |q|@>; +done: +!a <-- = --> @y +@<Modify the end of the line...@>= +q:=cur_break(cur_p); disc_break:=false; post_disc_break:=false; +if q<>null then {|q| cannot be a |char_node|} + if type(q)=glue_node then + begin delete_glue_ref(glue_ptr(q)); + glue_ptr(q):=right_skip; + subtype(q):=right_skip_code+1; add_glue_ref(right_skip); + goto done; + end + else begin + if type(q)=disc_node then begin + hyfdeb_b:=false; + if is_dirty_umlaut(q) then begin + si_debug(64) hyfdeb_b:=true; gubed_si; + si_put_cr; + si_put_ln(' ??? There's a line break at a dirty umlaut!?'); + end; + if not hyfdeb_b then begin + @<Change discretionary to compulsory and set |disc_break:=true|@> + end; + end else + if (type(q)=math_node)or(type(q)=kern_node) then width(q):=0; + end else begin + q:=temp_head; + while link(q)<>null do q:=link(q); + end; +@<Put the \(r)\.{\\rightskip} glue after node |q|@>; +done: +!a <-- = --> @z + + +========================================================================= + +If the break actually occurs, the penalty node is made a separate list +with only one node, which is immediately flushed. + +@x +begin s:=pre_break(q); link(q):=s; +while link(s)<>null do s:=link(s); +pre_break(q):=null; q:=s; +end +@y +begin + s:=pre_break(q); + if type(s)=penalty_node then begin + s:=link(s); + link(pre_break(q)):= null; + flush_node_list(pre_break(q)); + end; + link(q):=s; + while link(s)<>null do s:=link(s); + pre_break(q):=null; q:=s; +end +@z + +========================================================================= + +The type `array[0..65] of 0..256' is needed more often, so we make it +an explicit type (see big SISISI change at end of change file). hc is +now declared of this type. + +@x +@!hc:array[0..65] of 0..256; {word to be hyphenated} +@!hn:small_number; {the number of positions occupied in |hc|} +@!ha,@!hb:pointer; {nodes |ha..hb| should be replaced by the hyphenated result} +@y +@!hc:a_word; {word to be hyphenated} +@!hn:small_number; {the number of positions occupied in |hc|} +@!ha,@!hb:pointer; {nodes |ha..hb| should be replaced by the hyphenated result} +{ some variables for debugging output } +@!hyfdeb_i,hyfdeb_j: integer; +@!hyfdeb_b:boolean; +@!si_p, si_q, si_r, si_s: pointer; +@z + +------------------------------------------------------------------------- + +Our hyphenation routines need even more "more local variables". + +@x +@ Hyphenation routines need a few more local variables. +@y +@!dirty_umlaut:array [-1..64] of pointer; {the [-1] field is used, if a + whatsit node occurs inbetween a word. This can happen due to + Partl's changes in ``german.sty'' } + +@ Hyphenation routines need a few more local variables. +@z + +------------------------------------------------------------------------- + +@x +@!j:small_number; {an index into |hc| or |hu|} +@y +@!qq:pointer; +@!j:small_number; {two indices into |hc| or |hu|} +@!jj:integer; +@z + +========================================================================= + +The dirty_umlaut array must be initialized for each word. +And we enable watching the node list, representing the word +to be hyphenated. + +@x +if s<>null then + begin @<Skip to node |ha|, or |goto done1| if no hyphenation +@y +si_p:=cur_p; si_q:=null; +for jj:=-1 to 64 do dirty_umlaut[jj] := null; +if s<>null then begin + si_debug(1) +{ hyfdeb_i:=depth_threshold; depth_threshold:=100; + hyfdeb_j:=breadth_max; breadth_max:=100; +} + show_node_list(si_p); +{ depth_threshold:=hyfdeb_i; breadth_max:=hyfdeb_j; } + gubed_si; + @<Skip to node |ha|, or |goto done1| if no hyphenation +@z + +------------------------------------------------------------------------- + +@x + hyphenate; + end; +done1: end +@y + hyphenate; + end; +done1: +si_debug(32) + hyfdeb_i := depth_threshold; hyfdeb_j := breadth_max; + if si_q<>null then begin + depth_threshold:=100; {show all levels of a list} + breadth_max:=200; {show all nodes of one level of a list} + si_r:=link(si_q); link(si_q):=null; + end else begin + (* take the values, set by the user, for this variables! *) + breadth_max:=show_box_breadth; depth_threshold:=show_box_depth; + end; + show_node_list(si_p); + si_put_cr; + if si_q <> null then link( si_q ) := si_r; + + depth_threshold:=hyfdeb_i; breadth_max:=hyfdeb_j; +gubed_si; +end +@z + +========================================================================= + +MAIN CHANGE 1) + +Here, we add the SISISI-procedure abteilen for use in hyphenate and +another label done1. + +@x +procedure hyphenate; +label common_ending,done,found,found1,found2,not_found,exit; +var @<Local variables for hyphenation@>@; +@y + +@<Handling of dirty umlauts@> + +procedure hyphenate; +label common_ending,done,done1,found,found1,found2,not_found,exit; +var @<Local variables for hyphenation@>@; +@z + +========================================================================= + +MAIN CHANGE 3) + +The prehyphenation loop must now also skip over the "dirty umlauts". + +@x +loop@+ begin if is_char_node(s) then + begin c:=qo(character(s)); hf:=font(s); + end + else if type(s)=ligature_node then + if lig_ptr(s)=null then goto continue + else begin q:=lig_ptr(s); c:=qo(character(q)); hf:=font(q); + end + else if (type(s)=kern_node)and(subtype(s)=normal) then goto continue + else if type(s)=whatsit_node then + begin @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>; + goto continue; + end + else goto done1; + if lc_code(c)<>0 then + if (lc_code(c)=c)or(uc_hyph>0) then goto done2 +@y +loop@+ begin + if is_char_node(s) then begin + c:=qo(character(s)); hf:=font(s); + end else if type(s)=ligature_node then begin + if lig_ptr(s)=null then goto continue + else begin + q:=lig_ptr(s); c:=qo(character(q)); hf:=font(q); + end + end else if is_dirty_umlaut(s) then begin + c:=get_char_of(s); hf:=get_font_of(s); + end else if (type(s)=kern_node)and(subtype(s)=normal) then goto continue + else if type(s)=whatsit_node then begin + @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>; + goto continue; + end else goto done1; + + if lc_code(c)<>0 then + if (lc_code(c)=c)or(uc_hyph>0) then goto done2 +@z + +========================================================================= + +MAIN CHANGE 2) + +The interface variables for the hyphenation are extended: hyfpen[i] +holds the actual penalty of a hyphen at position i, hyf_disc[i] +contains a "special discretionary" for triple-consonant-hyphens and +ck-hyphens. hc_si is the word as given to the SISISI algorithm; +hyf_si is returned from SISISI and contains markers for the hyphens. + +After this change, there are many changes where `odd(hyf[i])' is +simply replaced by `hyfpen[i]<>inf_penalty'. + +Another procedure to be changed is `reconstitute': It now has to handle +special dicretionary nodes. For a detailed feeling about the code changes +in reconstitute, either (1) look through it bit by bit, or (2) ask Heini +Hofstaedter. + +@x + end + else if type(s)=ligature_node then + @<Move the characters of a ligature node to |hu| and |hc|; + but |goto done3| if they are not all letters@> +@y + end else if is_dirty_umlaut(s) then begin + if get_font_of(s)<>hf then goto done3; + c:=get_char_of(s); + if lc_code(c)=0 then goto done3; + if hn=63 then goto done3; + hb:=s; incr(hn); hu[hn]:=c; hc[hn]:=lc_code(c); + dirty_umlaut[hn]:=s; + for jj:=1 to replace_count(s) do s:=link(s); + end else if type(s)=whatsit_node then begin + @<Advance \(p)past a whatsit node in the \(p)pre-hyphenation loop@>; + dirty_umlaut[-1]:=s; + end else if type(s)=ligature_node then + @<Move the characters of a ligature node to |hu| and |hc|; + but |goto done3| if they are not all letters@> +@z + +========================================================================= + +MAIN CHANGE 3) + +Also in the conversion loop (where the node list is shuffled into the +hc array), we must skip a "dirty umlaut". + +@x +loop@+ begin if not(is_char_node(s)) then + case type(s) of + ligature_node: do_nothing; +@y +loop@+ begin +if not(is_char_node(s)) then + if is_dirty_umlaut(s) then begin + for jj:=1 to replace_count(s)-1 do s:=link(s); + end else + case type(s) of + ligature_node: do_nothing; +@z + +========================================================================= + +Well, there are a lot of new variables that are necessary for the new +hyphenation. Most of them are necessary for Heini's change in the +reconstitute function, where now discretionary nodes for hyphens with +more than one character (e.g. the german ck-hyphens or +three-consonant-hyphens) can be inserted. + +@x +@ @<Local variables for hyphenation@>= +@!i,@!j,@!l:0..65; {indices into |hc| or |hu|} +@!q,@!r,@!s:pointer; {temporary registers for list manipulation} +@!bchar:halfword; {right boundary character of hyphenated word, or |non_char|} +@y +@!hyfpen:array [0..64] of integer; {penalties for possible discretionary + hyphens} +@!hyf_si:trennvektor; +@!hc_si:wort; +@!hyf_disc:array [0..64] of pointer; + +@ @<Local variables for hyphenation@>= +@!i,@!j,@!l,@!kk:0..65; {indices into |hc| or |hu|} +@!q,@!r,@!s,@!qq,@!qr,@!hold_r:pointer; {temporary registers for list manipulation} +@!bchar:halfword; {right boundary character of hyphenated word, or |non_char|} + +@!xchg_char:array [0..10] of 0..256; {type of |hu| and |hc|} +@!add_char, {additional characters when hyphenating e.g.\ + Schiffahrt $\rightarrow$ Schif{\sl f}-fahrt: here + |add_char| = 1} +@!xchg_i,xchg_k,xchg_hu: 0..65; {type like |i|, |j| and |l| } +@!spec_hyf: pointer; {special hyphen; causes different spelling of the + word, when it is hyphenated at this point} +@!si_j:integer; +@z + +========================================================================= + +An odd->inf_penalty change. + +@x +for j:=l_hyf to hn-r_hyf do if odd(hyf[j]) then goto found1; +@y +for j:=l_hyf to hn-r_hyf do if hyfpen[j]<>inf_penalty then goto found1; +@z + +========================================================================= + +The new variable hold_r is initialized (the kern node is a dummy node, +as far as I can see). + +@x +if not is_char_node(hb) then + if type(hb)=ligature_node then if odd(subtype(hb)) then +@y +hold_r := new_kern(1235); link(hold_r):=r; +if not is_char_node(hb) then + if type(hb)=ligature_node then if odd(subtype(hb)) then +@z + +========================================================================= + +Initialize some variables if the list starts with a "dirty umlaut". + +@x +else if type(ha)=ligature_node then + if font(lig_char(ha))<>hf then goto found2 + else begin init_list:=lig_ptr(ha); init_lig:=true; init_lft:=(subtype(ha)>1); +@y +else if is_dirty_umlaut(ha) then begin + if get_font_of(ha) <> hf then goto found2 + else begin init_list:=ha; init_lig := false; hu[0]:=get_char_of(ha); + end +end else if type(ha)=ligature_node then + if font(lig_char(ha))<>hf then goto found2 + else begin init_list:=lig_ptr(ha); init_lig:=true; init_lft:=(subtype(ha)>1); +@z + +========================================================================= + +MAIN CHANGE 3) + +unhinge all "dirty umlauts". + +@x +common_ending: flush_node_list(r); +@<Reconstitute nodes for the hyphenated word, inserting discretionary hyphens@>; +flush_list(init_list) +@y +common_ending: +qq:=hold_r; +for kk:={1}j to hn do if dirty_umlaut[kk] <> null then begin + while link(qq) <> dirty_umlaut[kk] do qq := link(qq); + qr := link(qq); + for i:=1 to replace_count(qr) do + if qr<>null then qr:=link(qr) + else begin {test:} + si_put_ln('...??..X --> ????? !'); + end; {:test} + if qr<>null then begin + link(qq):=link(qr); link(qr):=null; + end else link(qq):=null; +end; +if dirty_umlaut[-1]<>null then begin + qq:=hold_r; + while (link(qq)<>dirty_umlaut[-1])and(link(qq)<>null) do qq:=link(qq); + if link(qq)=dirty_umlaut[-1] then begin + link(qq):=link(dirty_umlaut[-1]); + link(dirty_umlaut[-1]):=null; + end else begin + si_put(' *** ERROR: node list is damaged! '); + si_put_ln('(post hyphenation - unhinge a whatsit node)'); + end; +end; +{} +r:=hold_r; +while link(r)<>null do begin + if (mem_min<=link(r))and(link(r)<=mem_max) then r:=link(r) + else begin + wlog_cr; wterm_cr; + wlog_ln('???$ - ERROR in node list!'); + wterm_ln('???$ - ERROR in node list!'); + kk:=depth_threshold; l:=breadth_max; + depth_threshold:=100; breadth_max:=100; + show_node_list(hold_r); + link(r):=null; + depth_threshold:=kk; breadth_max:=l; + end; +end; +{} +flush_node_list(hold_r); +@<Reconstitute nodes for the hyphenated word, inserting discretionary hyphens@>; +flush_list(init_list) +@z + +------------------------------------------------------------------------ + +Another odd->inf_penalty change (this time only textual). + +@x +If there exists an index |k| in the range $j\le k\le m$ such that |hyf[k]| +is odd and such that the result of |reconstitute| would have been different +if $x_{k+1}$ had been |hchar|, then |reconstitute| sets |hyphen_passed| +to the smallest such~|k|. Otherwise it sets |hyphen_passed| to zero. +@y +If there exists an index |k| in the range $j\le k\le m$ such that +|hyfpen[k]<>inf_penalty| and such that the result of |reconstitute| +would have been different if $x_{k+1}$ had been |hchar|, then |reconstitute| +sets |hyphen_passed| to the smallest such~|k|. Otherwise it sets +|hyphen_passed| to zero. +@z + +------------------------------------------------------------------------- + +In the reconstitute function, we set the boundary value n immediately +before the next "dirty umlaut" by a simple for-loop starting at the +original n. + +@x +begin hyphen_passed:=0; t:=hold_head; w:=0; link(hold_head):=null; +@y +@!ii:small_number; +begin hyphen_passed:=0; t:=hold_head; w:=0; link(hold_head):=null; +for ii:=n downto j do + if dirty_umlaut[ii] <> null then n:=ii-1; +@z + +------------------------------------------------------------------------- + +Another odd->inf_penalty change. + +@x + if odd(hyf[j]) then cur_rh:=hchar@+else cur_rh:=non_char; +@y + if hyfpen[j]<>inf_penalty then cur_rh:=hchar@+else cur_rh:=non_char; +@z + +========================================================================= + +A first change in the reconstitute function. + +@x + else begin if hchar<non_char then if odd(hyf[j]) then + begin hyphen_passed:=j; hchar:=non_char; + end; + if op_byte(q)<kern_flag then + @<Carry out a ligature replacement, updating the cursor structure +@y + else begin if hchar<non_char then if hyfpen[j]<>inf_penalty then + begin hyphen_passed:=j; hchar:=non_char; + end; + if op_byte(q)<kern_flag then + @<Carry out a ligature replacement, updating the cursor structure +@z + + +------------------------------------------------------------------------- + +Now we are in the post-hyphenation's main loop; here must append a +"dirty umlaut" to the growing node list. This is simply done by an +if-statement that checks for the presence of a "dirty umlaut" and +appends it. + +Moreover, we have another textual odd->inf_penalty change. + +@x +repeat l:=j; j:=reconstitute(j,hn,bchar,qi(hyf_char))+1; +if hyphen_passed=0 then + begin link(s):=link(hold_head); + while link(s)>null do s:=link(s); + if odd(hyf[j-1]) then + begin l:=j; hyphen_passed:=j-1; link(hold_head):=null; + end; + end; +if hyphen_passed>0 then + @<Create and append a discretionary node as an alternative to the + unhyphenated word, and continue to develop both branches until they + become equivalent@>; +until j>hn; +link(s):=q + +@ In this repeat loop we will insert another discretionary if |hyf[j-1]| is +odd, when both branches of the previous discretionary end at position |j-1|. +@y +if dirty_umlaut[-1]<>null then begin + {hook in the previous saved whatsit node before the first + character of the hyphenated word} + link(s):=dirty_umlaut[-1]; + s:=link(s); +end; +repeat + if dirty_umlaut[j]<>null then begin + link(s):=dirty_umlaut[j]; + while link(s)>null do s:=link(s); + link(hold_head):=null; + j:=j+1; hyphen_passed:=0; + if hyfpen[j-1]<>inf_penalty then begin + l:=j; hyphen_passed:=j-1; + si_debug(16) + si_put_ln(' *** append a hyphen immediatly after a dirty umlaut!'); + gubed_si; + end; + end else begin + l:=j; j:=reconstitute(j,hn,bchar,qi(hyf_char))+1; + if hyphen_passed=0 then begin + link(s):=link(hold_head); + while link(s)>null do s:=link(s); + if hyfpen[j-1]<>inf_penalty then begin + l:=j; hyphen_passed:=j-1; link(hold_head):=null; + end; + end; + end; {if dirty_umlaut[j]<>null then-else} + if hyphen_passed>0 then + @<Create and append a discretionary node as an alternative to the + unhyphenated word, and continue to develop both branches until they + become equivalent@>; +until j>hn; +link(s):=q; +si_q:=s; {save the last node of the hyphenated word for debugging output} +for j:=0 to 64 do if hyf_disc[j]<>null then begin + flush_node_list( hyf_disc[j]); +end + +@ In this repeat loop we will insert another discretionary if +|hyfpen[j-1]<>inf_penalty|, when both branches of the previous +discretionary end at position |j-1|. +@z + +========================================================================= + +Another odd->inf_penalty change. + +@x +hyphen_passed:=j-1; link(hold_head):=null; +until not odd(hyf[j-1]) +@y +hyphen_passed:=j-1; link(hold_head):=null; +until (hyfpen[j-1]=inf_penalty) +@z + +========================================================================= + +Here comes the big reconstitution action (cheers to Heini!). + +@x +@<Put the \(c)characters |hu[l..i]| and a hyphen into |pre_break(r)|@>= +minor_tail:=null; pre_break(r):=null; hyf_node:=new_character(hf,hyf_char); +if hyf_node<>null then + begin incr(i); c:=hu[i]; hu[i]:=hyf_char; free_avail(hyf_node); + end; +while l<=i do + begin l:=reconstitute(l,i,font_bchar[hf],non_char)+1; + if link(hold_head)>null then + begin if minor_tail=null then pre_break(r):=link(hold_head) +@y +As the value of |hyfpen[i]| is necessary for creating a penalty node, +we must create this node before we ``kill'' the hyphenation information in +|hyfpen[i]| by assigning |inf_penalty|. |minor_tail| contains the +pointer to the penalty node or |null|, if no such node has been created. + +@<Put the \(c)characters |hu[l..i]| and a hyphen into |pre_break(r)|@>= +if (hyfpen[i]<>inf_penalty) and (hyfpen[i]<>hyphen_penalty) + then minor_tail:=new_penalty(hyfpen[i]) + else minor_tail:=null; +hyfpen[i]:=inf_penalty; +pre_break(r):=minor_tail; + +hyf_node:=new_character(hf,hyf_char); +{Exchange |pre_break|-list of the selfbuilt |disc_node| with |hu|} +xchg_k:=i; +if hyf_disc[xchg_k]<>null then begin + spec_hyf:=pre_break(hyf_disc[xchg_k]); + add_char:=subtype(spec_hyf); + xchg_i:=1; + repeat + spec_hyf:=link(spec_hyf); + if spec_hyf<>null then begin + xchg_char[xchg_i]:=qo(character(spec_hyf)); + incr(xchg_i); + end;{if} + until spec_hyf=null; + if hyf_node<>null then begin + xchg_char[xchg_i]:=hyf_char; + free_avail(hyf_node); + end else decr(xchg_i); + xchg_hu:=i-xchg_i+add_char+2; {this is the index of |hu| where the first + character is replaced by a character of the + |pre_break|-list of |spec_hyf|} + for xchg_k:=1 to xchg_i do begin + xchg_char[0]:=hu[xchg_hu]; + hu[xchg_hu]:=xchg_char[xchg_k]; + xchg_char[xchg_k]:=xchg_char[0]; + incr(xchg_hu); + end; {|for|} + xchg_k:=i; + i:=xchg_hu-1; + xchg_hu:=xchg_hu-xchg_i; +end {|if hyf_disc[]<>null|} +else if hyf_node<>null then begin + incr(i); c:=hu[i]; hu[i]:=hyf_char; free_avail(hyf_node); +end; +while l<=i do begin + l:=reconstitute(l,i,font_bchar[hf],non_char)+1; + if link(hold_head)>null then + begin if minor_tail=null then pre_break(r):=link(hold_head) +@z + +------------------------------------------------------------------------- + +... continued: + +@x +if hyf_node<>null then + begin hu[i]:=c; {restore the character in the hyphen position} + l:=i; decr(i); + end + +@y + if hyf_disc[xchg_k]<>null then begin +{ Restore the original word in |hu| } + i:=xchg_k; l:=i+1; + for xchg_k:=1 to xchg_i do begin + hu[xchg_hu]:=xchg_char[xchg_k]; + incr(xchg_hu); + end;{for} + end else if hyf_node<>null then begin + hu[i]:=c; {restore the character in the hyphen position} + l:=i; decr(i); + end + +@z + +========================================================================= + +MAIN CHANGE 1) + +Finally, we come to the SISISI hyphenation. At first, we define two +variables: + +@x +@ Assuming that these auxiliary tables have been set up properly, the +@y +@!funktioniert: boolean; +@!zerleg: integer; + +@ Assuming that these auxiliary tables have been set up properly, the +@z + +------------------------------------------------------------------------- + +And off we go; at first only slowly, ... + +@x +@<Find hyphen locations for the word in |hc|...@>= +@y +{\sl Here, the German Hyphenation of W.Barth and H.Nirschl has been added!} + + +@<Find hyphen locations for the word in |hc|...@>= +@z + +------------------------------------------------------------------------- + +... but now we kill all of Liang's code and replace it by some re- and +back-en- and decoding, a call to abteilen, and the construction of the +special discretionaries. Then we go right into the SISISI hyphenation. +========================================================================= +@x +if trie_char(cur_lang+1)<>qi(cur_lang) then return; {no patterns for |cur_lang|} +hc[0]:=0; hc[hn+1]:=0; hc[hn+2]:=256; {insert delimiters} +for j:=0 to hn-r_hyf+1 do + begin z:=trie_link(cur_lang+1)+hc[j]; l:=j; + while hc[l]=qo(trie_char(z)) do + begin if trie_op(z)<>min_quarterword then + @<Store \(m)maximum values in the |hyf| table@>; + incr(l); z:=trie_link(z)+hc[l]; + end; + end; +found: for j:=0 to l_hyf-1 do hyf[j]:=0; +for j:=0 to r_hyf-1 do hyf[hn-j]:=0 + +@ @<Store \(m)maximum values in the |hyf| table@>= +begin v:=trie_op(z); +repeat v:=v+op_start[cur_lang]; i:=l-hyf_distance[v]; +if hyf_num[v]>hyf[i] then hyf[i]:=hyf_num[v]; +v:=hyf_next[v]; +until v=min_quarterword; +end + +@ The exception table that is built by \TeX's \.{\\hyphenation} primitive is +@y + for j:=0 to hn do + hc_si[j] := ktab[hc[j]]; + si_debug(2) + si_put(' hc:'); + for j:=0 to hn do si_put( xchr[hc[j]] ); + si_put_ln(':'); + si_put(' hc_si:'); + for j:=0 to hn do si_put( xchr[rev_tab[hc_si[j]]] ); + si_put_ln(':'); + gubed_si; + si_debug(4) + si_put_ln('< decimal character codes >'); + si_put(' hc:'); + for j:=0 to hn do begin + si_put(hc[j]:3,'-'); + if ((j+1) mod 16)=0 then begin + si_put_cr; si_put(' '); + end; + end; + si_put_cr; + si_put(' hc_si:'); + for j:=0 to hn do begin + si_put( rev_tab[hc_si[j]]:3,'-' ); + if ((j+1) mod 16)=0 then begin + si_put_cr; si_put(' '); + end; + end; + si_put_cr; si_put_cr; + gubed_si; + + abteilen(hc_si,hyf_si,hn,funktioniert,zerleg); + for j:=0 to 64 do begin + hyf_disc[j]:=null; hyfpen[j]:=inf_penalty; + end; + if funktioniert then + for j:=0 to hn do begin + if hyf_si[j]=neben then hyfpen[j] := neben_hyphen_penalty + else if hyf_si[j]=haupt then hyfpen[j] := hyphen_penalty + else if hyf_si[j]=nebenck then begin + hyfpen[j+1] := neben_hyphen_penalty; + s:=get_node(small_node_size); {discretionary node erzeugen} + type(s):=disc_node; + hyf_disc[j+1]:=s; + {|pre_break|-Liste: } + pre_break(s):=new_penalty(neben_hyphen_penalty); s:=pre_break(s); + subtype(s):=0; { number of additional characters } + link(s):=new_character(hf,hu[j+2]); {'k' oder'K'} + link(link(s)):=null; + s:=hyf_disc[j+1]; + post_break(s):=null; link(s):=null; + end + else if hyf_si[j]=haupt3 then begin + hyfpen[j-1]:=hyphen_penalty; + s:=get_node(small_node_size); {discretionary node erzeugen} + type(s):=disc_node; + hyf_disc[j-1]:=s; + {|pre_break|-Liste: } + pre_break(s):=new_penalty(hyphen_penalty); s:=pre_break(s); + subtype(s):=1; + link(s):=new_character(hf,hu[j]); { Dreifachkonsonant } + link(link(s)):=null; + {|post_break|- und |link|-Liste: } + s:=hyf_disc[j-1]; + post_break(s):=null; + link(s):=null; + end + end; {|if funktioniert|} + si_debug(8) + if funktioniert then begin + for j:=0 to hn do + if hyfpen[j]<>inf_penalty then begin + if hyf_disc[j]<>null then begin + if subtype(pre_break(hyf_disc[j]))=0 then + si_put( xchr[hu[j+1]], '-' ) + else {if subty...} + si_put( xchr[hu[j+1]], xchr[hu[j+1]], '=' ); + { i hope so } + end else begin + si_put( xchr[hu[j]] ); + if hyfpen[j]=hyphen_penalty then + si_put('=') + else si_put('-'); + end; + end else begin + si_put( xchr[hu[j]] ); + end; + end else begin + si_put_ln(' no hyphens were found in this word!'); + end; + si_put_cr; + gubed_si; + goto done1; + +found: +hyfpen[0]:=inf_penalty; +for j:=1 to hn do + if odd(hyf[j]) then hyfpen[j]:=hyphen_penalty + else hyfpen[j]:=inf_penalty; + +done1: + +@ Das folgende Modul ersetzt die gesamte Liang'sche Trennung. Aufgabe +dieses Modules ist es, ein in hc (ein Array of 0..255 ) liegendes Wort +nach Trennstellen zu untersuchen und die gefundenen Trennstellen in +hyf (ebenfalls ein Array of neben...) an den entsprechenden Stellen +einzutragen. Die genaue Beschreibung der Vorgangsweise findet man im +INSTITUTSBERICHT NR. 26, TECHNISCHE UNIVERSIT\"AT WIEN, INSTITUT +F\"UR PRAKTISCHE INFORMATIK. + +Alle Prozeduren f\"ur die Silbentrennung \SISISI, die bei jedem +Start von TeX aufgerufen werden. + +@ Dieser Modul beinhaltet alle f\"ur die neue Silbentrennung |abteilen| +n\"otigen Initialisierungen bzw. Prozeduren, die nur einmal am Anfang +ausgef\"uhrt werden sollen. + +@<Set initial values of ...@>= + inittrennen; + +@ @<Constants in the outer block@>= + maxwl = 64; { Maximale Wortlaenge } + sonderzeichen= 0; + bst_a= 1; bst_b= 2; bst_c= 3; bst_d= 4; bst_e= 5; bst_f= 6; bst_g= 7; + bst_h= 8; bst_i= 9; bst_j=10; bst_k=11; bst_l=12; bst_m=13; bst_n=14; + bst_o=15; bst_p=16; bst_q=17; bst_r=18; bst_s=19; bst_t=20; bst_u=21; + bst_v=22; bst_w=23; bst_x=24; bst_y=25; bst_z=26; bst_ae=27; + bst_oe=28; bst_ue=29; bst_sz=30; trennzeichen=31; + keine = 1; neben = 2; nebenck = 3; haupt = 4 ; haupt3 = 5; + + tabsize = 8191; { 2**13 - 1 } + spec_letter_ID = 4321; + { const definitionen } + vok_a = 1; + vok_e = 2; + vok_i = 3; + vok_o = 4; + vok_u = 5; + vok_ae = 6; + vok_oe = 7; + vok_ue = 8; + vok_ie = 9; + vok_ai = 10; + vok_ei = 11; + vok_au = 12; + vok_aeu= 13; + vok_eu = 14; + vok_y = 15; + kons = 16; + +@ +@<Types in the outer block@>= + string80 = packed array [0..80] of eight_bits; + buchstabe = eight_bits; + a_word = array[0..maxwl] of 0..256; + wort = a_word; + sperrvektor=array [0..maxwl] of boolean; + dudt=array [0..maxwl] of boolean;{frueher kein type !!} + { trennung = (keine, neben, nebenck, haupt, haupt3); } + trennvektor = array [0..maxwl] of integer; { Trennstelle bei i ==> + zwischen Buchstabe i und i+1 wird getrennt } + ktabtype = packed array [0..255] of buchstabe; + verdschlue = 0..8388647; { 2**23 - 1 } { -PRAK!- unsigned long in C } + varr = array [0..maxwl] of verdschlue; + intarr = array [0..maxwl] of integer; + + { darf nicht als var Parameter uebergeben werden !!} + infotype = record + { frueher ein variantenRecord } + ausnahme:boolean; + untrennbar:boolean; + { erste :0..7; + zweite:0..7; } + erste :integer; + zweite:integer; + endung,vorsilbe,stamm,ehervor,stammallein:boolean; + end; + + infobyte = eight_bits; + + { darf nicht als var Parameter uebergeben werden !!} + tableentry=record + tabv:verdschlue; + tabb:infobyte; + frei:boolean; + wiederfrei:boolean; + end; + + hashelement = packed array [0..3] of eight_bits; + htabtype = packed array [0..tabsize] of hashelement; + +@ +@<Global variables@>= + ktab : ktabtype; + htab : htabtype; + anzahl : integer; + hashfile : alpha_file; + kombtab : array [1..5, 1..5] of integer; + konsonant : array [1 .. 30] of boolean; {array [bst_a .. bst_sz]} + rev_tab: array[0..255]of integer; + + +@ Prozedurdefinitionen + +function dig_count( v: integer): integer; + { calculates the number of decimal digits of ``v'' } + var x, e, c: integer; +begin + x := v div 10; e:=1; c:=1; + while e<=x do begin + e := e * 10; incr(c); + end; + dig_count:=c; +end; + +@<Handling of dirty umlauts@>= + +procedure hashfunk (var w:wort; anfang,ende:integer; + var v:varr; var ind,k:intarr ); + + { -PRAK!- in C long statt integer } + var vacc, indacc, kacc : integer; + i : integer; +begin + vacc := 31415; indacc := 152; kacc := 271; +dbg_put_ln(' * HFNC ='); + for i := anfang to ende do begin +dbg_put(' * HFNC ',i-anfang:3,' A'); + vacc := (vacc * 31 + w [i]) mod 8388648; +dbg_put('B'); + v[i] := vacc; +dbg_put('C'); + indacc := (indacc * 33 + w[i]) mod (tabsize+1); +dbg_put('D'); + ind[i] := indacc; +dbg_put('E'); + kacc := (kacc * 15 + w[i]) mod ((tabsize+1) div 2); +dbg_put('F'); + k[i] := 2*kacc + 1; +dbg_put_ln('G'); + end; {|for|} +end; {|hashfunk|} + +procedure unpackinfo ( b:infobyte; + { var i:infotype } + var iausnahme :boolean; + var iuntrennbar :boolean; + var ierste :integer; + var izweite :integer; + var iendung :boolean; + var ivorsilbe :boolean; + var istamm :boolean; + var iehervor :boolean; + var istammallein:boolean ); +begin + { with i do begin } + if odd(b) then begin { 87654321 } + iausnahme:= true; + b:= b div 2; { 08765432 } + if odd(b) then iuntrennbar:= true + else iuntrennbar:= false; + b:=b div 2; { 00876543 } + ierste := b mod 8; { 00876xxx } + izweite := b div 8; { 00000876 } + end else begin + iausnahme:= false; { 87654321 } + b:= b div 2; { 08765432 } + if odd(b) then iendung:= true + else iendung:= false; + b:= b div 2; { 00876543 } + if odd(b) then ivorsilbe:= true + else ivorsilbe:= false; + b:= b div 2; { 00087654 } + if odd(b) then istamm:= true + else istamm:= false; + b:= b div 2; { 00008765 } + if odd(b) then iehervor:= true + else iehervor:= false; + b:= b div 2; { 00000876 } + if odd(b) then istammallein:= true + else istammallein:= false; + end; {|if-then-else|} + { end; |with|} +end; {|unpackinfo|} + + +procedure unpackentry( h:hashelement; + { var e:tableentry } + var etabv:verdschlue; + var etabb:infobyte; + var efrei:boolean; + var ewiederfrei:boolean ); +begin + { with e do begin } +dbg_put_cr; +dbg_put(' ==> UPCKNTY 1'); + etabv:= h[0]+h[1]*256+h[2]*256*256; +dbg_put(' 2'); + if odd(h[3]) then begin { Ausnahme } +dbg_put(' 3 A'); + etabb:= h[3]; +dbg_put('1'); + efrei:= false; + ewiederfrei:= false; + end + else begin +dbg_put(' 3 B'); + etabb:= h[3] mod 64; +dbg_put('1'); + { h[3]:=h[3] div 64;} {-PRAK!- in C ein var-Paramter, darf daher + nicht ver„ndert werden. } +dbg_put('2'); + { durch folgende 2 Abfragen ersetzt. -PRAK!- } + if odd(h[3] div 64) then efrei := true + else efrei := false; + if odd(h[3] div 128) then ewiederfrei := true + else ewiederfrei := false; + end; +dbg_put_ln('- 4'); + { end; |with|} +end; {|unpackentry|} + + +procedure hashsuch ( v:verdschlue; + ind,k : integer; + { var i:infotype; } + var iausnahme :boolean; + var iuntrennbar :boolean; + var ierste :integer; + var izweite :integer; + var iendung :boolean; + var ivorsilbe :boolean; + var istamm :boolean; + var iehervor :boolean; + var istammallein:boolean; + var g:boolean ); + +{ sucht Eintragung in der Hashtabelle, g ist TRUE falls gefunden } + var + gef,ngef:boolean; + j:integer; + entry : tableentry; + +begin + gef := false; ngef := false; j := ind; + repeat + unpackentry(htab[j],entry.tabv,entry.tabb,entry.frei,entry.wiederfrei); + if entry.frei then ngef := true + else if (v = entry.tabv) and not entry.wiederfrei then begin + unpackinfo(entry.tabb,iausnahme,iuntrennbar,ierste,izweite, + iendung,ivorsilbe,istamm,iehervor,istammallein); + gef := true; + end else + j := (j+k) mod (tabsize + 1) + until gef or ngef; + g := gef; +end; {|hashsuch|} + + +procedure hashload ( var status:integer ); +{ einlesen der Hash-Tabelle von file fn } + var i : integer; + e : tableentry; +begin + { Orginal sitex3.cha -PRAK!- + for i:=1 to file_name_size do name_of_file:= ' '; + name_of_file[1]:='h'; + name_of_file[2]:='f'; + name_of_file[3]:='3'; + name_length := 3; + anzahl := 0; + if a_open_in(hashfile) then begin + } + + { geaendert !! -PRAK!- } + for i:=1 to file_name_size do name_of_file[i]:= ' '; + name_of_file[1]:='h'; + name_of_file[2]:='f'; + name_of_file[3]:='3'; + name_length := 3; + anzahl := 0; + { -PRAK!- texinputpath fr C notwendig } + if a_open_in(hashfile, TEX_INPUT_PATH) then begin + for i := 0 to tabsize do begin + { -PRAK!- in C Probleme mit den typen beim einlesen } + read (hashfile, htab[i][0]); { htab = packed array [0..tabsize] of } + read (hashfile, htab[i][1]); { hashelement, und } + read (hashfile, htab[i][2]); { hashelement = packed array 0..3 } + read (hashfile, htab[i][3]); + unpackentry (htab[i],e.tabv,e.tabb,e.frei,e.wiederfrei); + if not e.frei and not e.wiederfrei then anzahl := anzahl + 1; + end; {|for|} + status:= 0; + a_close(hashfile); + end else status:= 1; +end; {|hashload|} + + +procedure inittrennen; + var ch: 0..255; + bst: buchstabe; + i, status: integer; + is_iniTeX: boolean; +begin + { Konversionstabelle |ktab| initialisieren } + { ======================================== } + + for ch := 0 to 255 do begin + + { if (ch in [" ",",",";",":","-","/","?","!","(",")",".","""","'","^"]) then } + + case ch of + " ",",",";",":","-","/","?","!","(",")",".","""","'","^": + + if ch="." then ktab[ch]:= "." + else ktab[ch] := trennzeichen + { else ktab[ch] := sonderzeichen geht nicht !!} + end; { case } + +if (ktab[ch] <> ".") and (ktab[ch] <> trennzeichen) then ktab[ch] := sonderzeichen; + + end; { for } + for bst := bst_a to bst_z do begin + ktab[ord('A')+ord(bst)-ord(bst_a)]:=bst; + ktab[ord('a')+ord(bst)-ord(bst_a)]:=bst + end; + + { Umlaute und scharfes s - f\"ur ``production \TeX version'' } + ktab[255]:=bst_sz; + ktab[246]:=bst_oe; + ktab[252]:=bst_ue; + ktab[228]:=bst_ae; + + { Umlaute und scharfes s - f\"ur ``initialization \TeX version'' } + ktab["1"]:=bst_sz; + ktab["2"]:=bst_ue; + ktab["3"]:=bst_oe; + ktab["4"]:=bst_ae; + ktab[25]:=bst_sz; {?-wieso? HH} + +{testing:} +for i:=0 to 255 do rev_tab[ktab[i]]:=i; +rev_tab[ktab[255]]:=223; +xchr[223]:=chr(223); xchr[228]:=chr(228); xchr[246]:=chr(246); +xchr[252]:=chr(252); xchr[255]:=chr(223); xchr[ 25]:=chr(223); +{:end of testing} + + { Kombinationstabelle |kombtab| initialisieren } + { ============================================ } + { Diese Tabelle muss symetrisch sein, + kombtab[a,b] = kombtab[b,a] } + kombtab[ keine, keine] := keine; + kombtab[ keine, neben] := keine; + kombtab[ keine,nebenck] := keine; + kombtab[ keine, haupt] := keine; + kombtab[ keine, haupt3] := keine; + + kombtab[ neben, keine] := keine; + kombtab[ neben, neben] := neben; + kombtab[ neben,nebenck] := keine; + kombtab[ neben, haupt] := neben; + kombtab[ neben, haupt3] := keine; + + kombtab[nebenck, keine] := keine; + kombtab[nebenck, neben] := keine; + kombtab[nebenck,nebenck] := nebenck; + kombtab[nebenck, haupt] := keine; + kombtab[nebenck, haupt3] := keine; + + kombtab[ haupt, keine] := keine; + kombtab[ haupt, neben] := neben; + kombtab[ haupt,nebenck] := keine; + kombtab[ haupt, haupt] := haupt; + kombtab[ haupt, haupt3] := keine; + + kombtab[ haupt3, keine] := keine; + kombtab[ haupt3, neben] := keine; + kombtab[ haupt3,nebenck] := keine; + kombtab[ haupt3, haupt] := keine; + kombtab[ haupt3, haupt3] := haupt3; + + { Konsonantentabelle initialisieren } + for bst:=bst_a to bst_sz do konsonant[bst] := true; + konsonant[bst_a] := false; + konsonant[bst_e] := false; + konsonant[bst_i] := false; + konsonant[bst_o] := false; + konsonant[bst_u] := false; + konsonant[bst_ae] := false; + konsonant[bst_oe] := false; + konsonant[bst_ue] := false; + + +{ ================== Hashtabelle |htab| initialisieren ====================== + +Die Prozedur ``hashload'' darf im Initialisierungslauf von TeX auf +keinen Fall aufgerufen werden. Deshalb wird zun\"achst festgestellt, ob +dieser Programmlauf ein Initialisierungslauf ist oder nicht. Abh\"angig +davon wird ``hashload'' nur aufgerufen, wenn dies ein ``Arbeits''-lauf +(production-version) von \TeX ist. + +=============================================================================} + is_iniTeX:=false; + init is_iniTeX:=true; tini + if not is_iniTeX then begin + hashload(status); + if status <> 0 then begin + si_put_cr; + si_put_ln +(' * * * * * * * * * *!'); + si_put_ln('**** ERROR: Can not read hash-file!'); + si_put_cr; + jump_out; + end; + end; {|not iniTeX|} +end; {|inittrennen|} + + +procedure packinfo ( i:infotype; var b : infobyte ); +{ Byte: /zweite/zweite/zweite/erste/erste/erste/untrennbar/ausnahm/ } +{ bzw.: /0 /0 /stall /eherv/stamm/vors /endung /0 / } + +begin + b:=0; +dbg_put_cr; + { with i do begin } + if i.ausnahme then +begin +dbg_put(' ### PCKINF 1A utr:'); +if i.untrennbar then dbg_put('Y') else dbg_put('N'); +dbg_put_ln(',',ord(i.untrennbar):3,' 1.',i.erste:3,' 2.',i.zweite:3); + b:=1+2*ord(i.untrennbar)+4*i.erste+32*i.zweite +; dbg_put('B'); +end + else +begin +dbg_put(' ### PCKINF 2A'); + b:= 2*ord(i.endung)+4*ord(i.vorsilbe)+8*ord(i.stamm)+16*ord(i.ehervor) + +32*ord(i.stammallein); +dbg_put('B'); +end; + { end; with } +dbg_put_ln('-3'); +end; {|packinfo|} + +procedure packentry( e:tableentry; var h:hashelement ); +{ /infobyte+frei,wiederfrei/verdschhigh/verdschmiddle/verdschllow/ } + +begin + { with e do begin } +dbg_put_cr; +dbg_put(' +++ PCKNTY A'); + h[0]:= e.tabv mod 256; { 87654321abcdefghxxxxxxxx} +dbg_put('B'); + e.tabv:= e.tabv div 256; { 0000000087654321abcdefgh} +dbg_put('C'); + h[1]:= e.tabv mod 256; { 0000000087654321xxxxxxxx} +dbg_put('D'); + h[2]:= e.tabv div 256; { 000000000000000087654321} + +dbg_put('E'); + if odd(e.tabb) then h[3]:= e.tabb { Ausnahme !! } + else +begin +dbg_put('F1'); + h[3]:=e.tabb+64*ord(e.frei)+128*ord(e.wiederfrei); { wfxxxxxx } +dbg_put('-2'); +end; +dbg_put_ln('G'); + { end; |with|} +end; {|packentry|} + + + +procedure hashetr ( var w:wort; laenge:integer; i:infotype; + var g:boolean ); + + var v1: varr; + ind1, k1: intarr; + v: verdschlue; + ind, k, j, e: integer; + gef,ngef:boolean; + entry: tableentry; + helem: hashelement; + +begin +dbg_put_ln(' ** HTR 1'); + if anzahl >= tabsize then begin +dbg_put_ln(' ** HTR 2a'); + g := false; + end + else begin +dbg_put_ln(' ** HTR 2b'); + if (anzahl < 10) or (anzahl mod 100 = 0) then begin + si_put_cr; si_put(' -Anzahl:',anzahl,'. '); + end; +dbg_put_ln(' ** HTR 3'); + hashfunk(w,1,laenge,v1,ind1,k1); +dbg_put_ln(' ** HTR 4'); + v := v1[laenge]; + ind := ind1[laenge]; + k := k1[laenge]; + gef := false; ngef := false; + repeat +dbg_put_ln(' ** HTR 5 A'); + unpackentry(htab[ind],entry.tabv,entry.tabb,entry.frei,entry.wiederfrei); +dbg_put_ln(' ** HTR B'); + if entry.frei or entry.wiederfrei then begin + anzahl := anzahl + 1; + ngef := true; + entry.tabv := v; +dbg_put_ln(' ** HTR C1'); + packinfo (i,entry.tabb); +dbg_put_ln(' ** HTR D1'); + entry.frei := false; + entry.wiederfrei := false; +dbg_put_ln(' ** HTR E1'); + packentry(entry,helem); +dbg_put_ln(' ** HTR F1'); + htab[ind] := helem; { -PRAK!- in C memcpy() } + end else begin +dbg_put_ln(' ** HTR C2'); + gef := v = entry.tabv; + if not gef then ind := (ind+k) mod (tabsize + 1); +dbg_put_ln(' ** HTR D2'); + end; + until gef or ngef; +dbg_put_ln(' ** HTR 6'); + g := ngef; + end +end; {|hashetr|} + +procedure hashempty; + var i:integer; + elem : tableentry; + he : hashelement; +begin + { with elem do begin } + elem.tabv:=0; + elem.tabb := 0; { !!!!!! Irgend ein Affe hat diese Initialisierung vergessen. + ( Und dies ist eine Beleidigung fuer jeden Affen ) HM } + elem.frei := true; + elem.wiederfrei := false; + { end; } + packentry (elem, he); + for i := 0 to tabsize do htab[i] := he; { -PRAK!- in C memcpy() } + anzahl := 0; +end; {|hashempty|} + +procedure hashsave (var status:integer); +{ abspeichern der Hash-Tabelle auf file } + var i: integer; +begin + for i:=1 to file_name_size do name_of_file[i]:=' '; + name_of_file[1]:='h'; + name_of_file[2]:='f'; + name_of_file[3]:='3'; + name_length:=3; + if a_open_out(hashfile) then begin + for i := 0 to tabsize do begin + write (hashfile, htab[i][0]:4); + write (hashfile, htab[i][1]:4); + write (hashfile, htab[i][2]:4); + write (hashfile, htab[i][3]:4); + write_ln (hashfile); + end; + status:=0; + a_close(hashfile); + end else status:=1; +end; {|hashsave|} + + +function hashsize :integer; +begin + hashsize:=anzahl; +end; + + +procedure zahl(line:string80;var i:integer; ende:integer; var j:integer); + var aus: boolean; +begin + j:=0; + repeat + if i<=ende then + if ktab[line[i]]="." then i:=i+1 + else aus:=true + else aus:=true + until aus; + repeat + if i<=ende then begin + { if line[i] in ["0".."9"] then begin } + case line[i] of + "0","1","2","3","4","5","6","7","8","9": + begin j:=10*j+line[i]-"0";i:=i+1 + end; + { else aus:=true geht nicht !!! } + end; + if (line[i] <> "0") and + (line[i] <> "1") and + (line[i] <> "2") and + (line[i] <> "3") and + (line[i] <> "4") and + (line[i] <> "5") and + (line[i] <> "6") and + (line[i] <> "7") and + (line[i] <> "8") and + (line[i] <> "9") then aus :=true; + end else aus:=true + until aus; +end; {|zahl|} + + +procedure infobau(line: string80; anfang,ende: integer; + { var inform: infotype;} + var informausnahme :boolean; + var informuntrennbar :boolean; + var informerste :integer; + var informzweite :integer; + var informendung :boolean; + var informvorsilbe :boolean; + var informstamm :boolean; + var informehervor :boolean; + var informstammallein:boolean; + var g: boolean); + + var i,j:integer;ok,fehler:boolean; + b:buchstabe; +begin + g:=false; + { with inform do begin } { initialisierung } + informausnahme:=false; + informendung:=false; + informvorsilbe:=false; + informehervor:=false; + informstamm:=false; + informstammallein:=false; + i:=anfang; ok:=false; fehler:=false; + repeat + if i<=ende then + if line[i]="." then i:=i+1 else ok:=true + else fehler:=true + until ok or fehler; + if not fehler then begin + b:=ktab[line[i]]; + if b = bst_a then begin + {ausnahme} + informausnahme:=true; + i:=i+1; + if ktab[line[i]] = bst_u then begin + i := i + 1; informuntrennbar := true; + end else informuntrennbar := false; + zahl(line,i,ende,j); + if j=0 then begin + informerste:=7; informzweite:=7; + { Record-komponente ``zweite'' wird } + { initialisiert, damit beim packen keine } + { undefinierten Ergebnisse entstehen (die u.U. zu } + { RUN-TIME-ERRORS f\"uhren k\"onnen!) } + end else begin + j:=j-2; + if (j>=0) and (j<=6) then informerste:=j + else fehler:=true; + zahl(line,i,ende,j); + if j=0 then informzweite:=7 + else begin + j:=j-informerste-4; + if (j>=0) and (j<=6) then informzweite:=j + else fehler:=true; + end; + end; + if not fehler then g:=true; + end {|if b = bst_a |} + else begin + ok:=false; + repeat + case b of + {bst_v} 22: informvorsilbe:=true; + {bst_e} 5: informendung:=true; + {bst_s} 19: informstamm:=true; + {bst_b} 2: informehervor:=true; + {bst_t} 20: informstammallein:=true; + {trennzeichen} 31:; + othercases fehler:=true + endcases; + if i=ende then ok:=true + else begin + i:=i+1; + b:=ktab[line[i]] + end + until ok or fehler; + if not fehler then + g := (informvorsilbe or informendung or informstamm) + and (not informehervor or informvorsilbe and informendung) + and (not informstammallein or informstamm); + end; {|if b = bst_a then-else|} + end {|if not fehler|} + { end |with inform|} +end; {|infobau|} + + +procedure eintragen (line: string80; l: integer ); + var i, laenge: integer; + inform: infotype; + w: wort; + g: boolean; +begin + laenge := 1; + while line [laenge] <> "." do laenge := laenge + 1; + laenge := laenge -1; + if laenge >= 1 then begin + if laenge <= maxwl then begin + infobau(line,laenge+1,l, + inform.ausnahme,inform.untrennbar, + inform.erste,inform.zweite,inform.endung, + inform.vorsilbe,inform.stamm,inform.ehervor, + inform.stammallein,g); + + if not g then begin + si_put_cr; si_put(' Info falsch: ') + end else begin + for i:= 1 to laenge do w[i]:=ktab[line[i]]; + hashetr(w,laenge,inform,g); + if not g then begin + si_put_cr; si_put(' Tabellenfehler: '); + end; + end; + if not g then begin + for i:=1 to l do si_put( xchr[line[i]] ); + si_put_cr; + end + end {|if laenge <= maxwl|} + else begin + si_put_cr; si_put_ln(' zu langes Wort: '); + for i:=1 to l do si_put( xchr[line[i]] ); + si_put_cr; + end + end {|if laenge >= 1|} + else begin + si_put_cr; si_put_ln(' Falsche Zeile: '); + for i:=1 to l do si_put( xchr[line[i]] ); + si_put_cr; + end +end; {|eintragen|} + +{---------------------------------------------------------------------------} + +{ naechsterbst -> naechsterbst(i,tr,dudstop,b,w) } + +procedure naechsterbst(var i:integer;var tr:trennvektor; + var dudstop:sperrvektor;var b:buchstabe; + var w:wort); + begin + if (i>0) and (tr[i]=keine) and not dudstop[i] + then begin b:=w[i];i:=i-1 end + else b:=trennzeichen + end; +{---------------------------------------------------------------------------} +{ duden(tr) -> duden(tr,w,tr1,dudtr,dud,dudstop,laenge,ok,zerlegungen) } + + procedure duden (tr:trennvektor; + var w:wort; + var tr1 :trennvektor; + var dudtr:trennvektor; + dud :dudt; { array [0..maxwl] of boolean; } + var dudstop:sperrvektor; + laenge : integer; + var ok :boolean; + var zerlegungen:integer ); + + { traegt in dudtr die Trennstellen nach Dudenregeln ein } + + { frueher mtype laut = (.....) } + + var i:integer; + j:integer; + zust:integer; + aus:boolean; + tre:integer; + letzte:integer; + l,lalt:integer;{ vormals laut } + b:buchstabe; + + + begin { duden } + i:=laenge; + for j := 0 to laenge do dudtr[j] := tr[j]; + while (i>0) and not dud [i] do i:=i-1; + while i>0 do begin + zust:=1; aus:=false; letzte := 0; + l:=kons; + b:=w[i]; + i:=i-1; + repeat + {naechsten Laut lesen} + { procedure nlaut; } + begin { nlaut } + tre:=i+1; + lalt:=l; + case b of + {bst_a } 1:begin l:=vok_a; naechsterbst(i,tr,dudstop,b,w) end; + {bst_o } 15:begin l:=vok_o; naechsterbst(i,tr,dudstop,b,w) end; + {bst_ue} 29:begin l:=vok_ue; naechsterbst(i,tr,dudstop,b,w) end; + {bst_oe} 28:begin l:=vok_oe; naechsterbst(i,tr,dudstop,b,w) end; + {bst_ae} 27:begin l:=vok_ae; naechsterbst(i,tr,dudstop,b,w) end; + {bst_e } 5:begin + l:=vok_e; naechsterbst(i,tr,dudstop,b,w); + if b = bst_i then begin + l:=vok_ie; + naechsterbst(i,tr,dudstop,b,w); + if b = bst_e then begin + {ungetbst = } i := i + 1; + l:=vok_e; + b := bst_i; + end; + end + end; + {bst_i} 9:begin + l:=vok_i; naechsterbst(i,tr,dudstop,b,w); + if b = bst_e then begin l:=vok_ei; naechsterbst(i,tr,dudstop,b,w) end + else if b = bst_a then begin l:=vok_ai; naechsterbst(i,tr,dudstop,b,w) end + end; + {bst_u} 21:begin + l:=vok_u; naechsterbst(i,tr,dudstop,b,w); + if b = bst_e then begin l:=vok_eu; naechsterbst(i,tr,dudstop,b,w) end + else if b = bst_a then begin l:=vok_au; naechsterbst(i,tr,dudstop,b,w) end + else if b = bst_ae then begin l:=vok_aeu; naechsterbst(i,tr,dudstop,b,w) end + else if b = bst_q then begin l:=kons; naechsterbst(i,tr,dudstop,b,w) end + end; + {bst_t} 20:begin + l:=kons; naechsterbst(i,tr,dudstop,b,w); + if b = bst_s then naechsterbst(i,tr,dudstop,b,w) + end; + {bst_h} 8:begin + l:=kons; naechsterbst(i,tr,dudstop,b,w); + if b = bst_c then begin + naechsterbst(i,tr,dudstop,b,w); + if b = bst_s then naechsterbst(i,tr,dudstop,b,w) + end + else if b = bst_p then naechsterbst(i,tr,dudstop,b,w) + else if b = bst_t then naechsterbst(i,tr,dudstop,b,w) + end; + {bst_b, bst_c, bst_d, bst_f, bst_g, bst_j, bst_k, bst_l, bst_m, + bst_n, bst_p, + bst_q, bst_r, bst_s, bst_v, bst_w, bst_x, bst_z, bst_sz } + + 2,3,4,6,7,10,11,12,13,14,16,17,18,19,22,23,24,26,30 : + + begin l:=kons; naechsterbst(i,tr,dudstop,b,w) end; + {bst_y} 25:begin + l:=vok_y; + naechsterbst(i,tr,dudstop,b,w); + end; + {trennzeichen,sonderzeichen} + 31,0 :aus:=true + end; + end; { nlaut } + + if not aus then + {Naechster Zustand} + case zust of + 1:if l=kons then zust:=2 + else zust:=4; + 2:if l<>kons then zust:=3; + 3:if l=kons then zust:=6 + else if l<>lalt then begin + zust:=4; + letzte:=tre; + dudtr[letzte]:=neben + end; + 4:if l=kons then zust:=6 + else zust:=3; + 6:if l=kons then begin + zust:=2; + letzte:=tre; + if (w[tre]=bst_c) and (w[tre+1] = bst_k) then + dudtr[letzte]:=nebenck + else dudtr[letzte]:=neben + end + else begin + zust:=4; + letzte:=tre; + dudtr[letzte]:=neben + end + end + until aus; + if zust=2 then dudtr[letzte]:=keine + else if zust=4 then + { if not (lalt in [vok_ai,vok_ei,vok_au,vok_aeu,vok_eu,vok_ie]) then } + if (lalt < vok_ie) or (lalt > vok_eu) then + dudtr[letzte]:=keine; + while (i>0) and not dud[i] do i:=i-1 + end; + end { duden }; +{---------------------------------------------------------------------------} +{ procedure trennen (zustand : integer; anfang: integer; spv:sperrvektor; + var ok1 : boolean); +} + + procedure trennen ( + { trennen } + zustand : integer; + anfang : integer; + spv : sperrvektor; + var ok1 : boolean; + { abteilen } + var tr :trennvektor; + var dudtr:trennvektor; + var zerlegungen:integer ; + var dud:dudt; { array [0..maxwl] of boolean; } + var v:varr; + var ind,k:intarr; + var dudstop:sperrvektor; + { abteilen aufruf } + var w:wort; + var tr1:trennvektor; + laenge : integer ); + + { Zustand : 1 ... Es kann nur Vorsilbe oder Stamm kommen, + rechts muss noch ein Stamm kommen. + 2 ... Es kann Endung, Vorsilbe oder Stamm kommen. + 3 ... Es kann nur Vorsilbe oder Stamm kommen, im linken + Teil muessen noch Trennstellen eingefuegt werden, + rechts muss noch ein Stamm kommen. + 4 ... Es kann nur Vorsilbe oder Stamm kommen, im linken + Teil muessen noch Trennstellen eingefuegt werden. + 5 ... Trennstelle mit entfallenem Konsonanten } + + var + gef, nichtok:boolean; + schnitt:integer; + inform:infotype; + i:integer; + ok_stamm, ok_vor, ok_end, ok_help:boolean; + tri:integer; + { p_stamm } + i1,tre:integer; + ok : boolean; + stop_ptr :integer; + spvtmp :sperrvektor; { lokale Kopie des Sperrvektors, + fr die bersetzung nach C notwendig. + -PRAK!- } + + { procedure p_endung(var endok:boolean); } + + { procedure p_vorsilbe(var vorok:boolean); } + + { procedure p_stamm(var stok:boolean); } + + { procedure p_stammallein (var staok:boolean); } + + begin { trennen } + spvtmp := spv; + ok1:=false; + if anfang = laenge + 1 + then { Ende des Wortes erreicht} + if (zustand = 2) or (zustand=4) then {erfolgreich zerschnitten } + begin + dud[anfang-1]:=true; + + {duden(tr);} + duden(tr,w,tr1,dudtr,dud,dudstop,laenge,ok,zerlegungen); + + for i := laenge downto 1 do + begin + if dudtr[i-1] = haupt3 then + begin + dudtr[i-1] := keine; + tri := haupt3; + end + else + tri := dudtr[i]; + + if zerlegungen = 0 then + tr1[i] := tri + else + tr1[i] := kombtab[tr1[i],tri]; + end; + zerlegungen:=zerlegungen+1; + ok1:= true + end + else { kein Stamm im Wortrest ok1 = false } + else { restlichen Teil zerschneiden } + begin + hashfunk (w,anfang,laenge,v,ind,k); + schnitt := laenge; + nichtok := false; + repeat + { links abschneiden } + repeat + if spv[schnitt] then { Schnittstelle gesperrt } + gef:=false + else + begin + hashsuch (v[schnitt],ind[schnitt],k[schnitt], + inform.ausnahme,inform.untrennbar, + inform.erste,inform.zweite,inform.endung, + inform.vorsilbe,inform.stamm,inform.ehervor, + inform.stammallein,gef); + end; + if gef then + spv[schnitt]:=true + else + schnitt := schnitt - 1 + until gef or (schnitt = anfang - 1); + + if gef then { teilwortanfang ist bekanntes wort } + begin + if not inform.ausnahme then + begin + if inform.endung and (zustand=2) then + begin + + { --- p_endung(ok_end); --- } + ok_end:=false; + if (w[anfang]=bst_c) or (w[anfang]=bst_h) then + begin + dud[anfang-1]:=true; + tr[anfang-1]:=neben + end; + { Fugen 's' bevorzugen } + if schnitt < laenge then + if (w[schnitt+1] = bst_s) and not spv[schnitt+1] + then begin + spv[schnitt+1]:=true; + trennen (2, schnitt+2, spv, ok_help, + tr,dudtr,zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_end := ok_help + end; + trennen (2, schnitt+1, spv, ok_help, + tr,dudtr,zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_end := ok_end or ok_help; + {eingetragene Trennstellen loeschen} + tr[anfang-1]:=keine; + dud[anfang-1]:=false; + { --- p_endung(ok_end) - ende --- } + + ok1 := ok1 or ok_end + end + else + ok_end:=false; + if inform.vorsilbe + then begin + + { --- p_vorsilbe(ok_vor); --- } + { Trennstelle(n) vor der Vorsilbe eintragen } + if zustand = 1 then + tr[anfang-1]:=neben + else begin + dud[anfang-1]:=true; + if zustand = 5 then + tr[anfang-1] := haupt3 + else + tr[anfang-1]:=haupt; + end; + { Trennstellen innerhalb der Vorsilbe eintragen } + dud[schnitt]:=true; + { Rest des Wortes zerschneiden } + trennen(1, schnitt+1, spv, ok_vor, + tr,dudtr,zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + {eingetragene Trennstellen loeschen} + tr[anfang-1]:=keine; + dud[anfang-1]:=false; + dud[schnitt]:=false; + { --- p_vorsilbe(ok_vor) - ende --- } + + ok1 := ok1 or ok_vor + end + else + ok_vor := false; + if inform.stamm and not ok_vor + then begin + if not inform.stammallein + then begin + + { --- p_stamm(ok_stamm); --- } + ok_stamm := false; + stop_ptr := 0; + if zustand = 1 then + tr[anfang-1]:=neben + else begin + dud[anfang-1]:=true; + if zustand = 5 then + tr[anfang-1] := haupt3 + else + tr[anfang-1]:=haupt + end; + {ev. Ausnahmetrennstellen eintragen} + if inform.ausnahme then begin + if inform.erste<>7 then begin + tre:=anfang+inform.erste+1; + tr[tre]:=neben; + if inform.zweite<>7 then begin + tre:=tre+inform.zweite+2; + if inform.untrennbar then begin + stop_ptr := tre; + dudstop[stop_ptr] := true; + end + else + tr[tre]:=neben + end + else begin + if inform.untrennbar then begin + tr[tre] := keine; + stop_ptr := tre; + dudstop[tre]:=true; + end + end + end + else begin {inform.erste = 7} + stop_ptr := schnitt-1; + dudstop[stop_ptr] := true + end + end; + + { Fugen 's' bevorzugen } + if schnitt < laenge then + if (w[schnitt+1] = bst_s) and not spv[schnitt+1] + then begin + spv [schnitt+1] := true; + trennen (2, schnitt+2, spv, ok_help,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_stamm := ok_help + end; + + { Sonderbehandlung eines in der Wortfuge entfallenen mitlauts } + if (schnitt >=2) and (schnitt < laenge) then + if konsonant[w[schnitt]] and not konsonant[w[schnitt+1]] and + (w[schnitt] = w[schnitt-1]) then begin + trennen(5, schnitt, spv, ok_help,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_stamm := ok_stamm or ok_help; + end; + + { restlichen Teil zerschneiden } + trennen (2, schnitt+1, spv, ok_help,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_stamm := ok_stamm or ok_help; + + { eingetragene Trennstellen entfernen } + if inform.ausnahme then + for i1:=anfang-1 to schnitt do + begin + tr[i1]:=keine; + dud[i1]:=false; + dudstop[stop_ptr] := false; + end + else begin + tr[anfang-1]:=keine; + dud[anfang-1]:=false; + end; + { --- p_stamm(ok_stamm) - ende --- } + + ok1 := ok1 or ok_stamm; + end + else + if (anfang=1) and (schnitt=laenge) + then begin + + { --- p_stammallein(ok_stamm); --- } + dud[anfang-1]:=true; + tr[anfang-1]:=haupt; + trennen (4, schnitt+1, spv, ok_stamm,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + {eingetragene Trennstellen loeschen} + tr[anfang-1]:=keine; + dud[anfang-1]:=false; + { --- p_stammallein(ok_stamm) - ende --- } + + ok1 := ok1 or ok_stamm; + end; + end + end + else begin + + { --- p_stamm(ok_stamm); --- } + ok_stamm := false; + stop_ptr := 0; + + if zustand = 1 then + tr[anfang-1]:=neben + else begin + dud[anfang-1]:=true; + if zustand = 5 then + tr[anfang-1] := haupt3 + else + tr[anfang-1]:=haupt + end; + {ev. Ausnahmetrennstellen eintragen} + if inform.ausnahme then begin + if inform.erste<>7 then begin + tre:=anfang+inform.erste+1; + tr[tre]:=neben; + if inform.zweite<>7 then begin + tre:=tre+inform.zweite+2; + if inform.untrennbar then begin + stop_ptr := tre; + dudstop[stop_ptr] := true; + end + else + tr[tre]:=neben + end + else begin + if inform.untrennbar then begin + tr[tre] := keine; + stop_ptr := tre; + dudstop[tre]:=true; + end + end + end + else begin {inform.erste = 7} + stop_ptr := schnitt-1; + dudstop[stop_ptr] := true; + end; + end; + + { Fugen 's' bevorzugen } + if schnitt < laenge then + if (w[schnitt+1] = bst_s) and not spv[schnitt+1] + then begin + spv [schnitt+1] := true; + trennen (2, schnitt+2, spv, ok_help,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_stamm := ok_help + end; + + { Sonderbehandlung eines in der Wortfuge entfallenen mitlauts } + if (schnitt >=2) and (schnitt < laenge) then + if konsonant[w[schnitt]] and not konsonant[w[schnitt+1]] and + (w[schnitt] = w[schnitt-1]) then begin + trennen(5, schnitt, spv, ok_help,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_stamm := ok_stamm or ok_help; + end; + + { restlichen Teil zerschneiden } + trennen (2, schnitt+1, spv, ok_help,tr,dudtr, + zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + ok_stamm := ok_stamm or ok_help; + + { eingetragene Trennstellen entfernen } + if inform.ausnahme then + for i1:=anfang-1 to schnitt do + begin + tr[i1]:=keine; + dud[i1]:=false; + dudstop[stop_ptr] := false; + end + else begin + tr[anfang-1]:=keine; + dud[anfang-1]:=false; + end; + { --- p_stamm(ok_stamm) - ende --- } + + ok1 := ok1 or ok_stamm; + end; + + {naechsten Schleifendurchlauf vorbereiten} + schnitt := schnitt - 1; + nichtok := schnitt = anfang - 1 + end + else { kein bekanntes Wort am Beginn des Teilwortes } + nichtok := true; + + until nichtok + end; + spv := spvtmp; { spv wiederherstellen, fr die C Version. -PRAK!- } + end { trennen }; + +{----------------------------------------------------------------------------} + +procedure abteilen ( var w:wort; var tr1:trennvektor; + laenge : integer; var ok:boolean; + var zerlegungen:integer ); + + label 99; + + { kommt in den outer Block } + { mtype sperrvektor=array [0..maxwl] of boolean; } + + var + i:integer; + dud:dudt; { array [0..maxwl] of boolean; } + v:varr; + ind,k:intarr; + spv,dudstop:sperrvektor; + tr, dudtr:trennvektor; + + begin { abteilen } + tr1[0] := keine; + for i:=0 to laenge do begin + tr[i]:=keine; spv[i]:=false; dudstop[i]:=false; dud[i]:=false; + if i > 0 then + if (w[i] = trennzeichen) or (w[i] = sonderzeichen) + then begin + zerlegungen := 0; + ok := false; + goto 99; + end; + end; + zerlegungen:=0; + trennen(3, 1, spv, ok, + tr,dudtr,zerlegungen,dud,v,ind,k, + dudstop,w,tr1,laenge); + + for i:=0 to laenge do + if tr1[i]=nebenck then begin + tr1[i]:=keine; { c-k wird zu -ck da sp\"ater dement- } + tr1[i-1]:=nebenck; {sprechend getrennt wird } + end; +99: + end;{ abteilen } +{----------------------------------------------------------------------------} + + {identification number for dirty umlauts; see description in + change file} + + function is_dirty_umlaut(p:pointer):boolean; + var res:boolean; + q:pointer; + begin + res:=false; + if p<>null then + if type(p)=disc_node then + if pre_break(p)<>null then + if link(pre_break(p))<>null then + if link(link(pre_break(p)))<>null then begin + q:=pre_break(p); + if type(q)=penalty_node then q:=link(q); + if (type(q)=kern_node)and(width(q)=spec_letter_ID)and + is_char_node(link(q))and(type(link(link(q)))=kern_node) then res:=true; + end; + is_dirty_umlaut:=res; + end; {|is_dirty_umlaut|} + + function get_char_of(s:pointer):integer; + var q:pointer; + begin + q:=pre_break(s); + if type(q)=penalty_node then q:=link(q); + get_char_of:=width(link(link(q))); + end; {|get_char_of|} + + function get_font_of(s:pointer):integer; + var q:pointer; + begin + q:=pre_break(s); + if type(q)=penalty_node then q:=link(q); + get_font_of:=font(link(q)); + end; {|get_font_of|} + +{----------------------------------------------------------------------------} + +@ Ende ... +@z + +========================================================================= + +@x +@ Now let's go back to the easier problem, of building the linked +trie. When \.{INITEX} has scanned the `\.{\\patterns}' control +sequence, it calls on |new_patterns| to do the right thing. + +@<Declare procedures for preprocessing hyph...@>= +procedure new_patterns; {initializes the hyphenation pattern data} +label done, done1; +var k,@!l:small_number; {indices into |hc| and |hyf|} +@!digit_sensed:boolean; {should the next digit be treated as a letter?} +@!v:quarterword; {trie op code} +@!p,@!q:trie_pointer; {nodes of trie traversed during insertion} +@!first_child:boolean; {is |p=trie_l[q]|?} +@!c:ASCII_code; {character being inserted} +begin if trie_not_ready then + begin set_cur_lang; scan_left_brace; {a left brace must follow \.{\\patterns}} + @<Enter all of the patterns into a linked trie, until coming to a right + brace@>; + end +else begin print_err("Too late for "); print_esc("patterns"); + help1("All patterns must be given before typesetting begins."); + error; link(garbage):=scan_toks(false,false); flush_list(def_ref); + end; +end; +@y +@ We do not build a trie (wether a linked nor a packed). Instead, we +create a hash table for the \SISISI-hyphenation algorithm. But we +still use the data provided by the `\.{\\patterns}' primitive. + +@<Declare procedures for preprocessing hyph...@>= +procedure new_patterns; {initializes the hyphenation pattern data} + label done; + var k: small_number; {index into |zeile|} + @!zeile:string80; { Silbe <space> Type <,> als Eintrag der Hashtabelle } + @!status:integer; + @!c:ASCII_code; {character being inserted} +begin + if trie_not_ready then begin + set_cur_lang; scan_left_brace; {a left brace must follow \.{\\patterns}} + + hashempty; { create the empty hash table } + @<Enter all of the patterns into a hash table, until coming to a right + brace; then skip an optional space@>; + hashsave(status); + if status<>0 then begin + wterm_ln('Fehler bei hash save !!!!!'{?}); + wlog_ln( 'Fehler bei hash save !!!!!'{?}); + end; + end else begin + print_err("Too late for "); print_esc("patterns"); + help1("All patterns must be given before typesetting begins."); + error; link(garbage):=scan_toks(false,false); flush_list(def_ref); + end; +end; +@z + + +-------------------------------------------------------------------------- + + +@x +@ Novices are not supposed to be using \.{\\patterns}, so the error +messages are terse. (Note that all error messages appear in \TeX's string +pool, even if they are used only by \.{INITEX}.) + +@<Enter all of the patterns into a linked trie...@>= +k:=0; hyf[0]:=0; digit_sensed:=false; +loop@+ begin get_x_token; + case cur_cmd of + letter,other_char:@<Append a new letter or a hyphen level@>; + spacer,right_brace: begin if k>0 then + @<Insert a new pattern into the linked trie@>; + if cur_cmd=right_brace then goto done; + k:=0; hyf[0]:=0; digit_sensed:=false; + end; + othercases begin print_err("Bad "); print_esc("patterns"); +@.Bad \\patterns@> + help1("(See Appendix H.)"); error; + end + endcases; + end; +done: +@y +@ Here we build the hash table for the \SISISI-hyphenation. + +@<Enter all of the patterns into a hash table, until coming to a right...@>= +for k:=0 to maxwl do zeile[k]:=" "; +k:=0; +loop@+ begin + get_x_token; { \SISISI Worttabelle hat das Format 'Text.Type,'. + Der Beistrich wird eigens abgefragt, da er in TeX + umdefiniert werden kann. } + if (cur_cmd = right_brace)or(cur_chr = ",") then + begin + { Ein Eintrag der Worttabelle - letzter + (|cur_cmd|=|right_brace|) - gelesen } + if k>0 then eintragen(zeile,k); { ein Eintrag vorhanden } + if cur_cmd = right_brace then goto done; + k := 0; { hyf[] ist \"uberfl\"ussig, da die + Trenninformation in zeile mitverpackt ist. } + end + else { Das Wort ist noch nicht fertig gelesen } + if (cur_cmd = letter) or (cur_cmd = other_char) + or (cur_cmd = spacer) or (cur_chr = ".") + then begin + @<Append a new letter or a hyphen level@>; + end else begin + print_err("Bad "); print_esc("patterns"); +@.Bad \\patterns@> + help1("(See Appendix H.)"); error; + end; +end; {|loop|} +done: +@z + +----------------------------------------------------------------------------- + + +@x +@ @<Append a new letter or a hyphen level@>= +if digit_sensed or(cur_chr<"0")or(cur_chr>"9") then + begin if cur_chr="." then cur_chr:=0 {edge-of-word delimiter} + else begin cur_chr:=lc_code(cur_chr); + if cur_chr=0 then + begin print_err("Nonletter"); +@.Nonletter@> + help1("(See Appendix H.)"); error; + end; + end; + if k<63 then + begin incr(k); hc[k]:=cur_chr; hyf[k]:=0; digit_sensed:=false; + end; + end +else if k<63 then + begin hyf[k]:=cur_chr-"0"; digit_sensed:=true; + end +@y +@ @<Append a new letter or a hyphen level@>= +if (cur_chr<>" ")then begin + { Das Leerzeichen wird \"uberlesen! } + if (cur_chr <> ".") then begin + { der Punkt trennt die Silbe von der Silbenart und bleibt erhalten } + if (cur_chr<"0")or(cur_chr>"9") then begin + cur_chr:=lc_code(cur_chr); + if cur_chr=0 then begin + print_err("Nonletter"); +@.Nonletter@> + help1("(See Appendix H.)"); error; cur_chr:=128; + end; + end; + end; + if k<63 then begin + incr(k); zeile[k]:=cur_chr; + end; +end; +@z + +---------------------------------------------------------------------------- + + +@x +@ When the following code comes into play, the pattern $p_1\ldots p_k$ +appears in |hc[1..k]|, and the corresponding sequence of numbers $n_0\ldots +n_k$ appears in |hyf[0..k]|. + +@<Insert a new pattern into the linked trie@>= +begin @<Compute the trie op code, |v|, and set |l:=0|@>; +q:=0; hc[0]:=cur_lang; +while l<=k do + begin c:=hc[l]; incr(l); p:=trie_l[q]; first_child:=true; + while (p>0)and(c>so(trie_c[p])) do + begin q:=p; p:=trie_r[q]; first_child:=false; + end; + if (p=0)or(c<so(trie_c[p])) then + @<Insert a new trie node between |q| and |p|, and + make |p| point to it@>; + q:=p; {now node |q| represents $p_1\ldots p_l$} + end; +if trie_o[q]<>min_quarterword then + begin print_err("Duplicate pattern"); +@.Duplicate pattern@> + help1("(See Appendix H.)"); error; + end; +trie_o[q]:=v; +end +@y +@ Well, that was everything about the initialization of the \SISISI hash +table (at this place). + +All following sections, describing the initialization of the trie are +replaced by ``empty sections'' in order to have same section numbering +in SI\TeX as in \TeX. +@z + +---------------------------------------------------------------------------- + +@x +@ @<Insert a new trie node between |q| and |p|...@>= +begin if trie_ptr=trie_size then overflow("pattern memory",trie_size); +@:TeX capacity exceeded pattern memory}{\quad pattern memory@> +incr(trie_ptr); trie_r[trie_ptr]:=p; p:=trie_ptr; trie_l[p]:=0; +if first_child then trie_l[q]:=p@+else trie_r[q]:=p; +trie_c[p]:=si(c); trie_o[p]:=min_quarterword; +end +@y +@ ``Empty section''. +@z +------------------------------------------------------------------------------ +@x +@ @<Compute the trie op code, |v|...@>= +if hc[1]=0 then hyf[0]:=0; +if hc[k]=0 then hyf[k]:=0; +l:=k; v:=min_quarterword; +loop@+ begin if hyf[l]<>0 then v:=new_trie_op(k-l,hyf[l],v); + if l>0 then decr(l)@+else goto done1; + end; +done1: +@y +@ Further ``empty section''. +@z + +@x +@ Finally we put everything together: Here is how the trie gets to its +final, efficient form. +The following packing routine is rigged so that the root of the linked +tree gets mapped into location 1 of |trie|, as required by the hyphenation +algorithm. This happens because the first call of |first_fit| will +``take'' location~1. + +@<Declare procedures for preprocessing hyphenation patterns@>= +procedure init_trie; +var @!p:trie_pointer; {pointer for initialization} +@!j,@!k,@!t:integer; {all-purpose registers for initialization} +@!r,@!s:trie_pointer; {used to clean up the packed |trie|} +@!h:two_halves; {template used to zero out |trie|'s holes} +begin @<Get ready to compress the trie@>; +if trie_root<>0 then + begin first_fit(trie_root); trie_pack(trie_root); + end; +@y +@ Because we do not use the trie, we fill it with dummy data. +But the main reason, why we do not remove this procedure is, that +it is called and the used variables are referenced somewhere in \TeX. + + +@<Declare procedures for preprocessing hyphenation patterns@>= +procedure init_trie; + var @!p:trie_pointer; {pointer for initialization} + @!j,@!k,@!t:integer; {all-purpose registers for initialization} + @!r,@!s:trie_pointer; {used to clean up the packed |trie|} + @!h:two_halves; {template used to zero out |trie|'s holes} +begin + trie_root:=0; +@z + +========================================================================= + diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/tangle.ch b/obsolete/systems/sisisi/unix/SiTeX3.14/tangle.ch new file mode 100644 index 0000000000..4c0e00a9da --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/tangle.ch @@ -0,0 +1,687 @@ +% tangle.ch for C compilation with web2c. +% The original version of this file was created by Howard Trickey and +% Pavel Curtis. +% +% History: +% +% (more recent changes in ../ChangeLog.W2C) +% +% 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. +% 12/18/83 (ETM) Brought up to date with version 2.5 released November, 1983. +% 11/07/84 (ETM) Brought up to date with version 2.6. +% 12/15/85 (ETM) Brought up to date with version 2.8. +% 03/07/88 (ETM) Converted for use with WEB2C +% 01/02/89 (PAM) Cosmetic upgrade to version 2.9 +% 11/30/89 (KB) Version 4. +% (more recent changes in ../ChangeLog.W2C) + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [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 C} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1] Change banner message +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d banner=='This is TANGLE, Version 4.2' +@y +@d banner=='This is TANGLE, C Version 4.2' +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [2] add input and output, remove other files, add ref to scan_args, +% and #include external definition for exit(). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d end_of_TANGLE = 9999 {go here to wrap it up} + +@p @t\4@>@<Compiler directives@>@/ +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 +@d end_of_TANGLE = 9999 {go here to wrap it up} + +@p program TANGLE; +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@>@/ +@<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_names=4000; {number of identifiers, strings, module names; + must be less than 10240} +@!max_texts=2000; {number of replacement texts, must be less than 10240} +@!hash_size=353; {should be prime} +@!longest_name=400; {module names shouldn't be longer than this} +@!line_length=72; {lines of \PASCAL\ output have at most this many characters} +@!out_buf_size=144; {length of output buffer, should be twice |line_length|} +@!stack_size=50; {number of simultaneous levels of macro expansion} +@!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_names=9000; {number of identifiers, strings, module names; + must be less than 10240} +@!max_texts=2000; {number of replacement texts, must be less than 10240} +@!hash_size=353; {should be prime} +@!longest_name=400; {module names shouldn't be longer than this} +@!line_length=72; {lines of \PASCAL\ output have at most this many characters} +@!out_buf_size=144; {length of output buffer, should be twice |line_length|} +@!stack_size=100; {number of simultaneous levels of macro expansion} +@!max_id_length=50; {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 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [??] The text_char type is used as an array index into xord. The +% default type `char' produces signed integers, which are bad array +% indices in C. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d text_char == char {the data type of characters in text files} +@y +@d text_char == ASCII_code {the data type of characters in text files} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [17] enable maximum character set +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +for i:=1 to @'37 do xchr[i]:=' '; +for i:=@'200 to @'377 do xchr[i]:=' '; +@y +for i:=1 to @'37 do xchr[i]:=chr(i); +for i:=@'200 to @'377 do xchr[i]:=chr(i); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [20] terminal output: use standard i/o +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d print(#)==write(term_out,#) {`|print|' means write on the terminal} +@y +@d term_out==stdout +@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 for C.} +@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_name| and |chg_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_name); reset(change_file,chg_name); +end; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [26] Open output files (except for the pool file). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@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); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [28] Fix f^. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + 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); +@y + begin buffer[limit]:=xord[getc(f)]; + incr(limit); + if buffer[limit-1]<>" " then final_limit:=limit; + if limit=buf_size then + begin while not eoln(f) do vgetc(f); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [??] Fix `jump_out'. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d fatal_error(#)==begin new_line; print(#); error; mark_fatal; jump_out; + end + +@<Error handling...@>= +procedure jump_out; +begin goto end_of_TANGLE; +end; +@y +@d jump_out==uexit(1) +@d fatal_error(#)==begin new_line; print(#); error; mark_fatal; uexit(1); + end +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [38] Provide for a 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; {merge lowercase with uppercase} +@y + begin +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [64] Delayed pool file opening. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@<Define and output a new string...@>= +begin ilk[p]:=numeric; {strings are like numeric macros} +if l-double_chars=2 then {this string is for a single character} + equiv[p]:=buffer[id_first+1]+@'100000 +else begin equiv[p]:=string_ptr+@'100000; + l:=l-double_chars-1; +@y +@<Define and output a new string...@>= +begin ilk[p]:=numeric; {strings are like numeric macros} +if l-double_chars=2 then {this string is for a single character} + equiv[p]:=buffer[id_first+1]+@'100000 +else begin + if string_ptr = 256 then rewrite(pool,pool_file_name); + equiv[p]:=string_ptr+@'100000; + l:=l-double_chars-1; +@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 + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [??] Fix casting bug +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d add_in(#)==begin accumulator:=accumulator+next_sign*(#); next_sign:=+1; + end +@y +@d add_in(#)==begin accumulator:=accumulator+next_sign*toint(#); next_sign:=+1; + 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==stdin +@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@> +@z + +@x +@<Print the job |history|@>; +@y +@<Print the job |history|@>; +new_line; +if (history <> spotless) and (history <> harmless_message) +then uexit (1) +else uexit (0); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [188] system dependent changes--the |scan_args| procedure. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +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 +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@> + +@ 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 filename variables contain strings with the full +names of those files, as {\mc UNIX} knows them. + +There are no flags that affect \.{TANGLE} at the moment. + +@d max_file_name_length==FILENAMESIZE + +@<Globals...@>= +@!web_name,@!chg_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, slash_pos, i, a: integer; {indices} + c: char; + @!fname: array[1..max_file_name_length] 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_name|, |pascal_file_name|, + and |pool_file_name| variables from |fname|@> + else if not found_change + then @<Get |chg_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_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_name|...@>= +begin + dot_pos := -1; + slash_pos := -1; + i := 1; + while (fname[i] <> ' ') and (i <= max_file_name_length - 5) + do begin + web_name[i] := fname[i]; + if fname[i] = '.' then dot_pos := i; + if fname[i] = '/' then slash_pos := i; + incr (i); + end; + web_name[i] := ' '; + + if (dot_pos = -1) or (dot_pos < slash_pos) + then begin + dot_pos := i; + web_name[dot_pos] := '.'; + web_name[dot_pos+1] := 'w'; + web_name[dot_pos+2] := 'e'; + web_name[dot_pos+3] := 'b'; + web_name[dot_pos+4] := ' '; + end; + + for i := 1 to dot_pos + do begin + c := web_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 |chg_name|...@>= +begin + dot_pos := -1; + slash_pos := -1; + i := 1; + while (fname[i] <> ' ') and (i <= max_file_name_length - 5) + do begin + chg_name[i] := fname[i]; + if fname[i] = '.' then dot_pos := i; + if fname[i] = '/' then slash_pos := i; + incr (i); + end; + chg_name[i] := ' '; + + if (dot_pos = -1) or (dot_pos < slash_pos) + then begin + dot_pos := i; + chg_name[dot_pos] := '.'; + chg_name[dot_pos+1] := 'c'; + chg_name[dot_pos+2] := 'h'; + chg_name[dot_pos+3] := ' '; + end; + + found_change := true; +end + +@ @<Set up null...@>= +begin + chg_name[1]:='/'; + chg_name[2]:='d'; + chg_name[3]:='e'; + chg_name[4]:='v'; + chg_name[5]:='/'; + chg_name[6]:='n'; + chg_name[7]:='u'; + chg_name[8]:='l'; + chg_name[9]:='l'; + chg_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_ln ('Usage: tangle webfile[.web] [changefile[.ch]].'); + uexit (1); +end +@z diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/tex6.c b/obsolete/systems/sisisi/unix/SiTeX3.14/tex6.c new file mode 100644 index 0000000000..b3bebfedf1 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/tex6.c @@ -0,0 +1,2492 @@ +#define EXTERN extern +#include "texd.h" + +void zpostlinebreak ( finalwidowpenalty ) +integer finalwidowpenalty ; +{/* 30 31 */ postlinebreak_regmem + halfword q, r, s ; + boolean discbreak ; + boolean postdiscbreak ; + scaled curwidth ; + scaled curindent ; + quarterword t ; + integer pen ; + halfword curline ; + q = mem [ bestbet + 1 ] .hh .v.RH ; + curp = 0 ; + do { + r = q ; + q = mem [ q + 1 ] .hh .v.LH ; + mem [ r + 1 ] .hh .v.LH = curp ; + curp = r ; + } while ( ! ( q == 0 ) ) ; + curline = curlist .pgfield + 1 ; + do { + q = mem [ curp + 1 ] .hh .v.RH ; + discbreak = false ; + postdiscbreak = false ; + if ( q != 0 ) + if ( mem [ q ] .hh.b0 == 10 ) + { + deleteglueref ( mem [ q + 1 ] .hh .v.LH ) ; + mem [ q + 1 ] .hh .v.LH = eqtb [ 10290 ] .hh .v.RH ; + mem [ q ] .hh.b1 = 9 ; + incr ( mem [ eqtb [ 10290 ] .hh .v.RH ] .hh .v.RH ) ; + goto lab30 ; + } + else { + + if ( mem [ q ] .hh.b0 == 7 ) + { + t = mem [ q ] .hh.b1 ; + if ( t == 0 ) + r = mem [ q ] .hh .v.RH ; + else { + + r = q ; + while ( t > 1 ) { + + r = mem [ r ] .hh .v.RH ; + decr ( t ) ; + } + s = mem [ r ] .hh .v.RH ; + r = mem [ s ] .hh .v.RH ; + mem [ s ] .hh .v.RH = 0 ; + flushnodelist ( mem [ q ] .hh .v.RH ) ; + mem [ q ] .hh.b1 = 0 ; + } + if ( mem [ q + 1 ] .hh .v.RH != 0 ) + { + s = mem [ q + 1 ] .hh .v.RH ; + while ( mem [ s ] .hh .v.RH != 0 ) s = mem [ s ] .hh .v.RH ; + mem [ s ] .hh .v.RH = r ; + r = mem [ q + 1 ] .hh .v.RH ; + mem [ q + 1 ] .hh .v.RH = 0 ; + postdiscbreak = true ; + } + if ( mem [ q + 1 ] .hh .v.LH != 0 ) + { + s = mem [ q + 1 ] .hh .v.LH ; + if ( mem [ s ] .hh.b0 == 12 ) + { + s = mem [ s ] .hh .v.RH ; + mem [ mem [ q + 1 ] .hh .v.LH ] .hh .v.RH = 0 ; + flushnodelist ( mem [ q + 1 ] .hh .v.LH ) ; + } + mem [ q ] .hh .v.RH = s ; + while ( mem [ s ] .hh .v.RH != 0 ) s = mem [ s ] .hh .v.RH ; + mem [ q + 1 ] .hh .v.LH = 0 ; + q = s ; + } + mem [ q ] .hh .v.RH = r ; + discbreak = true ; + } + else if ( ( mem [ q ] .hh.b0 == 9 ) || ( mem [ q ] .hh.b0 == 11 ) ) + mem [ q + 1 ] .cint = 0 ; + } + else { + + q = memtop - 3 ; + while ( mem [ q ] .hh .v.RH != 0 ) q = mem [ q ] .hh .v.RH ; + } + r = newparamglue ( 8 ) ; + mem [ r ] .hh .v.RH = mem [ q ] .hh .v.RH ; + mem [ q ] .hh .v.RH = r ; + q = r ; + lab30: ; + r = mem [ q ] .hh .v.RH ; + mem [ q ] .hh .v.RH = 0 ; + q = mem [ memtop - 3 ] .hh .v.RH ; + mem [ memtop - 3 ] .hh .v.RH = r ; + if ( eqtb [ 10289 ] .hh .v.RH != 0 ) + { + r = newparamglue ( 7 ) ; + mem [ r ] .hh .v.RH = q ; + q = r ; + } + if ( curline > lastspecialline ) + { + curwidth = secondwidth ; + curindent = secondindent ; + } + else if ( eqtb [ 10812 ] .hh .v.RH == 0 ) + { + curwidth = firstwidth ; + curindent = firstindent ; + } + else { + + curwidth = mem [ eqtb [ 10812 ] .hh .v.RH + 2 * curline ] .cint ; + curindent = mem [ eqtb [ 10812 ] .hh .v.RH + 2 * curline - 1 ] .cint ; + } + adjusttail = memtop - 5 ; + justbox = hpack ( q , curwidth , 0 ) ; + mem [ justbox + 4 ] .cint = curindent ; + appendtovlist ( justbox ) ; + if ( memtop - 5 != adjusttail ) + { + mem [ curlist .tailfield ] .hh .v.RH = mem [ memtop - 5 ] .hh .v.RH ; + curlist .tailfield = adjusttail ; + } + adjusttail = 0 ; + if ( curline + 1 != bestline ) + { + pen = eqtb [ 12676 ] .cint ; + if ( curline == curlist .pgfield + 1 ) + pen = pen + eqtb [ 12668 ] .cint ; + if ( curline + 2 == bestline ) + pen = pen + finalwidowpenalty ; + if ( discbreak ) + pen = pen + eqtb [ 12671 ] .cint ; + if ( pen != 0 ) + { + r = newpenalty ( pen ) ; + mem [ curlist .tailfield ] .hh .v.RH = r ; + curlist .tailfield = r ; + } + } + incr ( curline ) ; + curp = mem [ curp + 1 ] .hh .v.LH ; + if ( curp != 0 ) + if ( ! postdiscbreak ) + { + r = memtop - 3 ; + while ( true ) { + + q = mem [ r ] .hh .v.RH ; + if ( q == mem [ curp + 1 ] .hh .v.RH ) + goto lab31 ; + if ( ( q >= himemmin ) ) + goto lab31 ; + if ( ( mem [ q ] .hh.b0 < 9 ) ) + goto lab31 ; + if ( mem [ q ] .hh.b1 == 2 ) + if ( mem [ q ] .hh.b0 == 11 ) + goto lab31 ; + r = q ; + } + lab31: if ( r != memtop - 3 ) + { + mem [ r ] .hh .v.RH = 0 ; + flushnodelist ( mem [ memtop - 3 ] .hh .v.RH ) ; + mem [ memtop - 3 ] .hh .v.RH = q ; + } + } + } while ( ! ( curp == 0 ) ) ; + if ( ( curline != bestline ) || ( mem [ memtop - 3 ] .hh .v.RH != 0 ) ) + confusion ( 935 ) ; + curlist .pgfield = bestline - 1 ; +} +smallnumber zreconstitute ( j , n , bchar , hchar ) +smallnumber j ; +smallnumber n ; +halfword bchar ; +halfword hchar ; +{/* 22 30 */ register smallnumber Result; reconstitute_regmem + halfword p ; + halfword t ; + fourquarters q ; + halfword currh ; + halfword testchar ; + scaled w ; + fontindex k ; + smallnumber ii ; + hyphenpassed = 0 ; + t = memtop - 4 ; + w = 0 ; + mem [ memtop - 4 ] .hh .v.RH = 0 ; + {register integer for_end; ii = n ; for_end = j ; if ( ii >= for_end) do + if ( dirtyumlaut [ ii ] != 0 ) + n = ii - 1 ; + while ( ii-- > for_end ) ; } + curl = hu [ j ] ; + curq = t ; + if ( j == 0 ) + { + ligaturepresent = initlig ; + p = initlist ; + if ( ligaturepresent ) + lfthit = initlft ; + while ( p > 0 ) { + + { + mem [ t ] .hh .v.RH = getavail () ; + t = mem [ t ] .hh .v.RH ; + mem [ t ] .hh.b0 = hf ; + mem [ t ] .hh.b1 = mem [ p ] .hh.b1 ; + } + p = mem [ p ] .hh .v.RH ; + } + } + else if ( curl < 256 ) + { + mem [ t ] .hh .v.RH = getavail () ; + t = mem [ t ] .hh .v.RH ; + mem [ t ] .hh.b0 = hf ; + mem [ t ] .hh.b1 = curl ; + } + ligstack = 0 ; + { + if ( j < n ) + curr = hu [ j + 1 ] ; + else curr = bchar ; + if ( hyfpen [ j ] != 10000 ) + currh = hchar ; + else currh = 256 ; + } + lab22: if ( curl == 256 ) + { + k = bcharlabel [ hf ] ; + if ( k == fontmemsize ) + goto lab30 ; + else q = fontinfo [ k ] .qqqq ; + } + else { + + q = fontinfo [ charbase [ hf ] + curl ] .qqqq ; + if ( ( ( q .b2 ) % 4 ) != 1 ) + goto lab30 ; + k = ligkernbase [ hf ] + q .b3 ; + q = fontinfo [ k ] .qqqq ; + if ( q .b0 > 128 ) + { + k = ligkernbase [ hf ] + 256 * q .b2 + q .b3 + 32768L - 256 * ( 128 ) ; + q = fontinfo [ k ] .qqqq ; + } + } + if ( currh < 256 ) + testchar = currh ; + else testchar = curr ; + while ( true ) { + + if ( q .b1 == testchar ) + if ( q .b0 <= 128 ) + if ( currh < 256 ) + { + hyphenpassed = j ; + hchar = 256 ; + currh = 256 ; + goto lab22 ; + } + else { + + if ( hchar < 256 ) + if ( hyfpen [ j ] != 10000 ) + { + hyphenpassed = j ; + hchar = 256 ; + } + if ( q .b2 < 128 ) + { + if ( curl == 256 ) + lfthit = true ; + if ( j == n ) + if ( ligstack == 0 ) + rthit = true ; + { + if ( interrupt != 0 ) + pauseforinstructions () ; + } + switch ( q .b2 ) + {case 1 : + case 5 : + { + curl = q .b3 ; + ligaturepresent = true ; + } + break ; + case 2 : + case 6 : + { + curr = q .b3 ; + if ( ligstack > 0 ) + mem [ ligstack ] .hh.b1 = curr ; + else { + + ligstack = newligitem ( curr ) ; + if ( j == n ) + bchar = 256 ; + else { + + p = getavail () ; + mem [ ligstack + 1 ] .hh .v.RH = p ; + mem [ p ] .hh.b1 = hu [ j + 1 ] ; + mem [ p ] .hh.b0 = hf ; + } + } + } + break ; + case 3 : + { + curr = q .b3 ; + p = ligstack ; + ligstack = newligitem ( curr ) ; + mem [ ligstack ] .hh .v.RH = p ; + } + break ; + case 7 : + case 11 : + { + if ( ligaturepresent ) + { + p = newligature ( hf , curl , mem [ curq ] .hh .v.RH ) ; + if ( lfthit ) + { + mem [ p ] .hh.b1 = 2 ; + lfthit = false ; + } + if ( false ) + if ( ligstack == 0 ) + { + incr ( mem [ p ] .hh.b1 ) ; + rthit = false ; + } + mem [ curq ] .hh .v.RH = p ; + t = p ; + ligaturepresent = false ; + } + curq = t ; + curl = q .b3 ; + ligaturepresent = true ; + } + break ; + default: + { + curl = q .b3 ; + ligaturepresent = true ; + if ( ligstack > 0 ) + { + if ( mem [ ligstack + 1 ] .hh .v.RH > 0 ) + { + mem [ t ] .hh .v.RH = mem [ ligstack + 1 ] .hh .v.RH ; + t = mem [ t ] .hh .v.RH ; + incr ( j ) ; + } + p = ligstack ; + ligstack = mem [ p ] .hh .v.RH ; + freenode ( p , 2 ) ; + if ( ligstack == 0 ) + { + if ( j < n ) + curr = hu [ j + 1 ] ; + else curr = bchar ; + if ( hyfpen [ j ] != 10000 ) + currh = hchar ; + else currh = 256 ; + } + else curr = mem [ ligstack ] .hh.b1 ; + } + else if ( j == n ) + goto lab30 ; + else { + + { + mem [ t ] .hh .v.RH = getavail () ; + t = mem [ t ] .hh .v.RH ; + mem [ t ] .hh.b0 = hf ; + mem [ t ] .hh.b1 = curr ; + } + incr ( j ) ; + { + if ( j < n ) + curr = hu [ j + 1 ] ; + else curr = bchar ; + if ( hyfpen [ j ] != 10000 ) + currh = hchar ; + else currh = 256 ; + } + } + } + break ; + } + if ( q .b2 > 4 ) + if ( q .b2 != 7 ) + goto lab30 ; + goto lab22 ; + } + w = fontinfo [ kernbase [ hf ] + 256 * q .b2 + q .b3 ] .cint ; + goto lab30 ; + } + if ( q .b0 >= 128 ) + if ( currh == 256 ) + goto lab30 ; + else { + + currh = 256 ; + goto lab22 ; + } + k = k + q .b0 + 1 ; + q = fontinfo [ k ] .qqqq ; + } + lab30: ; + if ( ligaturepresent ) + { + p = newligature ( hf , curl , mem [ curq ] .hh .v.RH ) ; + if ( lfthit ) + { + mem [ p ] .hh.b1 = 2 ; + lfthit = false ; + } + if ( rthit ) + if ( ligstack == 0 ) + { + incr ( mem [ p ] .hh.b1 ) ; + rthit = false ; + } + mem [ curq ] .hh .v.RH = p ; + t = p ; + ligaturepresent = false ; + } + if ( w != 0 ) + { + mem [ t ] .hh .v.RH = newkern ( w ) ; + t = mem [ t ] .hh .v.RH ; + w = 0 ; + } + if ( ligstack > 0 ) + { + curq = t ; + curl = mem [ ligstack ] .hh.b1 ; + ligaturepresent = true ; + { + if ( mem [ ligstack + 1 ] .hh .v.RH > 0 ) + { + mem [ t ] .hh .v.RH = mem [ ligstack + 1 ] .hh .v.RH ; + t = mem [ t ] .hh .v.RH ; + incr ( j ) ; + } + p = ligstack ; + ligstack = mem [ p ] .hh .v.RH ; + freenode ( p , 2 ) ; + if ( ligstack == 0 ) + { + if ( j < n ) + curr = hu [ j + 1 ] ; + else curr = bchar ; + if ( hyfpen [ j ] != 10000 ) + currh = hchar ; + else currh = 256 ; + } + else curr = mem [ ligstack ] .hh.b1 ; + } + goto lab22 ; + } + Result = j ; + return(Result) ; +} +void zhashfunk ( w , anfang , ende , v , ind , k ) +wort w ; +integer anfang ; +integer ende ; +varr v ; +intarr ind ; +intarr k ; +{hashfunk_regmem + long vacc, indacc, kacc ; + integer i ; + vacc = 31415L ; + indacc = 152L ; + kacc = 271L ; + {register integer for_end; i = anfang ; for_end = ende ; if ( i <= for_end) + do + { + ; + vacc = ( vacc * 31 + w [ i ] ) % 8388648L ; + v [ i ] = vacc ; + indacc = ( indacc * 33 + w [ i ] ) % ( tabsize + 1 ) ; + ind [ i ] = indacc ; + kacc = ( kacc * 15 + w [ i ] ) % ( ( tabsize + 1 ) / 2 ) ; + k [ i ] = 2 * kacc + 1 ; + } + while ( i++ < for_end ) ; } +} +void zunpackinfo ( b , iausnahme , iuntrennbar , ierste , izweite , iendung , +ivorsilbe , istamm , iehervor , istammallein ) +infobyte b ; +boolean * iausnahme ; +boolean * iuntrennbar ; +integer * ierste ; +integer * izweite ; +boolean * iendung ; +boolean * ivorsilbe ; +boolean * istamm ; +boolean * iehervor ; +boolean * istammallein ; +{unpackinfo_regmem + if ( odd ( b ) ) + { +* iausnahme = true ; + b = b / 2 ; + if ( odd ( b ) ) +* iuntrennbar = true ; + else *iuntrennbar = false ; + b = b / 2 ; +* ierste = b % 8 ; +* izweite = b / 8 ; + } + else { + +* iausnahme = false ; + b = b / 2 ; + if ( odd ( b ) ) +* iendung = true ; + else *iendung = false ; + b = b / 2 ; + if ( odd ( b ) ) +* ivorsilbe = true ; + else *ivorsilbe = false ; + b = b / 2 ; + if ( odd ( b ) ) +* istamm = true ; + else *istamm = false ; + b = b / 2 ; + if ( odd ( b ) ) +* iehervor = true ; + else *iehervor = false ; + b = b / 2 ; + if ( odd ( b ) ) +* istammallein = true ; + else *istammallein = false ; + } +} +void zunpackentry ( h , etabv , etabb , efrei , ewiederfrei ) +hashelement h ; +verdschlue * etabv ; +infobyte * etabb ; +boolean * efrei ; +boolean * ewiederfrei ; +{unpackentry_regmem + ; +* etabv = h [ 0 ] + h [ 1 ] * 256 + h [ 2 ] * 256 * 256 ; + if ( odd ( h [ 3 ] ) ) + { + ; +* etabb = h [ 3 ] ; +* efrei = false ; +* ewiederfrei = false ; + } + else { + + ; +* etabb = h [ 3 ] % 64 ; + if ( odd ( h [ 3 ] / 64 ) ) +* efrei = true ; + else *efrei = false ; + if ( odd ( h [ 3 ] / 128 ) ) +* ewiederfrei = true ; + else *ewiederfrei = false ; + } +} +void zhashsuch ( v , ind , k , iausnahme , iuntrennbar , ierste , izweite , +iendung , ivorsilbe , istamm , iehervor , istammallein , g ) +verdschlue v ; +integer ind ; +integer k ; +boolean * iausnahme ; +boolean * iuntrennbar ; +integer * ierste ; +integer * izweite ; +boolean * iendung ; +boolean * ivorsilbe ; +boolean * istamm ; +boolean * iehervor ; +boolean * istammallein ; +boolean * g ; +{hashsuch_regmem + boolean gef, ngef ; + integer j ; + tableentry entry ; + gef = false ; + ngef = false ; + j = ind ; + do { + unpackentry ( htab [ j ] , entry .tabv , entry .tabb , entry .frei , + entry .wiederfrei ) ; + if ( entry .frei ) + ngef = true ; + else if ( ( v == entry .tabv ) && ! entry .wiederfrei ) + { + unpackinfo ( entry .tabb , *iausnahme , *iuntrennbar , *ierste , *izweite , * + iendung , *ivorsilbe , *istamm , *iehervor , *istammallein ) ; + gef = true ; + } + else j = ( j + k ) % ( tabsize + 1 ) ; + } while ( ! ( gef || ngef ) ) ; +* g = gef ; +} +void zhashload ( status ) +integer * status ; +{hashload_regmem + integer i ; + tableentry e ; + {register integer for_end; i = 1 ; for_end = FILENAMESIZE ; if ( i <= + for_end) do + nameoffile [ i ] = ' ' ; + while ( i++ < for_end ) ; } + nameoffile [ 1 ] = 'h' ; + nameoffile [ 2 ] = 'f' ; + nameoffile [ 3 ] = '3' ; + namelength = 3 ; + anzahl = 0 ; + if ( aopenin ( hashfile , TEXINPUTPATH ) ) + { + {register integer for_end; i = 0 ; for_end = tabsize ; if ( i <= for_end) + do + { + int help; + fscanf ( hashfile, "%d", &help ); + htab [i][0] = (eightbits) help; + fscanf ( hashfile, "%d", &help ); + htab [i][1] = (eightbits) help; + fscanf ( hashfile, "%d", &help ); + htab [i][2] = (eightbits) help; + fscanf ( hashfile, "%d", &help ); + htab [i][3] = (eightbits) help; + unpackentry ( htab [ i ] , e .tabv , e .tabb , e .frei , e .wiederfrei + ) ; + if ( ! e .frei && ! e .wiederfrei ) + anzahl = anzahl + 1 ; + } + while ( i++ < for_end ) ; } +* status = 0 ; + aclose ( hashfile ) ; + } + else *status = 1 ; +} +void zpackinfo ( i , b ) +infotype i ; +infobyte * b ; +{packinfo_regmem +* b = 0 ; + if ( i .ausnahme ) + { + ; + if ( i .untrennbar ) + ; + else ; +* b = 1 + 2 * ord ( i .untrennbar ) + 4 * i .erste + 32 * i .zweite ; + } + else { + + ; +* b = 2 * ord ( i .endung ) + 4 * ord ( i .vorsilbe ) + 8 * ord ( i .stamm ) + + 16 * ord ( i .ehervor ) + 32 * ord ( i .stammallein ) ; + } +} +void zpackentry ( e , h ) +tableentry e ; +hashelement h ; +{packentry_regmem + ; + h [ 0 ] = e .tabv % 256 ; + e .tabv = e .tabv / 256 ; + h [ 1 ] = e .tabv % 256 ; + h [ 2 ] = e .tabv / 256 ; + if ( odd ( e .tabb ) ) + h [ 3 ] = e .tabb ; + else { + + ; + h [ 3 ] = e .tabb + 64 * ord ( e .frei ) + 128 * ord ( e .wiederfrei ) ; + } +} +void zhashetr ( w , laenge , i , g ) +wort w ; +integer laenge ; +infotype i ; +boolean * g ; +{hashetr_regmem + varr v1 ; + intarr ind1, k1 ; + verdschlue v ; + integer ind, k, j, e ; + boolean gef, ngef ; + tableentry entry ; + hashelement helem ; + if ( anzahl >= tabsize ) + { + ; +* g = false ; + } + else { + + ; + if ( ( anzahl < 10 ) || ( anzahl % 100 == 0 ) ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s%ld%s", " -Anzahl:" , (long)anzahl , ". " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s%ld%s", " -Anzahl:" , (long)anzahl , ". " ) ; + } + } + hashfunk ( w , 1 , laenge , v1 , ind1 , k1 ) ; + v = v1 [ laenge ] ; + ind = ind1 [ laenge ] ; + k = k1 [ laenge ] ; + gef = false ; + ngef = false ; + do { + ; + unpackentry ( htab [ ind ] , entry .tabv , entry .tabb , entry .frei , + entry .wiederfrei ) ; + if ( entry .frei || entry .wiederfrei ) + { + anzahl = anzahl + 1 ; + ngef = true ; + entry .tabv = v ; + packinfo ( i , entry .tabb ) ; + entry .frei = false ; + entry .wiederfrei = false ; + packentry ( entry , helem ) ; + memcpy((void *)htab [ ind ] , (void *)helem , sizeof(hashelement)); + } + else { + + ; + gef = v == entry .tabv ; + if ( ! gef ) + ind = ( ind + k ) % ( tabsize + 1 ) ; + } + } while ( ! ( gef || ngef ) ) ; +* g = ngef ; + } +} +void hashempty ( ) +{hashempty_regmem + integer i ; + tableentry elem ; + hashelement he ; + elem .tabv = 0 ; + elem .tabb = 0 ; + elem .frei = true ; + elem .wiederfrei = false ; + packentry ( elem , he ) ; + {register integer for_end; i = 0 ; for_end = tabsize ; if ( i <= for_end) + do + memcpy((void *)htab [ i ] , (void *)he, sizeof(hashelement)); + while ( i++ < for_end ) ; } + anzahl = 0 ; +} +void zhashsave ( status ) +integer * status ; +{hashsave_regmem + integer i ; + {register integer for_end; i = 1 ; for_end = FILENAMESIZE ; if ( i <= + for_end) do + nameoffile [ i ] = ' ' ; + while ( i++ < for_end ) ; } + nameoffile [ 1 ] = 'h' ; + nameoffile [ 2 ] = 'f' ; + nameoffile [ 3 ] = '3' ; + namelength = 3 ; + if ( aopenout ( hashfile ) ) + { + {register integer for_end; i = 0 ; for_end = tabsize ; if ( i <= for_end) + do + { + (void) fprintf( hashfile , "%4ld", (long)htab [ i ] [ 0 ] ) ; + (void) fprintf( hashfile , "%4ld", (long)htab [ i ] [ 1 ] ) ; + (void) fprintf( hashfile , "%4ld", (long)htab [ i ] [ 2 ] ) ; + (void) fprintf( hashfile , "%4ld", (long)htab [ i ] [ 3 ] ) ; + (void) putc('\n', hashfile ); + } + while ( i++ < for_end ) ; } +* status = 0 ; + aclose ( hashfile ) ; + } + else *status = 1 ; +} +integer hashsize ( ) +{register integer Result; hashsize_regmem + Result = anzahl ; + return(Result) ; +} +void zzahl ( line , i , ende , j ) +string80 line ; +integer * i ; +integer ende ; +integer * j ; +{zahl_regmem + boolean aus ; +* j = 0 ; + do { + if ( *i <= ende ) + if ( ktab [ line [ *i ] ] == 46 ) +* i = *i + 1 ; + else aus = true ; + else aus = true ; + } while ( ! ( aus ) ) ; + do { + if ( *i <= ende ) + { + switch ( line [ *i ] ) + {case 48 : + case 49 : + case 50 : + case 51 : + case 52 : + case 53 : + case 54 : + case 55 : + case 56 : + case 57 : + { +* j = 10 * *j + line [ *i ] - 48 ; +* i = *i + 1 ; + } + break ; + } + if ( ( line [ *i ] != 48 ) && ( line [ *i ] != 49 ) && ( line [ *i ] != 50 + ) && ( line [ *i ] != 51 ) && ( line [ *i ] != 52 ) && ( line [ *i ] != 53 + ) && ( line [ *i ] != 54 ) && ( line [ *i ] != 55 ) && ( line [ *i ] != 56 + ) && ( line [ *i ] != 57 ) ) + aus = true ; + } + else aus = true ; + } while ( ! ( aus ) ) ; +} +void zinfobau ( line , anfang , ende , informausnahme , informuntrennbar , +informerste , informzweite , informendung , informvorsilbe , informstamm , +informehervor , informstammallein , g ) +string80 line ; +integer anfang ; +integer ende ; +boolean * informausnahme ; +boolean * informuntrennbar ; +integer * informerste ; +integer * informzweite ; +boolean * informendung ; +boolean * informvorsilbe ; +boolean * informstamm ; +boolean * informehervor ; +boolean * informstammallein ; +boolean * g ; +{infobau_regmem + integer i, j ; + boolean ok, fehler ; + buchstabe b ; +* g = false ; +* informausnahme = false ; +* informendung = false ; +* informvorsilbe = false ; +* informehervor = false ; +* informstamm = false ; +* informstammallein = false ; + i = anfang ; + ok = false ; + fehler = false ; + do { + if ( i <= ende ) + if ( line [ i ] == 46 ) + i = i + 1 ; + else ok = true ; + else fehler = true ; + } while ( ! ( ok || fehler ) ) ; + if ( ! fehler ) + { + b = ktab [ line [ i ] ] ; + if ( b == bsta ) + { +* informausnahme = true ; + i = i + 1 ; + if ( ktab [ line [ i ] ] == bstu ) + { + i = i + 1 ; +* informuntrennbar = true ; + } + else *informuntrennbar = false ; + zahl ( line , i , ende , j ) ; + if ( j == 0 ) + { +* informerste = 7 ; +* informzweite = 7 ; + } + else { + + j = j - 2 ; + if ( ( j >= 0 ) && ( j <= 6 ) ) +* informerste = j ; + else fehler = true ; + zahl ( line , i , ende , j ) ; + if ( j == 0 ) +* informzweite = 7 ; + else { + + j = j - *informerste - 4 ; + if ( ( j >= 0 ) && ( j <= 6 ) ) +* informzweite = j ; + else fehler = true ; + } + } + if ( ! fehler ) +* g = true ; + } + else { + + ok = false ; + do { + switch ( b ) + {case 22 : +* informvorsilbe = true ; + break ; + case 5 : +* informendung = true ; + break ; + case 19 : +* informstamm = true ; + break ; + case 2 : +* informehervor = true ; + break ; + case 20 : +* informstammallein = true ; + break ; + case 31 : + ; + break ; + default: + fehler = true ; + break ; + } + if ( i == ende ) + ok = true ; + else { + + i = i + 1 ; + b = ktab [ line [ i ] ] ; + } + } while ( ! ( ok || fehler ) ) ; + if ( ! fehler ) +* g = ( *informvorsilbe || *informendung || *informstamm ) && ( ! * + informehervor || *informvorsilbe && *informendung ) && ( ! * + informstammallein || *informstamm ) ; + } + } +} +void zeintragen ( line , l ) +string80 line ; +integer l ; +{eintragen_regmem + integer i, laenge ; + infotype inform ; + wort w ; + boolean g ; + laenge = 1 ; + while ( line [ laenge ] != 46 ) laenge = laenge + 1 ; + laenge = laenge - 1 ; + if ( laenge >= 1 ) + { + if ( laenge <= maxwl ) + { + infobau ( line , laenge + 1 , l , inform .ausnahme , inform .untrennbar + , inform .erste , inform .zweite , inform .endung , inform .vorsilbe , + inform .stamm , inform .ehervor , inform .stammallein , g ) ; + if ( ! g ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " Info falsch: " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " Info falsch: " ) ; + } + } + else { + + {register integer for_end; i = 1 ; for_end = laenge ; if ( i <= + for_end) do + w [ i ] = ktab [ line [ i ] ] ; + while ( i++ < for_end ) ; } + hashetr ( w , laenge , inform , g ) ; + if ( ! g ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " Tabellenfehler: " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " Tabellenfehler: " ) ; + } + } + } + if ( ! g ) + { + {register integer for_end; i = 1 ; for_end = l ; if ( i <= for_end) + do + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( line [ i ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( line [ i ] ) , logfile ); + } + while ( i++ < for_end ) ; } + println () ; + } + } + else { + + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", " zu langes Wort: " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", " zu langes Wort: " ) ; + } + {register integer for_end; i = 1 ; for_end = l ; if ( i <= for_end) do + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( line [ i ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( line [ i ] ) , logfile ); + } + while ( i++ < for_end ) ; } + println () ; + } + } + else { + + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", " Falsche Zeile: " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", " Falsche Zeile: " ) ; + } + {register integer for_end; i = 1 ; for_end = l ; if ( i <= for_end) do + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( line [ i ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( line [ i ] ) , logfile ); + } + while ( i++ < for_end ) ; } + println () ; + } +} +void znaechsterbst ( i , tr , dudstop , b , w ) +integer * i ; +trennvektor tr ; +sperrvektor dudstop ; +buchstabe * b ; +wort w ; +{naechsterbst_regmem + if ( ( *i > 0 ) && ( tr [ *i ] == keine ) && ! dudstop [ *i ] ) + { +* b = w [ *i ] ; +* i = *i - 1 ; + } + else *b = trennzeichen ; +} +void zduden ( tr , w , tr1 , dudtr , dud , dudstop , laenge , ok , zerlegungen +) +trennvektor tr ; +wort w ; +trennvektor tr1 ; +trennvektor dudtr ; +dudt dud ; +sperrvektor dudstop ; +integer laenge ; +boolean * ok ; +integer * zerlegungen ; +{duden_regmem + integer i ; + integer j ; + integer zust ; + boolean aus ; + integer tre ; + integer letzte ; + integer l, lalt ; + buchstabe b ; + i = laenge ; + {register integer for_end; j = 0 ; for_end = laenge ; if ( j <= for_end) do + dudtr [ j ] = tr [ j ] ; + while ( j++ < for_end ) ; } + while ( ( i > 0 ) && ! dud [ i ] ) i = i - 1 ; + while ( i > 0 ) { + + zust = 1 ; + aus = false ; + letzte = 0 ; + l = kons ; + b = w [ i ] ; + i = i - 1 ; + do { + { + tre = i + 1 ; + lalt = l ; + switch ( b ) + {case 1 : + { + l = voka ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 15 : + { + l = voko ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 29 : + { + l = vokue ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 28 : + { + l = vokoe ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 27 : + { + l = vokae ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 5 : + { + l = voke ; + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bsti ) + { + l = vokie ; + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bste ) + { + i = i + 1 ; + l = voke ; + b = bsti ; + } + } + } + break ; + case 9 : + { + l = voki ; + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bste ) + { + l = vokei ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + else if ( b == bsta ) + { + l = vokai ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + } + break ; + case 21 : + { + l = voku ; + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bste ) + { + l = vokeu ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + else if ( b == bsta ) + { + l = vokau ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + else if ( b == bstae ) + { + l = vokaeu ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + else if ( b == bstq ) + { + l = kons ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + } + break ; + case 20 : + { + l = kons ; + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bsts ) + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 8 : + { + l = kons ; + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bstc ) + { + naechsterbst ( i , tr , dudstop , b , w ) ; + if ( b == bsts ) + naechsterbst ( i , tr , dudstop , b , w ) ; + } + else if ( b == bstp ) + naechsterbst ( i , tr , dudstop , b , w ) ; + else if ( b == bstt ) + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 2 : + case 3 : + case 4 : + case 6 : + case 7 : + case 10 : + case 11 : + case 12 : + case 13 : + case 14 : + case 16 : + case 17 : + case 18 : + case 19 : + case 22 : + case 23 : + case 24 : + case 26 : + case 30 : + { + l = kons ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 25 : + { + l = voky ; + naechsterbst ( i , tr , dudstop , b , w ) ; + } + break ; + case 31 : + case 0 : + aus = true ; + break ; + } + } + if ( ! aus ) + switch ( zust ) + {case 1 : + if ( l == kons ) + zust = 2 ; + else zust = 4 ; + break ; + case 2 : + if ( l != kons ) + zust = 3 ; + break ; + case 3 : + if ( l == kons ) + zust = 6 ; + else if ( l != lalt ) + { + zust = 4 ; + letzte = tre ; + dudtr [ letzte ] = neben ; + } + break ; + case 4 : + if ( l == kons ) + zust = 6 ; + else zust = 3 ; + break ; + case 6 : + if ( l == kons ) + { + zust = 2 ; + letzte = tre ; + if ( ( w [ tre ] == bstc ) && ( w [ tre + 1 ] == bstk ) ) + dudtr [ letzte ] = nebenck ; + else dudtr [ letzte ] = neben ; + } + else { + + zust = 4 ; + letzte = tre ; + dudtr [ letzte ] = neben ; + } + break ; + } + } while ( ! ( aus ) ) ; + if ( zust == 2 ) + dudtr [ letzte ] = keine ; + else if ( zust == 4 ) + if ( ( lalt < vokie ) || ( lalt > vokeu ) ) + dudtr [ letzte ] = keine ; + while ( ( i > 0 ) && ! dud [ i ] ) i = i - 1 ; + } +} +void ztrennen ( zustand , anfang , spv , ok1 , tr , dudtr , zerlegungen , dud +, v , ind , k , dudstop , w , tr1 , laenge ) +integer zustand ; +integer anfang ; +sperrvektor spv ; +boolean * ok1 ; +trennvektor tr ; +trennvektor dudtr ; +integer * zerlegungen ; +dudt dud ; +varr v ; +intarr ind ; +intarr k ; +sperrvektor dudstop ; +wort w ; +trennvektor tr1 ; +integer laenge ; +{trennen_regmem + boolean gef, nichtok ; + integer schnitt ; + infotype inform ; + integer i ; + boolean okstamm, okvor, okend, okhelp ; + integer tri ; + integer i1, tre ; + boolean ok ; + integer stopptr ; + sperrvektor spvtmp ; + memcpy((void *)spvtmp, (void *)spv, sizeof(sperrvektor)) ; +* ok1 = false ; + if ( anfang == laenge + 1 ) + if ( ( zustand == 2 ) || ( zustand == 4 ) ) + { + dud [ anfang - 1 ] = true ; + duden ( tr , w , tr1 , dudtr , dud , dudstop , laenge , ok , *zerlegungen ) + ; + {register integer for_end; i = laenge ; for_end = 1 ; if ( i >= for_end) + do + { + if ( dudtr [ i - 1 ] == haupt3 ) + { + dudtr [ i - 1 ] = keine ; + tri = haupt3 ; + } + else tri = dudtr [ i ] ; + if ( *zerlegungen == 0 ) + tr1 [ i ] = tri ; + else tr1 [ i ] = kombtab [ tr1 [ i ] ][ tri ] ; + } + while ( i-- > for_end ) ; } +* zerlegungen = *zerlegungen + 1 ; +* ok1 = true ; + } + else ; + else { + + hashfunk ( w , anfang , laenge , v , ind , k ) ; + schnitt = laenge ; + nichtok = false ; + do { + do { if ( spv [ schnitt ] ) + gef = false ; + else { + + hashsuch ( v [ schnitt ] , ind [ schnitt ] , k [ schnitt ] , inform + .ausnahme , inform .untrennbar , inform .erste , inform .zweite , + inform .endung , inform .vorsilbe , inform .stamm , inform .ehervor + , inform .stammallein , gef ) ; + } + if ( gef ) + spv [ schnitt ] = true ; + else schnitt = schnitt - 1 ; + } while ( ! ( gef || ( schnitt == anfang - 1 ) ) ) ; + if ( gef ) + { + if ( ! inform .ausnahme ) + { + if ( inform .endung && ( zustand == 2 ) ) + { + okend = false ; + if ( ( w [ anfang ] == bstc ) || ( w [ anfang ] == bsth ) ) + { + dud [ anfang - 1 ] = true ; + tr [ anfang - 1 ] = neben ; + } + if ( schnitt < laenge ) + if ( ( w [ schnitt + 1 ] == bsts ) && ! spv [ schnitt + 1 ] ) + { + spv [ schnitt + 1 ] = true ; + trennen ( 2 , schnitt + 2 , spv , okhelp , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + okend = okhelp ; + } + trennen ( 2 , schnitt + 1 , spv , okhelp , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + okend = okend || okhelp ; + tr [ anfang - 1 ] = keine ; + dud [ anfang - 1 ] = false ; +* ok1 = *ok1 || okend ; + } + else okend = false ; + if ( inform .vorsilbe ) + { + if ( zustand == 1 ) + tr [ anfang - 1 ] = neben ; + else { + + dud [ anfang - 1 ] = true ; + if ( zustand == 5 ) + tr [ anfang - 1 ] = haupt3 ; + else tr [ anfang - 1 ] = haupt ; + } + dud [ schnitt ] = true ; + trennen ( 1 , schnitt + 1 , spv , okvor , tr , dudtr , *zerlegungen + , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + tr [ anfang - 1 ] = keine ; + dud [ anfang - 1 ] = false ; + dud [ schnitt ] = false ; +* ok1 = *ok1 || okvor ; + } + else okvor = false ; + if ( inform .stamm && ! okvor ) + { + if ( ! inform .stammallein ) + { + okstamm = false ; + stopptr = 0 ; + if ( zustand == 1 ) + tr [ anfang - 1 ] = neben ; + else { + + dud [ anfang - 1 ] = true ; + if ( zustand == 5 ) + tr [ anfang - 1 ] = haupt3 ; + else tr [ anfang - 1 ] = haupt ; + } + if ( inform .ausnahme ) + { + if ( inform .erste != 7 ) + { + tre = anfang + inform .erste + 1 ; + tr [ tre ] = neben ; + if ( inform .zweite != 7 ) + { + tre = tre + inform .zweite + 2 ; + if ( inform .untrennbar ) + { + stopptr = tre ; + dudstop [ stopptr ] = true ; + } + else tr [ tre ] = neben ; + } + else { + + if ( inform .untrennbar ) + { + tr [ tre ] = keine ; + stopptr = tre ; + dudstop [ tre ] = true ; + } + } + } + else { + + stopptr = schnitt - 1 ; + dudstop [ stopptr ] = true ; + } + } + if ( schnitt < laenge ) + if ( ( w [ schnitt + 1 ] == bsts ) && ! spv [ schnitt + 1 ] ) + { + spv [ schnitt + 1 ] = true ; + trennen ( 2 , schnitt + 2 , spv , okhelp , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) + ; + okstamm = okhelp ; + } + if ( ( schnitt >= 2 ) && ( schnitt < laenge ) ) + if ( konsonant [ w [ schnitt ] ] && ! konsonant [ w [ schnitt + + 1 ] ] && ( w [ schnitt ] == w [ schnitt - 1 ] ) ) + { + trennen ( 5 , schnitt , spv , okhelp , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) + ; + okstamm = okstamm || okhelp ; + } + trennen ( 2 , schnitt + 1 , spv , okhelp , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + okstamm = okstamm || okhelp ; + if ( inform .ausnahme ) + {register integer for_end; i1 = anfang - 1 ; for_end = schnitt + ; if ( i1 <= for_end) do + { + tr [ i1 ] = keine ; + dud [ i1 ] = false ; + dudstop [ stopptr ] = false ; + } + while ( i1++ < for_end ) ; } + else { + + tr [ anfang - 1 ] = keine ; + dud [ anfang - 1 ] = false ; + } +* ok1 = *ok1 || okstamm ; + } + else if ( ( anfang == 1 ) && ( schnitt == laenge ) ) + { + dud [ anfang - 1 ] = true ; + tr [ anfang - 1 ] = haupt ; + trennen ( 4 , schnitt + 1 , spv , okstamm , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + tr [ anfang - 1 ] = keine ; + dud [ anfang - 1 ] = false ; +* ok1 = *ok1 || okstamm ; + } + } + } + else { + + okstamm = false ; + stopptr = 0 ; + if ( zustand == 1 ) + tr [ anfang - 1 ] = neben ; + else { + + dud [ anfang - 1 ] = true ; + if ( zustand == 5 ) + tr [ anfang - 1 ] = haupt3 ; + else tr [ anfang - 1 ] = haupt ; + } + if ( inform .ausnahme ) + { + if ( inform .erste != 7 ) + { + tre = anfang + inform .erste + 1 ; + tr [ tre ] = neben ; + if ( inform .zweite != 7 ) + { + tre = tre + inform .zweite + 2 ; + if ( inform .untrennbar ) + { + stopptr = tre ; + dudstop [ stopptr ] = true ; + } + else tr [ tre ] = neben ; + } + else { + + if ( inform .untrennbar ) + { + tr [ tre ] = keine ; + stopptr = tre ; + dudstop [ tre ] = true ; + } + } + } + else { + + stopptr = schnitt - 1 ; + dudstop [ stopptr ] = true ; + } + } + if ( schnitt < laenge ) + if ( ( w [ schnitt + 1 ] == bsts ) && ! spv [ schnitt + 1 ] ) + { + spv [ schnitt + 1 ] = true ; + trennen ( 2 , schnitt + 2 , spv , okhelp , tr , dudtr , * + zerlegungen , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + okstamm = okhelp ; + } + if ( ( schnitt >= 2 ) && ( schnitt < laenge ) ) + if ( konsonant [ w [ schnitt ] ] && ! konsonant [ w [ schnitt + 1 ] + ] && ( w [ schnitt ] == w [ schnitt - 1 ] ) ) + { + trennen ( 5 , schnitt , spv , okhelp , tr , dudtr , *zerlegungen , + dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + okstamm = okstamm || okhelp ; + } + trennen ( 2 , schnitt + 1 , spv , okhelp , tr , dudtr , *zerlegungen + , dud , v , ind , k , dudstop , w , tr1 , laenge ) ; + okstamm = okstamm || okhelp ; + if ( inform .ausnahme ) + {register integer for_end; i1 = anfang - 1 ; for_end = schnitt + ; if ( i1 <= for_end) do + { + tr [ i1 ] = keine ; + dud [ i1 ] = false ; + dudstop [ stopptr ] = false ; + } + while ( i1++ < for_end ) ; } + else { + + tr [ anfang - 1 ] = keine ; + dud [ anfang - 1 ] = false ; + } +* ok1 = *ok1 || okstamm ; + } + schnitt = schnitt - 1 ; + nichtok = schnitt == anfang - 1 ; + } + else nichtok = true ; + } while ( ! ( nichtok ) ) ; + } + memcpy((void *)spv, (void *)spvtmp, sizeof(sperrvektor)) ; +} +void zabteilen ( w , tr1 , laenge , ok , zerlegungen ) +wort w ; +trennvektor tr1 ; +integer laenge ; +boolean * ok ; +integer * zerlegungen ; +{/* 99 */ abteilen_regmem + integer i ; + dudt dud ; + varr v ; + intarr ind, k ; + sperrvektor spv, dudstop ; + trennvektor tr, dudtr ; + tr1 [ 0 ] = keine ; + {register integer for_end; i = 0 ; for_end = laenge ; if ( i <= for_end) do + { + tr [ i ] = keine ; + spv [ i ] = false ; + dudstop [ i ] = false ; + dud [ i ] = false ; + if ( i > 0 ) + if ( ( w [ i ] == trennzeichen ) || ( w [ i ] == sonderzeichen ) ) + { +* zerlegungen = 0 ; +* ok = false ; + goto lab99 ; + } + } + while ( i++ < for_end ) ; } +* zerlegungen = 0 ; + trennen ( 3 , 1 , spv , *ok , tr , dudtr , *zerlegungen , dud , v , ind , k , + dudstop , w , tr1 , laenge ) ; + {register integer for_end; i = 0 ; for_end = laenge ; if ( i <= for_end) do + if ( tr1 [ i ] == nebenck ) + { + tr1 [ i ] = keine ; + tr1 [ i - 1 ] = nebenck ; + } + while ( i++ < for_end ) ; } + lab99: ; +} +boolean zisdirtyumlaut ( p ) +halfword p ; +{register boolean Result; isdirtyumlaut_regmem + boolean res ; + halfword q ; + res = false ; + if ( p != 0 ) + if ( mem [ p ] .hh.b0 == 7 ) + if ( mem [ p + 1 ] .hh .v.LH != 0 ) + if ( mem [ mem [ p + 1 ] .hh .v.LH ] .hh .v.RH != 0 ) + if ( mem [ mem [ mem [ p + 1 ] .hh .v.LH ] .hh .v.RH ] .hh .v.RH != 0 ) + { + q = mem [ p + 1 ] .hh .v.LH ; + if ( mem [ q ] .hh.b0 == 12 ) + q = mem [ q ] .hh .v.RH ; + if ( ( mem [ q ] .hh.b0 == 11 ) && ( mem [ q + 1 ] .cint == specletterID ) + && ( mem [ q ] .hh .v.RH >= himemmin ) && ( mem [ mem [ mem [ q ] .hh + .v.RH ] .hh .v.RH ] .hh.b0 == 11 ) ) + res = true ; + } + Result = res ; + return(Result) ; +} +integer zgetcharof ( s ) +halfword s ; +{register integer Result; getcharof_regmem + halfword q ; + q = mem [ s + 1 ] .hh .v.LH ; + if ( mem [ q ] .hh.b0 == 12 ) + q = mem [ q ] .hh .v.RH ; + Result = mem [ mem [ mem [ q ] .hh .v.RH ] .hh .v.RH + 1 ] .cint ; + return(Result) ; +} +integer zgetfontof ( s ) +halfword s ; +{register integer Result; getfontof_regmem + halfword q ; + q = mem [ s + 1 ] .hh .v.LH ; + if ( mem [ q ] .hh.b0 == 12 ) + q = mem [ q ] .hh .v.RH ; + Result = mem [ mem [ q ] .hh .v.RH ] .hh.b0 ; + return(Result) ; +} +void hyphenate ( ) +{/* 50 30 31 40 41 42 45 10 */ hyphenate_regmem + schar i, j, l, kk ; + halfword q, r, s, qq, qr, holdr ; + halfword bchar ; + short xchgchar[11] ; + schar addchar, xchgi, xchgk, xchghu ; + halfword spechyf ; + integer sij ; + halfword majortail, minortail ; + ASCIIcode c ; + schar cloc ; + integer rcount ; + halfword hyfnode ; + triepointer z ; + integer v ; + boolean funktioniert ; + integer zerleg ; + hyphpointer h ; + strnumber k ; + poolpointer u ; + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + hyf [ j ] = 0 ; + while ( j++ < for_end ) ; } + h = hc [ 1 ] ; + incr ( hn ) ; + hc [ hn ] = curlang ; + {register integer for_end; j = 2 ; for_end = hn ; if ( j <= for_end) do + h = ( h + h + hc [ j ] ) % 607 ; + while ( j++ < for_end ) ; } + while ( true ) { + + k = hyphword [ h ] ; + if ( k == 0 ) + goto lab45 ; + if ( ( strstart [ k + 1 ] - strstart [ k ] ) < hn ) + goto lab45 ; + if ( ( strstart [ k + 1 ] - strstart [ k ] ) == hn ) + { + j = 1 ; + u = strstart [ k ] ; + do { + if ( strpool [ u ] < hc [ j ] ) + goto lab45 ; + if ( strpool [ u ] > hc [ j ] ) + goto lab30 ; + incr ( j ) ; + incr ( u ) ; + } while ( ! ( j > hn ) ) ; + s = hyphlist [ h ] ; + while ( s != 0 ) { + + hyf [ mem [ s ] .hh .v.LH ] = 1 ; + s = mem [ s ] .hh .v.RH ; + } + decr ( hn ) ; + goto lab40 ; + } + lab30: ; + if ( h > 0 ) + decr ( h ) ; + else h = 607 ; + } + lab45: decr ( hn ) ; + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + hcsi [ j ] = ktab [ hc [ j ] ] ; + while ( j++ < for_end ) ; } + if ( odd ( eqtb [ 12719 ] .cint / 2 ) ) + { + if ( ! odd ( eqtb [ 12720 ] .cint / 2 ) ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s%ld%s\n", " <* debugging output section #" , (long)2 , " *>" ) + ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s%ld%s\n", " <* debugging output section #" , (long)2 , " *>" ) ; + } + } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " hc:" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " hc:" ) ; + } + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( hc [ j ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( hc [ j ] ) , logfile ); + } + while ( j++ < for_end ) ; } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%c\n", ':' ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%c\n", ':' ) ; + } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " hc_si:" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " hc_si:" ) ; + } + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( revtab [ hcsi [ j ] ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( revtab [ hcsi [ j ] ] ) , logfile ); + } + while ( j++ < for_end ) ; } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%c\n", ':' ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%c\n", ':' ) ; + } + } + if ( odd ( eqtb [ 12719 ] .cint / 4 ) ) + { + if ( ! odd ( eqtb [ 12720 ] .cint / 4 ) ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s%ld%s\n", " <* debugging output section #" , (long)4 , " *>" ) + ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s%ld%s\n", " <* debugging output section #" , (long)4 , " *>" ) ; + } + } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", "< decimal character codes >" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", "< decimal character codes >" ) ; + } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " hc:" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " hc:" ) ; + } + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + { + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%ld%c", (long)hc [ j ] , '-' ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%ld%c", (long)hc [ j ] , '-' ) ; + } + if ( ( ( j + 1 ) % 16 ) == 0 ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " " ) ; + } + } + } + while ( j++ < for_end ) ; } + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " hc_si:" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " hc_si:" ) ; + } + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + { + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%ld%c", (long)revtab [ hcsi [ j ] ] , '-' ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%ld%c", (long)revtab [ hcsi [ j ] ] , '-' ) ; + } + if ( ( ( j + 1 ) % 16 ) == 0 ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " " ) ; + } + } + } + while ( j++ < for_end ) ; } + println () ; + println () ; + } + abteilen ( hcsi , hyfsi , hn , funktioniert , zerleg ) ; + {register integer for_end; j = 0 ; for_end = 64 ; if ( j <= for_end) do + { + hyfdisc [ j ] = 0 ; + hyfpen [ j ] = 10000 ; + } + while ( j++ < for_end ) ; } + if ( funktioniert ) + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + { + if ( hyfsi [ j ] == neben ) + hyfpen [ j ] = eqtb [ 12718 ] .cint ; + else if ( hyfsi [ j ] == haupt ) + hyfpen [ j ] = eqtb [ 12666 ] .cint ; + else if ( hyfsi [ j ] == nebenck ) + { + hyfpen [ j + 1 ] = eqtb [ 12718 ] .cint ; + s = getnode ( 2 ) ; + mem [ s ] .hh.b0 = 7 ; + hyfdisc [ j + 1 ] = s ; + mem [ s + 1 ] .hh .v.LH = newpenalty ( eqtb [ 12718 ] .cint ) ; + s = mem [ s + 1 ] .hh .v.LH ; + mem [ s ] .hh.b1 = 0 ; + mem [ s ] .hh .v.RH = newcharacter ( hf , hu [ j + 2 ] ) ; + mem [ mem [ s ] .hh .v.RH ] .hh .v.RH = 0 ; + s = hyfdisc [ j + 1 ] ; + mem [ s + 1 ] .hh .v.RH = 0 ; + mem [ s ] .hh .v.RH = 0 ; + } + else if ( hyfsi [ j ] == haupt3 ) + { + hyfpen [ j - 1 ] = eqtb [ 12666 ] .cint ; + s = getnode ( 2 ) ; + mem [ s ] .hh.b0 = 7 ; + hyfdisc [ j - 1 ] = s ; + mem [ s + 1 ] .hh .v.LH = newpenalty ( eqtb [ 12666 ] .cint ) ; + s = mem [ s + 1 ] .hh .v.LH ; + mem [ s ] .hh.b1 = 1 ; + mem [ s ] .hh .v.RH = newcharacter ( hf , hu [ j ] ) ; + mem [ mem [ s ] .hh .v.RH ] .hh .v.RH = 0 ; + s = hyfdisc [ j - 1 ] ; + mem [ s + 1 ] .hh .v.RH = 0 ; + mem [ s ] .hh .v.RH = 0 ; + } + } + while ( j++ < for_end ) ; } + if ( odd ( eqtb [ 12719 ] .cint / 8 ) ) + { + if ( ! odd ( eqtb [ 12720 ] .cint / 8 ) ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s%ld%s\n", " <* debugging output section #" , (long)8 , " *>" ) + ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s%ld%s\n", " <* debugging output section #" , (long)8 , " *>" ) ; + } + } + if ( funktioniert ) + { + {register integer for_end; j = 0 ; for_end = hn ; if ( j <= for_end) do + if ( hyfpen [ j ] != 10000 ) + { + if ( hyfdisc [ j ] != 0 ) + { + if ( mem [ mem [ hyfdisc [ j ] + 1 ] .hh .v.LH ] .hh.b1 == 0 ) + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%c%c", Xchr ( hu [ j + 1 ] ) , '-' ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%c%c", Xchr ( hu [ j + 1 ] ) , '-' ) ; + } + else { + + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%c%c%c", Xchr ( hu [ j + 1 ] ) , Xchr ( hu [ j + 1 ] ) , '=' ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%c%c%c", Xchr ( hu [ j + 1 ] ) , Xchr ( hu [ j + 1 ] ) , '=' ) ; + } + } + else { + + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( hu [ j ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( hu [ j ] ) , logfile ); + } + if ( hyfpen [ j ] == eqtb [ 12666 ] .cint ) + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( '=' , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( '=' , logfile ); + } + else { + + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( '-' , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( '-' , logfile ); + } + } + } + else { + + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) putc( Xchr ( hu [ j ] ) , stdout ); + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) putc( Xchr ( hu [ j ] ) , logfile ); + } + } + while ( j++ < for_end ) ; } + } + else { + + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", " no hyphens were found in this word!" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", " no hyphens were found in this word!" ) ; + } + } + println () ; + } + goto lab31 ; + lab40: hyfpen [ 0 ] = 10000 ; + {register integer for_end; j = 1 ; for_end = hn ; if ( j <= for_end) do + if ( odd ( hyf [ j ] ) ) + hyfpen [ j ] = eqtb [ 12666 ] .cint ; + else hyfpen [ j ] = 10000 ; + while ( j++ < for_end ) ; } + lab31: ; + {register integer for_end; j = lhyf ; for_end = hn - rhyf ; if ( j <= + for_end) do + if ( hyfpen [ j ] != 10000 ) + goto lab41 ; + while ( j++ < for_end ) ; } + return ; + lab41: ; + q = mem [ hb ] .hh .v.RH ; + mem [ hb ] .hh .v.RH = 0 ; + r = mem [ ha ] .hh .v.RH ; + mem [ ha ] .hh .v.RH = 0 ; + bchar = 256 ; + holdr = newkern ( 1235 ) ; + mem [ holdr ] .hh .v.RH = r ; + if ( ! ( hb >= himemmin ) ) + if ( mem [ hb ] .hh.b0 == 6 ) + if ( odd ( mem [ hb ] .hh.b1 ) ) + bchar = fontbchar [ hf ] ; + if ( ( ha >= himemmin ) ) + if ( mem [ ha ] .hh.b0 != hf ) + goto lab42 ; + else { + + initlist = ha ; + initlig = false ; + hu [ 0 ] = mem [ ha ] .hh.b1 ; + } + else if ( isdirtyumlaut ( ha ) ) + { + if ( getfontof ( ha ) != hf ) + goto lab42 ; + else { + + initlist = ha ; + initlig = false ; + hu [ 0 ] = getcharof ( ha ) ; + } + } + else if ( mem [ ha ] .hh.b0 == 6 ) + if ( mem [ ha + 1 ] .hh.b0 != hf ) + goto lab42 ; + else { + + initlist = mem [ ha + 1 ] .hh .v.RH ; + initlig = true ; + initlft = ( mem [ ha ] .hh.b1 > 1 ) ; + hu [ 0 ] = mem [ ha + 1 ] .hh.b1 ; + if ( initlist == 0 ) + if ( initlft ) + { + hu [ 0 ] = 256 ; + initlig = false ; + } + freenode ( ha , 2 ) ; + } + else { + + if ( ! ( r >= himemmin ) ) + if ( mem [ r ] .hh.b0 == 6 ) + if ( mem [ r ] .hh.b1 > 1 ) + goto lab42 ; + j = 1 ; + s = ha ; + initlist = 0 ; + goto lab50 ; + } + s = curp ; + while ( mem [ s ] .hh .v.RH != ha ) s = mem [ s ] .hh .v.RH ; + j = 0 ; + goto lab50 ; + lab42: s = ha ; + j = 0 ; + hu [ 0 ] = 256 ; + initlig = false ; + initlist = 0 ; + lab50: qq = holdr ; + {register integer for_end; kk = j ; for_end = hn ; if ( kk <= for_end) do + if ( dirtyumlaut [ kk ] != 0 ) + { + while ( mem [ qq ] .hh .v.RH != dirtyumlaut [ kk ] ) qq = mem [ qq ] .hh + .v.RH ; + qr = mem [ qq ] .hh .v.RH ; + {register integer for_end; i = 1 ; for_end = mem [ qr ] .hh.b1 ; if ( i + <= for_end) do + if ( qr != 0 ) + qr = mem [ qr ] .hh .v.RH ; + else { + + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", "...??..X --> ????? !" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", "...??..X --> ????? !" ) ; + } + } + while ( i++ < for_end ) ; } + if ( qr != 0 ) + { + mem [ qq ] .hh .v.RH = mem [ qr ] .hh .v.RH ; + mem [ qr ] .hh .v.RH = 0 ; + } + else mem [ qq ] .hh .v.RH = 0 ; + } + while ( kk++ < for_end ) ; } + if ( dirtyumlaut [ -1 ] != 0 ) + { + qq = holdr ; + while ( ( mem [ qq ] .hh .v.RH != dirtyumlaut [ -1 ] ) && ( mem [ qq ] .hh + .v.RH != 0 ) ) qq = mem [ qq ] .hh .v.RH ; + if ( mem [ qq ] .hh .v.RH == dirtyumlaut [ -1 ] ) + { + mem [ qq ] .hh .v.RH = mem [ dirtyumlaut [ -1 ] ] .hh .v.RH ; + mem [ dirtyumlaut [ -1 ] ] .hh .v.RH = 0 ; + } + else { + + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) Fputs( stdout , " *** ERROR: node list is damaged! " ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) Fputs( logfile , " *** ERROR: node list is damaged! " ) ; + } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", "(post hyphenation - unhinge a whatsit node)" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", "(post hyphenation - unhinge a whatsit node)" ) ; + } + } + } + r = holdr ; + while ( mem [ r ] .hh .v.RH != 0 ) { + + if ( ( memmin <= mem [ r ] .hh .v.RH ) && ( mem [ r ] .hh .v.RH <= memmax + ) ) + r = mem [ r ] .hh .v.RH ; + else { + + (void) putc('\n', logfile ); + (void) putc('\n', stdout ); + (void) fprintf( logfile , "%s\n", "???$ - ERROR in node list!" ) ; + (void) fprintf( stdout , "%s\n", "???$ - ERROR in node list!" ) ; + kk = depththreshold ; + l = breadthmax ; + depththreshold = 100 ; + breadthmax = 100 ; + shownodelist ( holdr ) ; + mem [ r ] .hh .v.RH = 0 ; + depththreshold = kk ; + breadthmax = l ; + } + } + flushnodelist ( holdr ) ; + if ( dirtyumlaut [ -1 ] != 0 ) + { + mem [ s ] .hh .v.RH = dirtyumlaut [ -1 ] ; + s = mem [ s ] .hh .v.RH ; + } + do { + if ( dirtyumlaut [ j ] != 0 ) + { + mem [ s ] .hh .v.RH = dirtyumlaut [ j ] ; + while ( mem [ s ] .hh .v.RH > 0 ) s = mem [ s ] .hh .v.RH ; + mem [ memtop - 4 ] .hh .v.RH = 0 ; + j = j + 1 ; + hyphenpassed = 0 ; + if ( hyfpen [ j - 1 ] != 10000 ) + { + l = j ; + hyphenpassed = j - 1 ; + if ( odd ( eqtb [ 12719 ] .cint / 16 ) ) + { + if ( ! odd ( eqtb [ 12720 ] .cint / 16 ) ) + { + println () ; + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s%ld%s\n", " <* debugging output section #" , (long)16 , " *>" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s%ld%s\n", " <* debugging output section #" , (long)16 , " *>" ) ; + } + } + { + if ( ( fileoffset != 0 ) || ( termoffset != 0 ) ) + println () ; + if ( selector != 18 ) + (void) fprintf( stdout , "%s\n", " *** append a hyphen immediatly after a dirty umlaut!" ) ; + if ( ( selector == 18 ) || ( selector == 19 ) ) + (void) fprintf( logfile , "%s\n", " *** append a hyphen immediatly after a dirty umlaut!" ) ; + } + } + } + } + else { + + l = j ; + j = reconstitute ( j , hn , bchar , hyfchar ) + 1 ; + if ( hyphenpassed == 0 ) + { + mem [ s ] .hh .v.RH = mem [ memtop - 4 ] .hh .v.RH ; + while ( mem [ s ] .hh .v.RH > 0 ) s = mem [ s ] .hh .v.RH ; + if ( hyfpen [ j - 1 ] != 10000 ) + { + l = j ; + hyphenpassed = j - 1 ; + mem [ memtop - 4 ] .hh .v.RH = 0 ; + } + } + } + if ( hyphenpassed > 0 ) + do { + r = getnode ( 2 ) ; + mem [ r ] .hh .v.RH = mem [ memtop - 4 ] .hh .v.RH ; + mem [ r ] .hh.b0 = 7 ; + majortail = r ; + rcount = 0 ; + while ( mem [ majortail ] .hh .v.RH > 0 ) { + + majortail = mem [ majortail ] .hh .v.RH ; + incr ( rcount ) ; + } + i = hyphenpassed ; + hyf [ i ] = 0 ; + if ( ( hyfpen [ i ] != 10000 ) && ( hyfpen [ i ] != eqtb [ 12666 ] .cint + ) ) + minortail = newpenalty ( hyfpen [ i ] ) ; + else minortail = 0 ; + hyfpen [ i ] = 10000 ; + mem [ r + 1 ] .hh .v.LH = minortail ; + hyfnode = newcharacter ( hf , hyfchar ) ; + xchgk = i ; + if ( hyfdisc [ xchgk ] != 0 ) + { + spechyf = mem [ hyfdisc [ xchgk ] + 1 ] .hh .v.LH ; + addchar = mem [ spechyf ] .hh.b1 ; + xchgi = 1 ; + do { + spechyf = mem [ spechyf ] .hh .v.RH ; + if ( spechyf != 0 ) + { + xchgchar [ xchgi ] = mem [ spechyf ] .hh.b1 ; + incr ( xchgi ) ; + } + } while ( ! ( spechyf == 0 ) ) ; + if ( hyfnode != 0 ) + { + xchgchar [ xchgi ] = hyfchar ; + { + mem [ hyfnode ] .hh .v.RH = avail ; + avail = hyfnode ; + ; +#ifdef STAT + decr ( dynused ) ; +#endif /* STAT */ + } + } + else decr ( xchgi ) ; + xchghu = i - xchgi + addchar + 2 ; + {register integer for_end; xchgk = 1 ; for_end = xchgi ; if ( xchgk + <= for_end) do + { + xchgchar [ 0 ] = hu [ xchghu ] ; + hu [ xchghu ] = xchgchar [ xchgk ] ; + xchgchar [ xchgk ] = xchgchar [ 0 ] ; + incr ( xchghu ) ; + } + while ( xchgk++ < for_end ) ; } + xchgk = i ; + i = xchghu - 1 ; + xchghu = xchghu - xchgi ; + } + else if ( hyfnode != 0 ) + { + incr ( i ) ; + c = hu [ i ] ; + hu [ i ] = hyfchar ; + { + mem [ hyfnode ] .hh .v.RH = avail ; + avail = hyfnode ; + ; +#ifdef STAT + decr ( dynused ) ; +#endif /* STAT */ + } + } + while ( l <= i ) { + + l = reconstitute ( l , i , fontbchar [ hf ] , 256 ) + 1 ; + if ( mem [ memtop - 4 ] .hh .v.RH > 0 ) + { + if ( minortail == 0 ) + mem [ r + 1 ] .hh .v.LH = mem [ memtop - 4 ] .hh .v.RH ; + else mem [ minortail ] .hh .v.RH = mem [ memtop - 4 ] .hh .v.RH ; + minortail = mem [ memtop - 4 ] .hh .v.RH ; + while ( mem [ minortail ] .hh .v.RH > 0 ) minortail = mem [ + minortail ] .hh .v.RH ; + } + } + if ( hyfdisc [ xchgk ] != 0 ) + { + i = xchgk ; + l = i + 1 ; + {register integer for_end; xchgk = 1 ; for_end = xchgi ; if ( xchgk + <= for_end) do + { + hu [ xchghu ] = xchgchar [ xchgk ] ; + incr ( xchghu ) ; + } + while ( xchgk++ < for_end ) ; } + } + else if ( hyfnode != 0 ) + { + hu [ i ] = c ; + l = i ; + decr ( i ) ; + } + minortail = 0 ; + mem [ r + 1 ] .hh .v.RH = 0 ; + cloc = 0 ; + if ( bcharlabel [ hf ] < fontmemsize ) + { + decr ( l ) ; + c = hu [ l ] ; + cloc = l ; + hu [ l ] = 256 ; + } + while ( l < j ) { + + do { + l = reconstitute ( l , hn , bchar , 256 ) + 1 ; + if ( cloc > 0 ) + { + hu [ cloc ] = c ; + cloc = 0 ; + } + if ( mem [ memtop - 4 ] .hh .v.RH > 0 ) + { + if ( minortail == 0 ) + mem [ r + 1 ] .hh .v.RH = mem [ memtop - 4 ] .hh .v.RH ; + else mem [ minortail ] .hh .v.RH = mem [ memtop - 4 ] .hh .v.RH ; + minortail = mem [ memtop - 4 ] .hh .v.RH ; + while ( mem [ minortail ] .hh .v.RH > 0 ) minortail = mem [ + minortail ] .hh .v.RH ; + } + } while ( ! ( l >= j ) ) ; + while ( l > j ) { + + j = reconstitute ( j , hn , bchar , 256 ) + 1 ; + mem [ majortail ] .hh .v.RH = mem [ memtop - 4 ] .hh .v.RH ; + while ( mem [ majortail ] .hh .v.RH > 0 ) { + + majortail = mem [ majortail ] .hh .v.RH ; + incr ( rcount ) ; + } + } + } + if ( rcount > 127 ) + { + mem [ s ] .hh .v.RH = mem [ r ] .hh .v.RH ; + mem [ r ] .hh .v.RH = 0 ; + flushnodelist ( r ) ; + } + else { + + mem [ s ] .hh .v.RH = r ; + mem [ r ] .hh.b1 = rcount ; + } + s = majortail ; + hyphenpassed = j - 1 ; + mem [ memtop - 4 ] .hh .v.RH = 0 ; + } while ( ! ( ( hyfpen [ j - 1 ] == 10000 ) ) ) ; + } while ( ! ( j > hn ) ) ; + mem [ s ] .hh .v.RH = q ; + siq = s ; + {register integer for_end; j = 0 ; for_end = 64 ; if ( j <= for_end) do + if ( hyfdisc [ j ] != 0 ) + { + flushnodelist ( hyfdisc [ j ] ) ; + } + while ( j++ < for_end ) ; } + flushlist ( initlist ) ; +} diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/texd.h b/obsolete/systems/sisisi/unix/SiTeX3.14/texd.h new file mode 100644 index 0000000000..d53c464953 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/texd.h @@ -0,0 +1,485 @@ +#undef TRIP +#undef TRAP +#define STAT +#undef DEBUG +#include "../common/texmf.h" +#define memmax 262140L +#define memmin 0 +#define bufsize 3000 +#define errorline 79 +#define halferrorline 50 +#define maxprintline 79 +#define stacksize 300 +#define maxinopen 15 +#define fontmax 255 +#define fontmemsize 72000L +#define paramsize 60 +#define nestsize 40 +#define maxstrings 7500 +#define stringvacancies 74000L +#define poolsize 100000L +#define savesize 4000 +#define triesize 24000 +#define trieopsize 750 +#define negtrieopsize -750 +#define mintrieop 0 +#define maxtrieop 500 +#define dvibufsize 16384 +#define poolname "sitex.pool" +#define memtop 262140L +#define maxwl 64 +#define sonderzeichen 0 +#define bsta 1 +#define bstb 2 +#define bstc 3 +#define bstd 4 +#define bste 5 +#define bstf 6 +#define bstg 7 +#define bsth 8 +#define bsti 9 +#define bstj 10 +#define bstk 11 +#define bstl 12 +#define bstm 13 +#define bstn 14 +#define bsto 15 +#define bstp 16 +#define bstq 17 +#define bstr 18 +#define bsts 19 +#define bstt 20 +#define bstu 21 +#define bstv 22 +#define bstw 23 +#define bstx 24 +#define bsty 25 +#define bstz 26 +#define bstae 27 +#define bstoe 28 +#define bstue 29 +#define bstsz 30 +#define trennzeichen 31 +#define keine 1 +#define neben 2 +#define nebenck 3 +#define haupt 4 +#define haupt3 5 +#define tabsize 8191 +#define specletterID 4321 +#define voka 1 +#define voke 2 +#define voki 3 +#define voko 4 +#define voku 5 +#define vokae 6 +#define vokoe 7 +#define vokue 8 +#define vokie 9 +#define vokai 10 +#define vokei 11 +#define vokau 12 +#define vokaeu 13 +#define vokeu 14 +#define voky 15 +#define kons 16 +typedef unsigned char ASCIIcode ; +typedef unsigned char eightbits ; +typedef integer poolpointer ; +typedef integer strnumber ; +typedef unsigned char packedASCIIcode ; +typedef integer scaled ; +typedef integer nonnegativeinteger ; +typedef schar smallnumber ; +typedef unsigned char quarterword ; +typedef integer halfword ; +typedef schar twochoices ; +typedef schar fourchoices ; +#include "memory.h" +typedef schar glueord ; +typedef struct { + short modefield ; + halfword headfield, tailfield ; + integer pgfield, mlfield ; + memoryword auxfield ; + quarterword lhmfield, rhmfield ; +} liststaterecord ; +typedef schar groupcode ; +typedef struct { + quarterword statefield, indexfield ; + halfword startfield, locfield, limitfield, namefield ; +} instaterecord ; +typedef integer internalfontnumber ; +typedef integer fontindex ; +typedef integer dviindex ; +typedef integer trieopcode ; +typedef integer triepointer ; +typedef eightbits string80 [81] ; +typedef eightbits buchstabe ; +typedef short aword [maxwl + 1] ; +typedef aword wort ; +typedef boolean sperrvektor [maxwl + 1] ; +typedef boolean dudt [maxwl + 1] ; +typedef integer trennvektor [maxwl + 1] ; +typedef buchstabe ktabtype [256] ; +typedef unsigned long verdschlue ; +typedef verdschlue varr [maxwl + 1] ; +typedef integer intarr [maxwl + 1] ; +typedef struct { + boolean ausnahme ; + boolean untrennbar ; + integer erste ; + integer zweite ; + boolean endung, vorsilbe, stamm, ehervor, stammallein ; +} infotype ; +typedef eightbits infobyte ; +typedef struct { + verdschlue tabv ; + infobyte tabb ; + boolean frei ; + boolean wiederfrei ; +} tableentry ; +typedef eightbits hashelement [4] ; +typedef hashelement htabtype [tabsize + 1] ; +typedef short hyphpointer ; +EXTERN integer bad ; +EXTERN ASCIIcode xord[256] ; +EXTERN ASCIIcode xchr[256] ; +EXTERN char nameoffile[FILENAMESIZE + 1] ; +EXTERN integer namelength ; +EXTERN ASCIIcode buffer[bufsize + 1] ; +EXTERN integer first ; +EXTERN integer last ; +EXTERN integer maxbufstack ; +EXTERN packedASCIIcode strpool[poolsize + 1] ; +EXTERN poolpointer strstart[maxstrings + 1] ; +EXTERN poolpointer poolptr ; +EXTERN strnumber strptr ; +EXTERN poolpointer initpoolptr ; +EXTERN strnumber initstrptr ; +#ifdef INITEX +EXTERN alphafile poolfile ; +#endif /* INITEX */ +EXTERN alphafile logfile ; +EXTERN schar selector ; +EXTERN schar dig[23] ; +EXTERN integer tally ; +EXTERN integer termoffset ; +EXTERN integer fileoffset ; +EXTERN ASCIIcode trickbuf[errorline + 1] ; +EXTERN integer trickcount ; +EXTERN integer firstcount ; +EXTERN schar interaction ; +EXTERN boolean deletionsallowed ; +EXTERN schar history ; +EXTERN schar errorcount ; +EXTERN strnumber helpline[6] ; +EXTERN schar helpptr ; +EXTERN boolean useerrhelp ; +EXTERN integer interrupt ; +EXTERN boolean OKtointerrupt ; +EXTERN boolean aritherror ; +EXTERN scaled remainder ; +EXTERN halfword tempptr ; +EXTERN memoryword +#define zmem (zzzaa - (int)(memmin)) + zzzaa[memmax - memmin + 1] ; +EXTERN halfword lomemmax ; +EXTERN halfword himemmin ; +EXTERN integer varused, dynused ; +EXTERN halfword avail ; +EXTERN halfword memend ; +EXTERN halfword rover ; +#ifdef DEBUG +EXTERN boolean +#define freearr (zzzab - (int)(memmin)) + zzzab[memmax - memmin + 1] ; +EXTERN boolean +#define wasfree (zzzac - (int)(memmin)) + zzzac[memmax - memmin + 1] ; +EXTERN halfword wasmemend, waslomax, washimin ; +EXTERN boolean panicking ; +#endif /* DEBUG */ +EXTERN integer fontinshortdisplay ; +EXTERN integer depththreshold ; +EXTERN integer breadthmax ; +EXTERN liststaterecord nest[nestsize + 1] ; +EXTERN integer nestptr ; +EXTERN integer maxneststack ; +EXTERN liststaterecord curlist ; +EXTERN short shownmode ; +EXTERN schar oldsetting ; +EXTERN memoryword zeqtb[13510] ; +EXTERN quarterword +#define xeqlevel (zzzad -12663) + zzzad[847] ; +EXTERN twohalves +#define hash (zzzae -514) + zzzae[9767] ; +EXTERN halfword hashused ; +EXTERN boolean nonewcontrolsequence ; +EXTERN integer cscount ; +EXTERN memoryword savestack[savesize + 1] ; +EXTERN integer saveptr ; +EXTERN integer maxsavestack ; +EXTERN quarterword curlevel ; +EXTERN groupcode curgroup ; +EXTERN integer curboundary ; +EXTERN integer magset ; +EXTERN eightbits curcmd ; +EXTERN halfword curchr ; +EXTERN halfword curcs ; +EXTERN halfword curtok ; +EXTERN instaterecord inputstack[stacksize + 1] ; +EXTERN integer inputptr ; +EXTERN integer maxinstack ; +EXTERN instaterecord curinput ; +EXTERN integer inopen ; +EXTERN integer openparens ; +EXTERN alphafile inputfile[maxinopen + 1] ; +EXTERN integer line ; +EXTERN integer linestack[maxinopen + 1] ; +EXTERN schar scannerstatus ; +EXTERN halfword warningindex ; +EXTERN halfword defref ; +EXTERN halfword paramstack[paramsize + 1] ; +EXTERN integer paramptr ; +EXTERN integer maxparamstack ; +EXTERN integer alignstate ; +EXTERN integer baseptr ; +EXTERN halfword parloc ; +EXTERN halfword partoken ; +EXTERN boolean forceeof ; +EXTERN halfword curmark[5] ; +EXTERN schar longstate ; +EXTERN halfword pstack[9] ; +EXTERN integer curval ; +EXTERN schar curvallevel ; +EXTERN smallnumber radix ; +EXTERN glueord curorder ; +EXTERN alphafile readfile[16] ; +EXTERN schar readopen[17] ; +EXTERN halfword condptr ; +EXTERN schar iflimit ; +EXTERN smallnumber curif ; +EXTERN integer ifline ; +EXTERN integer skipline ; +EXTERN strnumber curname ; +EXTERN strnumber curarea ; +EXTERN strnumber curext ; +EXTERN poolpointer areadelimiter ; +EXTERN poolpointer extdelimiter ; +EXTERN integer formatdefaultlength ; +EXTERN ccharpointer TEXformatdefault ; +EXTERN boolean nameinprogress ; +EXTERN strnumber jobname ; +EXTERN boolean logopened ; +EXTERN bytefile dvifile ; +EXTERN strnumber outputfilename ; +EXTERN strnumber logname ; +EXTERN bytefile tfmfile ; +EXTERN memoryword fontinfo[fontmemsize + 1] ; +EXTERN fontindex fmemptr ; +EXTERN internalfontnumber fontptr ; +EXTERN fourquarters fontcheck[fontmax + 1] ; +EXTERN scaled fontsize[fontmax + 1] ; +EXTERN scaled fontdsize[fontmax + 1] ; +EXTERN halfword fontparams[fontmax + 1] ; +EXTERN strnumber fontname[fontmax + 1] ; +EXTERN strnumber fontarea[fontmax + 1] ; +EXTERN eightbits fontbc[fontmax + 1] ; +EXTERN eightbits fontec[fontmax + 1] ; +EXTERN halfword fontglue[fontmax + 1] ; +EXTERN boolean fontused[fontmax + 1] ; +EXTERN integer hyphenchar[fontmax + 1] ; +EXTERN integer skewchar[fontmax + 1] ; +EXTERN fontindex bcharlabel[fontmax + 1] ; +EXTERN short fontbchar[fontmax + 1] ; +EXTERN short fontfalsebchar[fontmax + 1] ; +EXTERN integer charbase[fontmax + 1] ; +EXTERN integer widthbase[fontmax + 1] ; +EXTERN integer heightbase[fontmax + 1] ; +EXTERN integer depthbase[fontmax + 1] ; +EXTERN integer italicbase[fontmax + 1] ; +EXTERN integer ligkernbase[fontmax + 1] ; +EXTERN integer kernbase[fontmax + 1] ; +EXTERN integer extenbase[fontmax + 1] ; +EXTERN integer parambase[fontmax + 1] ; +EXTERN fourquarters nullcharacter ; +EXTERN integer totalpages ; +EXTERN scaled maxv ; +EXTERN scaled maxh ; +EXTERN integer maxpush ; +EXTERN integer lastbop ; +EXTERN integer deadcycles ; +EXTERN boolean doingleaders ; +EXTERN quarterword c, f ; +EXTERN scaled ruleht, ruledp, rulewd ; +EXTERN halfword g ; +EXTERN integer lq, lr ; +EXTERN eightbits dvibuf[dvibufsize + 1] ; +EXTERN dviindex halfbuf ; +EXTERN dviindex dvilimit ; +EXTERN dviindex dviptr ; +EXTERN integer dvioffset ; +EXTERN integer dvigone ; +EXTERN halfword downptr, rightptr ; +EXTERN scaled dvih, dviv ; +EXTERN scaled curh, curv ; +EXTERN internalfontnumber dvif ; +EXTERN integer curs ; +EXTERN scaled totalstretch[4], totalshrink[4] ; +EXTERN integer lastbadness ; +EXTERN halfword adjusttail ; +EXTERN integer packbeginline ; +EXTERN twohalves emptyfield ; +EXTERN fourquarters nulldelimiter ; +EXTERN halfword curmlist ; +EXTERN smallnumber curstyle ; +EXTERN smallnumber cursize ; +EXTERN scaled curmu ; +EXTERN boolean mlistpenalties ; +EXTERN internalfontnumber curf ; +EXTERN quarterword curc ; +EXTERN fourquarters curi ; +EXTERN integer magicoffset ; +EXTERN halfword curalign ; +EXTERN halfword curspan ; +EXTERN halfword curloop ; +EXTERN halfword alignptr ; +EXTERN halfword curhead, curtail ; +EXTERN halfword justbox ; +EXTERN halfword passive ; +EXTERN halfword printednode ; +EXTERN halfword passnumber ; +EXTERN scaled activewidth[7] ; +EXTERN scaled curactivewidth[7] ; +EXTERN scaled background[7] ; +EXTERN scaled breakwidth[7] ; +EXTERN boolean noshrinkerroryet ; +EXTERN halfword curp ; +EXTERN boolean secondpass ; +EXTERN boolean finalpass ; +EXTERN integer threshold ; +EXTERN integer minimaldemerits[4] ; +EXTERN integer minimumdemerits ; +EXTERN halfword bestplace[4] ; +EXTERN halfword bestplline[4] ; +EXTERN scaled discwidth ; +EXTERN halfword easyline ; +EXTERN halfword lastspecialline ; +EXTERN scaled firstwidth ; +EXTERN scaled secondwidth ; +EXTERN scaled firstindent ; +EXTERN scaled secondindent ; +EXTERN halfword bestbet ; +EXTERN integer fewestdemerits ; +EXTERN halfword bestline ; +EXTERN integer actuallooseness ; +EXTERN integer linediff ; +EXTERN aword hc ; +EXTERN smallnumber hn ; +EXTERN halfword ha, hb ; +EXTERN integer hyfdebi, hyfdebj ; +EXTERN boolean hyfdebb ; +EXTERN halfword sip, siq, sir, sis ; +EXTERN internalfontnumber hf ; +EXTERN short hu[64] ; +EXTERN integer hyfchar ; +EXTERN ASCIIcode curlang ; +EXTERN integer lhyf, rhyf ; +EXTERN halfword +#define dirtyumlaut (zzzaf +1) + zzzaf[66] ; +EXTERN schar hyf[65] ; +EXTERN halfword initlist ; +EXTERN boolean initlig ; +EXTERN boolean initlft ; +EXTERN integer hyfpen[65] ; +EXTERN trennvektor hyfsi ; +EXTERN wort hcsi ; +EXTERN halfword hyfdisc[65] ; +EXTERN smallnumber hyphenpassed ; +EXTERN halfword curl, curr ; +EXTERN halfword curq ; +EXTERN halfword ligstack ; +EXTERN boolean ligaturepresent ; +EXTERN boolean lfthit, rthit ; +EXTERN halfword trietrl[triesize + 1] ; +EXTERN halfword trietro[triesize + 1] ; +EXTERN quarterword trietrc[triesize + 1] ; +EXTERN smallnumber hyfdistance[trieopsize + 1] ; +EXTERN smallnumber hyfnum[trieopsize + 1] ; +EXTERN quarterword hyfnext[trieopsize + 1] ; +EXTERN integer opstart[256] ; +EXTERN ktabtype ktab ; +EXTERN htabtype htab ; +EXTERN integer anzahl ; +EXTERN alphafile hashfile ; +EXTERN integer kombtab[6][6] ; +EXTERN boolean konsonant[31] ; +EXTERN integer revtab[256] ; +EXTERN strnumber hyphword[608] ; +EXTERN halfword hyphlist[608] ; +EXTERN hyphpointer hyphcount ; +#ifdef INITEX +EXTERN integer +#define trieophash (zzzag - (int)(negtrieopsize)) + zzzag[trieopsize - negtrieopsize + 1] ; +EXTERN trieopcode trieused[256] ; +EXTERN ASCIIcode trieoplang[trieopsize + 1] ; +EXTERN trieopcode trieopval[trieopsize + 1] ; +EXTERN integer trieopptr ; +#endif /* INITEX */ +EXTERN trieopcode maxopused ; +EXTERN boolean smallop ; +#ifdef INITEX +EXTERN packedASCIIcode triec[triesize + 1] ; +EXTERN trieopcode trieo[triesize + 1] ; +EXTERN triepointer triel[triesize + 1] ; +EXTERN triepointer trier[triesize + 1] ; +EXTERN triepointer trieptr ; +EXTERN triepointer triehash[triesize + 1] ; +#endif /* INITEX */ +#ifdef INITEX +EXTERN boolean trietaken[triesize + 1] ; +EXTERN triepointer triemin[256] ; +EXTERN triepointer triemax ; +EXTERN boolean trienotready ; +#endif /* INITEX */ +EXTERN scaled bestheightplusdepth ; +EXTERN halfword pagetail ; +EXTERN schar pagecontents ; +EXTERN scaled pagemaxdepth ; +EXTERN halfword bestpagebreak ; +EXTERN integer leastpagecost ; +EXTERN scaled bestsize ; +EXTERN scaled pagesofar[8] ; +EXTERN halfword lastglue ; +EXTERN integer lastpenalty ; +EXTERN scaled lastkern ; +EXTERN integer insertpenalties ; +EXTERN boolean outputactive ; +EXTERN internalfontnumber mainf ; +EXTERN fourquarters maini ; +EXTERN fourquarters mainj ; +EXTERN fontindex maink ; +EXTERN halfword mainp ; +EXTERN integer mains ; +EXTERN halfword bchar ; +EXTERN halfword falsebchar ; +EXTERN boolean cancelboundary ; +EXTERN boolean insdisc ; +EXTERN halfword curbox ; +EXTERN halfword aftertoken ; +EXTERN boolean longhelpseen ; +EXTERN strnumber formatident ; +EXTERN wordfile fmtfile ; +EXTERN integer readyalready ; +EXTERN alphafile writefile[16] ; +EXTERN boolean writeopen[18] ; +EXTERN halfword writeloc ; +EXTERN poolpointer editnamestart ; +EXTERN integer editnamelength, editline, tfmtemp ; + +#include "coerce.h" diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/web2c.c b/obsolete/systems/sisisi/unix/SiTeX3.14/web2c.c new file mode 100644 index 0000000000..f4a956fd17 --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/web2c.c @@ -0,0 +1,334 @@ +/* + * This program converts (mostly) the pseudo-Pascal generated by Tangle to C. + * The output depends on many C macros and some postprocessing by other + * programs. + * + * Arguments: + * -f: force strict interpretation of semantics of for stmt + * (never used with TeX and friends) + * -t: special optimizations for tex.p->tex.c + * -m: special optimizations for mf.p->mf.c + * -c: supply the base part of the name of the coerce.h file + * -h: supply the name of the standard header file + * -a: generate ANSI-style function prototypes + * -d: generate some additional debugging output + * + * The majority of this program (which includes ptoc.yacc and ptoc.lex) + * was written by Tomas Rokicki, with modifications by Tim Morgan, et al. + */ + +#include <stdio.h> +#include "web2cy.h" +#include "web2c.h" + + +/* Changing this value will probably stimulate bugs in some + preprocessors---those which want to put the expansion of a macro + entirely on one line. */ +#define max_line_length (78) +#define max_strings (50000) +#define hash_prime (101) +#define sym_table_size (5000) +#define unused (271828) + +/* Says whether to give voluminous progress reports. */ +boolean debug=FALSE; +int indent = 0; +int line_pos = 0; +int last_brace = 0; +int block_level = 0; +int last_tok; +int tex = 0, strict_for = 0, mf = 0; + +char safe_string[80]; +char var_list[500]; +char field_list[500]; +char last_id[80]; +char z_id[80]; +char next_temp[] = "zzzaa"; +char coerce_name[100] = "coerce.h"; + +long last_i_num; +int ii, l_s; +long lower_bound, upper_bound; +extern FILE *fopen(); +FILE *std; +FILE *coerce; +int pf_count = 1; +#ifdef ANSI +boolean ansi = TRUE; +#else +boolean ansi = FALSE; +#endif + +char *std_header = "null.h"; /* Default include filename */ + +char strings[max_strings]; +int hash_list[hash_prime]; +short global = 1; +#ifdef MS_DOS +struct sym_entry huge sym_table[sym_table_size]; +#else +struct sym_entry sym_table[sym_table_size]; +#endif +int next_sym_free = -1, next_string_free = 0; +int mark_sym_free, mark_string_free; + +extern int yyleng; +#ifdef FLEX +extern char *yytext; +#else /* LEX */ +#ifdef HP +extern unsigned char yytext[]; +#else /* not HP */ +extern char yytext[]; +#endif /* not HP */ +#endif /* LEX */ + +void find_next_temp() +{ + next_temp[4]++; + if (next_temp[4] > 'z') { + next_temp[4] = 'a'; + next_temp[3]++; + } +} + +void normal() +{ + std = stdout; +} + +void new_line() +{ + if (!std) + return; + if (line_pos > 0) { + (void) putc('\n', std); + line_pos = 0; + } +} + +void indent_line() +{ + new_line(); +} + + +/* Output the string S to `std'. */ + +void +my_output (s) + char *s; +{ + int len = strlen (s); + int less_indent = 0; + + if (!std) + return; + + if (line_pos + len > max_line_length) + indent_line (); + + if (indent > 1 && (strcmp(s, "case") == 0 || strcmp(s, "default") == 0)) + less_indent = 2; + + while (line_pos < indent * 2 - less_indent) + { + fputs (" ", std); + line_pos += 2; + } + + (void) fprintf (std, "%s ", s); + line_pos += len + 1; + + last_brace = (s[0] == '}'); +} + +void semicolon() +{ + if (!last_brace) { + my_output(";"); + indent_line(); + last_brace = 1; + } +} + + +/* Since a syntax error can never be recovered from, we exit here with + bad status. */ + +void yyerror(s) char *s; +{ + (void) fflush(stdout); + (void) fprintf(stderr, " %s\n", s); + (void) fprintf(stderr, "Last token = %d, ", last_tok); + (void) fprintf(stderr, "error buffer = `%s',\n\t", yytext); + (void) fprintf(stderr, "last id = `%s' (", last_id); + ii = search_table(last_id); + if (ii == -1) + (void) fprintf(stderr, "not in symbol table"); + else + switch (sym_table[ii].typ) { + case undef_id_tok: + (void) fprintf(stderr, "undefined"); + break; + case var_id_tok: + (void) fprintf(stderr, "variable"); + break; + case const_id_tok: + (void) fprintf(stderr, "constant"); + break; + case type_id_tok: + (void) fprintf(stderr, "type"); + break; + case proc_id_tok: + (void) fprintf(stderr, "parameterless procedure"); + break; + case proc_param_tok: + (void) fprintf(stderr, "procedure with parameters"); + break; + case fun_id_tok: + (void) fprintf(stderr, "parameterless function"); + break; + case fun_param_tok: + (void) fprintf(stderr, "function with parameters"); + break; + default: + (void) fprintf(stderr, "unknown!"); + break; + } + fprintf(stderr, ").\n"); + exit(1); + if (debug) { + (void) fprintf(stderr, "Next sym free = %d\n", next_sym_free); + (void) fprintf(stderr, "Mark sym = %d\n", mark_sym_free); + (void) fprintf(stderr, "Next string free = %d\n", next_string_free); + (void) fprintf(stderr, "Mark string = %d\n", mark_string_free); + } +} + +int hash(id) char *id; +{ + register int i = 0, j; + for (j = 0; id[j] != 0; j++) + i = (i + i + id[j]) % hash_prime; + return (i); +} + +int search_table(id) char *id; +{ + int ptr; + ptr = hash_list[hash(id)]; + while (ptr != -1) { + if (strcmp(id, sym_table[ptr].id) == 0) + return (ptr); + else + ptr = sym_table[ptr].next; + } + return (-1); +} + +int add_to_table(id) char *id; +{ + int h, ptr; + h = hash(id); + ptr = hash_list[h]; + hash_list[h] = (++next_sym_free); + sym_table[next_sym_free].next = ptr; + sym_table[next_sym_free].val = unused; + sym_table[next_sym_free].id = strings + next_string_free; + sym_table[next_sym_free].var_formal = FALSE; + sym_table[next_sym_free].var_not_needed = FALSE; + (void) strcpy(strings + next_string_free, id); + next_string_free += strlen(id) + 1; + return (next_sym_free); +} + +void remove_locals() +{ + int h, ptr; + for (h = 0; h < hash_prime; h++) { + next_sym_free = mark_sym_free; + next_string_free = mark_string_free; + ptr = hash_list[h]; + while (ptr > next_sym_free) + ptr = sym_table[ptr].next; + hash_list[h] = ptr; + } + global = 1; +} + +void +mark() +{ + mark_sym_free = next_sym_free; + mark_string_free = next_string_free; + global = 0; +} + + +void +initialize() +{ + register int i; + + for (i = 0; i < hash_prime; hash_list[i++] = -1) + ; + + normal (); + + coerce = fopen (coerce_name, "w"); + if (coerce == NULL) + { + perror (coerce_name); + exit (1); + } +} + +void +main (argc, argv) + int argc; + char *argv[]; +{ + int error, i; + + for (i=1; i < argc; i++) if (argv[i][0] == '-') switch (argv[i][1]) { + case 't': + tex = TRUE; + break; + case 'm': + mf = TRUE; + break; + case 'f': + strict_for = TRUE; + break; + case 'h': + std_header = &argv[i][2]; + break; + case 'd': + debug = TRUE; + break; + case 'a': + ansi = TRUE; + break; + case 'c': + (void) sprintf(coerce_name, "%s.h", &argv[i][2]); + break; + default: + fprintf(stderr, "Unknown option %s, ignored\n", argv[i]); + break; + } + else { + fprintf(stderr, "Unknown option %s, ignored\n", argv[i]); + } + + initialize (); + error = yyparse (); + new_line (); + + if (debug) + (void) fprintf(stderr, "%d symbols.\n", next_sym_free); + + exit(error); +} diff --git a/obsolete/systems/sisisi/unix/SiTeX3.14/web2c.h b/obsolete/systems/sisisi/unix/SiTeX3.14/web2c.h new file mode 100644 index 0000000000..44fe85653c --- /dev/null +++ b/obsolete/systems/sisisi/unix/SiTeX3.14/web2c.h @@ -0,0 +1,93 @@ +/* web2c.h: general includes for web2c. */ + +#include <stdio.h> +#include "site.h" +#include "common.h" + +#ifdef SYSV +#define bcopy(s,d,n) memcpy((d),(s),(n)) +#define bcmp(s1,s2,n) memcmp((s1),(s2),(n)) +#define bzero(s,n) memset((s),0,(n)) +#endif + +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else +#ifdef sparc +#include <alloca.h> +#else +char *alloca (); +#endif +#endif + +#define ex_32 (2) +#define ex_real (3) +#define max(a,b) ((a>b)?a:b) + +extern int indent; +extern int line_pos; +extern int last_brace; +extern int block_level; +extern int ii; +extern int last_tok; + +extern char safe_string[80]; +extern char var_list[500]; +extern char field_list[500]; +extern char last_id[80]; +extern char z_id[80]; +extern char next_temp[]; + +extern long last_i_num; +extern int ii, l_s; +extern long lower_bound, upper_bound; +extern FILE *fopen(); +extern FILE *std; +extern int pf_count; + +#include "symtab.h" + +extern char strings[]; +extern int hash_list[]; +extern short global; +#ifdef MS_DOS +extern struct sym_entry huge sym_table[]; +#else +extern struct sym_entry sym_table[]; +#endif +extern int next_sym_free, next_string_free; +extern int mark_sym_free, mark_string_free; + +#ifdef FLEX_SCANNER +extern char *yytext; + +#else /* LEX */ +#ifdef HP +extern unsigned char yytext[]; +#else +extern char yytext[]; +#endif + +#endif /* LEX */ + +#ifdef ANSI +extern void exit(int); +extern int yyparse(void); +void find_next_temp(void); +void normal(void); +void new_line(void); +void indent_line(void); +void my_output(char *); +void semicolon(void); +void yyerror(char *); +int hash(char *); +int search_table(char *); +int add_to_table(char *); +void remove_locals(void); +void mark(void); +void initialize(void); +void main(int,char * *); +#else /* not ANSI */ +void find_next_temp(), normal(), new_line(), indent_line(), my_output(); +void semicolon(), yyerror(), remove_locals(), mark(), initialize(); +#endif /* not ANSI */ |