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