Annotation of 43BSD/contrib/bib/src/bibargs.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.