DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T U

⟦960056487⟧ TextFile

    Length: 59348 (0xe7d4)
    Types: TextFile
    Notes: Uncompressed file

Derivation

└─⟦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⟧ 

TextFile

#	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