113109Srrh #ifndef lint
2*65358Sbostic static char sccsid[] = "@(#)bib.c 2.12 01/03/94";
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
1760507Sbostic version 8/23/1988
1860507Sbostic
1960507Sbostic Adapted to use TiB style macro calls (i.e. |macro|)
2060507Sbostic A. Dain Samples
2115066Sgarrison
2260507Sbostic */
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
5160507Sbostic char *programName;
5260507Sbostic
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[];
5760507Sbostic extern int TibOption;
5812909Sgarrison
5915902Srrh #include <signal.h>
6012909Sgarrison
main(argc,argv)6112909Sgarrison main(argc, argv)
6212909Sgarrison int argc;
6312909Sgarrison char **argv;
6412909Sgarrison { int rcomp();
65*65358Sbostic void intr();
6612909Sgarrison
6712909Sgarrison /* the file INDEX in the current directory is the default index,
6812909Sgarrison if it is present */
6912909Sgarrison
7060507Sbostic InitDirectory(BMACLIB,N_BMACLIB);
7160507Sbostic InitDirectory(COMFILE,N_COMFILE);
7260507Sbostic 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
10160507Sbostic 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 */
130*65358Sbostic void
intr()13115902Srrh intr()
13215902Srrh {
13315902Srrh cleanup(1);
13415902Srrh }
13515902Srrh /* clean up and exit */
cleanup(val)13615902Srrh cleanup(val)
13715902Srrh {
13812909Sgarrison fclose(tfd);
13915902Srrh #ifndef INCORE
14012909Sgarrison fclose(rfd);
14115902Srrh unlink(reffile);
14215902Srrh #endif INCORE
14315902Srrh #ifndef DEBUG
14430590Sgarrison unlink(bibtmpfile);
14515902Srrh #endif DEBUG
14615902Srrh exit(val);
14712909Sgarrison }
14812909Sgarrison
14912909Sgarrison /* rdtext - read and process a text file, looking for [. commands */
rdtext(fd)15012909Sgarrison rdtext(fd)
15112909Sgarrison FILE *fd;
15212909Sgarrison { char lastc, c, d;
15312909Sgarrison
15415066Sgarrison lastc = '\0';
15515066Sgarrison biblineno = 1;
15612909Sgarrison while (getch(c, fd) != EOF)
15712909Sgarrison if (c == '[' || c == '{')
15812909Sgarrison if (getch(d, fd) == '.') { /* found a reference */
15912909Sgarrison if (c == '{') { if (lastc) putc(lastc, tfd);}
16012909Sgarrison else
16115066Sgarrison switch (lastc) {
16215066Sgarrison case '\0': break;
16315066Sgarrison case ' ': fputs("\\*([<", tfd); break;
16415066Sgarrison case '.': case ',': case '?': case ':':
16515066Sgarrison case ';': case '!': case '"': case '\'':
16615066Sgarrison fputs("\\*([", tfd); /* fall through */
16715066Sgarrison default: putc(lastc, tfd); break;
16815066Sgarrison }
16912909Sgarrison rdcite(fd, c);
17012909Sgarrison if (c == '[')
17115066Sgarrison switch (lastc) {
17215066Sgarrison case '\0': break;
17315066Sgarrison case ' ': fputs("\\*(>]", tfd); break;
17415066Sgarrison case '.': case ',': case '?': case ':':
17515066Sgarrison case ';': case '!': case '"': case '\'':
17615066Sgarrison fprintf(tfd,"\\*(%c]", lastc); break;
17715066Sgarrison }
17815066Sgarrison lastc = '\0';
17912909Sgarrison }
18012909Sgarrison else {
18115066Sgarrison if (lastc != '\0') putc(lastc, tfd);
18212909Sgarrison ungetc(d, fd);
18312909Sgarrison lastc = c;
18412909Sgarrison }
18512909Sgarrison else {
18615066Sgarrison if (lastc != '\0') putc(lastc, tfd);
18712909Sgarrison lastc = c;
18815066Sgarrison if (c == '\n') biblineno++;
18912909Sgarrison }
19015066Sgarrison if (lastc != '\0') putc(lastc, tfd);
19112909Sgarrison }
19212909Sgarrison
19312909Sgarrison /* rdcite - read citation information inside a [. command */
rdcite(fd,ch)19412909Sgarrison rdcite(fd, ch)
19512909Sgarrison FILE *fd;
19612909Sgarrison char ch;
19716245Srrh { int getref();
19812909Sgarrison char huntstr[HUNTSIZE], c, info[HUNTSIZE];
19912909Sgarrison
20012909Sgarrison if (ch == '[')
20117245Srrh if (doacite) fputs("\\*([[", tfd);
20212909Sgarrison else
20317245Srrh if (doacite) fputs("\\*([{", tfd);
20412909Sgarrison huntstr[0] = info[0] = 0;
20512909Sgarrison while (getch(c, fd) != EOF)
20612909Sgarrison switch (c) {
20712909Sgarrison case ',':
20860507Sbostic citemark(info, huntstr, "");
20912909Sgarrison huntstr[0] = info[0] = 0;
21012909Sgarrison break;
21112909Sgarrison case '.':
21212909Sgarrison while (getch(c, fd) == '.') ;
21312909Sgarrison if (c == ']') {
21415902Srrh citemark(info, huntstr, "\\*(]]");
21512909Sgarrison return;
21612909Sgarrison }
21712909Sgarrison else if (c == '}') {
21815902Srrh citemark(info, huntstr, "\\*(}]");
21912909Sgarrison return;
22012909Sgarrison }
22112909Sgarrison else
22212909Sgarrison addc(huntstr, c);
22312909Sgarrison break;
22412909Sgarrison
22512909Sgarrison case '{':
22612909Sgarrison while (getch(c, fd) != '}')
22712909Sgarrison if (c == EOF) {
22815902Srrh error("ill formed reference");
22912909Sgarrison }
23012909Sgarrison else
23112909Sgarrison addc(info, c);
23212909Sgarrison break;
23312909Sgarrison
23412909Sgarrison case '\n':
23515066Sgarrison biblineno++;
23612909Sgarrison case '\t':
23712909Sgarrison c = ' '; /* fall through */
23812909Sgarrison
23912909Sgarrison default:
24012909Sgarrison addc(huntstr,c);
24112909Sgarrison }
24212909Sgarrison error("end of file reading citation");
24312909Sgarrison }
24416245Srrh char ncitetemplate[64];
24516245Srrh int changecite;
citemark(info,huntstr,tail)24615902Srrh citemark(info, huntstr, tail)
24715902Srrh char *info, *huntstr, *tail;
24815902Srrh {
24915902Srrh char c = CITEMARK;
25015902Srrh long int n;
25116245Srrh /*
25216245Srrh * getref sets ncitetemplate as a side effect
25316245Srrh */
25415902Srrh n = getref(huntstr);
25516245Srrh if (ncitetemplate[0]){
25616245Srrh fprintf(tfd, "%c%s%c", FMTSTART, ncitetemplate, FMTEND);
25716245Srrh ncitetemplate[0] = 0;
25816245Srrh }
25960507Sbostic fprintf(tfd, "%c%d%c%s%c%s", c ,n, c, info, CITEEND, doacite?tail:"");
26024014Srrh
26115902Srrh }
26212909Sgarrison
26312909Sgarrison /* addc - add a character to hunt string */
addc(huntstr,c)26460507Sbostic addc(huntstr, c)
26512909Sgarrison char huntstr[HUNTSIZE], c;
26612909Sgarrison { int i;
26712909Sgarrison
26812909Sgarrison i = strlen(huntstr);
26912909Sgarrison if (i > HUNTSIZE)
27015902Srrh error("citation too long, max of %d", HUNTSIZE);
27112909Sgarrison huntstr[i] = c;
27212909Sgarrison huntstr[i+1] = 0;
27312909Sgarrison }
27460507Sbostic
27515902Srrh /* getref - if an item was already referenced, return its reference index
27615902Srrh otherwise create a new entry */
getref(huntstr)27760507Sbostic int getref(huntstr)
27812909Sgarrison char huntstr[HUNTSIZE];
27915902Srrh { char rf[REFSIZE], *r, *hunt();
28015902Srrh int match(), getwrd();
28115891Srrh char *realhstr;
28215902Srrh int hash;
28315902Srrh struct refinfo *rp;
28415902Srrh int lg;
28512909Sgarrison
28615891Srrh realhstr = huntstr;
28715891Srrh if (strncmp(huntstr, "$C$", 3) == 0){
28815891Srrh char *from, *to;
28916245Srrh changecite++;
29016245Srrh for(from = huntstr + 3, to = ncitetemplate; *from; from++, to++){
29115891Srrh switch(*from){
29215891Srrh case '\0':
29315891Srrh case ' ':
29415891Srrh case '\n':
29515891Srrh case '\t': goto outcopy;
29615891Srrh default: *to = *from;
29715891Srrh }
29815891Srrh }
29915891Srrh outcopy: ;
30015891Srrh *to = 0;
30115891Srrh *from = 0;
30215891Srrh realhstr = from + 1;
30315891Srrh }
30415891Srrh r = hunt(realhstr);
30512909Sgarrison if (r != NULL) {
30615902Srrh /* expand defined string */
30712909Sgarrison strcpy(rf, r);
30812909Sgarrison free(r);
30912909Sgarrison expand(rf);
31012909Sgarrison /* see if reference has already been cited */
31115902Srrh if (foot == false && (rp = refssearch(rf))){
31215902Srrh return(rp - refinfo);
31315902Srrh }
31412909Sgarrison /* didn't match any existing reference, create new one */
31515902Srrh if (numrefs >= MAXREFS)
31615902Srrh error("too many references, max of %d", MAXREFS);
31715902Srrh hash = strhash(rf);
31815902Srrh lg = strlen(rf) + 1;
31915902Srrh refinfo[numrefs].ri_pos = rend;
32015902Srrh refinfo[numrefs].ri_length = lg;
32115902Srrh refinfo[numrefs].ri_hp = refshash[hash];
32215902Srrh refinfo[numrefs].ri_n = numrefs;
32315902Srrh refshash[hash] = &refinfo[numrefs];
32415902Srrh wrref(&refinfo[numrefs], rf);
32515902Srrh return(numrefs++);
32612909Sgarrison }
32712909Sgarrison else {
32815891Srrh bibwarning("no reference matching %s\n", realhstr);
32915902Srrh return(-1);
33012909Sgarrison }
33112909Sgarrison }
33260507Sbostic
refssearch(rf)33315902Srrh struct refinfo *refssearch(rf)
33415902Srrh char *rf;
33515902Srrh {
33615902Srrh char ref[REFSIZE];
33715902Srrh reg int i;
33815902Srrh int lg;
33915902Srrh reg struct refinfo *rp;
34015902Srrh lg = strlen(rf) + 1;
34115902Srrh for (rp = refshash[strhash(rf)]; rp; rp = rp->ri_hp){
34215902Srrh if (rp->ri_length == lg){
34315902Srrh rdref(rp, ref);
34415902Srrh if (strcmp(ref, rf) == 0)
34515902Srrh return(rp);
34615902Srrh }
34715902Srrh }
34815902Srrh return(0);
34915902Srrh }
35012909Sgarrison /* hunt - hunt for reference from either personal or system index */
35160507Sbostic /* the old versions would stop at the first index file where a citation
35260507Sbostic * matched. This is NOT what is desired. I have changed it so that it still
35360507Sbostic * returns the first citation found, but also reports the existence of
35460507Sbostic * duplicate entries in an INDEX file as well as across INDEX files.
35560507Sbostic * Also, we do NOT assume that the SYSINDEX has been Tib'd. Therefore,
35660507Sbostic * if tib style expansion is in effect, the SYSINDEX is not searched.
35760507Sbostic * (Besides which, on Sun systems at least, the SYSINDEX files are
35860507Sbostic * created by refer, not bib, so we can't use them very effectively
35960507Sbostic * anyway. Besides which again, everything in SYSINDEX is in our
36060507Sbostic * local files anyway.)
36160507Sbostic * - ads 8/88
36260507Sbostic */
hunt(huntstr)36360507Sbostic char *hunt(huntstr)
36412909Sgarrison char huntstr[];
36560507Sbostic { char *found, *fhunt(), *r, *tp, *sp, fname[120];
36612909Sgarrison
36760507Sbostic found = NULL;
36812909Sgarrison if (personal) {
36960507Sbostic for (tp = fname, sp = pfile; ; sp++)
37060507Sbostic if (*sp == ',' || *sp == '\0') {
37160507Sbostic *tp = '\0';
37260507Sbostic if ((r = fhunt(fname, huntstr)) != NULL) {
37360507Sbostic if (found != NULL) {
37460507Sbostic /* we need an option to suppress this message -ads 5/89 */
37560507Sbostic bibwarning("multiple INDEX files match citation %s\n",
37660507Sbostic huntstr);
37760507Sbostic return (found);
37860507Sbostic }
37960507Sbostic found = r;
38060507Sbostic }
38160507Sbostic if (*sp == '\0')
38212909Sgarrison break;
38360507Sbostic tp = fname;
38412909Sgarrison }
38560507Sbostic else *tp++ = *sp;
38660507Sbostic if (found != NULL) return (found);
38712909Sgarrison }
38812909Sgarrison else if (findex) {
38960507Sbostic if ((r = fhunt(INDXFILE , huntstr)) != NULL)
39012909Sgarrison return(r);
39112909Sgarrison }
39260507Sbostic if (!TibOption) {
39360507Sbostic if ((r = fhunt(SYSINDEX , huntstr)) != NULL)
39460507Sbostic return(r);
39560507Sbostic }
39612909Sgarrison return(NULL);
39712909Sgarrison }
39812909Sgarrison
39912909Sgarrison /* fhunt - hunt from a specific file */
fhunt(file,huntstr)40012909Sgarrison char *fhunt(file, huntstr)
40112909Sgarrison char file[], huntstr[];
40212909Sgarrison { char *p, *r, *locate();
40312909Sgarrison
40423484Sgarrison r = locate(huntstr, file, max_klen, common);
40512909Sgarrison
40612909Sgarrison if (r == NULL)
40712909Sgarrison return(NULL); /* error */
40812909Sgarrison if (*r == 0)
40912909Sgarrison return(NULL); /* no match */
41012909Sgarrison
41112909Sgarrison for (p = r; *p; p++)
41212909Sgarrison if (*p == '\n')
41312909Sgarrison if (*(p+1) == '\n') { /* end */
41412909Sgarrison if (*(p+2) != 0)
41515066Sgarrison bibwarning("multiple references match %s\n",huntstr);
41612909Sgarrison *(p+1) = 0;
41712909Sgarrison break;
41812909Sgarrison }
41912909Sgarrison else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */
42012909Sgarrison *p = ' ';
42112909Sgarrison return(r);
42212909Sgarrison }
42315902Srrh struct cite{
42415902Srrh int num;
42515902Srrh char *info;
42615902Srrh };
42715902Srrh citesort(p1, p2)
42815902Srrh struct cite *p1, *p2;
42915902Srrh {
43015902Srrh return(p1->num - p2->num);
43115902Srrh }
43212909Sgarrison
43312909Sgarrison /* putrefs - gather contiguous references together, sort them if called
43412909Sgarrison for, hyphenate if necessary, and dump them out */
putrefs(ifd,ofd,footrefs,fn)43512909Sgarrison int putrefs(ifd, ofd, footrefs, fn)
43612909Sgarrison FILE *ifd, *ofd;
43712909Sgarrison int fn, footrefs[];
43815902Srrh {
43915902Srrh struct cite cites[MAXATONCE];
44015902Srrh char infoword[HUNTSIZE]; /* information line */
44115902Srrh reg int i;
44215902Srrh reg char *p;
44315902Srrh reg int ncites, n, j; /* number of citations being dumped */
44415902Srrh char c, *walloc();
44515902Srrh int neg;
44615902Srrh /*
44715902Srrh * first gather contiguous references together,
44815902Srrh * and order them if required
44915902Srrh */
45012909Sgarrison
45115902Srrh ncites = 0;
45215902Srrh do {
45323484Sgarrison neg = 1;
45415902Srrh n = 0;
45515902Srrh do{
45615902Srrh getch(c, ifd);
45715902Srrh if (isdigit(c))
45815902Srrh n = 10 * n + (c - '0');
45915902Srrh else if (c == '-')
46015902Srrh neg *= -1;
46115902Srrh else if (c == CITEMARK)
46215902Srrh break;
46315902Srrh else
46415902Srrh error("bad cite char 0%03o in pass two",c);
46515902Srrh } while(1);
46615902Srrh if (neg < 0) { /* reference not found */
46715902Srrh cites[ncites].num = -1;
46815902Srrh cites[ncites].info = 0;
46915902Srrh ncites++;
47015902Srrh } else {
47115902Srrh /*
47215902Srrh * Find reference n in the references
47315902Srrh */
47415902Srrh int i;
47515902Srrh for (i = 0; i < numrefs; i++){
47615902Srrh if (refinfo[i].ri_n == n){
47715902Srrh cites[ncites].num = i;
47815902Srrh cites[ncites].info = 0;
47915902Srrh ncites++;
48015902Srrh break;
48115902Srrh }
48215902Srrh }
48315902Srrh if (i == numrefs)
48415902Srrh error("citation %d not found in pass 2", n);
48515902Srrh }
48615902Srrh if (getch(c, ifd) != CITEEND) {
48715902Srrh for (p = infoword; c != CITEEND ; ) {
48815902Srrh *p++ = c;
48915902Srrh getch(c, ifd);
49015902Srrh }
49115902Srrh *p = 0;
49215902Srrh cites[ncites-1].info = walloc(infoword);
49315902Srrh }
49415902Srrh getch(c, ifd);
49515902Srrh } while (c == CITEMARK);
49615902Srrh ungetc(c, ifd);
49715902Srrh if (ordcite)
49815902Srrh qsort(cites, ncites, sizeof(struct cite), citesort);
49912909Sgarrison
50015902Srrh /* now dump out values */
50115902Srrh for (i = 0; i < ncites; i++) {
50216245Srrh if (cites[i].num >= 0) {
50316245Srrh if (changecite){
50416245Srrh char tempcite[128];
50516245Srrh char ref[REFSIZE];
50616245Srrh struct refinfo *p;
50716245Srrh /*
50816245Srrh * rebuild the citation string,
50916245Srrh * using the current template in effect
51016245Srrh */
51116245Srrh p = &refinfo[cites[i].num];
51216245Srrh rdref(p, ref);
51316245Srrh bldcite(tempcite, cites[i].num, ref);
51416245Srrh strcat(tempcite, p->ri_disambig);
51517245Srrh if (doacite) fputs(tempcite, ofd);
51616245Srrh } else {
51717245Srrh if (doacite) fputs(refinfo[cites[i].num].ri_cite, ofd);
51816245Srrh }
51917245Srrh if (!doacite) fputs("\\&", ofd);
52016245Srrh }
52115902Srrh if (cites[i].info) {
52217245Srrh if (doacite) fputs(cites[i].info, ofd);
52317245Srrh if (!doacite) fputs("\\&", ofd);
52415902Srrh free(cites[i].info);
52515902Srrh }
52615902Srrh if (hyphen) {
52715902Srrh for (j = 1;
52815902Srrh j + i <= ncites && cites[i+j].num == cites[i].num + j;
52915902Srrh j++)/*VOID*/;
53015902Srrh if (j + i > ncites)
53115902Srrh j = ncites;
53215902Srrh else
53315902Srrh j = j + i - 1;
53415902Srrh } else {
53515902Srrh j = i;
53615902Srrh }
53715902Srrh if (j > i + 1) {
53815902Srrh fputs("\\*(]-", ofd);
53915902Srrh i = j - 1;
54015902Srrh } else if (i != ncites - 1) {
54115902Srrh fputs("\\*(],", ofd);
54215902Srrh }
54315902Srrh if (foot) {
54415902Srrh fn++;
54515902Srrh footrefs[fn] = cites[i].num;
54615902Srrh }
54715902Srrh }
54815902Srrh return(fn);
54912909Sgarrison }
55012909Sgarrison
55112909Sgarrison /* pass2 - read pass 1 files entering citation */
pass2(ifd,ofd)55212909Sgarrison pass2(ifd, ofd)
55312909Sgarrison FILE *ifd, *ofd;
55412909Sgarrison {
55512909Sgarrison char c;
55612909Sgarrison int i, fn, footrefs[25], dumped;
55712909Sgarrison
55812909Sgarrison fn = -1;
55912909Sgarrison dumped = foot;
56012909Sgarrison while (getch(c, ifd) != EOF) {
56112909Sgarrison while (c == '\n') {
56212909Sgarrison putc(c, ofd);
56312909Sgarrison if (foot && fn >= 0) {
56412909Sgarrison for (i = 0; i <= fn; i++)
56512909Sgarrison dumpref(footrefs[i], ofd);
56612909Sgarrison fn = -1;
56712909Sgarrison }
56812909Sgarrison if (testc(c, '.', ifd, ofd))
56912909Sgarrison if (testc(c, '[', ifd, ofd))
57012909Sgarrison if (testc(c, ']', ifd, ofd)) {
57112909Sgarrison while (echoc(c, ifd, ofd) != '\n')
57212909Sgarrison ;
57312909Sgarrison dumped = true;
57415902Srrh for (i = 0; i < numrefs; i++){
57512909Sgarrison dumpref(i, ofd);
57615902Srrh }
57712909Sgarrison getch(c, ifd);
57812909Sgarrison }
57912909Sgarrison }
58016245Srrh if (c == FMTSTART)
58116245Srrh changefmt(ifd);
58216245Srrh else if (c == CITEMARK)
58312909Sgarrison fn = putrefs(ifd, ofd, footrefs, fn);
58412909Sgarrison else if (c != EOF)
58512909Sgarrison putc(c, ofd);
58612909Sgarrison }
58712909Sgarrison if (dumped == false)
58815066Sgarrison bibwarning("Warning: references never dumped\n","");
58912909Sgarrison }
59016245Srrh /*
59116245Srrh * change citation format
59216245Srrh */
changefmt(ifd)59316245Srrh changefmt(ifd)
59416245Srrh FILE *ifd;
59516245Srrh {
59616245Srrh char c;
59716245Srrh char *to;
59816245Srrh to = ncitetemplate;
59916245Srrh while (getch(c, ifd) != FMTEND)
60016245Srrh *to++ = c;
60116245Srrh *to = 0;
60216245Srrh strcpy(citetemplate, ncitetemplate);
60316245Srrh }
604