xref: /csrg-svn/contrib/bib/src/bib.c (revision 17247)
113109Srrh #ifndef lint
2*17247Srrh static char sccsid[] = "@(#)bib.c	2.7	10/12/84";
313109Srrh #endif not lint
415066Sgarrison /*
515066Sgarrison         Bib - bibliographic formatter
613109Srrh 
715066Sgarrison         Authored by: Tim Budd, University of Arizona, 1983.
815066Sgarrison                 lookup routines written by gary levin 2/82
915066Sgarrison 
1015066Sgarrison                 version 7/4/83
1115066Sgarrison 
1215066Sgarrison         Various modifications suggested by:
1315066Sgarrison                 David Cherveny - Duke University Medical Center
1415066Sgarrison                 Phil Garrison - UC Berkeley
1515066Sgarrison                 M. J. Hawley - Yale University
1615066Sgarrison 
1715066Sgarrison 
1815066Sgarrison 
1915066Sgarrison 
2015066Sgarrison                                                         */
2112909Sgarrison # include <stdio.h>
2212909Sgarrison # include <ctype.h>
2312909Sgarrison # include "bib.h"
2412909Sgarrison 
2512909Sgarrison # define HUNTSIZE 512                /* maximum size of hunt string         */
2612909Sgarrison # define MAXREFS  300                /* maximum number of references        */
2712909Sgarrison # define MAXATONCE 35                /* maximum references at one location  */
2812909Sgarrison 
2912909Sgarrison # define getch(c,fd) (c = getc(fd))
3012909Sgarrison # define echoc(c,ifd,ofd) (getch(c,ifd) == EOF ? c : putc(c,ofd))
3112909Sgarrison # define testc(c,d,ifd,ofd) (getch(c, ifd) == d ? putc(c, ofd) : 0)
3212909Sgarrison 
3312909Sgarrison /* global variables */
3412909Sgarrison    FILE *rfd;                   /* reference temporary file              */
3516245Srrh #ifndef INCORE
3612909Sgarrison    char reffile[] = TMPREFFILE ;/* temporary file (see bib.h)            */
3716245Srrh #endif not INCORE
3815902Srrh    struct refinfo refinfo[MAXREFS];	/* reference information */
3915902Srrh    struct refinfo *refssearch();
4015902Srrh    struct refinfo *refshash[HASHSIZE];
4112909Sgarrison    long int rend = 1;           /* last position in rfd (first char unused)*/
4215902Srrh    int numrefs = 0;            /* number of references generated so far */
4312909Sgarrison    FILE *tfd;                   /* output of pass 1 of file(s)           */
4412909Sgarrison    char tmpfile[] = TMPTEXTFILE ; /* output of pass 1                    */
45*17247Srrh    char *common = COMFILE;       /* common word file                      */
4612909Sgarrison    int  findex = false;         /* can we read the file INDEX ?          */
4712909Sgarrison 
4812909Sgarrison /* global variables in bibargs */
4917245Srrh    extern int foot, doacite, sort, personal;
5015066Sgarrison    extern int hyphen, ordcite, biblineno;
5115066Sgarrison    extern char sortstr[], pfile[], citetemplate[], bibfname[];
5212909Sgarrison 
5315902Srrh #include <signal.h>
5412909Sgarrison 
5512909Sgarrison main(argc, argv)
5612909Sgarrison    int argc;
5712909Sgarrison    char **argv;
5812909Sgarrison {  int rcomp();
5915902Srrh    int intr();
6012909Sgarrison 
6112909Sgarrison    /* the file INDEX in the current directory is the default index,
6212909Sgarrison       if it is present */
6312909Sgarrison 
64*17247Srrh    strcpy(BMACLIB, N_BMACLIB);
65*17247Srrh    strcpy(COMFILE, N_COMFILE);
66*17247Srrh    strcpy(DEFSTYLE, N_DEFSTYLE);
67*17247Srrh 
6815902Srrh    signal(SIGINT, intr);
6912909Sgarrison    rfd = fopen( INDXFILE , "r");
7012909Sgarrison    if (rfd != NULL) {
7112909Sgarrison       findex = true;
7212909Sgarrison       fclose(rfd);
7312909Sgarrison       }
7412909Sgarrison 
7515902Srrh #ifndef INCORE
7612909Sgarrison    /* open temporaries, reffile will contain references collected in
7712909Sgarrison       pass 1, and tmpfile will contain text.
7812909Sgarrison    */
7912909Sgarrison    mktemp(reffile);
8012909Sgarrison    rfd = fopen(reffile,"w+");
8112909Sgarrison    if (rfd == NULL)
8215902Srrh       error("can't open temporary reference file, %s", reffile);
8315066Sgarrison    putc('x', rfd);      /* put garbage in first position (not used) */
8415902Srrh #endif not INCORE
8512909Sgarrison    mktemp(tmpfile);
8612909Sgarrison    tfd = fopen(tmpfile,"w");
8712909Sgarrison    if (tfd == NULL)
8815902Srrh       error("can't open temporary output file, %s", tmpfile);
8912909Sgarrison 
9012909Sgarrison     /*
9112909Sgarrison        pass1 - read files, looking for citations
9212909Sgarrison                arguments are read by doargs (bibargs.c)
9312909Sgarrison     */
9412909Sgarrison 
9515066Sgarrison    if (doargs(argc, argv, DEFSTYLE ) == 0) {
9615066Sgarrison       strcpy(bibfname, "<stdin>");
9712909Sgarrison       rdtext(stdin);
9815066Sgarrison       }
9912909Sgarrison 
10012909Sgarrison    /*
10112909Sgarrison     sort references, make citations, add disambiguating characters
10212909Sgarrison    */
10312909Sgarrison 
10412909Sgarrison    if (sort)
10515902Srrh       qsort(refinfo, numrefs, sizeof(struct refinfo), rcomp);
10615902Srrh    makecites();
10712909Sgarrison    disambiguate();
10812909Sgarrison 
10912909Sgarrison    /*
11012909Sgarrison    reopen temporaries
11112909Sgarrison    */
11212909Sgarrison 
11312909Sgarrison    fclose(tfd);
11412909Sgarrison    tfd = fopen(tmpfile,"r");
11512909Sgarrison    if (tfd == NULL)
11615902Srrh       error("can't open temporary output file %s for reading", tmpfile);
11712909Sgarrison    /*
11812909Sgarrison    pass 2 - reread files, replacing references
11912909Sgarrison    */
12012909Sgarrison    pass2(tfd, stdout);
12115902Srrh    cleanup(0);
12215902Srrh }
12315902Srrh /* interrupt processing */
12415902Srrh intr()
12515902Srrh {
12615902Srrh    cleanup(1);
12715902Srrh }
12815902Srrh /* clean up and exit */
12915902Srrh cleanup(val)
13015902Srrh {
13112909Sgarrison    fclose(tfd);
13215902Srrh #ifndef INCORE
13312909Sgarrison    fclose(rfd);
13415902Srrh    unlink(reffile);
13515902Srrh #endif INCORE
13615902Srrh #ifndef DEBUG
13712909Sgarrison    unlink(tmpfile);
13815902Srrh #endif DEBUG
13915902Srrh    exit(val);
14012909Sgarrison }
14112909Sgarrison 
14212909Sgarrison /* rdtext - read and process a text file, looking for [. commands */
14312909Sgarrison    rdtext(fd)
14412909Sgarrison    FILE *fd;
14512909Sgarrison {  char lastc, c, d;
14612909Sgarrison 
14715066Sgarrison    lastc = '\0';
14815066Sgarrison    biblineno = 1;
14912909Sgarrison    while (getch(c, fd) != EOF)
15012909Sgarrison       if (c == '[' || c == '{')
15112909Sgarrison          if (getch(d, fd) == '.') { /* found a reference */
15212909Sgarrison             if (c == '{') { if (lastc) putc(lastc, tfd);}
15312909Sgarrison             else
15415066Sgarrison                switch (lastc) {
15515066Sgarrison                   case '\0': break;
15615066Sgarrison                   case ' ': fputs("\\*([<", tfd); break;
15715066Sgarrison                   case '.': case ',': case '?': case ':':
15815066Sgarrison                   case ';': case '!': case '"': case '\'':
15915066Sgarrison                             fputs("\\*([", tfd);  /* fall through */
16015066Sgarrison                   default:  putc(lastc, tfd); break;
16115066Sgarrison                   }
16212909Sgarrison             rdcite(fd, c);
16312909Sgarrison             if (c == '[')
16415066Sgarrison                switch (lastc) {
16515066Sgarrison                   case '\0': break;
16615066Sgarrison                   case ' ': fputs("\\*(>]", tfd); break;
16715066Sgarrison                   case '.': case ',': case '?': case ':':
16815066Sgarrison                   case ';': case '!': case '"': case '\'':
16915066Sgarrison                             fprintf(tfd,"\\*(%c]", lastc); break;
17015066Sgarrison                   }
17115066Sgarrison             lastc = '\0';
17212909Sgarrison             }
17312909Sgarrison          else {
17415066Sgarrison             if (lastc != '\0') putc(lastc, tfd);
17512909Sgarrison             ungetc(d, fd);
17612909Sgarrison             lastc = c;
17712909Sgarrison             }
17812909Sgarrison       else {
17915066Sgarrison          if (lastc != '\0') putc(lastc, tfd);
18012909Sgarrison          lastc = c;
18115066Sgarrison          if (c == '\n') biblineno++;
18212909Sgarrison          }
18315066Sgarrison    if (lastc != '\0') putc(lastc, tfd);
18412909Sgarrison }
18512909Sgarrison 
18612909Sgarrison /* rdcite - read citation information inside a [. command */
18712909Sgarrison    rdcite(fd, ch)
18812909Sgarrison    FILE *fd;
18912909Sgarrison    char ch;
19016245Srrh {  int getref();
19112909Sgarrison    char huntstr[HUNTSIZE], c, info[HUNTSIZE];
19212909Sgarrison 
19312909Sgarrison    if (ch == '[')
19417245Srrh       if (doacite) fputs("\\*([[", tfd);
19512909Sgarrison    else
19617245Srrh       if (doacite) fputs("\\*([{", tfd);
19712909Sgarrison    huntstr[0] = info[0] = 0;
19812909Sgarrison    while (getch(c, fd) != EOF)
19912909Sgarrison       switch (c) {
20012909Sgarrison          case ',':
20115902Srrh 	    citemark(info, huntstr, (char *)0);
20212909Sgarrison             huntstr[0] = info[0] = 0;
20312909Sgarrison             break;
20412909Sgarrison          case '.':
20512909Sgarrison             while (getch(c, fd) == '.') ;
20612909Sgarrison             if (c == ']') {
20715902Srrh 	       citemark(info, huntstr, "\\*(]]");
20812909Sgarrison                return;
20912909Sgarrison                }
21012909Sgarrison             else if (c == '}') {
21115902Srrh 	       citemark(info, huntstr, "\\*(}]");
21212909Sgarrison                return;
21312909Sgarrison                }
21412909Sgarrison             else
21512909Sgarrison                addc(huntstr, c);
21612909Sgarrison             break;
21712909Sgarrison 
21812909Sgarrison          case '{':
21912909Sgarrison             while (getch(c, fd) != '}')
22012909Sgarrison                if (c == EOF) {
22115902Srrh                   error("ill formed reference");
22212909Sgarrison                   }
22312909Sgarrison                 else
22412909Sgarrison                   addc(info, c);
22512909Sgarrison             break;
22612909Sgarrison 
22712909Sgarrison          case '\n':
22815066Sgarrison             biblineno++;
22912909Sgarrison          case '\t':
23012909Sgarrison             c = ' ';   /* fall through */
23112909Sgarrison 
23212909Sgarrison          default:
23312909Sgarrison             addc(huntstr,c);
23412909Sgarrison          }
23512909Sgarrison    error("end of file reading citation");
23612909Sgarrison }
23716245Srrh char	ncitetemplate[64];
23816245Srrh int	changecite;
23915902Srrh citemark(info, huntstr, tail)
24015902Srrh 	char *info, *huntstr, *tail;
24115902Srrh {
24215902Srrh 	char c = CITEMARK;
24315902Srrh         long int  n;
24416245Srrh 	/*
24516245Srrh 	 *	getref sets ncitetemplate as a side effect
24616245Srrh 	 */
24715902Srrh 	n = getref(huntstr);
24816245Srrh 	if (ncitetemplate[0]){
24916245Srrh 		fprintf(tfd, "%c%s%c", FMTSTART, ncitetemplate, FMTEND);
25016245Srrh 		ncitetemplate[0] = 0;
25116245Srrh 	}
25217245Srrh 	fprintf(tfd, "%c%d%c%s%c%s", c ,n, c, info, CITEEND, doacite?tail:0);
25315902Srrh }
25412909Sgarrison 
25512909Sgarrison /* addc - add a character to hunt string */
25612909Sgarrison    addc(huntstr, c)
25712909Sgarrison    char huntstr[HUNTSIZE], c;
25812909Sgarrison {  int  i;
25912909Sgarrison 
26012909Sgarrison    i = strlen(huntstr);
26112909Sgarrison    if (i > HUNTSIZE)
26215902Srrh       error("citation too long, max of %d", HUNTSIZE);
26312909Sgarrison    huntstr[i] = c;
26412909Sgarrison    huntstr[i+1] = 0;
26512909Sgarrison }
26615902Srrh /* getref - if an item was already referenced, return its reference index
26715902Srrh                 otherwise create a new entry */
26815902Srrh    int getref(huntstr)
26912909Sgarrison    char huntstr[HUNTSIZE];
27015902Srrh {  char rf[REFSIZE], *r, *hunt();
27115902Srrh    int	match(), getwrd();
27215891Srrh    char	*realhstr;
27315902Srrh    int hash;
27415902Srrh    struct refinfo *rp;
27515902Srrh    int	lg;
27612909Sgarrison 
27715891Srrh    realhstr = huntstr;
27815891Srrh    if (strncmp(huntstr, "$C$", 3) == 0){
27915891Srrh 	char *from, *to;
28016245Srrh 	changecite++;
28116245Srrh 	for(from = huntstr + 3, to = ncitetemplate; *from; from++, to++){
28215891Srrh 		switch(*from){
28315891Srrh 		case '\0':
28415891Srrh 		case ' ':
28515891Srrh 		case '\n':
28615891Srrh 		case '\t':	goto outcopy;
28715891Srrh 		default:	*to = *from;
28815891Srrh 		}
28915891Srrh 	}
29015891Srrh    outcopy: ;
29115891Srrh 	*to = 0;
29215891Srrh 	*from = 0;
29315891Srrh 	realhstr = from + 1;
29415891Srrh    }
29515891Srrh    r = hunt(realhstr);
29612909Sgarrison    if (r != NULL) {
29715902Srrh       /* expand defined string */
29812909Sgarrison       strcpy(rf, r);
29912909Sgarrison       free(r);
30012909Sgarrison       expand(rf);
30112909Sgarrison       /* see if reference has already been cited */
30215902Srrh       if (foot == false && (rp = refssearch(rf))){
30315902Srrh 		return(rp - refinfo);
30415902Srrh       }
30512909Sgarrison       /* didn't match any existing reference, create new one */
30615902Srrh       if (numrefs >= MAXREFS)
30715902Srrh 	error("too many references, max of %d", MAXREFS);
30815902Srrh       hash = strhash(rf);
30915902Srrh       lg = strlen(rf) + 1;
31015902Srrh       refinfo[numrefs].ri_pos = rend;
31115902Srrh       refinfo[numrefs].ri_length = lg;
31215902Srrh       refinfo[numrefs].ri_hp = refshash[hash];
31315902Srrh       refinfo[numrefs].ri_n = numrefs;
31415902Srrh       refshash[hash] = &refinfo[numrefs];
31515902Srrh       wrref(&refinfo[numrefs], rf);
31615902Srrh       return(numrefs++);
31712909Sgarrison       }
31812909Sgarrison    else {
31915891Srrh       bibwarning("no reference matching %s\n", realhstr);
32015902Srrh       return(-1);
32112909Sgarrison       }
32212909Sgarrison }
32315902Srrh struct refinfo *refssearch(rf)
32415902Srrh    char *rf;
32515902Srrh {
32615902Srrh    char ref[REFSIZE];
32715902Srrh    reg	int i;
32815902Srrh    int	lg;
32915902Srrh    reg	struct refinfo *rp;
33015902Srrh    lg = strlen(rf) + 1;
33115902Srrh    for (rp = refshash[strhash(rf)]; rp; rp = rp->ri_hp){
33215902Srrh 	     if (rp->ri_length == lg){
33315902Srrh 		     rdref(rp, ref);
33415902Srrh 		     if (strcmp(ref, rf) == 0)
33515902Srrh 			return(rp);
33615902Srrh 	     }
33715902Srrh    }
33815902Srrh    return(0);
33915902Srrh }
34012909Sgarrison /* hunt - hunt for reference from either personal or system index */
34112909Sgarrison    char *hunt(huntstr)
34212909Sgarrison    char huntstr[];
34312909Sgarrison {  char *fhunt(), *r, *p, *q, fname[120];
34412909Sgarrison 
34512909Sgarrison    if (personal) {
34612909Sgarrison       for (p = fname, q = pfile; ; q++)
34712909Sgarrison          if (*q == ',' || *q == 0) {
34812909Sgarrison             *p = 0;
34912909Sgarrison             if ((r = fhunt(fname, huntstr)) != NULL)
35012909Sgarrison                return(r);
35112909Sgarrison             else if (*q == 0)
35212909Sgarrison                break;
35312909Sgarrison             p = fname;
35412909Sgarrison             }
35512909Sgarrison          else *p++ = *q;
35612909Sgarrison       }
35712909Sgarrison    else if (findex) {
35812909Sgarrison       if ((r = fhunt( INDXFILE , huntstr)) != NULL)
35912909Sgarrison          return(r);
36012909Sgarrison       }
36112909Sgarrison    if ((r = fhunt(SYSINDEX , huntstr)) != NULL)
36212909Sgarrison       return(r);
36312909Sgarrison    return(NULL);
36412909Sgarrison }
36512909Sgarrison 
36612909Sgarrison /* fhunt - hunt from a specific file */
36712909Sgarrison    char *fhunt(file, huntstr)
36812909Sgarrison    char file[], huntstr[];
36912909Sgarrison {  char *p, *r, *locate();
37012909Sgarrison 
37112909Sgarrison    r = locate(huntstr, file, 6, common);
37212909Sgarrison 
37312909Sgarrison    if (r == NULL)
37412909Sgarrison       return(NULL);  /* error */
37512909Sgarrison    if (*r == 0)
37612909Sgarrison       return(NULL);  /* no match */
37712909Sgarrison 
37812909Sgarrison    for (p = r; *p; p++)
37912909Sgarrison       if (*p == '\n')
38012909Sgarrison          if (*(p+1) == '\n') { /* end */
38112909Sgarrison             if (*(p+2) != 0)
38215066Sgarrison                bibwarning("multiple references match %s\n",huntstr);
38312909Sgarrison             *(p+1) = 0;
38412909Sgarrison             break;
38512909Sgarrison             }
38612909Sgarrison          else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */
38712909Sgarrison             *p = ' ';
38812909Sgarrison    return(r);
38912909Sgarrison }
39015902Srrh struct cite{
39115902Srrh 	int	num;
39215902Srrh 	char	*info;
39315902Srrh };
39415902Srrh citesort(p1, p2)
39515902Srrh 	struct cite *p1, *p2;
39615902Srrh {
39715902Srrh 	return(p1->num - p2->num);
39815902Srrh }
39912909Sgarrison 
40012909Sgarrison /* putrefs - gather contiguous references together, sort them if called
40112909Sgarrison    for, hyphenate if necessary, and dump them out */
40212909Sgarrison int putrefs(ifd, ofd, footrefs, fn)
40312909Sgarrison FILE *ifd, *ofd;
40412909Sgarrison int  fn, footrefs[];
40515902Srrh {
40615902Srrh 	struct cite cites[MAXATONCE];
40715902Srrh 	char	infoword[HUNTSIZE];    /* information line */
40815902Srrh 	reg	int i;
40915902Srrh 	reg	char *p;
41015902Srrh 	reg	int  ncites, n, j;         /* number of citations being dumped */
41115902Srrh 	char	c, *walloc();
41215902Srrh 	int neg;
41315902Srrh 	/*
41415902Srrh 	 * first gather contiguous references together,
41515902Srrh 	 * and order them if required
41615902Srrh 	 */
41712909Sgarrison 
41815902Srrh 	ncites = 0;
41915902Srrh 	neg = 1;
42015902Srrh 	do {
42115902Srrh 		n = 0;
42215902Srrh 		do{
42315902Srrh 			getch(c, ifd);
42415902Srrh 			if (isdigit(c))
42515902Srrh 				n = 10 * n + (c - '0');
42615902Srrh 			else if (c == '-')
42715902Srrh 				neg *= -1;
42815902Srrh 			else if (c == CITEMARK)
42915902Srrh 				break;
43015902Srrh 			else
43115902Srrh 				error("bad cite char 0%03o in pass two",c);
43215902Srrh 		} while(1);
43315902Srrh 		if (neg < 0) {     /* reference not found */
43415902Srrh 			cites[ncites].num = -1;
43515902Srrh 			cites[ncites].info = 0;
43615902Srrh 			ncites++;
43715902Srrh 		} else {
43815902Srrh 			/*
43915902Srrh 			 * Find reference n in the references
44015902Srrh 			 */
44115902Srrh 			int i;
44215902Srrh 			for (i = 0; i < numrefs; i++){
44315902Srrh 				if (refinfo[i].ri_n == n){
44415902Srrh 					cites[ncites].num = i;
44515902Srrh 					cites[ncites].info = 0;
44615902Srrh 					ncites++;
44715902Srrh 					break;
44815902Srrh 				}
44915902Srrh 			}
45015902Srrh 			if (i == numrefs)
45115902Srrh 				error("citation	%d not found in pass 2", n);
45215902Srrh 		}
45315902Srrh 		if (getch(c, ifd) != CITEEND) {
45415902Srrh 			for (p = infoword; c != CITEEND ; ) {
45515902Srrh 				*p++ = c;
45615902Srrh 				getch(c, ifd);
45715902Srrh 			}
45815902Srrh 			*p = 0;
45915902Srrh 			cites[ncites-1].info = walloc(infoword);
46015902Srrh 		}
46115902Srrh 		getch(c, ifd);
46215902Srrh 	} while (c == CITEMARK);
46315902Srrh 	ungetc(c, ifd);
46415902Srrh 	if (ordcite)
46515902Srrh 		qsort(cites, ncites, sizeof(struct cite), citesort);
46612909Sgarrison 
46715902Srrh 	/* now dump out values */
46815902Srrh 	for (i = 0; i < ncites; i++) {
46916245Srrh 		if (cites[i].num >= 0) {
47016245Srrh 			if (changecite){
47116245Srrh 				char tempcite[128];
47216245Srrh 				char ref[REFSIZE];
47316245Srrh 				struct refinfo *p;
47416245Srrh 				/*
47516245Srrh 				 * rebuild the citation string,
47616245Srrh 				 * using the current template in effect
47716245Srrh 				 */
47816245Srrh 				p = &refinfo[cites[i].num];
47916245Srrh 				rdref(p, ref);
48016245Srrh 				bldcite(tempcite, cites[i].num, ref);
48116245Srrh 				strcat(tempcite, p->ri_disambig);
48217245Srrh 				if (doacite) fputs(tempcite, ofd);
48316245Srrh 			} else {
48417245Srrh 				if (doacite) fputs(refinfo[cites[i].num].ri_cite, ofd);
48516245Srrh 			}
48617245Srrh 			if (!doacite) fputs("\\&", ofd);
48716245Srrh 		}
48815902Srrh 		if (cites[i].info) {
48917245Srrh 			if (doacite) fputs(cites[i].info, ofd);
49017245Srrh 			if (!doacite) fputs("\\&", ofd);
49115902Srrh 			free(cites[i].info);
49215902Srrh 		}
49315902Srrh 		if (hyphen) {
49415902Srrh 			for (j = 1;
49515902Srrh 			     j + i <= ncites && cites[i+j].num == cites[i].num + j;
49615902Srrh 			     j++)/*VOID*/;
49715902Srrh 			if (j + i > ncites)
49815902Srrh 				j = ncites;
49915902Srrh 			else
50015902Srrh 				j = j + i - 1;
50115902Srrh 		} else {
50215902Srrh 			j = i;
50315902Srrh 		}
50415902Srrh 		if (j > i + 1) {
50515902Srrh 			fputs("\\*(]-", ofd);
50615902Srrh 			i = j - 1;
50715902Srrh 		} else if (i != ncites - 1) {
50815902Srrh 			fputs("\\*(],", ofd);
50915902Srrh 		}
51015902Srrh 		if (foot) {
51115902Srrh 			fn++;
51215902Srrh 			footrefs[fn] = cites[i].num;
51315902Srrh 		}
51415902Srrh 	}
51515902Srrh 	return(fn);
51612909Sgarrison }
51712909Sgarrison 
51812909Sgarrison /* pass2 - read pass 1 files entering citation */
51912909Sgarrison    pass2(ifd, ofd)
52012909Sgarrison    FILE *ifd, *ofd;
52112909Sgarrison {
52212909Sgarrison    char c;
52312909Sgarrison    int  i, fn, footrefs[25], dumped;
52412909Sgarrison 
52512909Sgarrison    fn = -1;
52612909Sgarrison    dumped = foot;
52712909Sgarrison    while (getch(c, ifd) != EOF) {
52812909Sgarrison       while (c == '\n') {
52912909Sgarrison          putc(c, ofd);
53012909Sgarrison          if (foot && fn >= 0) {
53112909Sgarrison             for (i = 0; i <= fn; i++)
53212909Sgarrison                 dumpref(footrefs[i], ofd);
53312909Sgarrison             fn = -1;
53412909Sgarrison             }
53512909Sgarrison          if (testc(c, '.', ifd, ofd))
53612909Sgarrison             if (testc(c, '[', ifd, ofd))
53712909Sgarrison                if (testc(c, ']', ifd, ofd)) {
53812909Sgarrison                   while (echoc(c, ifd, ofd) != '\n')
53912909Sgarrison                      ;
54012909Sgarrison                   dumped = true;
54115902Srrh                   for (i = 0; i < numrefs; i++){
54212909Sgarrison                      dumpref(i, ofd);
54315902Srrh 		  }
54412909Sgarrison                   getch(c, ifd);
54512909Sgarrison                   }
54612909Sgarrison          }
54716245Srrh       if (c == FMTSTART)
54816245Srrh 	 changefmt(ifd);
54916245Srrh       else if (c == CITEMARK)
55012909Sgarrison          fn = putrefs(ifd, ofd, footrefs, fn);
55112909Sgarrison       else if (c != EOF)
55212909Sgarrison          putc(c, ofd);
55312909Sgarrison       }
55412909Sgarrison    if (dumped == false)
55515066Sgarrison       bibwarning("Warning: references never dumped\n","");
55612909Sgarrison }
55716245Srrh /*
55816245Srrh  *	change citation format
55916245Srrh  */
56016245Srrh changefmt(ifd)
56116245Srrh 	FILE	*ifd;
56216245Srrh {
56316245Srrh 	char	c;
56416245Srrh 	char	*to;
56516245Srrh 	to = ncitetemplate;
56616245Srrh 	while (getch(c, ifd) != FMTEND)
56716245Srrh 		*to++ = c;
56816245Srrh 	*to = 0;
56916245Srrh 	strcpy(citetemplate, ncitetemplate);
57016245Srrh }
571