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