xref: /csrg-svn/contrib/bib/src/bib.c (revision 17245)
113109Srrh #ifndef lint
2*17245Srrh static char sccsid[] = "@(#)bib.c	2.6	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                    */
4512909Sgarrison    char common[] = COMFILE ;    /* common word file                      */
4612909Sgarrison    int  findex = false;         /* can we read the file INDEX ?          */
4712909Sgarrison 
4812909Sgarrison /* global variables in bibargs */
49*17245Srrh    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 
6415902Srrh    signal(SIGINT, intr);
6512909Sgarrison    rfd = fopen( INDXFILE , "r");
6612909Sgarrison    if (rfd != NULL) {
6712909Sgarrison       findex = true;
6812909Sgarrison       fclose(rfd);
6912909Sgarrison       }
7012909Sgarrison 
7115902Srrh #ifndef INCORE
7212909Sgarrison    /* open temporaries, reffile will contain references collected in
7312909Sgarrison       pass 1, and tmpfile will contain text.
7412909Sgarrison    */
7512909Sgarrison    mktemp(reffile);
7612909Sgarrison    rfd = fopen(reffile,"w+");
7712909Sgarrison    if (rfd == NULL)
7815902Srrh       error("can't open temporary reference file, %s", reffile);
7915066Sgarrison    putc('x', rfd);      /* put garbage in first position (not used) */
8015902Srrh #endif not INCORE
8112909Sgarrison    mktemp(tmpfile);
8212909Sgarrison    tfd = fopen(tmpfile,"w");
8312909Sgarrison    if (tfd == NULL)
8415902Srrh       error("can't open temporary output file, %s", tmpfile);
8512909Sgarrison 
8612909Sgarrison     /*
8712909Sgarrison        pass1 - read files, looking for citations
8812909Sgarrison                arguments are read by doargs (bibargs.c)
8912909Sgarrison     */
9012909Sgarrison 
9115066Sgarrison    if (doargs(argc, argv, DEFSTYLE ) == 0) {
9215066Sgarrison       strcpy(bibfname, "<stdin>");
9312909Sgarrison       rdtext(stdin);
9415066Sgarrison       }
9512909Sgarrison 
9612909Sgarrison    /*
9712909Sgarrison     sort references, make citations, add disambiguating characters
9812909Sgarrison    */
9912909Sgarrison 
10012909Sgarrison    if (sort)
10115902Srrh       qsort(refinfo, numrefs, sizeof(struct refinfo), rcomp);
10215902Srrh    makecites();
10312909Sgarrison    disambiguate();
10412909Sgarrison 
10512909Sgarrison    /*
10612909Sgarrison    reopen temporaries
10712909Sgarrison    */
10812909Sgarrison 
10912909Sgarrison    fclose(tfd);
11012909Sgarrison    tfd = fopen(tmpfile,"r");
11112909Sgarrison    if (tfd == NULL)
11215902Srrh       error("can't open temporary output file %s for reading", tmpfile);
11312909Sgarrison    /*
11412909Sgarrison    pass 2 - reread files, replacing references
11512909Sgarrison    */
11612909Sgarrison    pass2(tfd, stdout);
11715902Srrh    cleanup(0);
11815902Srrh }
11915902Srrh /* interrupt processing */
12015902Srrh intr()
12115902Srrh {
12215902Srrh    cleanup(1);
12315902Srrh }
12415902Srrh /* clean up and exit */
12515902Srrh cleanup(val)
12615902Srrh {
12712909Sgarrison    fclose(tfd);
12815902Srrh #ifndef INCORE
12912909Sgarrison    fclose(rfd);
13015902Srrh    unlink(reffile);
13115902Srrh #endif INCORE
13215902Srrh #ifndef DEBUG
13312909Sgarrison    unlink(tmpfile);
13415902Srrh #endif DEBUG
13515902Srrh    exit(val);
13612909Sgarrison }
13712909Sgarrison 
13812909Sgarrison /* rdtext - read and process a text file, looking for [. commands */
13912909Sgarrison    rdtext(fd)
14012909Sgarrison    FILE *fd;
14112909Sgarrison {  char lastc, c, d;
14212909Sgarrison 
14315066Sgarrison    lastc = '\0';
14415066Sgarrison    biblineno = 1;
14512909Sgarrison    while (getch(c, fd) != EOF)
14612909Sgarrison       if (c == '[' || c == '{')
14712909Sgarrison          if (getch(d, fd) == '.') { /* found a reference */
14812909Sgarrison             if (c == '{') { if (lastc) putc(lastc, tfd);}
14912909Sgarrison             else
15015066Sgarrison                switch (lastc) {
15115066Sgarrison                   case '\0': break;
15215066Sgarrison                   case ' ': fputs("\\*([<", tfd); break;
15315066Sgarrison                   case '.': case ',': case '?': case ':':
15415066Sgarrison                   case ';': case '!': case '"': case '\'':
15515066Sgarrison                             fputs("\\*([", tfd);  /* fall through */
15615066Sgarrison                   default:  putc(lastc, tfd); break;
15715066Sgarrison                   }
15812909Sgarrison             rdcite(fd, c);
15912909Sgarrison             if (c == '[')
16015066Sgarrison                switch (lastc) {
16115066Sgarrison                   case '\0': break;
16215066Sgarrison                   case ' ': fputs("\\*(>]", tfd); break;
16315066Sgarrison                   case '.': case ',': case '?': case ':':
16415066Sgarrison                   case ';': case '!': case '"': case '\'':
16515066Sgarrison                             fprintf(tfd,"\\*(%c]", lastc); break;
16615066Sgarrison                   }
16715066Sgarrison             lastc = '\0';
16812909Sgarrison             }
16912909Sgarrison          else {
17015066Sgarrison             if (lastc != '\0') putc(lastc, tfd);
17112909Sgarrison             ungetc(d, fd);
17212909Sgarrison             lastc = c;
17312909Sgarrison             }
17412909Sgarrison       else {
17515066Sgarrison          if (lastc != '\0') putc(lastc, tfd);
17612909Sgarrison          lastc = c;
17715066Sgarrison          if (c == '\n') biblineno++;
17812909Sgarrison          }
17915066Sgarrison    if (lastc != '\0') putc(lastc, tfd);
18012909Sgarrison }
18112909Sgarrison 
18212909Sgarrison /* rdcite - read citation information inside a [. command */
18312909Sgarrison    rdcite(fd, ch)
18412909Sgarrison    FILE *fd;
18512909Sgarrison    char ch;
18616245Srrh {  int getref();
18712909Sgarrison    char huntstr[HUNTSIZE], c, info[HUNTSIZE];
18812909Sgarrison 
18912909Sgarrison    if (ch == '[')
190*17245Srrh       if (doacite) fputs("\\*([[", tfd);
19112909Sgarrison    else
192*17245Srrh       if (doacite) fputs("\\*([{", tfd);
19312909Sgarrison    huntstr[0] = info[0] = 0;
19412909Sgarrison    while (getch(c, fd) != EOF)
19512909Sgarrison       switch (c) {
19612909Sgarrison          case ',':
19715902Srrh 	    citemark(info, huntstr, (char *)0);
19812909Sgarrison             huntstr[0] = info[0] = 0;
19912909Sgarrison             break;
20012909Sgarrison          case '.':
20112909Sgarrison             while (getch(c, fd) == '.') ;
20212909Sgarrison             if (c == ']') {
20315902Srrh 	       citemark(info, huntstr, "\\*(]]");
20412909Sgarrison                return;
20512909Sgarrison                }
20612909Sgarrison             else if (c == '}') {
20715902Srrh 	       citemark(info, huntstr, "\\*(}]");
20812909Sgarrison                return;
20912909Sgarrison                }
21012909Sgarrison             else
21112909Sgarrison                addc(huntstr, c);
21212909Sgarrison             break;
21312909Sgarrison 
21412909Sgarrison          case '{':
21512909Sgarrison             while (getch(c, fd) != '}')
21612909Sgarrison                if (c == EOF) {
21715902Srrh                   error("ill formed reference");
21812909Sgarrison                   }
21912909Sgarrison                 else
22012909Sgarrison                   addc(info, c);
22112909Sgarrison             break;
22212909Sgarrison 
22312909Sgarrison          case '\n':
22415066Sgarrison             biblineno++;
22512909Sgarrison          case '\t':
22612909Sgarrison             c = ' ';   /* fall through */
22712909Sgarrison 
22812909Sgarrison          default:
22912909Sgarrison             addc(huntstr,c);
23012909Sgarrison          }
23112909Sgarrison    error("end of file reading citation");
23212909Sgarrison }
23316245Srrh char	ncitetemplate[64];
23416245Srrh int	changecite;
23515902Srrh citemark(info, huntstr, tail)
23615902Srrh 	char *info, *huntstr, *tail;
23715902Srrh {
23815902Srrh 	char c = CITEMARK;
23915902Srrh         long int  n;
24016245Srrh 	/*
24116245Srrh 	 *	getref sets ncitetemplate as a side effect
24216245Srrh 	 */
24315902Srrh 	n = getref(huntstr);
24416245Srrh 	if (ncitetemplate[0]){
24516245Srrh 		fprintf(tfd, "%c%s%c", FMTSTART, ncitetemplate, FMTEND);
24616245Srrh 		ncitetemplate[0] = 0;
24716245Srrh 	}
248*17245Srrh 	fprintf(tfd, "%c%d%c%s%c%s", c ,n, c, info, CITEEND, doacite?tail:0);
24915902Srrh }
25012909Sgarrison 
25112909Sgarrison /* addc - add a character to hunt string */
25212909Sgarrison    addc(huntstr, c)
25312909Sgarrison    char huntstr[HUNTSIZE], c;
25412909Sgarrison {  int  i;
25512909Sgarrison 
25612909Sgarrison    i = strlen(huntstr);
25712909Sgarrison    if (i > HUNTSIZE)
25815902Srrh       error("citation too long, max of %d", HUNTSIZE);
25912909Sgarrison    huntstr[i] = c;
26012909Sgarrison    huntstr[i+1] = 0;
26112909Sgarrison }
26215902Srrh /* getref - if an item was already referenced, return its reference index
26315902Srrh                 otherwise create a new entry */
26415902Srrh    int getref(huntstr)
26512909Sgarrison    char huntstr[HUNTSIZE];
26615902Srrh {  char rf[REFSIZE], *r, *hunt();
26715902Srrh    int	match(), getwrd();
26815891Srrh    char	*realhstr;
26915902Srrh    int hash;
27015902Srrh    struct refinfo *rp;
27115902Srrh    int	lg;
27212909Sgarrison 
27315891Srrh    realhstr = huntstr;
27415891Srrh    if (strncmp(huntstr, "$C$", 3) == 0){
27515891Srrh 	char *from, *to;
27616245Srrh 	changecite++;
27716245Srrh 	for(from = huntstr + 3, to = ncitetemplate; *from; from++, to++){
27815891Srrh 		switch(*from){
27915891Srrh 		case '\0':
28015891Srrh 		case ' ':
28115891Srrh 		case '\n':
28215891Srrh 		case '\t':	goto outcopy;
28315891Srrh 		default:	*to = *from;
28415891Srrh 		}
28515891Srrh 	}
28615891Srrh    outcopy: ;
28715891Srrh 	*to = 0;
28815891Srrh 	*from = 0;
28915891Srrh 	realhstr = from + 1;
29015891Srrh    }
29115891Srrh    r = hunt(realhstr);
29212909Sgarrison    if (r != NULL) {
29315902Srrh       /* expand defined string */
29412909Sgarrison       strcpy(rf, r);
29512909Sgarrison       free(r);
29612909Sgarrison       expand(rf);
29712909Sgarrison       /* see if reference has already been cited */
29815902Srrh       if (foot == false && (rp = refssearch(rf))){
29915902Srrh 		return(rp - refinfo);
30015902Srrh       }
30112909Sgarrison       /* didn't match any existing reference, create new one */
30215902Srrh       if (numrefs >= MAXREFS)
30315902Srrh 	error("too many references, max of %d", MAXREFS);
30415902Srrh       hash = strhash(rf);
30515902Srrh       lg = strlen(rf) + 1;
30615902Srrh       refinfo[numrefs].ri_pos = rend;
30715902Srrh       refinfo[numrefs].ri_length = lg;
30815902Srrh       refinfo[numrefs].ri_hp = refshash[hash];
30915902Srrh       refinfo[numrefs].ri_n = numrefs;
31015902Srrh       refshash[hash] = &refinfo[numrefs];
31115902Srrh       wrref(&refinfo[numrefs], rf);
31215902Srrh       return(numrefs++);
31312909Sgarrison       }
31412909Sgarrison    else {
31515891Srrh       bibwarning("no reference matching %s\n", realhstr);
31615902Srrh       return(-1);
31712909Sgarrison       }
31812909Sgarrison }
31915902Srrh struct refinfo *refssearch(rf)
32015902Srrh    char *rf;
32115902Srrh {
32215902Srrh    char ref[REFSIZE];
32315902Srrh    reg	int i;
32415902Srrh    int	lg;
32515902Srrh    reg	struct refinfo *rp;
32615902Srrh    lg = strlen(rf) + 1;
32715902Srrh    for (rp = refshash[strhash(rf)]; rp; rp = rp->ri_hp){
32815902Srrh 	     if (rp->ri_length == lg){
32915902Srrh 		     rdref(rp, ref);
33015902Srrh 		     if (strcmp(ref, rf) == 0)
33115902Srrh 			return(rp);
33215902Srrh 	     }
33315902Srrh    }
33415902Srrh    return(0);
33515902Srrh }
33612909Sgarrison /* hunt - hunt for reference from either personal or system index */
33712909Sgarrison    char *hunt(huntstr)
33812909Sgarrison    char huntstr[];
33912909Sgarrison {  char *fhunt(), *r, *p, *q, fname[120];
34012909Sgarrison 
34112909Sgarrison    if (personal) {
34212909Sgarrison       for (p = fname, q = pfile; ; q++)
34312909Sgarrison          if (*q == ',' || *q == 0) {
34412909Sgarrison             *p = 0;
34512909Sgarrison             if ((r = fhunt(fname, huntstr)) != NULL)
34612909Sgarrison                return(r);
34712909Sgarrison             else if (*q == 0)
34812909Sgarrison                break;
34912909Sgarrison             p = fname;
35012909Sgarrison             }
35112909Sgarrison          else *p++ = *q;
35212909Sgarrison       }
35312909Sgarrison    else if (findex) {
35412909Sgarrison       if ((r = fhunt( INDXFILE , huntstr)) != NULL)
35512909Sgarrison          return(r);
35612909Sgarrison       }
35712909Sgarrison    if ((r = fhunt(SYSINDEX , huntstr)) != NULL)
35812909Sgarrison       return(r);
35912909Sgarrison    return(NULL);
36012909Sgarrison }
36112909Sgarrison 
36212909Sgarrison /* fhunt - hunt from a specific file */
36312909Sgarrison    char *fhunt(file, huntstr)
36412909Sgarrison    char file[], huntstr[];
36512909Sgarrison {  char *p, *r, *locate();
36612909Sgarrison 
36712909Sgarrison    r = locate(huntstr, file, 6, common);
36812909Sgarrison 
36912909Sgarrison    if (r == NULL)
37012909Sgarrison       return(NULL);  /* error */
37112909Sgarrison    if (*r == 0)
37212909Sgarrison       return(NULL);  /* no match */
37312909Sgarrison 
37412909Sgarrison    for (p = r; *p; p++)
37512909Sgarrison       if (*p == '\n')
37612909Sgarrison          if (*(p+1) == '\n') { /* end */
37712909Sgarrison             if (*(p+2) != 0)
37815066Sgarrison                bibwarning("multiple references match %s\n",huntstr);
37912909Sgarrison             *(p+1) = 0;
38012909Sgarrison             break;
38112909Sgarrison             }
38212909Sgarrison          else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */
38312909Sgarrison             *p = ' ';
38412909Sgarrison    return(r);
38512909Sgarrison }
38615902Srrh struct cite{
38715902Srrh 	int	num;
38815902Srrh 	char	*info;
38915902Srrh };
39015902Srrh citesort(p1, p2)
39115902Srrh 	struct cite *p1, *p2;
39215902Srrh {
39315902Srrh 	return(p1->num - p2->num);
39415902Srrh }
39512909Sgarrison 
39612909Sgarrison /* putrefs - gather contiguous references together, sort them if called
39712909Sgarrison    for, hyphenate if necessary, and dump them out */
39812909Sgarrison int putrefs(ifd, ofd, footrefs, fn)
39912909Sgarrison FILE *ifd, *ofd;
40012909Sgarrison int  fn, footrefs[];
40115902Srrh {
40215902Srrh 	struct cite cites[MAXATONCE];
40315902Srrh 	char	infoword[HUNTSIZE];    /* information line */
40415902Srrh 	reg	int i;
40515902Srrh 	reg	char *p;
40615902Srrh 	reg	int  ncites, n, j;         /* number of citations being dumped */
40715902Srrh 	char	c, *walloc();
40815902Srrh 	int neg;
40915902Srrh 	/*
41015902Srrh 	 * first gather contiguous references together,
41115902Srrh 	 * and order them if required
41215902Srrh 	 */
41312909Sgarrison 
41415902Srrh 	ncites = 0;
41515902Srrh 	neg = 1;
41615902Srrh 	do {
41715902Srrh 		n = 0;
41815902Srrh 		do{
41915902Srrh 			getch(c, ifd);
42015902Srrh 			if (isdigit(c))
42115902Srrh 				n = 10 * n + (c - '0');
42215902Srrh 			else if (c == '-')
42315902Srrh 				neg *= -1;
42415902Srrh 			else if (c == CITEMARK)
42515902Srrh 				break;
42615902Srrh 			else
42715902Srrh 				error("bad cite char 0%03o in pass two",c);
42815902Srrh 		} while(1);
42915902Srrh 		if (neg < 0) {     /* reference not found */
43015902Srrh 			cites[ncites].num = -1;
43115902Srrh 			cites[ncites].info = 0;
43215902Srrh 			ncites++;
43315902Srrh 		} else {
43415902Srrh 			/*
43515902Srrh 			 * Find reference n in the references
43615902Srrh 			 */
43715902Srrh 			int i;
43815902Srrh 			for (i = 0; i < numrefs; i++){
43915902Srrh 				if (refinfo[i].ri_n == n){
44015902Srrh 					cites[ncites].num = i;
44115902Srrh 					cites[ncites].info = 0;
44215902Srrh 					ncites++;
44315902Srrh 					break;
44415902Srrh 				}
44515902Srrh 			}
44615902Srrh 			if (i == numrefs)
44715902Srrh 				error("citation	%d not found in pass 2", n);
44815902Srrh 		}
44915902Srrh 		if (getch(c, ifd) != CITEEND) {
45015902Srrh 			for (p = infoword; c != CITEEND ; ) {
45115902Srrh 				*p++ = c;
45215902Srrh 				getch(c, ifd);
45315902Srrh 			}
45415902Srrh 			*p = 0;
45515902Srrh 			cites[ncites-1].info = walloc(infoword);
45615902Srrh 		}
45715902Srrh 		getch(c, ifd);
45815902Srrh 	} while (c == CITEMARK);
45915902Srrh 	ungetc(c, ifd);
46015902Srrh 	if (ordcite)
46115902Srrh 		qsort(cites, ncites, sizeof(struct cite), citesort);
46212909Sgarrison 
46315902Srrh 	/* now dump out values */
46415902Srrh 	for (i = 0; i < ncites; i++) {
46516245Srrh 		if (cites[i].num >= 0) {
46616245Srrh 			if (changecite){
46716245Srrh 				char tempcite[128];
46816245Srrh 				char ref[REFSIZE];
46916245Srrh 				struct refinfo *p;
47016245Srrh 				/*
47116245Srrh 				 * rebuild the citation string,
47216245Srrh 				 * using the current template in effect
47316245Srrh 				 */
47416245Srrh 				p = &refinfo[cites[i].num];
47516245Srrh 				rdref(p, ref);
47616245Srrh 				bldcite(tempcite, cites[i].num, ref);
47716245Srrh 				strcat(tempcite, p->ri_disambig);
478*17245Srrh 				if (doacite) fputs(tempcite, ofd);
47916245Srrh 			} else {
480*17245Srrh 				if (doacite) fputs(refinfo[cites[i].num].ri_cite, ofd);
48116245Srrh 			}
482*17245Srrh 			if (!doacite) fputs("\\&", ofd);
48316245Srrh 		}
48415902Srrh 		if (cites[i].info) {
485*17245Srrh 			if (doacite) fputs(cites[i].info, ofd);
486*17245Srrh 			if (!doacite) fputs("\\&", ofd);
48715902Srrh 			free(cites[i].info);
48815902Srrh 		}
48915902Srrh 		if (hyphen) {
49015902Srrh 			for (j = 1;
49115902Srrh 			     j + i <= ncites && cites[i+j].num == cites[i].num + j;
49215902Srrh 			     j++)/*VOID*/;
49315902Srrh 			if (j + i > ncites)
49415902Srrh 				j = ncites;
49515902Srrh 			else
49615902Srrh 				j = j + i - 1;
49715902Srrh 		} else {
49815902Srrh 			j = i;
49915902Srrh 		}
50015902Srrh 		if (j > i + 1) {
50115902Srrh 			fputs("\\*(]-", ofd);
50215902Srrh 			i = j - 1;
50315902Srrh 		} else if (i != ncites - 1) {
50415902Srrh 			fputs("\\*(],", ofd);
50515902Srrh 		}
50615902Srrh 		if (foot) {
50715902Srrh 			fn++;
50815902Srrh 			footrefs[fn] = cites[i].num;
50915902Srrh 		}
51015902Srrh 	}
51115902Srrh 	return(fn);
51212909Sgarrison }
51312909Sgarrison 
51412909Sgarrison /* pass2 - read pass 1 files entering citation */
51512909Sgarrison    pass2(ifd, ofd)
51612909Sgarrison    FILE *ifd, *ofd;
51712909Sgarrison {
51812909Sgarrison    char c;
51912909Sgarrison    int  i, fn, footrefs[25], dumped;
52012909Sgarrison 
52112909Sgarrison    fn = -1;
52212909Sgarrison    dumped = foot;
52312909Sgarrison    while (getch(c, ifd) != EOF) {
52412909Sgarrison       while (c == '\n') {
52512909Sgarrison          putc(c, ofd);
52612909Sgarrison          if (foot && fn >= 0) {
52712909Sgarrison             for (i = 0; i <= fn; i++)
52812909Sgarrison                 dumpref(footrefs[i], ofd);
52912909Sgarrison             fn = -1;
53012909Sgarrison             }
53112909Sgarrison          if (testc(c, '.', ifd, ofd))
53212909Sgarrison             if (testc(c, '[', ifd, ofd))
53312909Sgarrison                if (testc(c, ']', ifd, ofd)) {
53412909Sgarrison                   while (echoc(c, ifd, ofd) != '\n')
53512909Sgarrison                      ;
53612909Sgarrison                   dumped = true;
53715902Srrh                   for (i = 0; i < numrefs; i++){
53812909Sgarrison                      dumpref(i, ofd);
53915902Srrh 		  }
54012909Sgarrison                   getch(c, ifd);
54112909Sgarrison                   }
54212909Sgarrison          }
54316245Srrh       if (c == FMTSTART)
54416245Srrh 	 changefmt(ifd);
54516245Srrh       else if (c == CITEMARK)
54612909Sgarrison          fn = putrefs(ifd, ofd, footrefs, fn);
54712909Sgarrison       else if (c != EOF)
54812909Sgarrison          putc(c, ofd);
54912909Sgarrison       }
55012909Sgarrison    if (dumped == false)
55115066Sgarrison       bibwarning("Warning: references never dumped\n","");
55212909Sgarrison }
55316245Srrh /*
55416245Srrh  *	change citation format
55516245Srrh  */
55616245Srrh changefmt(ifd)
55716245Srrh 	FILE	*ifd;
55816245Srrh {
55916245Srrh 	char	c;
56016245Srrh 	char	*to;
56116245Srrh 	to = ncitetemplate;
56216245Srrh 	while (getch(c, ifd) != FMTEND)
56316245Srrh 		*to++ = c;
56416245Srrh 	*to = 0;
56516245Srrh 	strcpy(citetemplate, ncitetemplate);
56616245Srrh }
567