xref: /csrg-svn/contrib/bib/src/bib.c (revision 60507)
113109Srrh #ifndef lint
2*60507Sbostic static char sccsid[] = "@(#)bib.c	2.11	05/27/93";
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 
17*60507Sbostic 	       version 8/23/1988
18*60507Sbostic 
19*60507Sbostic 	 Adapted to use TiB style macro calls (i.e. |macro|)
20*60507Sbostic 	       A. Dain Samples
2115066Sgarrison 
22*60507Sbostic                                                         */
2315066Sgarrison 
2412909Sgarrison # include <stdio.h>
2512909Sgarrison # include <ctype.h>
2612909Sgarrison # include "bib.h"
2712909Sgarrison 
2812909Sgarrison # define HUNTSIZE 512                /* maximum size of hunt string         */
2912909Sgarrison # define MAXREFS  300                /* maximum number of references        */
3012909Sgarrison # define MAXATONCE 35                /* maximum references at one location  */
3112909Sgarrison 
3212909Sgarrison # define getch(c,fd) (c = getc(fd))
3312909Sgarrison # define echoc(c,ifd,ofd) (getch(c,ifd) == EOF ? c : putc(c,ofd))
3412909Sgarrison # define testc(c,d,ifd,ofd) (getch(c, ifd) == d ? putc(c, ofd) : 0)
3512909Sgarrison 
3612909Sgarrison /* global variables */
3712909Sgarrison    FILE *rfd;                   /* reference temporary file              */
3816245Srrh #ifndef INCORE
3912909Sgarrison    char reffile[] = TMPREFFILE ;/* temporary file (see bib.h)            */
4016245Srrh #endif not INCORE
4115902Srrh    struct refinfo refinfo[MAXREFS];	/* reference information */
4215902Srrh    struct refinfo *refssearch();
4315902Srrh    struct refinfo *refshash[HASHSIZE];
4412909Sgarrison    long int rend = 1;           /* last position in rfd (first char unused)*/
4515902Srrh    int numrefs = 0;            /* number of references generated so far */
4612909Sgarrison    FILE *tfd;                   /* output of pass 1 of file(s)           */
4730590Sgarrison    char bibtmpfile[] = TMPTEXTFILE ; /* output of pass 1                    */
4817247Srrh    char *common = COMFILE;       /* common word file                      */
4912909Sgarrison    int  findex = false;         /* can we read the file INDEX ?          */
5012909Sgarrison 
51*60507Sbostic char *programName;
52*60507Sbostic 
5312909Sgarrison /* global variables in bibargs */
5423484Sgarrison    extern int foot, doacite, sort, max_klen, personal;
5515066Sgarrison    extern int hyphen, ordcite, biblineno;
5615066Sgarrison    extern char sortstr[], pfile[], citetemplate[], bibfname[];
57*60507Sbostic    extern int TibOption;
5812909Sgarrison 
5915902Srrh #include <signal.h>
6012909Sgarrison 
6112909Sgarrison main(argc, argv)
6212909Sgarrison    int argc;
6312909Sgarrison    char **argv;
6412909Sgarrison {  int rcomp();
6515902Srrh    int intr();
6612909Sgarrison 
6712909Sgarrison    /* the file INDEX in the current directory is the default index,
6812909Sgarrison       if it is present */
6912909Sgarrison 
70*60507Sbostic    InitDirectory(BMACLIB,N_BMACLIB);
71*60507Sbostic    InitDirectory(COMFILE,N_COMFILE);
72*60507Sbostic    InitDirectory(DEFSTYLE,N_DEFSTYLE);
7317247Srrh 
7415902Srrh    signal(SIGINT, intr);
7512909Sgarrison    rfd = fopen( INDXFILE , "r");
7612909Sgarrison    if (rfd != NULL) {
7712909Sgarrison       findex = true;
7812909Sgarrison       fclose(rfd);
7912909Sgarrison       }
8012909Sgarrison 
8115902Srrh #ifndef INCORE
8212909Sgarrison    /* open temporaries, reffile will contain references collected in
8330590Sgarrison       pass 1, and bibtmpfile will contain text.
8412909Sgarrison    */
8512909Sgarrison    mktemp(reffile);
8612909Sgarrison    rfd = fopen(reffile,"w+");
8712909Sgarrison    if (rfd == NULL)
8815902Srrh       error("can't open temporary reference file, %s", reffile);
8915066Sgarrison    putc('x', rfd);      /* put garbage in first position (not used) */
9015902Srrh #endif not INCORE
9130590Sgarrison    mktemp(bibtmpfile);
9230590Sgarrison    tfd = fopen(bibtmpfile,"w");
9312909Sgarrison    if (tfd == NULL)
9430590Sgarrison       error("can't open temporary output file, %s", bibtmpfile);
9512909Sgarrison 
9612909Sgarrison     /*
9712909Sgarrison        pass1 - read files, looking for citations
9812909Sgarrison                arguments are read by doargs (bibargs.c)
9912909Sgarrison     */
10012909Sgarrison 
101*60507Sbostic    if (doargs(argc, argv, DEFSTYLE ) == 0) { /* may not return */
10215066Sgarrison       strcpy(bibfname, "<stdin>");
10312909Sgarrison       rdtext(stdin);
10415066Sgarrison       }
10512909Sgarrison 
10612909Sgarrison    /*
10712909Sgarrison     sort references, make citations, add disambiguating characters
10812909Sgarrison    */
10912909Sgarrison 
11012909Sgarrison    if (sort)
11115902Srrh       qsort(refinfo, numrefs, sizeof(struct refinfo), rcomp);
11215902Srrh    makecites();
11312909Sgarrison    disambiguate();
11412909Sgarrison 
11512909Sgarrison    /*
11612909Sgarrison    reopen temporaries
11712909Sgarrison    */
11812909Sgarrison 
11912909Sgarrison    fclose(tfd);
12030590Sgarrison    tfd = fopen(bibtmpfile,"r");
12112909Sgarrison    if (tfd == NULL)
12230590Sgarrison       error("can't open temporary output file %s for reading", bibtmpfile);
12312909Sgarrison    /*
12412909Sgarrison    pass 2 - reread files, replacing references
12512909Sgarrison    */
12612909Sgarrison    pass2(tfd, stdout);
12715902Srrh    cleanup(0);
12815902Srrh }
12915902Srrh /* interrupt processing */
13015902Srrh intr()
13115902Srrh {
13215902Srrh    cleanup(1);
13315902Srrh }
13415902Srrh /* clean up and exit */
13515902Srrh cleanup(val)
13615902Srrh {
13712909Sgarrison    fclose(tfd);
13815902Srrh #ifndef INCORE
13912909Sgarrison    fclose(rfd);
14015902Srrh    unlink(reffile);
14115902Srrh #endif INCORE
14215902Srrh #ifndef DEBUG
14330590Sgarrison    unlink(bibtmpfile);
14415902Srrh #endif DEBUG
14515902Srrh    exit(val);
14612909Sgarrison }
14712909Sgarrison 
14812909Sgarrison /* rdtext - read and process a text file, looking for [. commands */
14912909Sgarrison    rdtext(fd)
15012909Sgarrison    FILE *fd;
15112909Sgarrison {  char lastc, c, d;
15212909Sgarrison 
15315066Sgarrison    lastc = '\0';
15415066Sgarrison    biblineno = 1;
15512909Sgarrison    while (getch(c, fd) != EOF)
15612909Sgarrison       if (c == '[' || c == '{')
15712909Sgarrison          if (getch(d, fd) == '.') { /* found a reference */
15812909Sgarrison             if (c == '{') { if (lastc) putc(lastc, tfd);}
15912909Sgarrison             else
16015066Sgarrison                switch (lastc) {
16115066Sgarrison                   case '\0': break;
16215066Sgarrison                   case ' ': fputs("\\*([<", tfd); break;
16315066Sgarrison                   case '.': case ',': case '?': case ':':
16415066Sgarrison                   case ';': case '!': case '"': case '\'':
16515066Sgarrison                             fputs("\\*([", tfd);  /* fall through */
16615066Sgarrison                   default:  putc(lastc, tfd); break;
16715066Sgarrison                   }
16812909Sgarrison             rdcite(fd, c);
16912909Sgarrison             if (c == '[')
17015066Sgarrison                switch (lastc) {
17115066Sgarrison                   case '\0': break;
17215066Sgarrison                   case ' ': fputs("\\*(>]", tfd); break;
17315066Sgarrison                   case '.': case ',': case '?': case ':':
17415066Sgarrison                   case ';': case '!': case '"': case '\'':
17515066Sgarrison                             fprintf(tfd,"\\*(%c]", lastc); break;
17615066Sgarrison                   }
17715066Sgarrison             lastc = '\0';
17812909Sgarrison             }
17912909Sgarrison          else {
18015066Sgarrison             if (lastc != '\0') putc(lastc, tfd);
18112909Sgarrison             ungetc(d, fd);
18212909Sgarrison             lastc = c;
18312909Sgarrison             }
18412909Sgarrison       else {
18515066Sgarrison          if (lastc != '\0') putc(lastc, tfd);
18612909Sgarrison          lastc = c;
18715066Sgarrison          if (c == '\n') biblineno++;
18812909Sgarrison          }
18915066Sgarrison    if (lastc != '\0') putc(lastc, tfd);
19012909Sgarrison }
19112909Sgarrison 
19212909Sgarrison /* rdcite - read citation information inside a [. command */
19312909Sgarrison    rdcite(fd, ch)
19412909Sgarrison    FILE *fd;
19512909Sgarrison    char ch;
19616245Srrh {  int getref();
19712909Sgarrison    char huntstr[HUNTSIZE], c, info[HUNTSIZE];
19812909Sgarrison 
19912909Sgarrison    if (ch == '[')
20017245Srrh       if (doacite) fputs("\\*([[", tfd);
20112909Sgarrison    else
20217245Srrh       if (doacite) fputs("\\*([{", tfd);
20312909Sgarrison    huntstr[0] = info[0] = 0;
20412909Sgarrison    while (getch(c, fd) != EOF)
20512909Sgarrison       switch (c) {
20612909Sgarrison          case ',':
207*60507Sbostic 	    citemark(info, huntstr, "");
20812909Sgarrison             huntstr[0] = info[0] = 0;
20912909Sgarrison             break;
21012909Sgarrison          case '.':
21112909Sgarrison             while (getch(c, fd) == '.') ;
21212909Sgarrison             if (c == ']') {
21315902Srrh 	       citemark(info, huntstr, "\\*(]]");
21412909Sgarrison                return;
21512909Sgarrison                }
21612909Sgarrison             else if (c == '}') {
21715902Srrh 	       citemark(info, huntstr, "\\*(}]");
21812909Sgarrison                return;
21912909Sgarrison                }
22012909Sgarrison             else
22112909Sgarrison                addc(huntstr, c);
22212909Sgarrison             break;
22312909Sgarrison 
22412909Sgarrison          case '{':
22512909Sgarrison             while (getch(c, fd) != '}')
22612909Sgarrison                if (c == EOF) {
22715902Srrh                   error("ill formed reference");
22812909Sgarrison                   }
22912909Sgarrison                 else
23012909Sgarrison                   addc(info, c);
23112909Sgarrison             break;
23212909Sgarrison 
23312909Sgarrison          case '\n':
23415066Sgarrison             biblineno++;
23512909Sgarrison          case '\t':
23612909Sgarrison             c = ' ';   /* fall through */
23712909Sgarrison 
23812909Sgarrison          default:
23912909Sgarrison             addc(huntstr,c);
24012909Sgarrison          }
24112909Sgarrison    error("end of file reading citation");
24212909Sgarrison }
24316245Srrh char	ncitetemplate[64];
24416245Srrh int	changecite;
24515902Srrh citemark(info, huntstr, tail)
24615902Srrh 	char *info, *huntstr, *tail;
24715902Srrh {
24815902Srrh 	char c = CITEMARK;
24915902Srrh         long int  n;
25016245Srrh 	/*
25116245Srrh 	 *	getref sets ncitetemplate as a side effect
25216245Srrh 	 */
25315902Srrh 	n = getref(huntstr);
25416245Srrh 	if (ncitetemplate[0]){
25516245Srrh 		fprintf(tfd, "%c%s%c", FMTSTART, ncitetemplate, FMTEND);
25616245Srrh 		ncitetemplate[0] = 0;
25716245Srrh 	}
258*60507Sbostic 	fprintf(tfd, "%c%d%c%s%c%s", c ,n, c, info, CITEEND, doacite?tail:"");
25924014Srrh 
26015902Srrh }
26112909Sgarrison 
26212909Sgarrison /* addc - add a character to hunt string */
263*60507Sbostic addc(huntstr, c)
26412909Sgarrison    char huntstr[HUNTSIZE], c;
26512909Sgarrison {  int  i;
26612909Sgarrison 
26712909Sgarrison    i = strlen(huntstr);
26812909Sgarrison    if (i > HUNTSIZE)
26915902Srrh       error("citation too long, max of %d", HUNTSIZE);
27012909Sgarrison    huntstr[i] = c;
27112909Sgarrison    huntstr[i+1] = 0;
27212909Sgarrison }
273*60507Sbostic 
27415902Srrh /* getref - if an item was already referenced, return its reference index
27515902Srrh                 otherwise create a new entry */
276*60507Sbostic int getref(huntstr)
27712909Sgarrison    char huntstr[HUNTSIZE];
27815902Srrh {  char rf[REFSIZE], *r, *hunt();
27915902Srrh    int	match(), getwrd();
28015891Srrh    char	*realhstr;
28115902Srrh    int hash;
28215902Srrh    struct refinfo *rp;
28315902Srrh    int	lg;
28412909Sgarrison 
28515891Srrh    realhstr = huntstr;
28615891Srrh    if (strncmp(huntstr, "$C$", 3) == 0){
28715891Srrh 	char *from, *to;
28816245Srrh 	changecite++;
28916245Srrh 	for(from = huntstr + 3, to = ncitetemplate; *from; from++, to++){
29015891Srrh 		switch(*from){
29115891Srrh 		case '\0':
29215891Srrh 		case ' ':
29315891Srrh 		case '\n':
29415891Srrh 		case '\t':	goto outcopy;
29515891Srrh 		default:	*to = *from;
29615891Srrh 		}
29715891Srrh 	}
29815891Srrh    outcopy: ;
29915891Srrh 	*to = 0;
30015891Srrh 	*from = 0;
30115891Srrh 	realhstr = from + 1;
30215891Srrh    }
30315891Srrh    r = hunt(realhstr);
30412909Sgarrison    if (r != NULL) {
30515902Srrh       /* expand defined string */
30612909Sgarrison       strcpy(rf, r);
30712909Sgarrison       free(r);
30812909Sgarrison       expand(rf);
30912909Sgarrison       /* see if reference has already been cited */
31015902Srrh       if (foot == false && (rp = refssearch(rf))){
31115902Srrh 		return(rp - refinfo);
31215902Srrh       }
31312909Sgarrison       /* didn't match any existing reference, create new one */
31415902Srrh       if (numrefs >= MAXREFS)
31515902Srrh 	error("too many references, max of %d", MAXREFS);
31615902Srrh       hash = strhash(rf);
31715902Srrh       lg = strlen(rf) + 1;
31815902Srrh       refinfo[numrefs].ri_pos = rend;
31915902Srrh       refinfo[numrefs].ri_length = lg;
32015902Srrh       refinfo[numrefs].ri_hp = refshash[hash];
32115902Srrh       refinfo[numrefs].ri_n = numrefs;
32215902Srrh       refshash[hash] = &refinfo[numrefs];
32315902Srrh       wrref(&refinfo[numrefs], rf);
32415902Srrh       return(numrefs++);
32512909Sgarrison       }
32612909Sgarrison    else {
32715891Srrh       bibwarning("no reference matching %s\n", realhstr);
32815902Srrh       return(-1);
32912909Sgarrison       }
33012909Sgarrison }
331*60507Sbostic 
33215902Srrh struct refinfo *refssearch(rf)
33315902Srrh    char *rf;
33415902Srrh {
33515902Srrh    char ref[REFSIZE];
33615902Srrh    reg	int i;
33715902Srrh    int	lg;
33815902Srrh    reg	struct refinfo *rp;
33915902Srrh    lg = strlen(rf) + 1;
34015902Srrh    for (rp = refshash[strhash(rf)]; rp; rp = rp->ri_hp){
34115902Srrh 	     if (rp->ri_length == lg){
34215902Srrh 		     rdref(rp, ref);
34315902Srrh 		     if (strcmp(ref, rf) == 0)
34415902Srrh 			return(rp);
34515902Srrh 	     }
34615902Srrh    }
34715902Srrh    return(0);
34815902Srrh }
34912909Sgarrison /* hunt - hunt for reference from either personal or system index */
350*60507Sbostic /* the old versions would stop at the first index file where a citation
351*60507Sbostic  * matched.  This is NOT what is desired.  I have changed it so that it still
352*60507Sbostic  * returns the first citation found, but also reports the existence of
353*60507Sbostic  * duplicate entries in an INDEX file as well as across INDEX files.
354*60507Sbostic  * Also, we do NOT assume that the SYSINDEX has been Tib'd.  Therefore,
355*60507Sbostic  * if tib style expansion is in effect, the SYSINDEX is not searched.
356*60507Sbostic  * (Besides which, on Sun systems at least, the SYSINDEX files are
357*60507Sbostic  * created by refer, not bib, so we can't use them very effectively
358*60507Sbostic  * anyway.  Besides which again, everything in SYSINDEX is in our
359*60507Sbostic  * local files anyway.)
360*60507Sbostic  *                   - ads 8/88
361*60507Sbostic  */
362*60507Sbostic char *hunt(huntstr)
36312909Sgarrison    char huntstr[];
364*60507Sbostic {  char *found, *fhunt(), *r, *tp, *sp, fname[120];
36512909Sgarrison 
366*60507Sbostic    found = NULL;
36712909Sgarrison    if (personal) {
368*60507Sbostic       for (tp = fname, sp = pfile; ; sp++)
369*60507Sbostic          if (*sp == ',' || *sp == '\0') {
370*60507Sbostic             *tp = '\0';
371*60507Sbostic             if ((r = fhunt(fname, huntstr)) != NULL) {
372*60507Sbostic 		if (found != NULL) {
373*60507Sbostic 		    /* we need an option to suppress this message -ads 5/89 */
374*60507Sbostic 		    bibwarning("multiple INDEX files match citation %s\n",
375*60507Sbostic 							huntstr);
376*60507Sbostic 		    return (found);
377*60507Sbostic 		    }
378*60507Sbostic 		found = r;
379*60507Sbostic 		}
380*60507Sbostic             if (*sp == '\0')
38112909Sgarrison                break;
382*60507Sbostic             tp = fname;
38312909Sgarrison             }
384*60507Sbostic          else *tp++ = *sp;
385*60507Sbostic       if (found != NULL) return (found);
38612909Sgarrison       }
38712909Sgarrison    else if (findex) {
388*60507Sbostic       if ((r = fhunt(INDXFILE , huntstr)) != NULL)
38912909Sgarrison          return(r);
39012909Sgarrison       }
391*60507Sbostic    if (!TibOption) {
392*60507Sbostic       if ((r = fhunt(SYSINDEX , huntstr)) != NULL)
393*60507Sbostic 	 return(r);
394*60507Sbostic       }
39512909Sgarrison    return(NULL);
39612909Sgarrison }
39712909Sgarrison 
39812909Sgarrison /* fhunt - hunt from a specific file */
39912909Sgarrison    char *fhunt(file, huntstr)
40012909Sgarrison    char file[], huntstr[];
40112909Sgarrison {  char *p, *r, *locate();
40212909Sgarrison 
40323484Sgarrison    r = locate(huntstr, file, max_klen, common);
40412909Sgarrison 
40512909Sgarrison    if (r == NULL)
40612909Sgarrison       return(NULL);  /* error */
40712909Sgarrison    if (*r == 0)
40812909Sgarrison       return(NULL);  /* no match */
40912909Sgarrison 
41012909Sgarrison    for (p = r; *p; p++)
41112909Sgarrison       if (*p == '\n')
41212909Sgarrison          if (*(p+1) == '\n') { /* end */
41312909Sgarrison             if (*(p+2) != 0)
41415066Sgarrison                bibwarning("multiple references match %s\n",huntstr);
41512909Sgarrison             *(p+1) = 0;
41612909Sgarrison             break;
41712909Sgarrison             }
41812909Sgarrison          else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */
41912909Sgarrison             *p = ' ';
42012909Sgarrison    return(r);
42112909Sgarrison }
42215902Srrh struct cite{
42315902Srrh 	int	num;
42415902Srrh 	char	*info;
42515902Srrh };
42615902Srrh citesort(p1, p2)
42715902Srrh 	struct cite *p1, *p2;
42815902Srrh {
42915902Srrh 	return(p1->num - p2->num);
43015902Srrh }
43112909Sgarrison 
43212909Sgarrison /* putrefs - gather contiguous references together, sort them if called
43312909Sgarrison    for, hyphenate if necessary, and dump them out */
43412909Sgarrison int putrefs(ifd, ofd, footrefs, fn)
43512909Sgarrison FILE *ifd, *ofd;
43612909Sgarrison int  fn, footrefs[];
43715902Srrh {
43815902Srrh 	struct cite cites[MAXATONCE];
43915902Srrh 	char	infoword[HUNTSIZE];    /* information line */
44015902Srrh 	reg	int i;
44115902Srrh 	reg	char *p;
44215902Srrh 	reg	int  ncites, n, j;         /* number of citations being dumped */
44315902Srrh 	char	c, *walloc();
44415902Srrh 	int neg;
44515902Srrh 	/*
44615902Srrh 	 * first gather contiguous references together,
44715902Srrh 	 * and order them if required
44815902Srrh 	 */
44912909Sgarrison 
45015902Srrh 	ncites = 0;
45115902Srrh 	do {
45223484Sgarrison 		neg = 1;
45315902Srrh 		n = 0;
45415902Srrh 		do{
45515902Srrh 			getch(c, ifd);
45615902Srrh 			if (isdigit(c))
45715902Srrh 				n = 10 * n + (c - '0');
45815902Srrh 			else if (c == '-')
45915902Srrh 				neg *= -1;
46015902Srrh 			else if (c == CITEMARK)
46115902Srrh 				break;
46215902Srrh 			else
46315902Srrh 				error("bad cite char 0%03o in pass two",c);
46415902Srrh 		} while(1);
46515902Srrh 		if (neg < 0) {     /* reference not found */
46615902Srrh 			cites[ncites].num = -1;
46715902Srrh 			cites[ncites].info = 0;
46815902Srrh 			ncites++;
46915902Srrh 		} else {
47015902Srrh 			/*
47115902Srrh 			 * Find reference n in the references
47215902Srrh 			 */
47315902Srrh 			int i;
47415902Srrh 			for (i = 0; i < numrefs; i++){
47515902Srrh 				if (refinfo[i].ri_n == n){
47615902Srrh 					cites[ncites].num = i;
47715902Srrh 					cites[ncites].info = 0;
47815902Srrh 					ncites++;
47915902Srrh 					break;
48015902Srrh 				}
48115902Srrh 			}
48215902Srrh 			if (i == numrefs)
48315902Srrh 				error("citation	%d not found in pass 2", n);
48415902Srrh 		}
48515902Srrh 		if (getch(c, ifd) != CITEEND) {
48615902Srrh 			for (p = infoword; c != CITEEND ; ) {
48715902Srrh 				*p++ = c;
48815902Srrh 				getch(c, ifd);
48915902Srrh 			}
49015902Srrh 			*p = 0;
49115902Srrh 			cites[ncites-1].info = walloc(infoword);
49215902Srrh 		}
49315902Srrh 		getch(c, ifd);
49415902Srrh 	} while (c == CITEMARK);
49515902Srrh 	ungetc(c, ifd);
49615902Srrh 	if (ordcite)
49715902Srrh 		qsort(cites, ncites, sizeof(struct cite), citesort);
49812909Sgarrison 
49915902Srrh 	/* now dump out values */
50015902Srrh 	for (i = 0; i < ncites; i++) {
50116245Srrh 		if (cites[i].num >= 0) {
50216245Srrh 			if (changecite){
50316245Srrh 				char tempcite[128];
50416245Srrh 				char ref[REFSIZE];
50516245Srrh 				struct refinfo *p;
50616245Srrh 				/*
50716245Srrh 				 * rebuild the citation string,
50816245Srrh 				 * using the current template in effect
50916245Srrh 				 */
51016245Srrh 				p = &refinfo[cites[i].num];
51116245Srrh 				rdref(p, ref);
51216245Srrh 				bldcite(tempcite, cites[i].num, ref);
51316245Srrh 				strcat(tempcite, p->ri_disambig);
51417245Srrh 				if (doacite) fputs(tempcite, ofd);
51516245Srrh 			} else {
51617245Srrh 				if (doacite) fputs(refinfo[cites[i].num].ri_cite, ofd);
51716245Srrh 			}
51817245Srrh 			if (!doacite) fputs("\\&", ofd);
51916245Srrh 		}
52015902Srrh 		if (cites[i].info) {
52117245Srrh 			if (doacite) fputs(cites[i].info, ofd);
52217245Srrh 			if (!doacite) fputs("\\&", ofd);
52315902Srrh 			free(cites[i].info);
52415902Srrh 		}
52515902Srrh 		if (hyphen) {
52615902Srrh 			for (j = 1;
52715902Srrh 			     j + i <= ncites && cites[i+j].num == cites[i].num + j;
52815902Srrh 			     j++)/*VOID*/;
52915902Srrh 			if (j + i > ncites)
53015902Srrh 				j = ncites;
53115902Srrh 			else
53215902Srrh 				j = j + i - 1;
53315902Srrh 		} else {
53415902Srrh 			j = i;
53515902Srrh 		}
53615902Srrh 		if (j > i + 1) {
53715902Srrh 			fputs("\\*(]-", ofd);
53815902Srrh 			i = j - 1;
53915902Srrh 		} else if (i != ncites - 1) {
54015902Srrh 			fputs("\\*(],", ofd);
54115902Srrh 		}
54215902Srrh 		if (foot) {
54315902Srrh 			fn++;
54415902Srrh 			footrefs[fn] = cites[i].num;
54515902Srrh 		}
54615902Srrh 	}
54715902Srrh 	return(fn);
54812909Sgarrison }
54912909Sgarrison 
55012909Sgarrison /* pass2 - read pass 1 files entering citation */
55112909Sgarrison    pass2(ifd, ofd)
55212909Sgarrison    FILE *ifd, *ofd;
55312909Sgarrison {
55412909Sgarrison    char c;
55512909Sgarrison    int  i, fn, footrefs[25], dumped;
55612909Sgarrison 
55712909Sgarrison    fn = -1;
55812909Sgarrison    dumped = foot;
55912909Sgarrison    while (getch(c, ifd) != EOF) {
56012909Sgarrison       while (c == '\n') {
56112909Sgarrison          putc(c, ofd);
56212909Sgarrison          if (foot && fn >= 0) {
56312909Sgarrison             for (i = 0; i <= fn; i++)
56412909Sgarrison                 dumpref(footrefs[i], ofd);
56512909Sgarrison             fn = -1;
56612909Sgarrison             }
56712909Sgarrison          if (testc(c, '.', ifd, ofd))
56812909Sgarrison             if (testc(c, '[', ifd, ofd))
56912909Sgarrison                if (testc(c, ']', ifd, ofd)) {
57012909Sgarrison                   while (echoc(c, ifd, ofd) != '\n')
57112909Sgarrison                      ;
57212909Sgarrison                   dumped = true;
57315902Srrh                   for (i = 0; i < numrefs; i++){
57412909Sgarrison                      dumpref(i, ofd);
57515902Srrh 		  }
57612909Sgarrison                   getch(c, ifd);
57712909Sgarrison                   }
57812909Sgarrison          }
57916245Srrh       if (c == FMTSTART)
58016245Srrh 	 changefmt(ifd);
58116245Srrh       else if (c == CITEMARK)
58212909Sgarrison          fn = putrefs(ifd, ofd, footrefs, fn);
58312909Sgarrison       else if (c != EOF)
58412909Sgarrison          putc(c, ofd);
58512909Sgarrison       }
58612909Sgarrison    if (dumped == false)
58715066Sgarrison       bibwarning("Warning: references never dumped\n","");
58812909Sgarrison }
58916245Srrh /*
59016245Srrh  *	change citation format
59116245Srrh  */
59216245Srrh changefmt(ifd)
59316245Srrh 	FILE	*ifd;
59416245Srrh {
59516245Srrh 	char	c;
59616245Srrh 	char	*to;
59716245Srrh 	to = ncitetemplate;
59816245Srrh 	while (getch(c, ifd) != FMTEND)
59916245Srrh 		*to++ = c;
60016245Srrh 	*to = 0;
60116245Srrh 	strcpy(citetemplate, ncitetemplate);
60216245Srrh }
603