|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)bibargs.c 2.10 11/22/85"; ! 3: #endif not lint ! 4: /* ! 5: Authored by: Tim Budd, University of Arizona, 1983. ! 6: version 7/4/83 ! 7: ! 8: Various modifications suggested by: ! 9: David Cherveny - Duke University Medical Center ! 10: Phil Garrison - UC Berkeley ! 11: M. J. Hawley - Yale University ! 12: ! 13: ! 14: ! 15: ! 16: read argument strings for bib and listrefs ! 17: do name formatting, printing lines, other actions common to both ! 18: */ ! 19: # include <stdio.h> ! 20: # include <ctype.h> ! 21: # include "bib.h" ! 22: # define LINELENGTH 1024 ! 23: # define MAXDEFS 500 /* maximum number of defined words */ ! 24: ! 25: /* global variables */ ! 26: char bibfname[120]; /* file name currently being read */ ! 27: int biblineno; /* line number currently being referenced */ ! 28: int abbrev = false; /* automatically abbreviate names */ ! 29: int capsmcap = false; /* print names in caps small caps (CACM form)*/ ! 30: int numrev = 0; /* number of authors names to reverse */ ! 31: int edabbrev = false; /* abbreviate editors names ? */ ! 32: int edcapsmcap = false; /* print editors in cap small caps */ ! 33: int ednumrev = 0; /* number of editors to reverse */ ! 34: int max_klen = 6; /* max size of key */ ! 35: int sort = false; /* sort references ? (default no) */ ! 36: int foot = false; /* footnoted references ? (default endnotes) */ ! 37: int doacite = true; /* place citations ? */ ! 38: int hyphen = false; /* hypenate contiguous references */ ! 39: int ordcite = true; /* order multiple citations */ ! 40: char sortstr[80] = "1"; /* sorting template */ ! 41: char trailstr[80] = ""; /* trailing characters to output */ ! 42: char pfile[400]; /* private file name */ ! 43: int personal = false; /* personal file given ? (default no) */ ! 44: char citetemplate[80] = "1"; /* citation template */ ! 45: struct wordinfo words[MAXDEFS]; /* defined words */ ! 46: struct wordinfo *wordhash[HASHSIZE]; ! 47: struct wordinfo *wordsearch(); ! 48: int wordtop = 0; /* number of defined words */ ! 49: ! 50: /* where output goes */ ! 51: extern FILE *tfd; ! 52: /* reference file information */ ! 53: extern struct refinfo refinfo[]; ! 54: extern char reffile[]; ! 55: #ifndef INCORE ! 56: extern FILE *rfd; ! 57: #endif not INCORE ! 58: extern int numrefs; ! 59: ! 60: /* doargs - read command argument line for both bib and listrefs ! 61: set switch values ! 62: call rdtext on file arguments, after dumping ! 63: default style file if no alternative style is given ! 64: */ ! 65: int doargs(argc, argv, defstyle) ! 66: int argc; ! 67: char **argv, defstyle[]; ! 68: { int numfiles, i, style; ! 69: char *p, *q, *walloc(); ! 70: FILE *fd; ! 71: ! 72: numfiles = 0; ! 73: style = true; ! 74: newbibdir(BMACLIB); ! 75: ! 76: for (i = 1; i < argc; i++) ! 77: if (argv[i][0] == '-') ! 78: switch(argv[i][1]) { ! 79: case 'd': ! 80: if (argv[i][2]) ! 81: p = &argv[i][2]; ! 82: else { /* take next arg */ ! 83: i++; ! 84: p = argv[i]; ! 85: } ! 86: newbibdir(p); ! 87: case 'a': for (p = &argv[i][2]; *p; p++) ! 88: if (*p == 'a' || *p == 0) ! 89: abbrev = true; ! 90: else if (*p == 'x') ! 91: capsmcap = true; ! 92: else if (*p == 'r') { ! 93: if (*(p+1)) ! 94: numrev = atoi(p+1); ! 95: else ! 96: numrev = 1000; ! 97: break; ! 98: } ! 99: break; ! 100: ! 101: case 'c': if (argv[i][2] == 0) ! 102: error("citation string expected for 'c'"); ! 103: else ! 104: for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; ); ! 105: break; ! 106: ! 107: case 'e': for (p = &argv[i][2]; *p; p++) ! 108: if (*p == 'a') ! 109: edabbrev = true; ! 110: else if (*p == 'x') ! 111: edcapsmcap = true; ! 112: else if (*p == 'r') { ! 113: if (*(p+1)) ! 114: ednumrev = atoi(p+1); ! 115: else ! 116: ednumrev = 1000; ! 117: break; ! 118: } ! 119: break; ! 120: ! 121: case 'l': if (argv[i][2]){ ! 122: max_klen = atoi(&argv[i][2]); ! 123: if (max_klen > REFSIZE) ! 124: error("too long key size"); ! 125: } else { ! 126: error("-l needs a numeric value"); ! 127: } ! 128: break; ! 129: ! 130: case 'v': doacite = false; ! 131: /*FALLTHROUGH*/ ! 132: case 'f': foot = true; ! 133: hyphen = false; ! 134: break; ! 135: ! 136: case 'h': hyphen = ordcite = true; ! 137: break; ! 138: ! 139: case 'n': for (p = &argv[i][2]; *p; p++) ! 140: if (*p == 'a') ! 141: abbrev = false; ! 142: else if (*p == 'v') ! 143: doacite = true; ! 144: else if (*p == 'f') ! 145: foot = false; ! 146: else if (*p == 'h') ! 147: hyphen = false; ! 148: else if (*p == 'o') ! 149: ordcite = false; ! 150: else if (*p == 'r') ! 151: numrev = 0; ! 152: else if (*p == 's') ! 153: sort = false; ! 154: else if (*p == 'x') ! 155: capsmcap = false; ! 156: break; ! 157: ! 158: case 'o': ordcite = true; ! 159: break; ! 160: ! 161: case 'p': if (argv[i][2]) ! 162: p = &argv[i][2]; ! 163: else { /* take next arg */ ! 164: i++; ! 165: p = argv[i]; ! 166: } ! 167: strcpy(pfile, p); ! 168: personal = true; ! 169: break; ! 170: ! 171: case 'r': if (argv[i][2] == 0) /* this is now replaced by -ar */ ! 172: numrev = 1000; ! 173: else ! 174: numrev = atoi(&argv[i][2]); ! 175: break; ! 176: ! 177: case 's': sort = true; ! 178: if (argv[i][2]) ! 179: for (p = sortstr,q = &argv[i][2]; *p++ = *q++; ); ! 180: break; ! 181: ! 182: case 't': style = false; /* fall through */ ! 183: case 'i': if (argv[i][2]) ! 184: p = &argv[i][2]; ! 185: else { /* take next arg */ ! 186: i++; ! 187: p = argv[i]; ! 188: } ! 189: incfile(p); ! 190: break; ! 191: ! 192: case 'x': capsmcap = true; /* this is now replaced by -ax */ ! 193: break; ! 194: ! 195: case 0: if (style) { /* no style command given, take default */ ! 196: style = false; ! 197: incfile( defstyle ); ! 198: } ! 199: strcpy(bibfname,"<stdin>"); ! 200: rdtext(stdin); ! 201: numfiles++; ! 202: break; ! 203: ! 204: default: fputs(argv[i], stderr); ! 205: error("'%c' invalid switch", argv[i][1]); ! 206: } ! 207: else { /* file name */ ! 208: numfiles++; ! 209: if (style) { ! 210: style = false; ! 211: incfile( defstyle ); ! 212: } ! 213: fd = fopen(argv[i], "r"); ! 214: if (fd == NULL) { ! 215: error("can't open file %s", argv[i]); ! 216: } ! 217: else { ! 218: strcpy(bibfname, argv[i]); ! 219: rdtext(fd); ! 220: fclose(fd); ! 221: } ! 222: } ! 223: ! 224: if (style) incfile( defstyle ); ! 225: return(numfiles); ! 226: ! 227: } ! 228: ! 229: newbibdir(name) ! 230: char *name; ! 231: { ! 232: strreplace(COMFILE, BMACLIB, name); ! 233: strreplace(DEFSTYLE, BMACLIB, name); ! 234: strcpy(BMACLIB, name); ! 235: wordstuff("BMACLIB", BMACLIB); ! 236: fprintf(tfd, ".ds l] %s\n", BMACLIB); ! 237: } ! 238: ! 239: /* incfile - read in an included file */ ! 240: incfile(np) ! 241: char *np; ! 242: { char name[120]; ! 243: FILE *fd; ! 244: char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets(); ! 245: int i, getwrd(); ! 246: ! 247: strcpy(bibfname, np); ! 248: fd = fopen(np, "r"); ! 249: if (fd == NULL && *np != '/') { ! 250: strcpy(name, "bib."); ! 251: strcat(name, np); ! 252: strcpy(bibfname, name); ! 253: fd = fopen(name, "r"); ! 254: } ! 255: if (fd == NULL && *np != '/') { ! 256: strcpy(name,BMACLIB); ! 257: strcat(name, "/bib."); ! 258: strcat(name, np); ! 259: strcpy(bibfname, name); ! 260: fd = fopen(name, "r"); ! 261: } ! 262: if (fd == NULL) { ! 263: bibwarning("%s: can't open", np); ! 264: exit(1); ! 265: } ! 266: ! 267: /* now go off and process file */ ! 268: biblineno = 1; ! 269: while (tfgets(line, LINELENGTH, fd) != NULL) { ! 270: biblineno++; ! 271: switch(line[0]) { ! 272: ! 273: case '#': break; ! 274: ! 275: case 'A': for (p = &line[1]; *p; p++) ! 276: if (*p == 'A' || *p == '\0') ! 277: abbrev = true; ! 278: else if (*p == 'X') ! 279: capsmcap = true; ! 280: else if (*p == 'R') { ! 281: if (*(p+1)) ! 282: numrev = atoi(p+1); ! 283: else ! 284: numrev = 1000; ! 285: break; ! 286: } ! 287: break; ! 288: ! 289: case 'C': for (p = &line[1]; *p == ' '; p++) ; ! 290: strcpy(citetemplate, p); ! 291: break; ! 292: ! 293: case 'D': if ((i = getwrd(line, 1, word)) == 0) ! 294: error("word expected in definition"); ! 295: if (wordsearch(word)) { /* already there-toss rest of def.*/ ! 296: while(line[strlen(line)-1] == '\\' ) { ! 297: if (tfgets(line, LINELENGTH, fd) == NULL) break; ! 298: } ! 299: break; ! 300: } ! 301: for (p = &line[i]; *p == ' '; p++) ; ! 302: for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){ ! 303: dline[strlen(dline)-1] = '\n'; ! 304: if (tfgets(line, LINELENGTH, fd) == NULL) break; ! 305: strcat(dline, line); ! 306: } ! 307: wordstuff(word, dline); ! 308: break; ! 309: ! 310: case 'E': for (p = &line[1]; *p; p++) ! 311: if (*p == 'A') ! 312: edabbrev = true; ! 313: else if (*p == 'X') ! 314: edcapsmcap = true; ! 315: else if (*p == 'R') { ! 316: if (*(p+1)) ! 317: ednumrev = atoi(p+1); ! 318: else ! 319: ednumrev = 1000; ! 320: break; ! 321: } ! 322: break; ! 323: ! 324: case 'F': foot = true; ! 325: hyphen = false; ! 326: break; ! 327: ! 328: case 'I': for (p = &line[1]; *p == ' '; p++); ! 329: expand(p); ! 330: incfile(p); ! 331: break; ! 332: ! 333: case 'H': hyphen = ordcite = true; ! 334: break; ! 335: ! 336: case 'O': ordcite = true; ! 337: break; ! 338: ! 339: case 'R': if (line[1] == 0) /* this is now replaced by AR */ ! 340: numrev = 1000; ! 341: else ! 342: numrev = atoi(&line[1]); ! 343: break; ! 344: ! 345: case 'S': sort = true; ! 346: for (p = &line[1]; *p == ' '; p++) ; ! 347: strcpy(sortstr, p); ! 348: break; ! 349: ! 350: case 'T': for (p = &line[1]; *p == ' '; p++) ; ! 351: strcpy(trailstr, p); ! 352: break; ! 353: ! 354: case 'X': capsmcap = true; /* this is now replace by AX */ ! 355: break; ! 356: ! 357: default: fprintf(tfd,"%s\n",line); ! 358: while (fgets(line, LINELENGTH, fd) != NULL) ! 359: fputs(line, tfd); ! 360: return; ! 361: } ! 362: ! 363: } ! 364: /* close up */ ! 365: fclose(fd); ! 366: } ! 367: ! 368: /* bibwarning - print out a warning message */ ! 369: /*VARARGS1*/ ! 370: bibwarning(msg, a1, a2) ! 371: char *msg; ! 372: { ! 373: fprintf(stderr,"`%s', line %d: ", bibfname, biblineno); ! 374: fprintf(stderr, msg, a1, a2); ! 375: fprintf(stderr, "\n"); ! 376: } ! 377: ! 378: /* error - report unrecoverable error message */ ! 379: /*VARARGS1*/ ! 380: error(str, a1, a2) ! 381: char *str; ! 382: { ! 383: bibwarning(str, a1, a2); ! 384: /* ! 385: * clean up temp files and exit ! 386: */ ! 387: cleanup(1); ! 388: } ! 389: ! 390: #ifndef INCORE ! 391: #ifdef READWRITE ! 392: /* ! 393: ** fixrfd( mode ) -- re-opens the rfd file to be read or write, ! 394: ** depending on the mode. Uses a static int to save the current mode ! 395: ** and avoid unnecessary re-openings. ! 396: */ ! 397: fixrfd( mode ) ! 398: register int mode; ! 399: { ! 400: static int cur_mode = WRITE; /* rfd open for writing initially */ ! 401: ! 402: if (mode != cur_mode) ! 403: { ! 404: rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd); ! 405: cur_mode = mode; ! 406: if (rfd == NULL) ! 407: error("Hell! Couldn't re-open reference file %s", ! 408: reffile); ! 409: } ! 410: } ! 411: #endif ! 412: #endif not INCORE ! 413: ! 414: ! 415: /* tfgets - fgets which trims off newline */ ! 416: char *tfgets(line, n, ptr) ! 417: char line[]; ! 418: int n; ! 419: FILE *ptr; ! 420: { reg char *p; ! 421: ! 422: p = fgets(line, n, ptr); ! 423: if (p == NULL) ! 424: return(NULL); ! 425: else ! 426: for (p = line; *p; p++) ! 427: if (*p == '\n') ! 428: *p = 0; ! 429: return(line); ! 430: } ! 431: ! 432: /* getwrd - place next word from in[i] into out */ ! 433: int getwrd(in, i, out) ! 434: reg char in[], out[]; ! 435: reg int i; ! 436: { int j; ! 437: ! 438: j = 0; ! 439: while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t') ! 440: i++; ! 441: if (in[i]) ! 442: while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n') ! 443: out[j++] = in[i++]; ! 444: else ! 445: i = 0; /* signals end of in[i..] */ ! 446: out[j] = 0; ! 447: return (i); ! 448: } ! 449: ! 450: /* walloc - allocate enough space for a word */ ! 451: char *walloc(word) ! 452: char *word; ! 453: { char *i, *malloc(); ! 454: i = malloc(1 + strlen(word)); ! 455: if (i == NULL) ! 456: error("out of storage"); ! 457: strcpy(i, word); ! 458: return(i); ! 459: } ! 460: ! 461: /* isword - see if character is legit word char */ ! 462: int iswordc(c) ! 463: char c; ! 464: { ! 465: if (isalnum(c) || c == '&' || c == '_') ! 466: return(true); ! 467: return(false); ! 468: } ! 469: expand(line) ! 470: char *line; ! 471: { char line2[REFSIZE], word[LINELENGTH]; ! 472: reg struct wordinfo *wp; ! 473: reg char *p, *q, *w; ! 474: ! 475: q = line2; ! 476: for (p = line; *p; /*VOID*/){ ! 477: if (isalnum(*p)) { ! 478: for (w = word; *p && iswordc(*p); ) *w++ = *p++; ! 479: *w = 0; ! 480: if (wp = wordsearch(word)){ ! 481: strcpy(word, wp->wi_def); ! 482: expand(word); ! 483: } ! 484: strcpy(q, word); ! 485: q += strlen(q); ! 486: } else { ! 487: *q++ = *p++; ! 488: } ! 489: } ! 490: *q = 0; ! 491: strcpy(line, line2); ! 492: } ! 493: ! 494: /* wordstuff- save a word and its definition, building a hash table */ ! 495: wordstuff(word, def) ! 496: char *word, *def; ! 497: { ! 498: int i; ! 499: if (wordtop >= MAXDEFS) ! 500: error("too many definitions, max of %d", MAXDEFS); ! 501: words[wordtop].wi_length = strlen(word); ! 502: words[wordtop].wi_word = word ? walloc(word) : 0; ! 503: words[wordtop].wi_def = def ? walloc(def) : 0; ! 504: i = strhash(word); ! 505: words[wordtop].wi_hp = wordhash[i]; ! 506: wordhash[i] = &words[wordtop]; ! 507: wordtop++; ! 508: } ! 509: struct wordinfo *wordsearch(word) ! 510: char *word; ! 511: { ! 512: reg int lg; ! 513: reg struct wordinfo *wp; ! 514: lg = strlen(word); ! 515: for (wp = wordhash[strhash(word)]; wp; wp = wp->wi_hp){ ! 516: if (wp->wi_length == lg && (strcmp(wp->wi_word, word) == 0)){ ! 517: return(wp); ! 518: } ! 519: } ! 520: return(0); ! 521: } ! 522: ! 523: int strhash(str) ! 524: reg char *str; ! 525: { ! 526: reg int value = 0; ! 527: for (value = 0; *str; value <<= 2, value += *str++)/*VOID*/; ! 528: value %= HASHSIZE; ! 529: if (value < 0) ! 530: value += HASHSIZE; ! 531: return(value); ! 532: } ! 533: ! 534: /* rdref - read text for an already cited reference */ ! 535: rdref(p, ref) ! 536: struct refinfo *p; ! 537: char ref[REFSIZE]; ! 538: { ! 539: ref[0] = 0; ! 540: #ifndef INCORE ! 541: #ifdef READWRITE ! 542: fixrfd( READ ); /* fix access mode of rfd, if nec. */ ! 543: #endif ! 544: fseek(rfd, p->ri_pos, 0); ! 545: fread(ref, p->ri_length, 1, rfd); ! 546: #else INCORE ! 547: strcpy(ref, p->ri_ref); ! 548: #endif INCORE ! 549: } ! 550: ! 551: /* wrref - write text for a new reference */ ! 552: wrref(p, ref) ! 553: struct refinfo *p; ! 554: char ref[REFSIZE]; ! 555: { ! 556: #ifndef INCORE ! 557: #ifdef READWRITE ! 558: fixrfd( WRITE ); /* fix access mode of rfd, if nec. */ ! 559: #else ! 560: fseek(rfd, p->ri_pos, 0); /* go to end of rfd */ ! 561: #endif ! 562: fwrite(ref, p->ri_length, 1, rfd); ! 563: #else INCORE ! 564: p->ri_ref = walloc(ref); ! 565: #endif INCORE ! 566: } ! 567: ! 568: /* breakname - break a name into first and last name */ ! 569: breakname(line, first, last) ! 570: char line[], first[], last[]; ! 571: { reg char *t, *f, *q, *r, *p; ! 572: ! 573: for (t = line; *t != '\n'; t++); ! 574: for (t--; isspace(*t); t--); ! 575: ! 576: /* now strip off last name */ ! 577: for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--) ! 578: if (q == line) ! 579: break; ! 580: f = q; ! 581: if (q != line) { ! 582: q++; ! 583: for (; isspace(*f); f--); ! 584: f++; ! 585: } ! 586: ! 587: /* first name is start to f, last name is q to t */ ! 588: ! 589: for (r = first, p = line; p != f; ) ! 590: *r++ = *p++; ! 591: *r = 0; ! 592: for (r = last, p = q, t++; q != t; ) ! 593: *r++ = *q++; ! 594: *r = 0; ! 595: ! 596: } ! 597: ! 598: /* match - see if string1 is a substring of string2 (case independent)*/ ! 599: int match(str1, str2) ! 600: reg char str1[], str2[]; ! 601: { reg int j, i; ! 602: char a, b; ! 603: ! 604: for (i = 0; str2[i]; i++) { ! 605: for (j = 0; str1[j]; j++) { ! 606: if (isupper(a = str2[i+j])) ! 607: a = (a - 'A') + 'a'; ! 608: if (isupper(b = str1[j])) ! 609: b = (b - 'A') + 'a'; ! 610: if (a != b) ! 611: break; ! 612: } ! 613: if (str1[j] == 0) ! 614: return(true); ! 615: } ! 616: return(false); ! 617: } ! 618: ! 619: /* scopy - append a copy of one string to another */ ! 620: char *scopy(p, q) ! 621: reg char *p, *q; ! 622: { ! 623: while (*p++ = *q++) ! 624: ; ! 625: return(--p); ! 626: } ! 627: ! 628: /* rcomp - reference comparison routine for qsort utility */ ! 629: int rcomp(ap, bp) ! 630: struct refinfo *ap, *bp; ! 631: { char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD]; ! 632: reg char *p, *q; ! 633: char *getfield(); ! 634: int neg, res; ! 635: int fields_found; ! 636: ! 637: rdref(ap, ref1); ! 638: rdref(bp, ref2); ! 639: for (p = sortstr; *p; p = q) { ! 640: if (*p == '-') { ! 641: p++; ! 642: neg = true; ! 643: } ! 644: else ! 645: neg = false; ! 646: q = getfield(p, field1, ref1); ! 647: fields_found = true; ! 648: if (q == 0) { ! 649: res = 1; ! 650: fields_found = false; ! 651: } else if (strcmp (field1, "") == 0) { /* field not found */ ! 652: if (*p == 'A') { ! 653: getfield("F", field1, ref1); ! 654: if (strcmp (field1, "") == 0) { ! 655: getfield("I", field1, ref1); ! 656: if (strcmp (field1, "") == 0) { ! 657: res = 1; ! 658: fields_found = false; ! 659: } ! 660: } ! 661: } else { ! 662: res = 1; ! 663: fields_found = false; ! 664: } ! 665: } ! 666: ! 667: if (getfield(p, field2, ref2) == 0) { ! 668: res = -1; ! 669: fields_found = false; ! 670: } else if (strcmp (field2, "") == 0) { /* field not found */ ! 671: if (*p == 'A') { ! 672: getfield("F", field2, ref2); ! 673: if (strcmp (field2, "") == 0) { ! 674: getfield("I", field2, ref2); ! 675: if (strcmp (field2, "") == 0) { ! 676: res = -1; ! 677: fields_found = false; ! 678: } ! 679: } ! 680: } else { ! 681: res = -1; ! 682: fields_found = false; ! 683: } ! 684: } ! 685: if (fields_found) { ! 686: if (*p == 'A') { ! 687: if (isupper(field1[0])) ! 688: field1[0] -= 'A' - 'a'; ! 689: if (isupper(field2[0])) ! 690: field2[0] -= 'A' - 'a'; ! 691: } ! 692: res = strcmp(field1, field2); ! 693: } ! 694: if (neg) ! 695: res = - res; ! 696: if (res != 0) ! 697: break; ! 698: } ! 699: if (res == 0) ! 700: if (ap < bp) ! 701: res = -1; ! 702: else ! 703: res = 1; ! 704: return(res); ! 705: } ! 706: ! 707: /* makecites - make standard citation strings, using citetemplate currently in effect */ ! 708: makecites() ! 709: { char ref[REFSIZE], tempcite[100], *malloc(); ! 710: reg int i; ! 711: ! 712: for (i = 0; i < numrefs; i++) { ! 713: rdref(&refinfo[i], ref); ! 714: bldcite(tempcite, i, ref); ! 715: refinfo[i].ri_cite = malloc(2 + strlen(tempcite)); ! 716: if (refinfo[i].ri_cite == NULL) ! 717: error("out of storage"); ! 718: strcpy(refinfo[i].ri_cite, tempcite); ! 719: } ! 720: } ! 721: ! 722: /* bldcite - build a single citation string */ ! 723: bldcite(cp, i, ref) ! 724: char *cp, ref[]; ! 725: int i; ! 726: { reg char *p, *q, *fp; ! 727: char c; ! 728: char field[REFSIZE]; ! 729: char *getfield(), *aabet(), *aabetlast(), *fullaabet(), *astro(); ! 730: ! 731: getfield("F", field, ref); ! 732: if (field[0] != 0) ! 733: for (p = field; *p; p++) ! 734: *cp++ = *p; ! 735: else { ! 736: p = citetemplate; ! 737: field[0] = 0; ! 738: while (c = *p++) { ! 739: if (isalpha(c)) { /* field name */ ! 740: q = getfield(p-1, field, ref); ! 741: if (q != 0) { ! 742: p = q; ! 743: for (fp = field; *fp; ) ! 744: *cp++ = *fp++; ! 745: } ! 746: } ! 747: else if (c == '1') { /* numeric order */ ! 748: sprintf(field,"%d",1 + i); ! 749: for (fp = field; *fp; ) ! 750: *cp++ = *fp++; ! 751: } ! 752: else if (c == '2') /* alternate alphabetic */ ! 753: cp = aabet(cp, ref); ! 754: else if (c == '3') /* Astrophysical Journal style*/ ! 755: cp = astro(cp, ref); ! 756: else if (c == '8') /* Full alphabetic */ ! 757: cp = fullaabet(cp, ref); ! 758: else if (c == '9') /* Last name of Senior Author*/ ! 759: cp = aabetlast(cp, ref); ! 760: else if (c == '0') { /* print nothing */ ! 761: for (fp = field; *fp; ) ! 762: *cp++ = *fp++; ! 763: } ! 764: /* else if (c == '4') here is how to add new styles */ ! 765: else if (c == '{') { /* other information */ ! 766: while (*p != '}') ! 767: if (*p == 0) ! 768: error("unexpected end of citation template"); ! 769: else ! 770: *cp++ = *p++; ! 771: p++; ! 772: } ! 773: else if (c == '<') { ! 774: while (*p != '>') { ! 775: if (*p == 0) ! 776: error("unexpected end of citation template"); ! 777: else ! 778: *cp++ = *p++; ! 779: } ! 780: p++; ! 781: } ! 782: else if (c != '@') ! 783: *cp++ = c; ! 784: } ! 785: } ! 786: *cp++ = 0; ! 787: } ! 788: ! 789: /* alternate alphabetic citation style - ! 790: if 1 author - first three letters of last name ! 791: if 2 authors - first two letters of first, followed by first letter of ! 792: seond ! 793: if 3 or more authors - first letter of first three authors */ ! 794: char *aabet(cp, ref) ! 795: char *cp, ref[]; ! 796: { char field[REFSIZE], temp[100]; ! 797: reg char *np, *fp; ! 798: int j, getname(); ! 799: ! 800: if (getname(1, field, temp, ref)) { ! 801: np = cp; ! 802: fp = field; ! 803: for (j = 1; j <= 3; j++) ! 804: if (*fp != 0) ! 805: *cp++ = *fp++; ! 806: if (getname(2, field, temp, ref)) ! 807: np[2] = field[0]; ! 808: if (getname(3, field, temp, ref)) { ! 809: np[1] = np[2]; ! 810: np[2] = field[0]; ! 811: } ! 812: } ! 813: return(cp); ! 814: } ! 815: ! 816: /* alternate alphabetic citation style - ! 817: first two characters of last names of all authors ! 818: up to max_klen characters. ! 819: */ ! 820: char *fullaabet(cp, ref) ! 821: char *cp, ref[]; ! 822: { char field[REFSIZE], temp[100]; ! 823: reg char *fp; ! 824: char *lastcp; ! 825: int getname(); ! 826: int i; ! 827: ! 828: lastcp = cp + max_klen; ! 829: for (i= 1; getname(i, field, temp, ref); i++) { ! 830: for (fp = field; *fp && (fp < &(field[3])); ) ! 831: if (cp > lastcp) ! 832: break; ! 833: else if (isalpha(*fp)) ! 834: *cp++ = *fp++; ! 835: else ! 836: fp++; ! 837: } ! 838: return(cp); ! 839: } ! 840: ! 841: ! 842: /* alternate alphabetic citation style - ! 843: entire last name of senior author ! 844: */ ! 845: char *aabetlast(cp, ref) ! 846: char *cp, ref[]; ! 847: { char field[REFSIZE], temp[100]; ! 848: reg char *fp; ! 849: int getname(); ! 850: ! 851: if (getname(1, field, temp, ref)) { ! 852: for (fp = field; *fp; ) ! 853: *cp++ = *fp++; ! 854: } ! 855: return(cp); ! 856: } ! 857: ! 858: /* Astrophysical Journal style ! 859: if 1 author - last name date ! 860: if 2 authors - last name and last name date ! 861: if 3 authors - last name, last name and last name date ! 862: if 4 or more authors - last name et al. date */ ! 863: char *astro(cp, ref) ! 864: char *cp, ref[]; ! 865: { char name1[100], name2[100], name3[100], temp[100]; ! 866: reg char *fp; ! 867: int getname(); ! 868: ! 869: if (getname(1, name1, temp, ref)) { ! 870: for (fp = name1; *fp; ) ! 871: *cp++ = *fp++; ! 872: if (getname(4, name3, temp, ref)) { ! 873: for (fp = " et al."; *fp; ) ! 874: *cp++ = *fp++; ! 875: } ! 876: else if (getname(2, name2, temp, ref)) { ! 877: if (getname(3, name3, temp, ref)) { ! 878: for (fp = "\\*(c]"; *fp; ) ! 879: *cp++ = *fp++; ! 880: for (fp = name2; *fp; ) ! 881: *cp++ = *fp++; ! 882: for (fp = "\\*(m]"; *fp; ) ! 883: *cp++ = *fp++; ! 884: for (fp = name3; *fp; ) ! 885: *cp++ = *fp++; ! 886: } ! 887: else { ! 888: for (fp = "\\*(n]"; *fp; ) ! 889: *cp++ = *fp++; ! 890: for (fp = name2; *fp; ) ! 891: *cp++ = *fp++; ! 892: } ! 893: } ! 894: } ! 895: return(cp); ! 896: } ! 897: ! 898: /* getfield - get a single field from reference */ ! 899: char *getfield(ptr, field, ref) ! 900: char *ptr, field[], ref[]; ! 901: { reg char *p, *q; ! 902: char temp[100]; ! 903: int n, len, i, getname(); ! 904: ! 905: field[0] = 0; ! 906: if (*ptr == 'A') ! 907: getname(1, field, temp, ref); ! 908: else ! 909: for (p = ref; *p; p++) ! 910: if (*p == '%' && *(p+1) == *ptr) { ! 911: for (p = p + 2; *p == ' '; p++) ! 912: ; ! 913: for (q = field; (*p != '\n') && (*p != '\0'); ) ! 914: *q++ = *p++; ! 915: *q = 0; ! 916: break; ! 917: } ! 918: n = 0; ! 919: len = strlen(field); ! 920: if (*++ptr == '-') { ! 921: for (ptr++; isdigit(*ptr); ptr++) ! 922: n = 10 * n + (*ptr - '0'); ! 923: if (n > len) ! 924: n = 0; ! 925: else ! 926: n = len - n; ! 927: for (i = 0; field[i] = field[i+n]; i++) ! 928: ; ! 929: } ! 930: else if (isdigit(*ptr)) { ! 931: for (; isdigit(*ptr); ptr++) ! 932: n = 10 * n + (*ptr - '0'); ! 933: if (n > len) ! 934: n = len; ! 935: field[n] = 0; ! 936: } ! 937: ! 938: if (*ptr == 'u') { ! 939: ptr++; ! 940: for (p = field; *p; p++) ! 941: if (islower(*p)) ! 942: *p = (*p - 'a') + 'A'; ! 943: } ! 944: else if (*ptr == 'l') { ! 945: ptr++; ! 946: for (p = field; *p; p++) ! 947: if (isupper(*p)) ! 948: *p = (*p - 'A') + 'a'; ! 949: } ! 950: return(ptr); ! 951: } ! 952: ! 953: /* getname - get the nth name field from reference, breaking into ! 954: first and last names */ ! 955: int getname(n, last, first, ref) ! 956: int n; ! 957: char last[], first[], ref[]; ! 958: { reg char *p; ! 959: int m; ! 960: ! 961: m = n; ! 962: for (p = ref; *p; p++) ! 963: if (*p == '%' & *(p+1) == 'A') { ! 964: n--; ! 965: if (n == 0) { ! 966: for (p = p + 2; *p == ' '; p++) ; ! 967: breakname(p, first, last) ; ! 968: return(true); ! 969: } ! 970: } ! 971: ! 972: if (n == m) /* no authors, try editors */ ! 973: for (p = ref; *p; p++) ! 974: if (*p == '%' & *(p+1) == 'E') { ! 975: n--; ! 976: if (n == 0) { ! 977: for (p = p + 2; *p == ' '; p++) ; ! 978: breakname(p, first, last) ; ! 979: return(true); ! 980: } ! 981: } ! 982: ! 983: if (n == m) { /* no editors, either, try institution */ ! 984: first[0] = last[0] = '\0'; ! 985: getfield("I", last, ref); ! 986: if (last[0] != '\0') ! 987: return(true); ! 988: } ! 989: ! 990: return(false); ! 991: } ! 992: ! 993: /* disambiguate - compare adjacent citation strings, and if equal, add ! 994: single character disambiguators */ ! 995: disambiguate() ! 996: { reg int i, j; ! 997: char adstr; ! 998: ! 999: for (i = 0; i < numrefs-1; i = j) { ! 1000: j = i + 1; ! 1001: if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) { ! 1002: adstr = 'a'; ! 1003: for(j = i+1; ! 1004: j<numrefs && strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0; ! 1005: j++) { ! 1006: adstr = 'a' + (j-i); ! 1007: refinfo[j].ri_disambig[0] = adstr; ! 1008: } ! 1009: refinfo[i].ri_disambig[0] = 'a'; ! 1010: } ! 1011: } ! 1012: for (i = 0; i < numrefs; i++){ ! 1013: strcat(refinfo[i].ri_cite, refinfo[i].ri_disambig); ! 1014: } ! 1015: } ! 1016: ! 1017: ! 1018: /* bldname - build a name field ! 1019: doing abbreviations, reversals, and caps/small caps ! 1020: */ ! 1021: bldname(first, last, name, reverse) ! 1022: char *first, *last, name[]; ! 1023: int reverse; ! 1024: { ! 1025: char newfirst[120], newlast[120]; ! 1026: reg char *p, *q, *f, *l; ! 1027: char *scopy(); ! 1028: int flag; ! 1029: ! 1030: if (abbrev) { ! 1031: p = first; ! 1032: q = newfirst; ! 1033: flag = false; ! 1034: while (*p) { ! 1035: while (*p == ' ') ! 1036: p++; ! 1037: if (*p == 0) ! 1038: break; ! 1039: if (isupper(*p)) { ! 1040: if (flag) /* between initial gap */ ! 1041: q = scopy(q, "\\*(a]"); ! 1042: flag = true; ! 1043: *q++ = *p; ! 1044: q = scopy(q, "\\*(p]"); ! 1045: } ! 1046: if (*++p == '.') ! 1047: p++; ! 1048: else while (*p != 0 && ! isspace(*p)) ! 1049: p++; ! 1050: } ! 1051: *q = 0; ! 1052: f = newfirst; ! 1053: } ! 1054: else ! 1055: f = first; ! 1056: ! 1057: if (capsmcap) { ! 1058: p = last; ! 1059: q = newlast; ! 1060: flag = 0; /* 1 - printing cap, 2 - printing small */ ! 1061: while (*p) ! 1062: if (islower(*p)) { ! 1063: if (flag != 2) ! 1064: q = scopy(q, "\\s-2"); ! 1065: flag = 2; ! 1066: *q++ = (*p++ - 'a') + 'A'; ! 1067: } ! 1068: else { ! 1069: if (flag == 2) ! 1070: q = scopy(q,"\\s+2"); ! 1071: flag = 1; ! 1072: *q++ = *p++; ! 1073: } ! 1074: if (flag == 2) ! 1075: q = scopy(q, "\\s+2"); ! 1076: *q = 0; ! 1077: l = newlast; ! 1078: } ! 1079: else ! 1080: l = last; ! 1081: ! 1082: if (f[0] == 0) ! 1083: sprintf(name, "%s\n", l); ! 1084: else if (reverse) ! 1085: sprintf(name, "%s\\*(b]%s\n", l, f); ! 1086: else ! 1087: sprintf(name, "%s %s\n", f, l); ! 1088: } ! 1089: ! 1090: /* prtauth - print author or editor field */ ! 1091: prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev) ! 1092: char c, *line; ! 1093: int num, max, abbrev, capsmcap, numrev; ! 1094: FILE *ofd; ! 1095: { char first[LINELENGTH], last[LINELENGTH]; ! 1096: ! 1097: if (num <= numrev || abbrev || capsmcap) { ! 1098: breakname(line, first, last); ! 1099: bldname(first, last, line, num <= numrev); ! 1100: } ! 1101: if (num == 1) ! 1102: fprintf(ofd,".ds [%c %s", c, line); ! 1103: else if (num < max) ! 1104: fprintf(ofd,".as [%c \\*(c]%s", c, line); ! 1105: else if (max == 2) ! 1106: fprintf(ofd,".as [%c \\*(n]%s", c, line); ! 1107: else ! 1108: fprintf(ofd,".as [%c \\*(m]%s", c, line); ! 1109: if (num == max && index(trailstr, c)) ! 1110: fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]); ! 1111: } ! 1112: ! 1113: /* doline - actually print out a line of reference information */ ! 1114: doline(c, line, numauths, maxauths, numeds, maxeds, ofd) ! 1115: char c, *line; ! 1116: int numauths, maxauths, numeds, maxeds; ! 1117: FILE *ofd; ! 1118: { ! 1119: ! 1120: switch(c) { ! 1121: case 'A': ! 1122: prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev); ! 1123: break; ! 1124: ! 1125: case 'E': ! 1126: prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev); ! 1127: if (numeds == maxeds) ! 1128: fprintf(ofd,".nr [E %d\n", maxeds); ! 1129: break; ! 1130: ! 1131: case 'P': ! 1132: if (index(line, '-')) ! 1133: fprintf(ofd,".nr [P 1\n"); ! 1134: else ! 1135: fprintf(ofd,".nr [P 0\n"); ! 1136: fprintf(ofd,".ds [P %s",line); ! 1137: if (index(trailstr, 'P')) ! 1138: fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]); ! 1139: break; ! 1140: ! 1141: case 'F': ! 1142: case 'K': break; ! 1143: ! 1144: default: ! 1145: fprintf(ofd,".ds [%c %s", c, line); ! 1146: if (index(trailstr, c)) ! 1147: fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]); ! 1148: } ! 1149: } ! 1150: ! 1151: /* dumpref - dump reference number i */ ! 1152: dumpref(i, ofd) ! 1153: int i; ! 1154: FILE *ofd; ! 1155: { char ref[REFSIZE], line[REFSIZE]; ! 1156: reg char *p, *q; ! 1157: char *from; ! 1158: int numauths, maxauths, numeds, maxeds; ! 1159: ! 1160: rdref(&refinfo[i], ref); ! 1161: maxauths = maxeds = 0; ! 1162: numauths = numeds = 0; ! 1163: for (p = ref; *p; p++) ! 1164: if (*p == '%') ! 1165: if (*(p+1) == 'A') maxauths++; ! 1166: else if (*(p+1) == 'E') maxeds++; ! 1167: fprintf(ofd, ".[-\n"); ! 1168: fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite); ! 1169: #ifndef INCORE ! 1170: fseek(rfd, (long)refinfo[i].ri_pos, 0); ! 1171: while (fgets(line, REFSIZE, rfd) != NULL) { ! 1172: #else INCORE ! 1173: for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */ ! 1174: if (*from == '\n'){ ! 1175: *q++ = '\n'; ! 1176: *q = 0; ! 1177: q = line; ! 1178: from++; ! 1179: } else { ! 1180: *q++ = *from++; ! 1181: continue; ! 1182: } ! 1183: #endif INCORE ! 1184: switch(line[0]){ ! 1185: case 0: ! 1186: goto doneref; ! 1187: case '.': ! 1188: fprintf(ofd, "%s", line); ! 1189: break; ! 1190: case '%': ! 1191: switch(line[1]){ ! 1192: case 'A': numauths++; break; ! 1193: case 'E': numeds++; break; ! 1194: } ! 1195: for (p = &line[2]; *p == ' '; p++) /*VOID*/; ! 1196: doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd); ! 1197: } ! 1198: } ! 1199: doneref:; ! 1200: fprintf(ofd,".][\n"); ! 1201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.