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[]; 3612909Sgarrison 3712909Sgarrison 3812909Sgarrison main(argc, argv) 3912909Sgarrison int argc; 4012909Sgarrison char **argv; 4112909Sgarrison { int rcomp(); 4212909Sgarrison 4312909Sgarrison /* the file INDEX in the current directory is the default index, 4412909Sgarrison if it is present */ 4512909Sgarrison 4612909Sgarrison rfd = fopen( INDXFILE , "r"); 4712909Sgarrison if (rfd != NULL) { 4812909Sgarrison findex = true; 4912909Sgarrison fclose(rfd); 5012909Sgarrison } 5112909Sgarrison 5212909Sgarrison /* open temporaries, reffile will contain references collected in 5312909Sgarrison pass 1, and tmpfile will contain text. 5412909Sgarrison */ 5512909Sgarrison mktemp(reffile); 5612909Sgarrison rfd = fopen(reffile,"w+"); 5712909Sgarrison if (rfd == NULL) 5812909Sgarrison error("can't open temporary reference file"); 5912909Sgarrison mktemp(tmpfile); 6012909Sgarrison tfd = fopen(tmpfile,"w"); 6112909Sgarrison if (tfd == NULL) 6212909Sgarrison error("can't open temporary output file"); 6312909Sgarrison 6412909Sgarrison /* 6512909Sgarrison pass1 - read files, looking for citations 6612909Sgarrison arguments are read by doargs (bibargs.c) 6712909Sgarrison */ 6812909Sgarrison 6912909Sgarrison if (doargs(argc, argv, DEFSTYLE ) == 0) 7012909Sgarrison rdtext(stdin); 7112909Sgarrison 7212909Sgarrison /* 7312909Sgarrison sort references, make citations, add disambiguating characters 7412909Sgarrison */ 7512909Sgarrison 7612909Sgarrison if (sort) 7712909Sgarrison qsort(refspos, numrefs+1, sizeof(long), rcomp); 7812909Sgarrison makecites(citestr); 7912909Sgarrison disambiguate(); 8012909Sgarrison 8112909Sgarrison /* 8212909Sgarrison reopen temporaries 8312909Sgarrison */ 8412909Sgarrison 8512909Sgarrison fclose(tfd); 8612909Sgarrison tfd = fopen(tmpfile,"r"); 8712909Sgarrison if (tfd == NULL) 8812909Sgarrison error("can't open temporary output file for reading"); 8912909Sgarrison 9012909Sgarrison /* 9112909Sgarrison pass 2 - reread files, replacing references 9212909Sgarrison */ 9312909Sgarrison 9412909Sgarrison pass2(tfd, stdout); 9512909Sgarrison 9612909Sgarrison /* 9712909Sgarrison clean up 9812909Sgarrison */ 9912909Sgarrison 10012909Sgarrison fclose(tfd); 10112909Sgarrison fclose(rfd); 10212909Sgarrison unlink(tmpfile); 10312909Sgarrison unlink(reffile); 10412909Sgarrison exit(0); 10512909Sgarrison } 10612909Sgarrison 10712909Sgarrison /* rdtext - read and process a text file, looking for [. commands */ 10812909Sgarrison rdtext(fd) 10912909Sgarrison FILE *fd; 11012909Sgarrison { char lastc, c, d; 11112909Sgarrison 11212909Sgarrison lastc = 0; 11312909Sgarrison while (getch(c, fd) != EOF) 11412909Sgarrison if (c == '[' || c == '{') 11512909Sgarrison if (getch(d, fd) == '.') { /* found a reference */ 11612909Sgarrison if (c == '{') { if (lastc) putc(lastc, tfd);} 11712909Sgarrison else 118*12960Sgarrison switch (lastc) { 119*12960Sgarrison case ' ': fputs("\\*([<", tfd); 120*12960Sgarrison break; 121*12960Sgarrison case '.': fputs("\\*([.", tfd); 122*12960Sgarrison break; 123*12960Sgarrison case ',': fputs("\\*([,", tfd); 124*12960Sgarrison break; 125*12960Sgarrison case '?': fputs("\\*([?", tfd); 126*12960Sgarrison break; 127*12960Sgarrison case ':': fputs("\\*([:", tfd); 128*12960Sgarrison break; 129*12960Sgarrison case ';': fputs("\\*([;", tfd); 130*12960Sgarrison break; 131*12960Sgarrison case '!': fputs("\\*([!", tfd); 132*12960Sgarrison break; 133*12960Sgarrison case '"': fputs("\\*([\"", tfd); 134*12960Sgarrison break; 135*12960Sgarrison case '\'': fputs("\\*(['", tfd); 136*12960Sgarrison break; 137*12960Sgarrison default : putc(lastc, tfd); 138*12960Sgarrison break; 139*12960Sgarrison } 14012909Sgarrison rdcite(fd, c); 14112909Sgarrison if (c == '[') 142*12960Sgarrison switch (lastc) { 143*12960Sgarrison case ' ': fputs("\\*(<]", tfd); 144*12960Sgarrison break; 145*12960Sgarrison case '.': fputs("\\*(.]", tfd); 146*12960Sgarrison break; 147*12960Sgarrison case ',': fputs("\\*(,]", tfd); 148*12960Sgarrison break; 149*12960Sgarrison case '?': fputs("\\*(?]", tfd); 150*12960Sgarrison break; 151*12960Sgarrison case ':': fputs("\\*(:]", tfd); 152*12960Sgarrison break; 153*12960Sgarrison case ';': fputs("\\*(;]", tfd); 154*12960Sgarrison break; 155*12960Sgarrison case '!': fputs("\\*(!]", tfd); 156*12960Sgarrison break; 157*12960Sgarrison case '"': fputs("\\*(\"]", tfd); 158*12960Sgarrison break; 159*12960Sgarrison case '\'': fputs("\\*(']", tfd); 160*12960Sgarrison break; 161*12960Sgarrison } 16212909Sgarrison lastc = 0; 16312909Sgarrison } 16412909Sgarrison else { 16512909Sgarrison if (lastc) putc(lastc, tfd); 16612909Sgarrison ungetc(d, fd); 16712909Sgarrison lastc = c; 16812909Sgarrison } 16912909Sgarrison else { 17012909Sgarrison if (lastc) putc(lastc, tfd); 17112909Sgarrison lastc = c; 17212909Sgarrison } 17312909Sgarrison if (lastc) putc(lastc, tfd); 17412909Sgarrison } 17512909Sgarrison 17612909Sgarrison /* rdcite - read citation information inside a [. command */ 17712909Sgarrison rdcite(fd, ch) 17812909Sgarrison FILE *fd; 17912909Sgarrison char ch; 18012909Sgarrison { long int n, getref(); 18112909Sgarrison char huntstr[HUNTSIZE], c, info[HUNTSIZE]; 18212909Sgarrison 18312909Sgarrison if (ch == '[') 18412909Sgarrison fputs("\\*([[", tfd); 18512909Sgarrison else 18612909Sgarrison fputs("\\*([{", tfd); 18712909Sgarrison huntstr[0] = info[0] = 0; 18812909Sgarrison while (getch(c, fd) != EOF) 18912909Sgarrison switch (c) { 19012909Sgarrison case ',': 19112909Sgarrison n = getref(huntstr); 19212909Sgarrison if (n > 0) 19312909Sgarrison fprintf(tfd, "%c%ld%c%s%c", CITEMARK, n, CITEMARK, info, CITEEND); 19412909Sgarrison else 19512909Sgarrison fprintf(tfd, "%c0%c%s%s%c", CITEMARK, CITEMARK, 19612909Sgarrison huntstr, info, CITEEND); 19712909Sgarrison huntstr[0] = info[0] = 0; 19812909Sgarrison break; 19912909Sgarrison 20012909Sgarrison case '.': 20112909Sgarrison while (getch(c, fd) == '.') ; 20212909Sgarrison if (c == ']') { 20312909Sgarrison n = getref(huntstr); 20412909Sgarrison if (n > 0) 20512909Sgarrison fprintf(tfd, "%c%ld%c%s%c\\*(]]", CITEMARK, n, 20612909Sgarrison CITEMARK, info, CITEEND); 20712909Sgarrison else 20812909Sgarrison fprintf(tfd, "%c0%c%s%s%c\\*(]]", CITEMARK, CITEMARK, 20912909Sgarrison huntstr, info, CITEEND); 21012909Sgarrison return; 21112909Sgarrison } 21212909Sgarrison else if (c == '}') { 21312909Sgarrison n = getref(huntstr); 21412909Sgarrison if (n > 0) 21512909Sgarrison fprintf(tfd, "%c%ld%c%s%c\\*(}]", CITEMARK, n, 21612909Sgarrison CITEMARK, info, CITEEND); 21712909Sgarrison else 21812909Sgarrison fprintf(tfd, "%c0%c%s%s%c\\*(}]", CITEMARK, CITEMARK, 21912909Sgarrison huntstr, info, CITEEND); 22012909Sgarrison return; 22112909Sgarrison } 22212909Sgarrison else 22312909Sgarrison addc(huntstr, c); 22412909Sgarrison break; 22512909Sgarrison 22612909Sgarrison case '{': 22712909Sgarrison while (getch(c, fd) != '}') 22812909Sgarrison if (c == EOF) { 22912909Sgarrison fprintf(stderr, "Error: ill formed reference\n"); 23012909Sgarrison exit(1); 23112909Sgarrison } 23212909Sgarrison else 23312909Sgarrison addc(info, c); 23412909Sgarrison break; 23512909Sgarrison 23612909Sgarrison case '\n': 23712909Sgarrison case '\t': 23812909Sgarrison c = ' '; /* fall through */ 23912909Sgarrison 24012909Sgarrison default: 24112909Sgarrison addc(huntstr,c); 24212909Sgarrison } 24312909Sgarrison error("end of file reading citation"); 24412909Sgarrison } 24512909Sgarrison 24612909Sgarrison /* addc - add a character to hunt string */ 24712909Sgarrison addc(huntstr, c) 24812909Sgarrison char huntstr[HUNTSIZE], c; 24912909Sgarrison { int i; 25012909Sgarrison 25112909Sgarrison i = strlen(huntstr); 25212909Sgarrison if (i > HUNTSIZE) 25312909Sgarrison error("citation too long"); 25412909Sgarrison huntstr[i] = c; 25512909Sgarrison huntstr[i+1] = 0; 25612909Sgarrison } 25712909Sgarrison 25812909Sgarrison /* getref - if an item was already referenced, return its pointer in 25912909Sgarrison the reference file, otherwise create a new entry */ 26012909Sgarrison long int getref(huntstr) 26112909Sgarrison char huntstr[HUNTSIZE]; 26212909Sgarrison { char rf[REFSIZE], ref[REFSIZE], *r, *hunt(); 26312909Sgarrison int i, match(), getwrd(); 26412909Sgarrison 26512909Sgarrison r = hunt(huntstr); 26612909Sgarrison if (r != NULL) { 26712909Sgarrison /* exapand defined string */ 26812909Sgarrison strcpy(rf, r); 26912909Sgarrison free(r); 27012909Sgarrison expand(rf); 27112909Sgarrison 27212909Sgarrison /* see if reference has already been cited */ 27312909Sgarrison 27412909Sgarrison if (foot == false) 27512909Sgarrison for (i = 0; i <= numrefs; i++) { 27612909Sgarrison rdref(refspos[i], ref); 27712909Sgarrison if (strcmp(ref, rf) == 0) 27812909Sgarrison return(refspos[i]); 27912909Sgarrison } 28012909Sgarrison 28112909Sgarrison /* didn't match any existing reference, create new one */ 28212909Sgarrison 28312909Sgarrison numrefs++; 28412909Sgarrison refspos[numrefs] = rend; 28512909Sgarrison fseek(rfd, rend, 0); 28612909Sgarrison i = strlen(rf) + 1; 28712909Sgarrison fwrite(rf, 1, i, rfd); 28812909Sgarrison rend = rend + i; 28912909Sgarrison return(refspos[numrefs]); 29012909Sgarrison } 29112909Sgarrison else { 29212909Sgarrison fprintf(stderr,"no reference matching %s\n", huntstr); 29312909Sgarrison return( (long) -1 ); 29412909Sgarrison } 29512909Sgarrison } 29612909Sgarrison 29712909Sgarrison /* rdref - read text for an already cited reference */ 29812909Sgarrison rdref(i, ref) 29912909Sgarrison long int i; 30012909Sgarrison char ref[REFSIZE]; 30112909Sgarrison { 30212909Sgarrison ref[0] = 0; 30312909Sgarrison fseek(rfd, i, 0); 30412909Sgarrison fread(ref, 1, REFSIZE, rfd); 30512909Sgarrison } 30612909Sgarrison 30712909Sgarrison /* hunt - hunt for reference from either personal or system index */ 30812909Sgarrison char *hunt(huntstr) 30912909Sgarrison char huntstr[]; 31012909Sgarrison { char *fhunt(), *r, *p, *q, fname[120]; 31112909Sgarrison 31212909Sgarrison if (personal) { 31312909Sgarrison for (p = fname, q = pfile; ; q++) 31412909Sgarrison if (*q == ',' || *q == 0) { 31512909Sgarrison *p = 0; 31612909Sgarrison if ((r = fhunt(fname, huntstr)) != NULL) 31712909Sgarrison return(r); 31812909Sgarrison else if (*q == 0) 31912909Sgarrison break; 32012909Sgarrison p = fname; 32112909Sgarrison } 32212909Sgarrison else *p++ = *q; 32312909Sgarrison } 32412909Sgarrison else if (findex) { 32512909Sgarrison if ((r = fhunt( INDXFILE , huntstr)) != NULL) 32612909Sgarrison return(r); 32712909Sgarrison } 32812909Sgarrison if ((r = fhunt(SYSINDEX , huntstr)) != NULL) 32912909Sgarrison return(r); 33012909Sgarrison return(NULL); 33112909Sgarrison } 33212909Sgarrison 33312909Sgarrison /* fhunt - hunt from a specific file */ 33412909Sgarrison char *fhunt(file, huntstr) 33512909Sgarrison char file[], huntstr[]; 33612909Sgarrison { char *p, *r, *locate(); 33712909Sgarrison 33812909Sgarrison r = locate(huntstr, file, 6, common); 33912909Sgarrison 34012909Sgarrison if (r == NULL) 34112909Sgarrison return(NULL); /* error */ 34212909Sgarrison if (*r == 0) 34312909Sgarrison return(NULL); /* no match */ 34412909Sgarrison 34512909Sgarrison for (p = r; *p; p++) 34612909Sgarrison if (*p == '\n') 34712909Sgarrison if (*(p+1) == '\n') { /* end */ 34812909Sgarrison if (*(p+2) != 0) 34912909Sgarrison fprintf(stderr,"multiple references match %s\n",huntstr); 35012909Sgarrison *(p+1) = 0; 35112909Sgarrison break; 35212909Sgarrison } 35312909Sgarrison else if (*(p+1) != '%' && *(p+1) != '.') /* unnecessary newline */ 35412909Sgarrison *p = ' '; 35512909Sgarrison return(r); 35612909Sgarrison } 35712909Sgarrison 35812909Sgarrison /* rcomp - reference comparison routine for qsort utility */ 35912909Sgarrison int rcomp(ap, bp) 36012909Sgarrison long int *ap, *bp; 36112909Sgarrison { char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD]; 36212909Sgarrison char *p, *q, *getfield(); 36312909Sgarrison int neg, res; 364*12960Sgarrison int fields_found; 36512909Sgarrison 36612909Sgarrison rdref(*ap, ref1); 36712909Sgarrison rdref(*bp, ref2); 36812909Sgarrison for (p = sortstr; *p; p = q) { 36912909Sgarrison if (*p == '-') { 37012909Sgarrison p++; 37112909Sgarrison neg = true; 37212909Sgarrison } 37312909Sgarrison else 37412909Sgarrison neg = false; 37512909Sgarrison q = getfield(p, field1, ref1); 376*12960Sgarrison fields_found = true; 377*12960Sgarrison if (q == 0) { 378*12960Sgarrison res = 1; 379*12960Sgarrison fields_found = false; 380*12960Sgarrison } else if (strcmp (field1, "") == 0) { /* field not found */ 38112909Sgarrison if (*p == 'A') { 382*12960Sgarrison getfield("F", field1, ref1); 383*12960Sgarrison if (strcmp (field1, "") == 0) { 384*12960Sgarrison getfield("I", field1, ref1); 385*12960Sgarrison if (strcmp (field1, "") == 0) { 386*12960Sgarrison res = 1; 387*12960Sgarrison fields_found = false; 388*12960Sgarrison } 389*12960Sgarrison } 390*12960Sgarrison } else { 391*12960Sgarrison res = 1; 392*12960Sgarrison fields_found = false; 393*12960Sgarrison } 394*12960Sgarrison } 395*12960Sgarrison 396*12960Sgarrison if (getfield(p, field2, ref2) == 0) { 397*12960Sgarrison res = -1; 398*12960Sgarrison fields_found = false; 399*12960Sgarrison } else if (strcmp (field2, "") == 0) { /* field not found */ 400*12960Sgarrison if (*p == 'A') { 401*12960Sgarrison getfield("F", field2, ref2); 402*12960Sgarrison if (strcmp (field2, "") == 0) { 403*12960Sgarrison getfield("I", field2, ref2); 404*12960Sgarrison if (strcmp (field2, "") == 0) { 405*12960Sgarrison res = -1; 406*12960Sgarrison fields_found = false; 407*12960Sgarrison } 408*12960Sgarrison } 409*12960Sgarrison } else { 410*12960Sgarrison res = -1; 411*12960Sgarrison fields_found = false; 412*12960Sgarrison } 413*12960Sgarrison } 414*12960Sgarrison if (fields_found) { 415*12960Sgarrison if (*p == 'A') { 41612909Sgarrison if (isupper(field1[0])) 41712909Sgarrison field1[0] -= 'A' - 'a'; 41812909Sgarrison if (isupper(field2[0])) 41912909Sgarrison field2[0] -= 'A' - 'a'; 42012909Sgarrison } 42112909Sgarrison res = strcmp(field1, field2); 42212909Sgarrison } 42312909Sgarrison if (neg) 42412909Sgarrison res = - res; 42512909Sgarrison if (res != 0) 42612909Sgarrison break; 42712909Sgarrison } 42812909Sgarrison if (res == 0) 42912909Sgarrison if (ap < bp) 43012909Sgarrison res = -1; 43112909Sgarrison else 43212909Sgarrison res = 1; 43312909Sgarrison return(res); 43412909Sgarrison } 43512909Sgarrison 43612909Sgarrison /* makecites - make citation strings */ 43712909Sgarrison makecites(citestr) 43812909Sgarrison char *citestr[]; 43912909Sgarrison { char ref[REFSIZE], tempcite[100], *malloc(); 44012909Sgarrison int i; 44112909Sgarrison 44212909Sgarrison for (i = 0; i <= numrefs; i++) { 44312909Sgarrison rdref(refspos[i], ref); 44412909Sgarrison bldcite(tempcite, i, ref); 44512909Sgarrison citestr[i] = malloc(2 + strlen(tempcite)); /* leave room for disambig */ 44612909Sgarrison if (citestr[i] == NULL) 44712909Sgarrison error("out of storage"); 44812909Sgarrison strcpy(citestr[i], tempcite); 44912909Sgarrison } 45012909Sgarrison } 45112909Sgarrison 45212909Sgarrison /* bldcite - build a single citation string */ 45312909Sgarrison bldcite(cp, i, ref) 45412909Sgarrison char *cp, ref[]; 45512909Sgarrison int i; 45612909Sgarrison { char *p, *q, c, *fp, *np, field[REFSIZE], temp[100], *getfield(); 45712909Sgarrison int j; 45812909Sgarrison 45912909Sgarrison getfield("F", field, ref); 46012909Sgarrison if (field[0] != 0) 46112909Sgarrison for (p = field; *p; p++) 46212909Sgarrison *cp++ = *p; 46312909Sgarrison else { 46412909Sgarrison p = citetemplate; 46512909Sgarrison field[0] = 0; 46612909Sgarrison while (c = *p++) 46712909Sgarrison if (isalpha(c)) { 46812909Sgarrison q = getfield(p-1, field, ref); 46912909Sgarrison if (q != 0) { 47012909Sgarrison p = q; 47112909Sgarrison for (fp = field; *fp; ) 47212909Sgarrison *cp++ = *fp++; 47312909Sgarrison } 47412909Sgarrison } 47512909Sgarrison else if (c == '1') { 47612909Sgarrison sprintf(field,"%d",1 + i); 47712909Sgarrison for (fp = field; *fp; ) 47812909Sgarrison *cp++ = *fp++; 47912909Sgarrison } 48012909Sgarrison else if (c == '2') { 48112909Sgarrison if (getname(1, field, temp, ref)) { 48212909Sgarrison np = cp; 48312909Sgarrison fp = field; 48412909Sgarrison for (j = 1; j <= 3; j++) 48512909Sgarrison if (*fp != 0) 48612909Sgarrison *cp++ = *fp++; 48712909Sgarrison if (getname(2, field, temp, ref)) 48812909Sgarrison np[2] = field[0]; 48912909Sgarrison if (getname(3, field, temp, ref)) { 49012909Sgarrison np[1] = np[2]; 49112909Sgarrison np[2] = field[0]; 49212909Sgarrison } 49312909Sgarrison } 49412909Sgarrison } 49512909Sgarrison else if (c == '{') { 49612909Sgarrison while (*p ^= '}') 49712909Sgarrison if (*p == 0) 49812909Sgarrison error("unexpected end of citation template"); 49912909Sgarrison else 50012909Sgarrison *cp++ = *p++; 50112909Sgarrison p++; 50212909Sgarrison } 50312909Sgarrison else if (c == '<') { 50412909Sgarrison while (*p ^= '>') 50512909Sgarrison if (*p == 0) 50612909Sgarrison error("unexpected end of citation template"); 50712909Sgarrison else 50812909Sgarrison *cp++ = *p++; 50912909Sgarrison p++; 51012909Sgarrison } 51112909Sgarrison else if (c != '@') 51212909Sgarrison *cp++ = c; 51312909Sgarrison } 51412909Sgarrison *cp++ = 0; 51512909Sgarrison } 51612909Sgarrison 51712909Sgarrison /* getfield - get a single field from reference */ 51812909Sgarrison char *getfield(ptr, field, ref) 51912909Sgarrison char *ptr, field[], ref[]; 52012909Sgarrison { char *p, *q, temp[100]; 52112909Sgarrison int n, len, i, getname(); 52212909Sgarrison 52312909Sgarrison field[0] = 0; 52412909Sgarrison if (*ptr == 'A') 52512909Sgarrison getname(1, field, temp, ref); 52612909Sgarrison else 52712909Sgarrison for (p = ref; *p; p++) 52812909Sgarrison if (*p == '%' && *(p+1) == *ptr) { 52912909Sgarrison for (p = p + 2; *p == ' '; p++) 53012909Sgarrison ; 53112909Sgarrison for (q = field; *p != '\n'; ) 53212909Sgarrison *q++ = *p++; 53312909Sgarrison *q = 0; 53412909Sgarrison break; 53512909Sgarrison } 53612909Sgarrison n = 0; 53712909Sgarrison len = strlen(field); 53812909Sgarrison if (*++ptr == '-') { 53912909Sgarrison for (ptr++; isdigit(*ptr); ptr++) 54012909Sgarrison n = 10 * n + (*ptr - '0'); 54112909Sgarrison if (n > len) 54212909Sgarrison n = 0; 54312909Sgarrison else 54412909Sgarrison n = len - n; 54512909Sgarrison for (i = 0; field[i] = field[i+n]; i++) 54612909Sgarrison ; 54712909Sgarrison } 54812909Sgarrison else if (isdigit(*ptr)) { 54912909Sgarrison for (; isdigit(*ptr); ptr++) 55012909Sgarrison n = 10 * n + (*ptr - '0'); 55112909Sgarrison if (n > len) 55212909Sgarrison n = len; 55312909Sgarrison field[n] = 0; 55412909Sgarrison } 55512909Sgarrison 55612909Sgarrison if (*ptr == 'u') { 55712909Sgarrison ptr++; 55812909Sgarrison for (p = field; *p; p++) 55912909Sgarrison if (islower(*p)) 56012909Sgarrison *p = (*p - 'a') + 'A'; 56112909Sgarrison } 56212909Sgarrison else if (*ptr == 'l') { 56312909Sgarrison ptr++; 56412909Sgarrison for (p = field; *p; p++) 56512909Sgarrison if (isupper(*p)) 56612909Sgarrison *p = (*p - 'A') + 'a'; 56712909Sgarrison } 56812909Sgarrison return(ptr); 56912909Sgarrison } 57012909Sgarrison 57112909Sgarrison /* getname - get the nth name field from reference, breaking into 57212909Sgarrison first and last names */ 57312909Sgarrison int getname(n, last, first, ref) 57412909Sgarrison int n; 57512909Sgarrison char last[], first[], ref[]; 57612909Sgarrison { char *p; 57712909Sgarrison 57812909Sgarrison for (p = ref; *p; p++) 579*12960Sgarrison if (*p == '%' & (*(p+1) == 'A' || *(p+1) == 'E')) { 58012909Sgarrison n--; 58112909Sgarrison if (n == 0) { 58212909Sgarrison for (p = p + 2; *p == ' '; p++) ; 58312909Sgarrison breakname(p, first, last) ; 58412909Sgarrison return(true); 58512909Sgarrison } 58612909Sgarrison } 58712909Sgarrison return(false); 58812909Sgarrison } 58912909Sgarrison 59012909Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add 59112909Sgarrison single character disambiguators */ 59212909Sgarrison disambiguate() 59312909Sgarrison { int i, j; 59412909Sgarrison char adstr[2]; 59512909Sgarrison 59612909Sgarrison for (i = 0; i < numrefs; i = j) { 59712909Sgarrison j = i + 1; 59812909Sgarrison if (strcmp(citestr[i], citestr[j])==0) { 59912909Sgarrison adstr[0] = 'a'; adstr[1] = 0; 60012909Sgarrison for (j = i+1; strcmp(citestr[i],citestr[j]) == 0; j++) { 60112909Sgarrison adstr[0] = 'a' + (j-i); 60212909Sgarrison strcat(citestr[j], adstr); 60312909Sgarrison if (j == numrefs) 60412909Sgarrison break; 60512909Sgarrison } 60612909Sgarrison adstr[0] = 'a'; 60712909Sgarrison strcat(citestr[i], adstr); 60812909Sgarrison } 60912909Sgarrison } 61012909Sgarrison } 61112909Sgarrison 61212909Sgarrison /* putrefs - gather contiguous references together, sort them if called 61312909Sgarrison for, hyphenate if necessary, and dump them out */ 61412909Sgarrison int putrefs(ifd, ofd, footrefs, fn) 61512909Sgarrison FILE *ifd, *ofd; 61612909Sgarrison int fn, footrefs[]; 61712909Sgarrison { int citenums[MAXATONCE]; /* reference numbers */ 61812909Sgarrison char *citeinfo[MAXATONCE]; /* reference information */ 61912909Sgarrison char infoword[HUNTSIZE]; /* information line */ 62012909Sgarrison int rtop, n, i, j; /* number of citations being dumped */ 62112909Sgarrison char c, *p, *walloc(); 62212909Sgarrison 62312909Sgarrison /* first gather contiguous references together, and order them if 62412909Sgarrison required */ 62512909Sgarrison 62612909Sgarrison rtop = -1; 62712909Sgarrison do { 62812909Sgarrison n = 0; 62912909Sgarrison while (isdigit(getch(c, ifd))) 63012909Sgarrison n = 10 * n + (c - '0'); 63112909Sgarrison if (c ^= CITEMARK) 63212909Sgarrison error("inconsistant citation found in pass two"); 63312909Sgarrison if (n == 0) { /* reference not found */ 63412909Sgarrison rtop++; 63512909Sgarrison j = rtop; 63612909Sgarrison citenums[j] = -1; 63712909Sgarrison citeinfo[j] = 0; 63812909Sgarrison } 63912909Sgarrison else { 64012909Sgarrison for (i = 0; i <= numrefs; i++) 64112909Sgarrison if (refspos[i] == n) { /* its the ith item in reference list */ 64212909Sgarrison rtop++; 64312909Sgarrison j = rtop; 64412909Sgarrison if (ordcite) 64512909Sgarrison for ( ; j > 0 && citenums[j-1] > i; j--) { 64612909Sgarrison citenums[j] = citenums[j-1]; 64712909Sgarrison citeinfo[j] = citeinfo[j-1]; 64812909Sgarrison } 64912909Sgarrison citenums[j] = i; 65012909Sgarrison citeinfo[j] = 0; 65112909Sgarrison break; 65212909Sgarrison } 65312909Sgarrison if (i > numrefs) 65412909Sgarrison error("citation not found in pass two"); 65512909Sgarrison } 65612909Sgarrison if (getch(c, ifd) != CITEEND) { 65712909Sgarrison for (p = infoword; c != CITEEND ; ) { 65812909Sgarrison *p++ = c; 65912909Sgarrison getch(c, ifd); 66012909Sgarrison } 66112909Sgarrison *p = 0; 66212909Sgarrison citeinfo[j] = walloc(infoword); 66312909Sgarrison } 66412909Sgarrison getch(c, ifd); 66512909Sgarrison } while (c == CITEMARK); 66612909Sgarrison ungetc(c, ifd); 66712909Sgarrison 66812909Sgarrison /* now dump out values */ 66912909Sgarrison for (i = 0; i <= rtop; i++) { 67012909Sgarrison if (citenums[i] >= 0) 67112909Sgarrison fputs(citestr[citenums[i]], ofd); 67212909Sgarrison if (citeinfo[i]) { 67312909Sgarrison fputs(citeinfo[i], ofd); 67412909Sgarrison free(citeinfo[i]); 67512909Sgarrison } 67612909Sgarrison if (hyphen) { 67712909Sgarrison for (j = 1; j + i <= rtop && citenums[i+j] == citenums[i] + j; j++); 67812909Sgarrison if (j + i > rtop) j = rtop; 67912909Sgarrison else j = j + i - 1; 68012909Sgarrison } 68112909Sgarrison else 68212909Sgarrison j = i; 68312909Sgarrison if (j > i + 1) { 68412909Sgarrison fputs("\\*(]-", ofd); 68512909Sgarrison i = j - 1; 68612909Sgarrison } 68712909Sgarrison else if (i != rtop) 68812909Sgarrison fputs("\\*(],", ofd); 68912909Sgarrison if (foot) { 69012909Sgarrison fn++; 69112909Sgarrison footrefs[fn] = citenums[i]; 69212909Sgarrison } 69312909Sgarrison } 69412909Sgarrison return(fn); 69512909Sgarrison } 69612909Sgarrison 69712909Sgarrison /* pass2 - read pass 1 files entering citation */ 69812909Sgarrison pass2(ifd, ofd) 69912909Sgarrison FILE *ifd, *ofd; 70012909Sgarrison { 70112909Sgarrison char c; 70212909Sgarrison int i, fn, footrefs[25], dumped; 70312909Sgarrison 70412909Sgarrison fn = -1; 70512909Sgarrison dumped = foot; 70612909Sgarrison while (getch(c, ifd) != EOF) { 70712909Sgarrison while (c == '\n') { 70812909Sgarrison putc(c, ofd); 70912909Sgarrison if (foot && fn >= 0) { 71012909Sgarrison for (i = 0; i <= fn; i++) 71112909Sgarrison dumpref(footrefs[i], ofd); 71212909Sgarrison fn = -1; 71312909Sgarrison } 71412909Sgarrison if (testc(c, '.', ifd, ofd)) 71512909Sgarrison if (testc(c, '[', ifd, ofd)) 71612909Sgarrison if (testc(c, ']', ifd, ofd)) { 71712909Sgarrison while (echoc(c, ifd, ofd) != '\n') 71812909Sgarrison ; 71912909Sgarrison dumped = true; 72012909Sgarrison for (i = 0; i <= numrefs; i++) 72112909Sgarrison dumpref(i, ofd); 72212909Sgarrison getch(c, ifd); 72312909Sgarrison } 72412909Sgarrison } 72512909Sgarrison if (c == CITEMARK) 72612909Sgarrison fn = putrefs(ifd, ofd, footrefs, fn); 72712909Sgarrison else if (c != EOF) 72812909Sgarrison putc(c, ofd); 72912909Sgarrison } 73012909Sgarrison if (dumped == false) 73112909Sgarrison fprintf(stderr,"Warning: references never dumped\n"); 73212909Sgarrison } 73312909Sgarrison 73412909Sgarrison 73512909Sgarrison /* dumpref - dump reference number i */ 73612909Sgarrison dumpref(i, ofd) 73712909Sgarrison int i; 73812909Sgarrison FILE *ofd; 73912909Sgarrison { char ref[REFSIZE], *p, line[REFSIZE]; 74012909Sgarrison int numauths, maxauths, numeds, maxeds; 74112909Sgarrison 74212909Sgarrison rdref(refspos[i], ref); 74312909Sgarrison maxauths = maxeds = 0; 74412909Sgarrison numauths = numeds = 0; 74512909Sgarrison for (p = ref; *p; p++) 74612909Sgarrison if (*p == '%') 74712909Sgarrison if (*(p+1) == 'A') maxauths++; 74812909Sgarrison else if (*(p+1) == 'E') maxeds++; 74912909Sgarrison fprintf(ofd, ".[-\n"); 75012909Sgarrison fprintf(ofd, ".ds [F %s\n",citestr[i]); 75112909Sgarrison fseek(rfd, (long) refspos[i], 0); 75212909Sgarrison while (fgets(line, REFSIZE, rfd) != NULL) { 75312909Sgarrison if (line[0] == 0) break; 75412909Sgarrison else if (line[0] == '.') fprintf(ofd,"%s",line); 75512909Sgarrison else { 75612909Sgarrison if (line[0] == '%') { 75712909Sgarrison for (p = &line[2]; *p == ' '; p++); 75812909Sgarrison if (line[1] == 'A') numauths++; 75912909Sgarrison else if (line[1] == 'E') numeds++; 76012909Sgarrison 76112909Sgarrison doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd); 76212909Sgarrison } 76312909Sgarrison } 76412909Sgarrison } 76512909Sgarrison fprintf(ofd,".][\n"); 76612909Sgarrison } 767