|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U
Length: 59348 (0xe7d4)
Types: TextFile
Notes: Uncompressed file
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦c319c2751⟧ »unix3.0/TeX3.0.tar.Z«
└─⟦036c765ac⟧
└─⟦28cc16162⟧ »TeX3.0/BibTeX.inputs/pascal_bibtex.shar.Z«
└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
└─⟦28cc16162⟧ »./tex82/LaTeX/LaTeXbibtex/pascal_bibtex.shar.Z«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
└─⟦63303ae94⟧ »unix3.14/TeX3.14.tar.Z«
└─⟦c58930e5c⟧
└─⟦28cc16162⟧ »TeX3.14/BibTeX.inputs/pascal_bibtex.shar.Z«
└─⟦this⟧
# This is a shell archive.
# Remove everything above and including the cut line.
# Then run the rest of the file through sh.
#-----cut here-----cut here-----cut here-----cut here-----
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# Makefile.BSD4_n
# Makefile.PYR
# Makefile.SUN
# Makefile.SYS_V
# Setup.PYR
# Setup.SUN
# Setup.SYS_V
# Setup.VAX
# bibext.BSD4_n.c
# bibext.PYR.c
# bibext.h
# bibsep.SYS_V.sed
# bibtex.BSD4_n.ch
# bibtex.PYR.ch
# bibtex.SYS_V.ch
# makebib.SYS_V
# This archive created: Fri Jul 22 15:50:21 1988
cat << \SHAR_EOF > Makefile.BSD4_n
#
# Makefile for BibTeX
#
# Note: The -J option on the 'pc' commands below is the only way to
# 'pc' to use the -J option to the assembler (which makes it
# do the sensible thing with branches). This flag is not
# documented, which is correct, since 'pc' should really be
# using it all of the time... (Grrr..)
#
BINDIR=/usr/stanford/bin
PC = pc
PCLIB =
PFLAGS= -J -w
CFLAGS= -O -I../..
.SUFFIXES:
.SUFFIXES: .o .p .c .ch
.ch.o:
tangle $*.web $*.ch
$(PC) $(PFLAGS) -c $*.p
.ch.p:
tangle $*.web $*.ch
pxp -O $*.p > tmp
mv tmp $*.p
.p.o:
$(PC) $(PFLAGS) -c $*.p
all: bibtex
install: bibtex
mv bibtex $(BINDIR)
bibtex: bibtex.o bibext.o
$(PC) $(PFLAGS) -o bibtex bibtex.o bibext.o $(PCLIB)
bibtex.o: bibtex.p bibext.h
bibtex.p: bibtex.web
bibext.o: bibext.c ../../h00vars.h ../../texpaths.h
clean:
rm -f bibtex.p bibtex.o bibtex.pool
rm -f bibext.o
SHAR_EOF
cat << \SHAR_EOF > Makefile.PYR
#
# Makefile for BibTeX
#
# Note: The -J option on the 'pc' commands below is the only way to
# 'pc' to use the -J option to the assembler (which makes it
# do the sensible thing with branches). This flag is not
# documented, which is correct, since 'pc' should really be
# using it all of the time... (Grrr..)
#
BINDIR=/usr/stanford/bin
PC = pascal
PCLIB =
PFLAGS= -T4/bin/nas
CFLAGS= -O -I../..
.SUFFIXES:
.SUFFIXES: .o .p .c .ch
.ch.o:
tangle $*.web $*.ch
$(PC) $(PFLAGS) -c $*.p
.ch.p:
tangle $*.web $*.ch
sed 's/others:/otherwise:/' < $*.p > tmp
mv tmp $*.p
.p.o:
$(PC) $(PFLAGS) -c $*.p
all: bibtex
install: bibtex
mv bibtex $(BINDIR)
bibtex: bibtex.o bibext.o
$(PC) $(PFLAGS) -o bibtex bibtex.o bibext.o $(PCLIB)
bibtex.o: bibtex.p bibext.h
bibtex.p: bibtex.web
bibext.o: bibext.c ../../h00vars.h ../../texpaths.h
clean:
rm -f bibtex.p bibtex.o bibtex.pool
rm -f bibext.o
SHAR_EOF
cat << \SHAR_EOF > Makefile.SUN
#
# Makefile for BibTeX
#
#
BINDIR=/usr/stanford/bin
PC = pc
PCLIB =
PFLAGS= -w
CFLAGS= -O -I../..
.SUFFIXES:
.SUFFIXES: .o .p .c .ch
.ch.o:
tangle $*.web $*.ch
$(PC) $(PFLAGS) -c $*.p
.ch.p:
tangle $*.web $*.ch
pxp -O $*.p > tmp
mv tmp $*.p
.p.o:
$(PC) $(PFLAGS) -c $*.p
all: bibtex
install: bibtex
mv bibtex $(BINDIR)
bibtex: bibtex.o bibext.o
$(PC) $(PFLAGS) -o bibtex bibtex.o bibext.o $(PCLIB)
bibtex.o: bibtex.p bibext.h
bibtex.p: bibtex.web
bibext.o: bibext.c ../../h00vars.h ../../texpaths.h
clean:
rm -f bibtex.p bibtex.o bibtex.pool
rm -f bibext.o
SHAR_EOF
cat << \SHAR_EOF > Makefile.SYS_V
#
# Makefile for BibTeX
#
#
#BINDIR=/usr/stanford/bin
BINDIR=/usr/local/bin
PC = pc
PCLIB =
PFLAGS= -w -Tr
CFLAGS= -O -I../..
.SUFFIXES:
.SUFFIXES: .o .p .c .ch
.ch.o:
tangle $*.web $*.ch
$(PC) $(PFLAGS) -c $*.p
.ch.p:
tangle $*.web $*.ch
pxp -O -L140 $*.p > tmp
mv tmp $*.p
.p.o:
$(PC) $(PFLAGS) -c $*.p
all: bibtex
install: bibtex
mv bibtex $(BINDIR)
bibtex: bibtex.p bibext.o
makebib
bibtex.o: bibtex.p bibext.h
bibtex.p: bibtex.web
bibext.o: bibext.c ../../h00vars.h ../../texpaths.h
clean:
rm -f bibtex.p bibtex.o bibtex.pool
rm -f bibext.o bibtex?.?
SHAR_EOF
cat << \SHAR_EOF > Setup.PYR
# /bin/sh
# arrange things in the ./LaTeX/LaTeXbibtex area for compilation on
# Pyramid OSx machines
cp Makefile.PYR Makefile
cp bibext.PYR.c bibext.c
cp bibtex.PYR.ch bibtex.ch
SHAR_EOF
cat << \SHAR_EOF > Setup.SUN
#!/bin/sh
# arrange things in the ./tex82/LaTeX/LaTeXbibtex area for compilation on
# SUN2 or SUN3 (largely 4.2/3BSD but no longer called that)
cp Makefile.SUN Makefile
cp bibext.BSD4_n.c bibext.c
cp bibtex.BSD4_n.ch bibtex.ch
SHAR_EOF
cat << \SHAR_EOF > Setup.SYS_V
#!/bin/sh
#
cp Makefile.SYS_V Makefile
cp bibsep.SYS_V.sed bibsep.sed
cp bibtex.SYS_V.ch bibtex.ch
cp makebib.SYS_V makebib
SHAR_EOF
cat << \SHAR_EOF > Setup.VAX
#!/bin/sh
# arrange things in the ./LaTeX/LaTeXbibtex area for compilation on
# Vax 4.2/3BSD
cp Makefile.BSD4_n Makefile
cp bibext.BSD4_n.c bibext.c
cp bibtex.BSD4_n.ch bibtex.ch
SHAR_EOF
cat << \SHAR_EOF > bibext.BSD4_n.c
/* external procedures for use with BibTeX */
#include "texpaths.h"
#include "h00vars.h"
char inputpath[MAXINPATHCHARS] = defaultinputpath;
char *getenv();
/*
* setpaths is called to set up the arrays inputpath as follows:
* if the user's environment has a value for TEXINPUTS then use it;
* appropriate value, then use it; otherwise, leave the current value of
* the array (which will be the default path)
*/
setpaths()
{
register char *envpath;
if ((envpath = getenv("TEXINPUTS")) != NULL)
copypath(inputpath,envpath,MAXINPATHCHARS);
}
/*
* copypath(s1,s2,n) copies at most n characters (including the null)
* from string s2 to string s1, giving an error message for paths
* that are too long.
*/
copypath(s1,s2,n)
register char *s1,*s2;
register int n;
{
while ((*s1++ = *s2++) != '\0')
if (--n == 0) {
fprintf(stderr, "! Environment search path is too big\n");
*--s1 = '\0';
return; /* let user continue with truncated path */
}
}
extern char buffer[],xord[];
extern short last; /* pointer into buffer */
/*
* lineread reads from the Pascal text file with iorec pointer filep
* into buffer[0], buffer[1],..., buffer[last-1] (and setting "last").
* Characters are read until a newline is found (which isn't put in the
* buffer) or until the next character would go into buffer[lastlim].
* The characters need to be translated, so really xord[c] is put into
* the buffer when c is read.
* If end-of-file is encountered, the funit field of *filep is set
* appropriately.
*/
lineread(filep, lastlim)
struct iorec *filep;
int lastlim;
{
register c;
register char *cs; /* pointer into buffer where next char goes */
register FILE *iop; /* stdio-style FILE pointer */
int l; /* how many more chars are allowed before buffer overflow */
char *bf; /* hold address of buffer[0] */
iop = filep->fbuf;
bf = cs = &(buffer[0]);
l = lastlim;
/* overflow when next char would go into buffer[lastlim] */
while (--l>=0 && (c = getc(iop))>=0 && c!='\n')
*cs++ = xord[c];
if (c<=0)
filep->funit |= EOFF; /* we hit end-of-file */
last = cs-bf;
}
#define filenamesize 1024 /* should agree with initex.ch */
extern char nameoffile[],realnameoffile[]; /* these have size filenamesize */
/*
* testaccess(amode,filepath)
*
* Test whether or not the file whose name is in the global nameoffile
* can be opened for reading (if mode=READACCESS)
* or writing (if mode=WRITEACCESS).
*
* The filepath argument is one of the ...FILEPATH constants defined below.
* If the filename given in nameoffile does not begin with '/', we try
* prepending all the ':'-separated areanames in the appropriate path to the
* filename until access can be made, if it ever can.
*
* The realnameoffile global array will contain the name that yielded an
* access success.
*/
#define READACCESS 4
#define WRITEACCESS 2
#define NOFILEPATH 0
#define INPUTFILEPATH 1
bool
testaccess(amode,filepath)
int amode,filepath;
{
register bool ok;
register char *p;
char *curpathplace;
int f;
switch(filepath) {
case NOFILEPATH: curpathplace = NULL; break;
case INPUTFILEPATH:
curpathplace = inputpath; break;
}
if (nameoffile[0]=='/') /* file name has absolute path */
curpathplace = NULL;
do {
packrealnameoffile(&curpathplace);
if (amode==READACCESS)
/* use system call "access" to see if we could read it */
if (access(realnameoffile,READACCESS)==0) ok = TRUE;
else ok = FALSE;
else {
/* WRITEACCESS: use creat to see if we could create it, but close
the file again if we're OK, to let pc open it for real */
f = creat(realnameoffile,0666);
if (f>=0) ok = TRUE;
else ok = FALSE;
if (ok)
close(f);
}
} while (!ok && curpathplace != NULL);
if (ok) { /* pad realnameoffile with blanks, as Pascal wants */
for (p = realnameoffile; *p != '\0'; p++)
/* nothing: find end of string */ ;
while (p < &(realnameoffile[filenamesize]))
*p++ = ' ';
}
return (ok);
}
/*
* packrealnameoffile(cpp) makes realnameoffile contain the directory at *cpp,
* followed by '/', followed by the characters in nameoffile up until the
* first blank there, and finally a '\0'. The cpp pointer is left pointing
* at the next directory in the path.
* But: if *cpp == NULL, then we are supposed to use nameoffile as is.
*/
packrealnameoffile(cpp)
char **cpp;
{
register char *p,*realname;
realname = realnameoffile;
if ((p = *cpp)!=NULL) {
while ((*p != ':') && (*p != '\0')) {
*realname++ = *p++;
if (realname == &(realnameoffile[filenamesize-1]))
break;
}
if (*p == '\0') *cpp = NULL; /* at end of path now */
else *cpp = p+1; /* else get past ':' */
*realname++ = '/'; /* separate the area from the name to follow */
}
/* now append nameoffile to realname... */
p = nameoffile;
while (*p != ' ') {
if (realname >= &(realnameoffile[filenamesize-1])) {
fprintf(stderr,"! Full file name is too long\n");
break;
}
*realname++ = *p++;
}
*realname = '\0';
}
/*
** testeof(filep)
**
** Test whether or not the Pascal text file with iorec pointer filep
** has reached end-of-file (when the only I/O on it is done with
** lineread, above).
** We may have to read the next character and unget it to see if perhaps
** the end-of-file is next.
*/
bool
testeof(filep)
register struct iorec *filep;
{
register char c;
register FILE *iop; /* stdio-style FILE pointer */
if (filep->funit & EOFF)
return(TRUE);
else { /* check to see if next is EOF */
iop = filep->fbuf;
c = getc(iop);
if (c<0)
return(TRUE);
else {
ungetc(c,iop);
return(FALSE);
}
}
}
SHAR_EOF
cat << \SHAR_EOF > bibext.PYR.c
/* external procedures for use with BibTeX */
#include "texpaths.h"
#include "h00vars.h"
char inputpath[MAXINPATHCHARS] = defaultinputpath;
char *getenv();
/*
* setpaths is called to set up the arrays inputpath as follows:
* if the user's environment has a value for TEXINPUTS then use it;
* appropriate value, then use it; otherwise, leave the current value of
* the array (which will be the default path)
*/
setpaths()
{
register char *envpath;
if ((envpath = getenv("TEXINPUTS")) != NULL)
copypath(inputpath,envpath,MAXINPATHCHARS);
}
/*
* copypath(s1,s2,n) copies at most n characters (including the null)
* from string s2 to string s1, giving an error message for paths
* that are too long.
*/
copypath(s1,s2,n)
register char *s1,*s2;
register int n;
{
while ((*s1++ = *s2++) != '\0')
if (--n == 0) {
fprintf(stderr, "! Environment search path is too big\n");
*--s1 = '\0';
return; /* let user continue with truncated path */
}
}
extern int buffer[],xord[];
extern int last; /* pointer into buffer */
/*
* lineread reads from the Pascal text file with iorec pointer filep
* into buffer[0], buffer[1],..., buffer[last-1] (and setting "last").
* Characters are read until a newline is found (which isn't put in the
* buffer) or until the next character would go into buffer[lastlim].
* The characters need to be translated, so really xord[c] is put into
* the buffer when c is read.
* If end-of-file is encountered, the funit field of *filep is set
* appropriately.
*/
lineread(filep, lastlim)
struct iorec *filep;
int lastlim;
{
register c;
register int *cs; /* pointer into buffer where next char goes */
register FILE *iop; /* stdio-style FILE pointer */
int l; /* how many more chars are allowed before buffer overflow */
int *bf; /* hold address of buffer[0] */
iop = filep->fbuf;
bf = cs = &(buffer[0]);
l = lastlim;
/* overflow when next char would go into buffer[lastlim] */
while (--l>=0 && (c = getc(iop))>=0 && c!='\n')
*cs++ = xord[c];
if (c<=0)
filep->funit |= EOFF; /* we hit end-of-file */
last = cs-bf;
}
#define filenamesize 1024 /* should agree with initex.ch */
extern char nameoffile[],realnameoffile[]; /* these have size filenamesize */
/*
* testaccess(amode,filepath)
*
* Test whether or not the file whose name is in the global nameoffile
* can be opened for reading (if mode=READACCESS)
* or writing (if mode=WRITEACCESS).
*
* The filepath argument is one of the ...FILEPATH constants defined below.
* If the filename given in nameoffile does not begin with '/', we try
* prepending all the ':'-separated areanames in the appropriate path to the
* filename until access can be made, if it ever can.
*
* The realnameoffile global array will contain the name that yielded an
* access success.
*/
#define READACCESS 4
#define WRITEACCESS 2
#define NOFILEPATH 0
#define INPUTFILEPATH 1
bool
testaccess(amode,filepath)
int amode,filepath;
{
register bool ok;
register char *p;
char *curpathplace;
int f;
switch(filepath) {
case NOFILEPATH: curpathplace = NULL; break;
case INPUTFILEPATH:
curpathplace = inputpath; break;
}
if (nameoffile[0]=='/') /* file name has absolute path */
curpathplace = NULL;
do {
packrealnameoffile(&curpathplace);
if (amode==READACCESS)
/* use system call "access" to see if we could read it */
if (access(realnameoffile,READACCESS)==0) ok = TRUE;
else ok = FALSE;
else {
/* WRITEACCESS: use creat to see if we could create it, but close
the file again if we're OK, to let pc open it for real */
f = creat(realnameoffile,0666);
if (f>=0) ok = TRUE;
else ok = FALSE;
if (ok)
close(f);
}
} while (!ok && curpathplace != NULL);
if (ok) { /* pad realnameoffile with blanks, as Pascal wants */
for (p = realnameoffile; *p != '\0'; p++)
/* nothing: find end of string */ ;
while (p < &(realnameoffile[filenamesize]))
*p++ = ' ';
}
return (ok);
}
/*
* packrealnameoffile(cpp) makes realnameoffile contain the directory at *cpp,
* followed by '/', followed by the characters in nameoffile up until the
* first blank there, and finally a '\0'. The cpp pointer is left pointing
* at the next directory in the path.
* But: if *cpp == NULL, then we are supposed to use nameoffile as is.
*/
packrealnameoffile(cpp)
char **cpp;
{
register char *p,*realname;
realname = realnameoffile;
if ((p = *cpp)!=NULL) {
while ((*p != ':') && (*p != '\0')) {
*realname++ = *p++;
if (realname == &(realnameoffile[filenamesize-1]))
break;
}
if (*p == '\0') *cpp = NULL; /* at end of path now */
else *cpp = p+1; /* else get past ':' */
*realname++ = '/'; /* separate the area from the name to follow */
}
/* now append nameoffile to realname... */
p = nameoffile;
while (*p != ' ') {
if (realname >= &(realnameoffile[filenamesize-1])) {
fprintf(stderr,"! Full file name is too long\n");
break;
}
*realname++ = *p++;
}
*realname = '\0';
}
/*
** testeof(filep)
**
** Test whether or not the Pascal text file with iorec pointer filep
** has reached end-of-file (when the only I/O on it is done with
** lineread, above).
** We may have to read the next character and unget it to see if perhaps
** the end-of-file is next.
*/
bool
testeof(filep)
register struct iorec *filep;
{
register char c;
register FILE *iop; /* stdio-style FILE pointer */
if (filep->funit & EOFF)
return(TRUE);
else { /* check to see if next is EOF */
iop = filep->fbuf;
c = getc(iop);
if (c<0)
return(TRUE);
else {
ungetc(c,iop);
return(FALSE);
}
}
}
SHAR_EOF
cat << \SHAR_EOF > bibext.h
procedure setpaths;
external;
function testaccess(accessmode:integer; filepath:integer): boolean;
external;
function testeof(var f: text): boolean;
external;
procedure lineread(var f: text; lastlim: integer);
external;
SHAR_EOF
cat << \SHAR_EOF > bibsep.SYS_V.sed
/^ procedure/{
s/$/ external;/w bibtex1.h
s/^\( procedure [^(;]*\).*/\1;/
}
/^ function/{
s/$/ external;/w bibtex1.h
s/^\( function [^(:]*\).*/\1;/
}
/^program/,/^const/{
/^const/b co
w bibtex0.h
d
}
:co
/^const/,/^ function inputln/{
/^ function inputln/b t1
w bibtex1.h
d
}
:t1
/^ function inputln/,/^ procedure xinttochr/{
/^ procedure xinttochr/b t2
/^ function inputln/s/^/#include "bibtex1.h"\
/
w bibtex1.p
d
}
:t2
/^ procedure xinttochr/,${
/^ procedure xinttochr/s/^/#include "bibtex0.h"\
#include "bibtex1.h"\
/
w bibtex2.p
d
}
SHAR_EOF
cat << \SHAR_EOF > bibtex.BSD4_n.ch
% Change file for BibTeX for Berkeley UNIX, by H. Trickey
% History:
% 5/28/84 Initial implementation, version 0.41 of BibTeX
% 7/1/84 Version 0.41a of BibTeX.
% 12/17/84 Version 0.97c of BibTeX.
% 2/12/85 Version 0.98c of BibTeX.
% 2/25/85 Newer Version 0.98c of BibTeX
% 3/25/85 Version 0.98f of BibTeX
% 5/23/85 Version 0.98i of BibTeX
% 2/6/88 Version 0.99a of BibTeX (PAM)
% 2/16/88 Version 0.99c of BibTeX (PAM)
@x banner
@d banner=='This is BibTeX, Version 0.99c' {printed when the program starts}
@y
@d banner=='This is BibTeX, Version 0.99c for Berkeley UNIX'
{printed when the program starts}
@z
@x terminal
@d term_out == tty
@d term_in == tty
@y
@d term_out == output
@d term_in == input
@z
@x debug..gubed, stat..tats
@d debug == @{ { remove the `|@{|' when debugging }
@d gubed == @t@>@} { remove the `|@}|' when debugging }
@f debug == begin
@f gubed == end
@#
@d stat == @{ { remove the `|@{|' when keeping statistics }
@d tats == @t@>@} { remove the `|@}|' when keeping statistics }
@f stat == begin
@f tats == end
@y
@d debug == @{ { remove the `|@{|' when debugging }
@d gubed == @t@>@} { remove the `|@}|' when debugging }
@f debug == begin
@f gubed == end
@#
@d stat == @{ { remove the `|@{|' when keeping statistic }
@d tats == @t@>@} { remove the `|@}|' when keeping statistic }
@f stat==begin
@f tats==end
@z
@x program header
program BibTEX; {all files are opened dynamically}
label close_up_shop,@!exit_program @<Labels in the outer block@>;
const @<Constants in the outer block@>
type @<Types in the outer block@>
var @<Globals in the outer block@>@;
@y
program BibTEX(input,output);
label close_up_shop,@!exit_program @<Labels in the outer block@>;
const @<Constants in the outer block@>
type @<Types in the outer block@>
var @<Globals in the outer block@>
@\@=#include "bibext.h"@>@\ {declarations for external C procedures}
@z
@x compiler directives
@{@&$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, catch arithmetic overflow, no debug overhead}
@!debug @=(*C+*)@>@+ gubed {but turn everything on when debugging}
@z
@x increase buf_size
@!buf_size=1000; {maximum number of characters in an input line (or string)}
@y
@!buf_size=3000; {maximum number of characters in an input line (or string)}
@z
@x increase pool_size
@!pool_size=65000; {maximum number of characters in strings}
@y
@!pool_size=200000; {maximum number of characters in strings}
@z
@x increase file_name_size
@d file_name_size=40 {file names shouldn't be longer than this}
@y
@d file_name_size=1024 {file names shouldn't be longer than this}
@z
@x alpha_file type
@!alpha_file=packed file of text_char; {files that contain textual data}
@y
@!alpha_file=text; {files that contain textual data}
@z
@x declare real_name_of_file
|name_of_file|. \BibTeX\ does no case conversion for file names.
@<Globals in the outer block@>=
@!name_of_file:packed array[1..file_name_size] of char;
{on some systems this is a \&{record} variable}
@y
|name_of_file|. \BibTeX\ does no case conversion for file names.
The Berkeley UNIX version uses search paths to look for files to open.
We use |real_name_of_file| to hold the |name_of_file| with a directory name
from the path in front of it.
@<Globals in the outer block@>=
@!name_of_file,@!real_name_of_file:packed array[1..file_name_size] of char;
@z
@x opening files
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 `\ignorespaces|packed
array[@t\<\\{any}>@>] of text_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.
\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
@<Procedures and functions for file-system interacting@>=
function erstat(var f:file):integer; extern; {in the runtime library}
@#@t\2@>
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;
@y
@ The \ph\ compiler with which the present version of \TeX\ was prepared has
extended the rules of \PASCAL\ in a very convenient way for file opening.
Berkeley {\mc UNIX} \PASCAL\ isn't nearly as nice as \ph.
Normally, it bombs out if a file open fails.
An external C procedure, |test_access| is used to check whether or not the
open will work. It is declared in the ``ext.h'' include file, and it returns
|true| or |false|. The |name_of_file| global holds the file name whose access
is to be tested.
The first parameter for |test_access| is the access mode,
one of |read_access_mode| or |write_access_mode|.
We also implement path searching in |test_access|: its second parameter is
one of the ``file path'' constants defined below. If |name_of_file|
doesn't start with |'/'| then |test_access| tries prepending pathnames
from the appropriate path list until success or the end of path list
is reached.
On return, |real_name_of_file| contains the original name with the path
that succeeded (if any) prepended. It is the name used in the various
open procedures.
Path searching is not done for output files.
@d read_access_mode=4 {``read'' mode for |test_access|}
@d write_access_mode=2 {``write'' mode for |test_access|}
@d no_file_path=0 {no path searching should be done}
@d input_file_path=1 {path specifier for input files}
@<Procedures and functions for file-system interacting@>=
function a_open_in(var f:alpha_file):boolean;
{open a text file for input}
var @!ok:boolean;
begin
if test_access(read_access_mode,input_file_path) then
begin reset(f,real_name_of_file); ok:=true@+end
else
ok:=false;
a_open_in:=ok;
end;
@#
function a_open_out(var f:alpha_file):boolean;
{open a text file for output}
var @!ok:boolean;
begin
if test_access(write_access_mode,no_file_path) then
begin rewrite(f,real_name_of_file); ok:=true @+end
else ok:=false;
a_open_out:=ok;
end;
@z
@x closing files
Files can be closed with the \ph\ routine `|close(f)|', which 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.
@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file); {close a text file}
begin close(f);
end;
@y
Files can be closed with the \ph\ routine `|close(f)|', which should
be used when all input or output with respect to |f| has been
completed.
With the pc library, files will be automatically closed when the program stops
and when one reopens them.
@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file); {close a text file}
begin do_nothing;
end;
@z
@x faster input_ln
Standard \PASCAL\ says that a file should have |eoln| immediately
before |eof|, but \BibTeX\ needs only a weaker restriction: If |eof|
occurs in the middle of a line, the system function |eoln| should return
a |true| result (even though |f^| will be undefined).
@<Procedures and functions for all file I/O, error messages, and such@>=
function input_ln(var f:alpha_file) : boolean;
{inputs the next line or returns |false|}
label loop_exit;
begin
last:=0;
if (eof(f)) then input_ln:=false
else
begin
while (not eoln(f)) do
begin
if (last >= buf_size) then
buffer_overflow;
buffer[last]:=xord[f^];
get(f); incr(last);
end;
get(f);
while (last > 0) do {remove trailing |white_space|}
if (lex_class[buffer[last-1]] = white_space) then
decr(last)
else
goto loop_exit;
loop_exit:
input_ln:=true;
end;
end;
@y
With Berkeley {\mc UNIX} we call an external C procedure, |line_read|.
That routine fills |buffer| from |0| onwards with the |xord|'ed values
of the next line, setting |last| appropriately. It will stop if
|last=buf_size|, and the following will cause an ``overflow'' abort.
If one uses |input_ln| on a file, the normal |read|
and |get| routines shouldn't be used, nor the |eof| and |eoln| tests.
End of file can be tested with the external function |test_eof|.
@<Procedures and functions for all file I/O, error messages, and such@>=
function input_ln(var f:alpha_file) : boolean;
{inputs the next line or returns |false|}
label loop_exit;
begin
last:=0;
if test_eof(f) then input_ln:=false
else
begin
line_read(f,buf_size);
if last>=buf_size then
overflow('buffer size ',buf_size);
while (last > 0) do {remove trailing |white_space|}
if lex_class[buffer[last-1]] = white_space then
decr(last)
else
goto loop_exit;
loop_exit:
input_ln:=true;
end;
end;
@z
@x getting top-level name: it comes from command line
These modules read the name of the top-level \.{.aux} file. Some
systems will try to find this on the command line; if it's not there
it will come from the user's terminal. In either case, the name goes
into the |char| array |name_of_file|, and the files relevant to this
name are opened.
@d aux_found=41 {go here when the \.{.aux} name is legit}
@d aux_not_found=46 {go here when it's not}
@y
These modules read the name of the top-level \.{.aux} file. Some
systems will try to find this on the command line; if it's not there
it will come from the user's terminal. In either case, the name goes
into the |char| array |name_of_file|, and the files relevant to this
name are opened.
@z
@x redirect goto from |sam_you_made_the_file_name_too_long|
@d sam_you_made_the_file_name_too_long == begin
sam_too_long_file_name_print;
goto aux_not_found;
end
@y
@d sam_you_made_the_file_name_too_long == begin
sam_too_long_file_name_print;
goto exit_program
end
@z
@x redirect goto from |sam_you_made_the_file_name_wrong|
@d sam_you_made_the_file_name_wrong == begin
sam_wrong_file_name_print;
goto aux_not_found;
end
@y
@d sam_you_made_the_file_name_wrong == begin
sam_wrong_file_name_print;
goto exit_program;
end
@z
@x reading the command line
This procedure consists of a loop that reads and processes a (nonnull)
\.{.aux} file name. It's this module and the next two that must be
changed on those systems using command-line arguments. Note: The
|term_out| and |term_in| files are system dependent.
@<Procedures and functions for the reading and processing of input files@>=
procedure get_the_top_level_aux_file_name;
label aux_found,@!aux_not_found;
var @<Variables for possible command-line processing@>@/
begin
check_cmnd_line := false; {many systems will change this}
loop
begin
if (check_cmnd_line) then
@<Process a possible command line@>
else
begin
write (term_out,'Please type input file name (no extension)--');
if (eoln(term_in)) then {so the first |read| works}
read_ln (term_in);
aux_name_length := 0;
while (not eoln(term_in)) do
begin
if (aux_name_length = file_name_size) then
begin
while (not eoln(term_in)) do {discard the rest of the line}
get(term_in);
sam_you_made_the_file_name_too_long;
end;
incr(aux_name_length);
name_of_file[aux_name_length] := term_in^;
get(term_in);
end;
end;
@<Handle this \.{.aux} name@>;
aux_not_found:
check_cmnd_line := false;
end;
aux_found: {now we're ready to read the \.{.aux} file}
end;
@y
This module gets the file name from the UNIX command line, adds the various
extensions, and tries to open the files with the resulting name.
If there is a problem, just stop.
@<Procedures and functions for the reading and processing of input files@>=
procedure get_the_top_level_aux_file_name;
begin
setpaths; {sets up things for path searching}
if argc <> 2 then begin
write_ln(term_out,'Usage: bibtex <top-level-aux-file (no extension)>');
goto exit_program;
end;
aux_name_length:=1;
argv(1,name_of_file);
while (name_of_file[aux_name_length]<>' ')and (aux_name_length<file_name_size)
do incr(aux_name_length);
decr(aux_name_length);
@<Handle this \.{.aux} name@>;
end;
@z
@x
goto aux_found;
@y
@z
@x eof-->test_eof
while (not eof(cur_bib_file)) do
@y
while (not test_eof(cur_bib_file)) do
@z
SHAR_EOF
cat << \SHAR_EOF > bibtex.PYR.ch
% Change file for BibTeX for Berkeley UNIX, by H. Trickey
% History:
% 5/28/84 Initial implementation, version 0.41 of BibTeX
% 7/1/84 Version 0.41a of BibTeX.
% 12/17/84 Version 0.97c of BibTeX.
% 2/12/85 Version 0.98c of BibTeX.
% 2/25/85 Newer Version 0.98c of BibTeX
% 3/25/85 Version 0.98f of BibTeX
% 5/23/85 Version 0.98i of BibTeX
% 12/24/87 (SWS)Corrected for Pyramid 4.0 Pascal compiler
% 2/6/88 Version 0.99a of BibTeX (PAM)
% 2/16/88 Version 0.99c of BibTeX (PAM)
@x banner
@d banner=='This is BibTeX, Version 0.99c' {printed when the program starts}
@y
@d banner=='This is BibTeX, Version 0.99c for Berkeley UNIX'
{printed when the program starts}
@z
@x term_out-->output
Terminal output goes to the file |term_out|, while terminal input
comes from |term_in|. On our system, these (system-dependent) files
are already opened at the beginning of the program, and have the same
real name.
@d term_out == tty
@d term_in == tty
@y
Terminal output goes to the (system-dependent) file |term_out|, while
terminal input comes from |term_in|. On our system, they are already
opened at the beginning of the program, and have the same real name.
We define |term_out| to be |output|. |term_in| shouldn't be needed.
@d term_out == output
@z
@x debug..gubed, stat..tats
@d debug == @{ { remove the `|@{|' when debugging }
@d gubed == @t@>@} { remove the `|@}|' when debugging }
@f debug == begin
@f gubed == end
@#
@d stat == @{ { remove the `|@{|' when keeping statistics }
@d tats == @t@>@} { remove the `|@}|' when keeping statistics }
@f stat == begin
@f tats == end
@y
@d debug == @{ { remove the `|@{|' when debugging }
@d gubed == @t@>@} { remove the `|@}|' when debugging }
@f debug == begin
@f gubed == end
@#
@d stat == @{ { remove the `|@{|' when keeping statistic }
@d tats == @t@>@} { remove the `|@}|' when keeping statistic }
@f stat==begin
@f tats==end
@z
@x program header
program BibTEX; {all files are opened dynamically}
label close_up_shop,@!exit_program @<Labels in the outer block@>;
const @<Constants in the outer block@>
type @<Types in the outer block@>
var @<Globals in the outer block@>@;
@y
program BibTEX(input,output);
label close_up_shop,@!exit_program @<Labels in the outer block@>;
const @<Constants in the outer block@>
type @<Types in the outer block@>
var @<Globals in the outer block@>
@\@=#include "bibext.h"@>@\ {declarations for external C procedures}
@z
@x compiler directives
@{@&$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, catch arithmetic overflow, no debug overhead}
@!debug @=(*C+*)@>@+ gubed {but turn everything on when debugging}
@z
@x increase buf_size
@!buf_size=1000; {maximum number of characters in an input line (or string)}
@y
@!buf_size=3000; {maximum number of characters in an input line (or string)}
@z
@x increase pool_size
@!pool_size=65000; {maximum number of characters in strings}
@y
@!pool_size=200000; {maximum number of characters in strings}
@z
@x increase file_name_size
@d file_name_size=40 {file names shouldn't be longer than this}
@y
@d file_name_size=1024 {file names shouldn't be longer than this}
@z
@x alpha_file type
@!alpha_file=packed file of text_char; {files that contain textual data}
@y
@!alpha_file=text; {files that contain textual data}
@z
@x declare real_name_of_file
|name_of_file|. \BibTeX\ does no case conversion for file names.
@<Globals in the outer block@>=
@!name_of_file:packed array[1..file_name_size] of char;
{on some systems this is a \&{record} variable}
@y
|name_of_file|. \BibTeX\ does no case conversion for file names.
The Berkeley UNIX version uses search paths to look for files to open.
We use |real_name_of_file| to hold the |name_of_file| with a directory name
from the path in front of it.
@<Globals in the outer block@>=
@!name_of_file,@!real_name_of_file:packed array[1..file_name_size] of char;
@z
@x opening files
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 `\ignorespaces|packed
array[@t\<\\{any}>@>] of text_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.
\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
@<Procedures and functions for file-system interacting@>=
function erstat(var f:file):integer; extern; {in the runtime library}
@#@t\2@>
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;
@y
@ The \ph\ compiler with which the present version of \TeX\ was prepared has
extended the rules of \PASCAL\ in a very convenient way for file opening.
Berkeley {\mc UNIX} \PASCAL\ isn't nearly as nice as \ph.
Normally, it bombs out if a file open fails.
An external C procedure, |test_access| is used to check whether or not the
open will work. It is declared in the ``ext.h'' include file, and it returns
|true| or |false|. The |name_of_file| global holds the file name whose access
is to be tested.
The first parameter for |test_access| is the access mode,
one of |read_access_mode| or |write_access_mode|.
We also implement path searching in |test_access|: its second parameter is
one of the ``file path'' constants defined below. If |name_of_file|
doesn't start with |'/'| then |test_access| tries prepending pathnames
from the appropriate path list until success or the end of path list
is reached.
On return, |real_name_of_file| contains the original name with the path
that succeeded (if any) prepended. It is the name used in the various
open procedures.
Path searching is not done for output files.
@d read_access_mode=4 {``read'' mode for |test_access|}
@d write_access_mode=2 {``write'' mode for |test_access|}
@d no_file_path=0 {no path searching should be done}
@d input_file_path=1 {path specifier for input files}
@<Procedures and functions for file-system interacting@>=
function a_open_in(var f:alpha_file):boolean;
{open a text file for input}
var @!ok:boolean;
begin
if test_access(read_access_mode,input_file_path) then
begin reset(f,real_name_of_file); ok:=true@+end
else
ok:=false;
a_open_in:=ok;
end;
@#
function a_open_out(var f:alpha_file):boolean;
{open a text file for output}
var @!ok:boolean;
begin
if test_access(write_access_mode,no_file_path) then
begin rewrite(f,real_name_of_file); ok:=true @+end
else ok:=false;
a_open_out:=ok;
end;
@z
@x closing files
Files can be closed with the \ph\ routine `|close(f)|', which 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.
@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file); {close a text file}
begin close(f);
end;
@y
Files can be closed with the \ph\ routine `|close(f)|', which should
be used when all input or output with respect to |f| has been
completed.
With the pc library, files will be automatically closed when the program stops
and when one reopens them.
@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file); {close a text file}
begin do_nothing;
end;
@z
@x faster input_ln
Standard \PASCAL\ says that a file should have |eoln| immediately
before |eof|, but \BibTeX\ needs only a weaker restriction: If |eof|
occurs in the middle of a line, the system function |eoln| should return
a |true| result (even though |f^| will be undefined).
@<Procedures and functions for all file I/O, error messages, and such@>=
function input_ln(var f:alpha_file) : boolean;
{inputs the next line or returns |false|}
label loop_exit;
begin
last:=0;
if (eof(f)) then input_ln:=false
else
begin
while (not eoln(f)) do
begin
if (last >= buf_size) then
buffer_overflow;
buffer[last]:=xord[f^];
get(f); incr(last);
end;
get(f);
while (last > 0) do {remove trailing |white_space|}
if (lex_class[buffer[last-1]] = white_space) then
decr(last)
else
goto loop_exit;
loop_exit:
input_ln:=true;
end;
end;
@y
With Berkeley {\mc UNIX} we call an external C procedure, |line_read|.
That routine fills |buffer| from |0| onwards with the |xord|'ed values
of the next line, setting |last| appropriately. It will stop if
|last=buf_size|, and the following will cause an ``overflow'' abort.
If one uses |input_ln| on a file, the normal |read|
and |get| routines shouldn't be used, nor the |eof| and |eoln| tests.
End of file can be tested with the external function |test_eof|.
@<Procedures and functions for all file I/O, error messages, and such@>=
function input_ln(var f:alpha_file) : boolean;
{inputs the next line or returns |false|}
label loop_exit;
begin
last:=0;
if test_eof(f) then input_ln:=false
else
begin
line_read(f,buf_size);
if last>=buf_size then
overflow('buffer size ',buf_size);
while (last > 0) do {remove trailing |white_space|}
if lex_class[buffer[last-1]] = white_space then
decr(last)
else
goto loop_exit;
loop_exit:
input_ln:=true;
end;
end;
@z
@x getting top-level name: it comes from command line
These modules read the name of the top-level \.{.aux} file. Some
systems will try to find this on the command line; if it's not there
it will come from the user's terminal. In either case, the name goes
into the |char| array |name_of_file|, and the files relevant to this
name are opened.
@d aux_found=41 {go here when the \.{.aux} name is legit}
@d aux_not_found=46 {go here when it's not}
@y
These modules read the name of the top-level \.{.aux} file. Some
systems will try to find this on the command line; if it's not there
it will come from the user's terminal. In either case, the name goes
into the |char| array |name_of_file|, and the files relevant to this
name are opened.
@z
@x redirect goto from |sam_you_made_the_file_name_too_long|
@d sam_you_made_the_file_name_too_long == begin
sam_too_long_file_name_print;
goto aux_not_found;
end
@y
@d sam_you_made_the_file_name_too_long == begin
sam_too_long_file_name_print;
goto exit_program
end
@z
@x redirect goto from |sam_you_made_the_file_name_wrong|
@d sam_you_made_the_file_name_wrong == begin
sam_wrong_file_name_print;
goto aux_not_found;
end
@y
@d sam_you_made_the_file_name_wrong == begin
sam_wrong_file_name_print;
goto exit_program;
end
@z
@x reading the command line
This procedure consists of a loop that reads and processes a (nonnull)
\.{.aux} file name. It's this module and the next two that must be
changed on those systems using command-line arguments. Note: The
|term_out| and |term_in| files are system dependent.
@<Procedures and functions for the reading and processing of input files@>=
procedure get_the_top_level_aux_file_name;
label aux_found,@!aux_not_found;
var @<Variables for possible command-line processing@>@/
begin
check_cmnd_line := false; {many systems will change this}
loop
begin
if (check_cmnd_line) then
@<Process a possible command line@>
else
begin
write (term_out,'Please type input file name (no extension)--');
if (eoln(term_in)) then {so the first |read| works}
read_ln (term_in);
aux_name_length := 0;
while (not eoln(term_in)) do
begin
if (aux_name_length = file_name_size) then
begin
while (not eoln(term_in)) do {discard the rest of the line}
get(term_in);
sam_you_made_the_file_name_too_long;
end;
incr(aux_name_length);
name_of_file[aux_name_length] := term_in^;
get(term_in);
end;
end;
@<Handle this \.{.aux} name@>;
aux_not_found:
check_cmnd_line := false;
end;
aux_found: {now we're ready to read the \.{.aux} file}
end;
@y
This module gets the file name from the UNIX command line, adds the various
extensions, and tries to open the files with the resulting name.
If there is a problem, just stop.
@<Procedures and functions for the reading and processing of input files@>=
procedure get_the_top_level_aux_file_name;
begin
setpaths; {sets up things for path searching}
if argc <> 2 then begin
write_ln(term_out,'Usage: bibtex <top-level-aux-file (no extension)>');
goto exit_program;
end;
aux_name_length:=1;
argv(1,name_of_file);
while (name_of_file[aux_name_length]<>' ')and (aux_name_length<file_name_size)
do incr(aux_name_length);
decr(aux_name_length);
@<Handle this \.{.aux} name@>;
end;
@z
@x
goto aux_found;
@y
@z
@x eof-->test_eof
while (not eof(cur_bib_file)) do
@y
while (not test_eof(cur_bib_file)) do
@z
SHAR_EOF
cat << \SHAR_EOF > bibtex.SYS_V.ch
% Change file for BibTeX for System V UNIX.
% based on Berkeley UNIX Change file, by H. Trickey
% History:
% 5/28/84 Initial implementation, version 0.41 of BibTeX
% 7/1/84 Version 0.41a of BibTeX.
% 12/17/84 Version 0.97c of BibTeX.
% 2/12/85 Version 0.98c of BibTeX.
% 2/25/85 Newer Version 0.98c of BibTeX
% 3/25/85 Version 0.98f of BibTeX
% 5/23/85 Version 0.98i of BibTeX
% 3/23/87 Mods for System V (lks)
% 2/6/88 Version 0.99a of BibTeX (PAM)
% 2/16/88 Version 0.99c of BibTeX (PAM)
@x banner
@d banner=='This is BibTeX, Version 0.99c' {printed when the program starts}
@y
@d banner=='This is BibTeX, Version 0.99c for System V UNIX'
{printed when the program starts}
@z
@x terminal
@d term_out == tty
@d term_in == tty
@y
@d term_out == output
@d term_in == input
@z
@x debug..gubed, stat..tats
@d debug == @{ { remove the `|@{|' when debugging }
@d gubed == @t@>@} { remove the `|@}|' when debugging }
@f debug == begin
@f gubed == end
@#
@d stat == @{ { remove the `|@{|' when keeping statistics }
@d tats == @t@>@} { remove the `|@}|' when keeping statistics }
@f stat == begin
@f tats == end
@y
@d debug == @{ { remove the `|@{|' when debugging }
@d gubed == @t@>@} { remove the `|@}|' when debugging }
@f debug == begin
@f gubed == end
@#
@d stat == @{ { remove the `|@{|' when keeping statistic }
@d tats == @t@>@} { remove the `|@}|' when keeping statistic }
@f stat==begin
@f tats==end
@z
@x
|log_file| and terminal.
@y
|log_file| and terminal.
@d UNIXexit==e@&x@&i@&t
@z
@x program header
program BibTEX; {all files are opened dynamically}
label close_up_shop,@!exit_program @<Labels in the outer block@>;
const @<Constants in the outer block@>
type @<Types in the outer block@>
var @<Globals in the outer block@>@;
@y
program BibTEX(input,output);
label close_up_shop,@!exit_program @<Labels in the outer block@>;
const @<Constants in the outer block@>
type @<Types in the outer block@>
var @<Globals in the outer block@>
@\@=#include "bibext.h"@>@\ {declarations for external C procedures}
@z
@x
exit_program:
@y
exit_program:
UNIXexit(0);
@z
@x
goto exit_program;
@y
UNIXexit(1);
@z
@x increase buf_size
@!buf_size=1000; {maximum number of characters in an input line (or string)}
@y
@!buf_size=3000; {maximum number of characters in an input line (or string)}
@z
@x increase pool_size
@!pool_size=65000; {maximum number of characters in strings}
@y
@!pool_size=200000; {maximum number of characters in strings}
@z
@x increase file_name_size
@d file_name_size=40 {file names shouldn't be longer than this}
@y
@d file_name_size=1024 {file names shouldn't be longer than this}
@z
@x alpha_file type
@!alpha_file=packed file of text_char; {files that contain textual data}
@y
@!alpha_file=text; {files that contain textual data}
@z
@x declare real_name_of_file
|name_of_file|. \BibTeX\ does no case conversion for file names.
@<Globals in the outer block@>=
@!name_of_file:packed array[1..file_name_size] of char;
{on some systems this is a \&{record} variable}
@y
|name_of_file|. \BibTeX\ does no case conversion for file names.
The System V UNIX version uses search paths to look for files to open.
We use |real_name_of_file| to hold the |name_of_file| with a directory name
from the path in front of it.
@<Globals in the outer block@>=
@!name_of_file,@!real_name_of_file:packed array[1..file_name_size] of char;
@z
@x opening files
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 `\ignorespaces|packed
array[@t\<\\{any}>@>] of text_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.
\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
@<Procedures and functions for file-system interacting@>=
function erstat(var f:file):integer; extern; {in the runtime library}
@#@t\2@>
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;
@y
@ The \ph\ compiler with which the present version of \TeX\ was prepared has
extended the rules of \PASCAL\ in a very convenient way for file opening.
System V {\mc UNIX} \PASCAL\ isn't nearly as nice as \ph.
Normally, it bombs out if a file open fails.
An external C procedure, |test_access| is used to check whether or not the
open will work. It is declared in the ``ext.h'' include file, and it returns
|true| or |false|. The |name_of_file| global holds the file name whose access
is to be tested.
The first parameter for |test_access| is the access mode,
one of |read_access_mode| or |write_access_mode|.
We also implement path searching in |test_access|: its second parameter is
one of the ``file path'' constants defined below. If |name_of_file|
doesn't start with |'/'| then |test_access| tries prepending pathnames
from the appropriate path list until success or the end of path list
is reached.
On return, |real_name_of_file| contains the original name with the path
that succeeded (if any) prepended. It is the name used in the various
open procedures.
Path searching is not done for output files.
@d read_access_mode=4 {``read'' mode for |test_access|}
@d write_access_mode=2 {``write'' mode for |test_access|}
@d no_file_path=0 {no path searching should be done}
@d input_file_path=1 {path specifier for input files}
@<Procedures and functions for file-system interacting@>=
function a_open_in(var f:alpha_file):boolean;
{open a text file for input}
var @!ok:boolean;
begin
if test_access(read_access_mode,input_file_path) then
begin reset(f,real_name_of_file); ok:=true@+end
else
ok:=false;
a_open_in:=ok;
end;
@#
function a_open_out(var f:alpha_file):boolean;
{open a text file for output}
var @!ok:boolean;
begin
if test_access(write_access_mode,no_file_path) then
begin rewrite(f,real_name_of_file); ok:=true @+end
else ok:=false;
a_open_out:=ok;
end;
@z
@x closing files
Files can be closed with the \ph\ routine `|close(f)|', which 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.
@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file); {close a text file}
begin close(f);
end;
@y
Files can be closed with the \ph\ routine `|close(f)|', which should
be used when all input or output with respect to |f| has been
completed.
With the pc library, files will be automatically closed when the program stops
and when one reopens them.
@<Procedures and functions for file-system interacting@>=
procedure a_close(var f:alpha_file); {close a text file}
begin do_nothing;
end;
@z
% remove non-local goto's (allows source to separated in pieces)
@x
@d confusion(#)==begin {fatal error---close up shop}
print (#);
print_confusion;
goto close_up_shop;
end
@y
@d confusion(#)==begin {fatal error---close up shop}
print_ln(#);
trace_and_stat_printing;
a_close(log_file);
UNIXexit(1);
end
@z
@x faster input_ln
Standard \PASCAL\ says that a file should have |eoln| immediately
before |eof|, but \BibTeX\ needs only a weaker restriction: If |eof|
occurs in the middle of a line, the system function |eoln| should return
a |true| result (even though |f^| will be undefined).
@<Procedures and functions for all file I/O, error messages, and such@>=
function input_ln(var f:alpha_file) : boolean;
{inputs the next line or returns |false|}
label loop_exit;
begin
last:=0;
if (eof(f)) then input_ln:=false
else
begin
while (not eoln(f)) do
begin
if (last >= buf_size) then
buffer_overflow;
buffer[last]:=xord[f^];
get(f); incr(last);
end;
get(f);
while (last > 0) do {remove trailing |white_space|}
if (lex_class[buffer[last-1]] = white_space) then
decr(last)
else
goto loop_exit;
loop_exit:
input_ln:=true;
end;
end;
@y
With System V {\mc UNIX} we call an external C procedure, |line_read|.
That routine fills |buffer| from |0| onwards with the |xord|'ed values
of the next line, setting |last| appropriately. It will stop if
|last=buf_size|, and the following will cause an ``overflow'' abort.
If one uses |input_ln| on a file, the normal |read|
and |get| routines shouldn't be used, nor the |eof| and |eoln| tests.
End of file can be tested with the external function |test_eof|.
@<Procedures and functions for all file I/O, error messages, and such@>=
function input_ln(var f:alpha_file) : boolean;
{inputs the next line or returns |false|}
label loop_exit;
begin
last:=0;
if test_eof(f) then input_ln:=false
else
begin
line_read(f,buf_size);
if last>=buf_size then
overflow('buffer size ',buf_size);
while (last > 0) do {remove trailing |white_space|}
if lex_class[buffer[last-1]] = white_space then
decr(last)
else
goto loop_exit;
loop_exit:
input_ln:=true;
end;
end;
@z
@x getting top-level name: it comes from command line
These modules read the name of the top-level \.{.aux} file. Some
systems will try to find this on the command line; if it's not there
it will come from the user's terminal. In either case, the name goes
into the |char| array |name_of_file|, and the files relevant to this
name are opened.
@d aux_found=41 {go here when the \.{.aux} name is legit}
@d aux_not_found=46 {go here when it's not}
@y
These modules read the name of the top-level \.{.aux} file. Some
systems will try to find this on the command line; if it's not there
it will come from the user's terminal. In either case, the name goes
into the |char| array |name_of_file|, and the files relevant to this
name are opened.
@z
@x redirect goto from |sam_you_made_the_file_name_too_long|
@d sam_you_made_the_file_name_too_long == begin
sam_too_long_file_name_print;
goto aux_not_found;
end
@y
@d sam_you_made_the_file_name_too_long == begin
sam_too_long_file_name_print;
UNIXexit(1)
end
@z
@x redirect goto from |sam_you_made_the_file_name_wrong|
@d sam_you_made_the_file_name_wrong == begin
sam_wrong_file_name_print;
goto aux_not_found;
end
@y
@d sam_you_made_the_file_name_wrong == begin
sam_wrong_file_name_print;
UNIXexit(1);
end
@z
@x reading the command line
This procedure consists of a loop that reads and processes a (nonnull)
\.{.aux} file name. It's this module and the next two that must be
changed on those systems using command-line arguments. Note: The
|term_out| and |term_in| files are system dependent.
@<Procedures and functions for the reading and processing of input files@>=
procedure get_the_top_level_aux_file_name;
label aux_found,@!aux_not_found;
var @<Variables for possible command-line processing@>@/
begin
check_cmnd_line := false; {many systems will change this}
loop
begin
if (check_cmnd_line) then
@<Process a possible command line@>
else
begin
write (term_out,'Please type input file name (no extension)--');
if (eoln(term_in)) then {so the first |read| works}
read_ln (term_in);
aux_name_length := 0;
while (not eoln(term_in)) do
begin
if (aux_name_length = file_name_size) then
begin
while (not eoln(term_in)) do {discard the rest of the line}
get(term_in);
sam_you_made_the_file_name_too_long;
end;
incr(aux_name_length);
name_of_file[aux_name_length] := term_in^;
get(term_in);
end;
end;
@<Handle this \.{.aux} name@>;
aux_not_found:
check_cmnd_line := false;
end;
aux_found: {now we're ready to read the \.{.aux} file}
end;
@y
This module gets the file name from the UNIX command line, adds the various
extensions, and tries to open the files with the resulting name.
If there is a problem, just stop.
@<Procedures and functions for the reading and processing of input files@>=
procedure get_the_top_level_aux_file_name;
begin
setpaths; {sets up things for path searching}
if argc <> 2 then begin
write_ln(term_out,'Usage: bibtex <top-level-aux-file (no extension)>');
UNIXexit(1);
end;
aux_name_length:=1;
argv(2,name_of_file);
while (name_of_file[aux_name_length]<>' ')and (aux_name_length<file_name_size)
do incr(aux_name_length);
decr(aux_name_length);
@<Handle this \.{.aux} name@>;
end;
@z
@x
goto aux_found;
@y
@z
% eliminate non-local goto's (yucch)
@x
@!bst_line_num : integer; {line number of the \.{.bst} file}
@y
@!bst_line_num : integer; {line number of the \.{.bst} file}
@!bst_done_flag: boolean;
@z
@x
procedure bst_err_print_and_look_for_blank_line;
@y
procedure bst_err_print_and_look_for_blank_line;
label exit;
@z
@x
goto bst_done
@y
begin bst_done_flag:=true; return end
@z
@x
end;
@y
exit:
end;
@z
@x
if (bst_str = 0) then {there's no \.{.bst} file to read}
@y
bst_done_flag:=false;
if (bst_str = 0) then {there's no \.{.bst} file to read}
@z
@x
get_bst_command_and_process;
@y
get_bst_command_and_process;
if bst_done_flag then goto bst_done;
@z
@x eof-->test_eof
while (not eof(cur_bib_file)) do
@y
while (not test_eof(cur_bib_file)) do
@z
SHAR_EOF
cat << \SHAR_EOF > makebib.SYS_V
set -x
# change the following to remove intermediate files
RM=echo
# definitions needed for Pascal compilation
PC0=/usr/lib/pc0
PC1=/usr/lib/pc1
PC2=/usr/lib/pc2
# compile with no range check
PC0OPTS="-T r"
# where assembler temporaries are put
TMPDIR=/usr/tmp
export TMPDIR
name=bibtex
# break up the monolithic pascal source into
# six pieces. this prevents the System V Pascal
# compiler or assembler from running out of internal
# table space.
sed -f bibsep.sed <$name.p
# simulate pc -c on each individual piece.
# we don't use pc because it insists on placing temporaries
# in /tmp, and we don't have much disk space there.
# see also the definition of TMPDIR above.
for i in 1 2
do
piece=${name}$i
$PC0 -o $piece.0 $PC0OPTS $piece.p
case $? in
0)
$PC1 <$piece.0 >$piece.s
$PC2 <$piece.s >$piece.0
as -o $piece.o $piece.0
;;
1)
$PC1 <$piece.0 >$piece.s
# can not run optimizer
as -o $piece.o $piece.s
;;
esac
$RM $piece.0 $piece.s
done
pc -o bibtex bibtex2.o bibtex1.o bibext.o
SHAR_EOF
# End of shell archive
exit 0