1*13109Srrh #ifndef lint 2*13109Srrh static char sccsid[] = "@(#)bib.c 1.4 06/14/83"; 3*13109Srrh #endif not lint 4*13109Srrh 512909Sgarrison /* 612909Sgarrison bib - bibliographic formatter 712909Sgarrison timothy a. budd, 1/82 812909Sgarrison lookup routines supplied by gary levin 2/82 912909Sgarrison reworked several new features added, 11/82. 1012909Sgarrison */ 1112909Sgarrison # include <stdio.h> 1212909Sgarrison # include <ctype.h> 1312909Sgarrison # include "bib.h" 1412909Sgarrison 1512909Sgarrison # define HUNTSIZE 512 /* maximum size of hunt string */ 1612909Sgarrison # define MAXFIELD 250 /* maximum field length */ 1712909Sgarrison # define MAXREFS 300 /* maximum number of references */ 1812909Sgarrison # define MAXATONCE 35 /* maximum references at one location */ 1912909Sgarrison 2012909Sgarrison # define getch(c,fd) (c = getc(fd)) 2112909Sgarrison # define echoc(c,ifd,ofd) (getch(c,ifd) == EOF ? c : putc(c,ofd)) 2212909Sgarrison # define testc(c,d,ifd,ofd) (getch(c, ifd) == d ? putc(c, ofd) : 0) 2312909Sgarrison 2412909Sgarrison /* global variables */ 2512909Sgarrison FILE *rfd; /* reference temporary file */ 2612909Sgarrison char reffile[] = TMPREFFILE ;/* temporary file (see bib.h) */ 2712909Sgarrison long int refspos[MAXREFS]; /* reference seek positions */ 2812909Sgarrison long int rend = 1; /* last position in rfd (first char unused)*/ 2912909Sgarrison int numrefs = -1; /* number of references generated so far */ 3012909Sgarrison FILE *tfd; /* output of pass 1 of file(s) */ 3112909Sgarrison char tmpfile[] = TMPTEXTFILE ; /* output of pass 1 */ 3212909Sgarrison char common[] = COMFILE ; /* common word file */ 3312909Sgarrison char *citestr[MAXREFS]; /* citation strings */ 3412909Sgarrison int findex = false; /* can we read the file INDEX ? */ 3512909Sgarrison 3612909Sgarrison /* global variables in bibargs */ 3712909Sgarrison extern int foot, sort, personal; 3812909Sgarrison extern int hyphen, ordcite; 3912909Sgarrison extern char sortstr[], pfile[], citetemplate[]; 4013107Srrh char *bibfname; /* file name currently reading */ 4113107Srrh char *biblineno; /* line number in that file */ 4212909Sgarrison 4312909Sgarrison 4412909Sgarrison main(argc, argv) 4512909Sgarrison int argc; 4612909Sgarrison char **argv; 4712909Sgarrison { int rcomp(); 4812909Sgarrison 4912909Sgarrison /* the file INDEX in the current directory is the default index, 5012909Sgarrison if it is present */ 5112909Sgarrison 5212909Sgarrison rfd = fopen( INDXFILE , "r"); 5312909Sgarrison if (rfd != NULL) { 5412909Sgarrison findex = true; 5512909Sgarrison fclose(rfd); 5612909Sgarrison } 5712909Sgarrison 5812909Sgarrison /* open temporaries, reffile will contain references collected in 5912909Sgarrison pass 1, and tmpfile will contain text. 6012909Sgarrison */ 6112909Sgarrison mktemp(reffile); 6212909Sgarrison rfd = fopen(reffile,"w+"); 6312909Sgarrison if (rfd == NULL) 6412909Sgarrison error("can't open temporary reference file"); 6512909Sgarrison mktemp(tmpfile); 6612909Sgarrison tfd = fopen(tmpfile,"w"); 6712909Sgarrison if (tfd == NULL) 6812909Sgarrison error("can't open temporary output file"); 6912909Sgarrison 7012909Sgarrison /* 7112909Sgarrison pass1 - read files, looking for citations 7212909Sgarrison arguments are read by doargs (bibargs.c) 7312909Sgarrison */ 7412909Sgarrison 7513107Srrh if (doargs(argc, argv, DEFSTYLE ) == 0){ 7613107Srrh bibfname = "<stdin>"; 7712909Sgarrison rdtext(stdin); 7813107Srrh } 7912909Sgarrison 8012909Sgarrison /* 8112909Sgarrison sort references, make citations, add disambiguating characters 8212909Sgarrison */ 8312909Sgarrison 8412909Sgarrison if (sort) 8512909Sgarrison qsort(refspos, numrefs+1, sizeof(long), rcomp); 8612909Sgarrison makecites(citestr); 8712909Sgarrison disambiguate(); 8812909Sgarrison 8912909Sgarrison /* 9012909Sgarrison reopen temporaries 9112909Sgarrison */ 9212909Sgarrison 9312909Sgarrison fclose(tfd); 9412909Sgarrison tfd = fopen(tmpfile,"r"); 9512909Sgarrison if (tfd == NULL) 9612909Sgarrison error("can't open temporary output file for reading"); 9712909Sgarrison 9812909Sgarrison /* 9912909Sgarrison pass 2 - reread files, replacing references 10012909Sgarrison */ 10112909Sgarrison 10212909Sgarrison pass2(tfd, stdout); 10312909Sgarrison 10412909Sgarrison /* 10512909Sgarrison clean up 10612909Sgarrison */ 10712909Sgarrison 10812909Sgarrison fclose(tfd); 10912909Sgarrison fclose(rfd); 11012909Sgarrison unlink(tmpfile); 11112909Sgarrison unlink(reffile); 11212909Sgarrison exit(0); 11312909Sgarrison } 11412909Sgarrison 11512909Sgarrison /* rdtext - read and process a text file, looking for [. commands */ 11612909Sgarrison rdtext(fd) 11712909Sgarrison FILE *fd; 11812909Sgarrison { char lastc, c, d; 11912909Sgarrison 12013107Srrh biblineno = 0; 12112909Sgarrison lastc = 0; 12212909Sgarrison while (getch(c, fd) != EOF) 12312909Sgarrison if (c == '[' || c == '{') 12412909Sgarrison if (getch(d, fd) == '.') { /* found a reference */ 12512909Sgarrison if (c == '{') { if (lastc) putc(lastc, tfd);} 12612909Sgarrison else 12712960Sgarrison switch (lastc) { 12812960Sgarrison case ' ': fputs("\\*([<", tfd); 12912960Sgarrison break; 13012960Sgarrison case '.': fputs("\\*([.", tfd); 13112960Sgarrison break; 13212960Sgarrison case ',': fputs("\\*([,", tfd); 13312960Sgarrison break; 13412960Sgarrison case '?': fputs("\\*([?", tfd); 13512960Sgarrison break; 13612960Sgarrison case ':': fputs("\\*([:", tfd); 13712960Sgarrison break; 13812960Sgarrison case ';': fputs("\\*([;", tfd); 13912960Sgarrison break; 14012960Sgarrison case '!': fputs("\\*([!", tfd); 14112960Sgarrison break; 14212960Sgarrison case '"': fputs("\\*([\"", tfd); 14312960Sgarrison break; 14412960Sgarrison case '\'': fputs("\\*(['", tfd); 14512960Sgarrison break; 14612960Sgarrison default : putc(lastc, tfd); 14712960Sgarrison break; 14812960Sgarrison } 14912909Sgarrison rdcite(fd, c); 15012909Sgarrison if (c == '[') 15112960Sgarrison switch (lastc) { 15212960Sgarrison case ' ': fputs("\\*(<]", tfd); 15312960Sgarrison break; 15412960Sgarrison case '.': fputs("\\*(.]", tfd); 15512960Sgarrison break; 15612960Sgarrison case ',': fputs("\\*(,]", tfd); 15712960Sgarrison break; 15812960Sgarrison case '?': fputs("\\*(?]", tfd); 15912960Sgarrison break; 16012960Sgarrison case ':': fputs("\\*(:]", tfd); 16112960Sgarrison break; 16212960Sgarrison case ';': fputs("\\*(;]", tfd); 16312960Sgarrison break; 16412960Sgarrison case '!': fputs("\\*(!]", tfd); 16512960Sgarrison break; 16612960Sgarrison case '"': fputs("\\*(\"]", tfd); 16712960Sgarrison break; 16812960Sgarrison case '\'': fputs("\\*(']", tfd); 16912960Sgarrison break; 17012960Sgarrison } 17112909Sgarrison lastc = 0; 17212909Sgarrison } 17312909Sgarrison else { 17412909Sgarrison if (lastc) putc(lastc, tfd); 17512909Sgarrison ungetc(d, fd); 17612909Sgarrison lastc = c; 17712909Sgarrison } 17812909Sgarrison else { 17912909Sgarrison if (lastc) putc(lastc, tfd); 18012909Sgarrison lastc = c; 18113107Srrh if (c == '\n') 18213107Srrh biblineno++; 18312909Sgarrison } 18412909Sgarrison if (lastc) putc(lastc, tfd); 18512909Sgarrison } 18612909Sgarrison 18712909Sgarrison /* rdcite - read citation information inside a [. command */ 18812909Sgarrison rdcite(fd, ch) 18912909Sgarrison FILE *fd; 19012909Sgarrison char ch; 19112909Sgarrison { long int n, getref(); 19212909Sgarrison char huntstr[HUNTSIZE], c, info[HUNTSIZE]; 19312909Sgarrison 19412909Sgarrison if (ch == '[') 19512909Sgarrison fputs("\\*([[", tfd); 19612909Sgarrison else 19712909Sgarrison fputs("\\*([{", tfd); 19812909Sgarrison huntstr[0] = info[0] = 0; 19912909Sgarrison while (getch(c, fd) != EOF) 20012909Sgarrison switch (c) { 20112909Sgarrison case ',': 20212909Sgarrison n = getref(huntstr); 20312909Sgarrison if (n > 0) 20412909Sgarrison fprintf(tfd, "%c%ld%c%s%c", CITEMARK, n, CITEMARK, info, CITEEND); 20512909Sgarrison else 20612909Sgarrison fprintf(tfd, "%c0%c%s%s%c", CITEMARK, CITEMARK, 20712909Sgarrison huntstr, info, CITEEND); 20812909Sgarrison huntstr[0] = info[0] = 0; 20912909Sgarrison break; 21012909Sgarrison 21112909Sgarrison case '.': 21212909Sgarrison while (getch(c, fd) == '.') ; 21312909Sgarrison if (c == ']') { 21412909Sgarrison n = getref(huntstr); 21512909Sgarrison if (n > 0) 21612909Sgarrison fprintf(tfd, "%c%ld%c%s%c\\*(]]", CITEMARK, n, 21712909Sgarrison CITEMARK, info, CITEEND); 21812909Sgarrison else 21912909Sgarrison fprintf(tfd, "%c0%c%s%s%c\\*(]]", CITEMARK, CITEMARK, 22012909Sgarrison huntstr, info, CITEEND); 22112909Sgarrison return; 22212909Sgarrison } 22312909Sgarrison else if (c == '}') { 22412909Sgarrison n = getref(huntstr); 22512909Sgarrison if (n > 0) 22612909Sgarrison fprintf(tfd, "%c%ld%c%s%c\\*(}]", CITEMARK, n, 22712909Sgarrison CITEMARK, info, CITEEND); 22812909Sgarrison else 22912909Sgarrison fprintf(tfd, "%c0%c%s%s%c\\*(}]", CITEMARK, CITEMARK, 23012909Sgarrison huntstr, info, CITEEND); 23112909Sgarrison return; 23212909Sgarrison } 23312909Sgarrison else 23412909Sgarrison addc(huntstr, c); 23512909Sgarrison break; 23612909Sgarrison 23712909Sgarrison case '{': 23812909Sgarrison while (getch(c, fd) != '}') 23912909Sgarrison if (c == EOF) { 24012909Sgarrison fprintf(stderr, "Error: ill formed reference\n"); 24112909Sgarrison exit(1); 24212909Sgarrison } 24312909Sgarrison else 24412909Sgarrison addc(info, c); 24512909Sgarrison break; 24612909Sgarrison 24712909Sgarrison case '\n': 24812909Sgarrison case '\t': 24912909Sgarrison c = ' '; /* fall through */ 25012909Sgarrison 25112909Sgarrison default: 25212909Sgarrison addc(huntstr,c); 25312909Sgarrison } 25412909Sgarrison error("end of file reading citation"); 25512909Sgarrison } 25612909Sgarrison 25712909Sgarrison /* addc - add a character to hunt string */ 25812909Sgarrison addc(huntstr, c) 25912909Sgarrison char huntstr[HUNTSIZE], c; 26012909Sgarrison { int i; 26112909Sgarrison 26212909Sgarrison i = strlen(huntstr); 26312909Sgarrison if (i > HUNTSIZE) 26412909Sgarrison error("citation too long"); 26512909Sgarrison huntstr[i] = c; 26612909Sgarrison huntstr[i+1] = 0; 26712909Sgarrison } 26812909Sgarrison 26912909Sgarrison /* getref - if an item was already referenced, return its pointer in 27012909Sgarrison the reference file, otherwise create a new entry */ 27112909Sgarrison long int getref(huntstr) 27212909Sgarrison char huntstr[HUNTSIZE]; 27312909Sgarrison { char rf[REFSIZE], ref[REFSIZE], *r, *hunt(); 27412909Sgarrison int i, match(), getwrd(); 27512909Sgarrison 27612909Sgarrison r = hunt(huntstr); 27712909Sgarrison if (r != NULL) { 27812909Sgarrison /* exapand defined string */ 27912909Sgarrison strcpy(rf, r); 28012909Sgarrison free(r); 28112909Sgarrison expand(rf); 28212909Sgarrison 28312909Sgarrison /* see if reference has already been cited */ 28412909Sgarrison 28512909Sgarrison if (foot == false) 28612909Sgarrison for (i = 0; i <= numrefs; i++) { 28712909Sgarrison rdref(refspos[i], ref); 28812909Sgarrison if (strcmp(ref, rf) == 0) 28912909Sgarrison return(refspos[i]); 29012909Sgarrison } 29112909Sgarrison 29212909Sgarrison /* didn't match any existing reference, create new one */ 29312909Sgarrison 29412909Sgarrison numrefs++; 29512909Sgarrison refspos[numrefs] = rend; 29612909Sgarrison fseek(rfd, rend, 0); 29712909Sgarrison i = strlen(rf) + 1; 29812909Sgarrison fwrite(rf, 1, i, rfd); 29912909Sgarrison rend = rend + i; 30012909Sgarrison return(refspos[numrefs]); 30112909Sgarrison } 30212909Sgarrison else { 30313107Srrh bibwarning("no reference matching %s\n", huntstr); 30412909Sgarrison return( (long) -1 ); 30512909Sgarrison } 30612909Sgarrison } 30712909Sgarrison 30812909Sgarrison /* rdref - read text for an already cited reference */ 30912909Sgarrison rdref(i, ref) 31012909Sgarrison long int i; 31112909Sgarrison char ref[REFSIZE]; 31212909Sgarrison { 31312909Sgarrison ref[0] = 0; 31412909Sgarrison fseek(rfd, i, 0); 31512909Sgarrison fread(ref, 1, REFSIZE, rfd); 31612909Sgarrison } 31712909Sgarrison 31812909Sgarrison /* hunt - hunt for reference from either personal or system index */ 31912909Sgarrison char *hunt(huntstr) 32012909Sgarrison char huntstr[]; 32112909Sgarrison { char *fhunt(), *r, *p, *q, fname[120]; 32212909Sgarrison 32312909Sgarrison if (personal) { 32412909Sgarrison for (p = fname, q = pfile; ; q++) 32512909Sgarrison if (*q == ',' || *q == 0) { 32612909Sgarrison *p = 0; 32712909Sgarrison if ((r = fhunt(fname, huntstr)) != NULL) 32812909Sgarrison return(r); 32912909Sgarrison else if (*q == 0) 33012909Sgarrison break; 33112909Sgarrison p = fname; 33212909Sgarrison } 33312909Sgarrison else *p++ = *q; 33412909Sgarrison } 33512909Sgarrison else if (findex) { 33612909Sgarrison if ((r = fhunt( INDXFILE , huntstr)) != NULL) 33712909Sgarrison return(r); 33812909Sgarrison } 33912909Sgarrison if ((r = fhunt(SYSINDEX , huntstr)) != NULL) 34012909Sgarrison return(r); 34112909Sgarrison return(NULL); 34212909Sgarrison } 34312909Sgarrison 34412909Sgarrison /* fhunt - hunt from a specific file */ 34512909Sgarrison char *fhunt(file, huntstr) 34612909Sgarrison char file[], huntstr[]; 34712909Sgarrison { char *p, *r, *locate(); 34812909Sgarrison 34912909Sgarrison r = locate(huntstr, file, 6, common); 35012909Sgarrison 35112909Sgarrison if (r == NULL) 35212909Sgarrison return(NULL); /* error */ 35312909Sgarrison if (*r == 0) 35412909Sgarrison return(NULL); /* no match */ 35512909Sgarrison 35612909Sgarrison for (p = r; *p; p++) 35712909Sgarrison if (*p == '\n') 35812909Sgarrison if (*(p+1) == '\n') { /* end */ 35912909Sgarrison if (*(p+2) != 0) 36013107Srrh bibwarning("multiple references match %s\n", huntstr); 36112909Sgarrison *(p+1) = 0; 36212909Sgarrison break; 36312909Sgarrison } 36412909Sgarrison else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */ 36512909Sgarrison *p = ' '; 36612909Sgarrison return(r); 36712909Sgarrison } 36812909Sgarrison 36912909Sgarrison /* rcomp - reference comparison routine for qsort utility */ 37012909Sgarrison int rcomp(ap, bp) 37112909Sgarrison long int *ap, *bp; 37212909Sgarrison { char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD]; 37312909Sgarrison char *p, *q, *getfield(); 37412909Sgarrison int neg, res; 37512960Sgarrison int fields_found; 37612909Sgarrison 37712909Sgarrison rdref(*ap, ref1); 37812909Sgarrison rdref(*bp, ref2); 37912909Sgarrison for (p = sortstr; *p; p = q) { 38012909Sgarrison if (*p == '-') { 38112909Sgarrison p++; 38212909Sgarrison neg = true; 38312909Sgarrison } 38412909Sgarrison else 38512909Sgarrison neg = false; 38612909Sgarrison q = getfield(p, field1, ref1); 38712960Sgarrison fields_found = true; 38812960Sgarrison if (q == 0) { 38912960Sgarrison res = 1; 39012960Sgarrison fields_found = false; 39112960Sgarrison } else if (strcmp (field1, "") == 0) { /* field not found */ 39212909Sgarrison if (*p == 'A') { 39312960Sgarrison getfield("F", field1, ref1); 39412960Sgarrison if (strcmp (field1, "") == 0) { 39512960Sgarrison getfield("I", field1, ref1); 39612960Sgarrison if (strcmp (field1, "") == 0) { 39712960Sgarrison res = 1; 39812960Sgarrison fields_found = false; 39912960Sgarrison } 40012960Sgarrison } 40112960Sgarrison } else { 40212960Sgarrison res = 1; 40312960Sgarrison fields_found = false; 40412960Sgarrison } 40512960Sgarrison } 40612960Sgarrison 40712960Sgarrison if (getfield(p, field2, ref2) == 0) { 40812960Sgarrison res = -1; 40912960Sgarrison fields_found = false; 41012960Sgarrison } else if (strcmp (field2, "") == 0) { /* field not found */ 41112960Sgarrison if (*p == 'A') { 41212960Sgarrison getfield("F", field2, ref2); 41312960Sgarrison if (strcmp (field2, "") == 0) { 41412960Sgarrison getfield("I", field2, ref2); 41512960Sgarrison if (strcmp (field2, "") == 0) { 41612960Sgarrison res = -1; 41712960Sgarrison fields_found = false; 41812960Sgarrison } 41912960Sgarrison } 42012960Sgarrison } else { 42112960Sgarrison res = -1; 42212960Sgarrison fields_found = false; 42312960Sgarrison } 42412960Sgarrison } 42512960Sgarrison if (fields_found) { 42612960Sgarrison if (*p == 'A') { 42712909Sgarrison if (isupper(field1[0])) 42812909Sgarrison field1[0] -= 'A' - 'a'; 42912909Sgarrison if (isupper(field2[0])) 43012909Sgarrison field2[0] -= 'A' - 'a'; 43112909Sgarrison } 43212909Sgarrison res = strcmp(field1, field2); 43312909Sgarrison } 43412909Sgarrison if (neg) 43512909Sgarrison res = - res; 43612909Sgarrison if (res != 0) 43712909Sgarrison break; 43812909Sgarrison } 43912909Sgarrison if (res == 0) 44012909Sgarrison if (ap < bp) 44112909Sgarrison res = -1; 44212909Sgarrison else 44312909Sgarrison res = 1; 44412909Sgarrison return(res); 44512909Sgarrison } 44612909Sgarrison 44712909Sgarrison /* makecites - make citation strings */ 44812909Sgarrison makecites(citestr) 44912909Sgarrison char *citestr[]; 45012909Sgarrison { char ref[REFSIZE], tempcite[100], *malloc(); 45112909Sgarrison int i; 45212909Sgarrison 45312909Sgarrison for (i = 0; i <= numrefs; i++) { 45412909Sgarrison rdref(refspos[i], ref); 45512909Sgarrison bldcite(tempcite, i, ref); 45612909Sgarrison citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */ 45712909Sgarrison if (citestr[i] == NULL) 45812909Sgarrison error("out of storage"); 45912909Sgarrison strcpy(citestr[i], tempcite); 46012909Sgarrison } 46112909Sgarrison } 46212909Sgarrison 46312909Sgarrison /* bldcite - build a single citation string */ 46412909Sgarrison bldcite(cp, i, ref) 46512909Sgarrison char *cp, ref[]; 46612909Sgarrison int i; 46712909Sgarrison { char *p, *q, c, *fp, *np, field[REFSIZE], temp[100], *getfield(); 46812909Sgarrison int j; 46912909Sgarrison 47012909Sgarrison getfield("F", field, ref); 47112909Sgarrison if (field[0] != 0) 47212909Sgarrison for (p = field; *p; p++) 47312909Sgarrison *cp++ = *p; 47412909Sgarrison else { 47512909Sgarrison p = citetemplate; 47612909Sgarrison field[0] = 0; 47712909Sgarrison while (c = *p++) 47812909Sgarrison if (isalpha(c)) { 47912909Sgarrison q = getfield(p-1, field, ref); 48012909Sgarrison if (q != 0) { 48112909Sgarrison p = q; 48212909Sgarrison for (fp = field; *fp; ) 48312909Sgarrison *cp++ = *fp++; 48412909Sgarrison } 48512909Sgarrison } 48612909Sgarrison else if (c == '1') { 48712909Sgarrison sprintf(field,"%d",1 + i); 48812909Sgarrison for (fp = field; *fp; ) 48912909Sgarrison *cp++ = *fp++; 49012909Sgarrison } 49112909Sgarrison else if (c == '2') { 49212909Sgarrison if (getname(1, field, temp, ref)) { 49312909Sgarrison np = cp; 49412909Sgarrison fp = field; 49512909Sgarrison for (j = 1; j <= 3; j++) 49612909Sgarrison if (*fp != 0) 49712909Sgarrison *cp++ = *fp++; 49812909Sgarrison if (getname(2, field, temp, ref)) 49912909Sgarrison np[2] = field[0]; 50012909Sgarrison if (getname(3, field, temp, ref)) { 50112909Sgarrison np[1] = np[2]; 50212909Sgarrison np[2] = field[0]; 50312909Sgarrison } 50412909Sgarrison } 50512909Sgarrison } 50612909Sgarrison else if (c == '{') { 50712909Sgarrison while (*p ^= '}') 50812909Sgarrison if (*p == 0) 50912909Sgarrison error("unexpected end of citation template"); 51012909Sgarrison else 51112909Sgarrison *cp++ = *p++; 51212909Sgarrison p++; 51312909Sgarrison } 51412909Sgarrison else if (c == '<') { 51512909Sgarrison while (*p ^= '>') 51612909Sgarrison if (*p == 0) 51712909Sgarrison error("unexpected end of citation template"); 51812909Sgarrison else 51912909Sgarrison *cp++ = *p++; 52012909Sgarrison p++; 52112909Sgarrison } 52212909Sgarrison else if (c != '@') 52312909Sgarrison *cp++ = c; 52412909Sgarrison } 52512909Sgarrison *cp++ = 0; 52612909Sgarrison } 52712909Sgarrison 52812909Sgarrison /* getfield - get a single field from reference */ 52912909Sgarrison char *getfield(ptr, field, ref) 53012909Sgarrison char *ptr, field[], ref[]; 53112909Sgarrison { char *p, *q, temp[100]; 53212909Sgarrison int n, len, i, getname(); 53312909Sgarrison 53412909Sgarrison field[0] = 0; 53512909Sgarrison if (*ptr == 'A') 53612909Sgarrison getname(1, field, temp, ref); 53712909Sgarrison else 53812909Sgarrison for (p = ref; *p; p++) 53912909Sgarrison if (*p == '%' && *(p+1) == *ptr) { 54012909Sgarrison for (p = p + 2; *p == ' '; p++) 54112909Sgarrison ; 54212909Sgarrison for (q = field; *p != '\n'; ) 54312909Sgarrison *q++ = *p++; 54412909Sgarrison *q = 0; 54512909Sgarrison break; 54612909Sgarrison } 54712909Sgarrison n = 0; 54812909Sgarrison len = strlen(field); 54912909Sgarrison if (*++ptr == '-') { 55012909Sgarrison for (ptr++; isdigit(*ptr); ptr++) 55112909Sgarrison n = 10 * n + (*ptr - '0'); 55212909Sgarrison if (n > len) 55312909Sgarrison n = 0; 55412909Sgarrison else 55512909Sgarrison n = len - n; 55612909Sgarrison for (i = 0; field[i] = field[i+n]; i++) 55712909Sgarrison ; 55812909Sgarrison } 55912909Sgarrison else if (isdigit(*ptr)) { 56012909Sgarrison for (; isdigit(*ptr); ptr++) 56112909Sgarrison n = 10 * n + (*ptr - '0'); 56212909Sgarrison if (n > len) 56312909Sgarrison n = len; 56412909Sgarrison field[n] = 0; 56512909Sgarrison } 56612909Sgarrison 56712909Sgarrison if (*ptr == 'u') { 56812909Sgarrison ptr++; 56912909Sgarrison for (p = field; *p; p++) 57012909Sgarrison if (islower(*p)) 57112909Sgarrison *p = (*p - 'a') + 'A'; 57212909Sgarrison } 57312909Sgarrison else if (*ptr == 'l') { 57412909Sgarrison ptr++; 57512909Sgarrison for (p = field; *p; p++) 57612909Sgarrison if (isupper(*p)) 57712909Sgarrison *p = (*p - 'A') + 'a'; 57812909Sgarrison } 57912909Sgarrison return(ptr); 58012909Sgarrison } 58112909Sgarrison 58212909Sgarrison /* getname - get the nth name field from reference, breaking into 58312909Sgarrison first and last names */ 58412909Sgarrison int getname(n, last, first, ref) 58512909Sgarrison int n; 58612909Sgarrison char last[], first[], ref[]; 58712909Sgarrison { char *p; 58812909Sgarrison 58912909Sgarrison for (p = ref; *p; p++) 59012960Sgarrison if (*p == '%' & (*(p+1) == 'A' || *(p+1) == 'E')) { 59112909Sgarrison n--; 59212909Sgarrison if (n == 0) { 59312909Sgarrison for (p = p + 2; *p == ' '; p++) ; 59412909Sgarrison breakname(p, first, last) ; 59512909Sgarrison return(true); 59612909Sgarrison } 59712909Sgarrison } 59812909Sgarrison return(false); 59912909Sgarrison } 60012909Sgarrison 60112909Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add 60212909Sgarrison single character disambiguators */ 60312909Sgarrison disambiguate() 60412909Sgarrison { int i, j; 60512909Sgarrison char adstr[2]; 60612909Sgarrison 60712909Sgarrison for (i = 0; i < numrefs; i = j) { 60812909Sgarrison j = i + 1; 60912909Sgarrison if (strcmp(citestr[i], citestr[j])==0) { 61012909Sgarrison adstr[0] = 'a'; adstr[1] = 0; 61112909Sgarrison for (j = i+1; strcmp(citestr[i],citestr[j]) == 0; j++) { 61212909Sgarrison adstr[0] = 'a' + (j-i); 61312909Sgarrison strcat(citestr[j], adstr); 61412909Sgarrison if (j == numrefs) 61512909Sgarrison break; 61612909Sgarrison } 61712909Sgarrison adstr[0] = 'a'; 61812909Sgarrison strcat(citestr[i], adstr); 61912909Sgarrison } 62012909Sgarrison } 62112909Sgarrison } 62212909Sgarrison 62312909Sgarrison /* putrefs - gather contiguous references together, sort them if called 62412909Sgarrison for, hyphenate if necessary, and dump them out */ 62512909Sgarrison int putrefs(ifd, ofd, footrefs, fn) 62612909Sgarrison FILE *ifd, *ofd; 62712909Sgarrison int fn, footrefs[]; 62812909Sgarrison { int citenums[MAXATONCE]; /* reference numbers */ 62912909Sgarrison char *citeinfo[MAXATONCE]; /* reference information */ 63012909Sgarrison char infoword[HUNTSIZE]; /* information line */ 63112909Sgarrison int rtop, n, i, j; /* number of citations being dumped */ 63212909Sgarrison char c, *p, *walloc(); 63312909Sgarrison 63412909Sgarrison /* first gather contiguous references together, and order them if 63512909Sgarrison required */ 63612909Sgarrison 63712909Sgarrison rtop = -1; 63812909Sgarrison do { 63912909Sgarrison n = 0; 64012909Sgarrison while (isdigit(getch(c, ifd))) 64112909Sgarrison n = 10 * n + (c - '0'); 64212909Sgarrison if (c ^= CITEMARK) 64312909Sgarrison error("inconsistant citation found in pass two"); 64412909Sgarrison if (n == 0) { /* reference not found */ 64512909Sgarrison rtop++; 64612909Sgarrison j = rtop; 64712909Sgarrison citenums[j] = -1; 64812909Sgarrison citeinfo[j] = 0; 64912909Sgarrison } 65012909Sgarrison else { 65112909Sgarrison for (i = 0; i <= numrefs; i++) 65212909Sgarrison if (refspos[i] == n) { /* its the ith item in reference list */ 65312909Sgarrison rtop++; 65412909Sgarrison j = rtop; 65512909Sgarrison if (ordcite) 65612909Sgarrison for ( ; j > 0 && citenums[j-1] > i; j--) { 65712909Sgarrison citenums[j] = citenums[j-1]; 65812909Sgarrison citeinfo[j] = citeinfo[j-1]; 65912909Sgarrison } 66012909Sgarrison citenums[j] = i; 66112909Sgarrison citeinfo[j] = 0; 66212909Sgarrison break; 66312909Sgarrison } 66412909Sgarrison if (i > numrefs) 66512909Sgarrison error("citation not found in pass two"); 66612909Sgarrison } 66712909Sgarrison if (getch(c, ifd) != CITEEND) { 66812909Sgarrison for (p = infoword; c != CITEEND ; ) { 66912909Sgarrison *p++ = c; 67012909Sgarrison getch(c, ifd); 67112909Sgarrison } 67212909Sgarrison *p = 0; 67312909Sgarrison citeinfo[j] = walloc(infoword); 67412909Sgarrison } 67512909Sgarrison getch(c, ifd); 67612909Sgarrison } while (c == CITEMARK); 67712909Sgarrison ungetc(c, ifd); 67812909Sgarrison 67912909Sgarrison /* now dump out values */ 68012909Sgarrison for (i = 0; i <= rtop; i++) { 68112909Sgarrison if (citenums[i] >= 0) 68212909Sgarrison fputs(citestr[citenums[i]], ofd); 68312909Sgarrison if (citeinfo[i]) { 68412909Sgarrison fputs(citeinfo[i], ofd); 68512909Sgarrison free(citeinfo[i]); 68612909Sgarrison } 68712909Sgarrison if (hyphen) { 68812909Sgarrison for (j = 1; j + i <= rtop && citenums[i+j] == citenums[i] + j; j++); 68912909Sgarrison if (j + i > rtop) j = rtop; 69012909Sgarrison else j = j + i - 1; 69112909Sgarrison } 69212909Sgarrison else 69312909Sgarrison j = i; 69412909Sgarrison if (j > i + 1) { 69512909Sgarrison fputs("\\*(]-", ofd); 69612909Sgarrison i = j - 1; 69712909Sgarrison } 69812909Sgarrison else if (i != rtop) 69912909Sgarrison fputs("\\*(],", ofd); 70012909Sgarrison if (foot) { 70112909Sgarrison fn++; 70212909Sgarrison footrefs[fn] = citenums[i]; 70312909Sgarrison } 70412909Sgarrison } 70512909Sgarrison return(fn); 70612909Sgarrison } 70712909Sgarrison 70812909Sgarrison /* pass2 - read pass 1 files entering citation */ 70912909Sgarrison pass2(ifd, ofd) 71012909Sgarrison FILE *ifd, *ofd; 71112909Sgarrison { 71212909Sgarrison char c; 71312909Sgarrison int i, fn, footrefs[25], dumped; 71412909Sgarrison 71512909Sgarrison fn = -1; 71612909Sgarrison dumped = foot; 71712909Sgarrison while (getch(c, ifd) != EOF) { 71812909Sgarrison while (c == '\n') { 71912909Sgarrison putc(c, ofd); 72012909Sgarrison if (foot && fn >= 0) { 72112909Sgarrison for (i = 0; i <= fn; i++) 72212909Sgarrison dumpref(footrefs[i], ofd); 72312909Sgarrison fn = -1; 72412909Sgarrison } 72512909Sgarrison if (testc(c, '.', ifd, ofd)) 72612909Sgarrison if (testc(c, '[', ifd, ofd)) 72712909Sgarrison if (testc(c, ']', ifd, ofd)) { 72812909Sgarrison while (echoc(c, ifd, ofd) != '\n') 72912909Sgarrison ; 73012909Sgarrison dumped = true; 73112909Sgarrison for (i = 0; i <= numrefs; i++) 73212909Sgarrison dumpref(i, ofd); 73312909Sgarrison getch(c, ifd); 73412909Sgarrison } 73512909Sgarrison } 73612909Sgarrison if (c == CITEMARK) 73712909Sgarrison fn = putrefs(ifd, ofd, footrefs, fn); 73812909Sgarrison else if (c != EOF) 73912909Sgarrison putc(c, ofd); 74012909Sgarrison } 74112909Sgarrison if (dumped == false) 74213107Srrh bibwarning("Warning: references never dumped\n", (char *)0); 74312909Sgarrison } 74412909Sgarrison 74512909Sgarrison 74612909Sgarrison /* dumpref - dump reference number i */ 74712909Sgarrison dumpref(i, ofd) 74812909Sgarrison int i; 74912909Sgarrison FILE *ofd; 75012909Sgarrison { char ref[REFSIZE], *p, line[REFSIZE]; 75112909Sgarrison int numauths, maxauths, numeds, maxeds; 75212909Sgarrison 75312909Sgarrison rdref(refspos[i], ref); 75412909Sgarrison maxauths = maxeds = 0; 75512909Sgarrison numauths = numeds = 0; 75612909Sgarrison for (p = ref; *p; p++) 75712909Sgarrison if (*p == '%') 75812909Sgarrison if (*(p+1) == 'A') maxauths++; 75912909Sgarrison else if (*(p+1) == 'E') maxeds++; 76012909Sgarrison fprintf(ofd, ".[-\n"); 76112909Sgarrison fprintf(ofd, ".ds [F %s\n",citestr[i]); 76212909Sgarrison fseek(rfd, (long) refspos[i], 0); 76312909Sgarrison while (fgets(line, REFSIZE, rfd) != NULL) { 76412909Sgarrison if (line[0] == 0) break; 76512909Sgarrison else if (line[0] == '.') fprintf(ofd,"%s",line); 76612909Sgarrison else { 76712909Sgarrison if (line[0] == '%') { 76812909Sgarrison for (p = &line[2]; *p == ' '; p++); 76912909Sgarrison if (line[1] == 'A') numauths++; 77012909Sgarrison else if (line[1] == 'E') numeds++; 77112909Sgarrison 77212909Sgarrison doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd); 77312909Sgarrison } 77412909Sgarrison } 77512909Sgarrison } 77612909Sgarrison fprintf(ofd,".][\n"); 77712909Sgarrison } 77813107Srrh /* 77913107Srrh * print out a warning message 78013107Srrh */ 78113107Srrh bibwarning(msg, arg) 78213107Srrh char *msg; 78313107Srrh char *arg; 78413107Srrh { 78513107Srrh fprintf(stderr, "`%s', line %d: ", bibfname, biblineno); 78613107Srrh fprintf(stderr, msg, arg); 78713107Srrh } 788