Annotation of 43BSDReno/contrib/bib/src/bibargs.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)bibargs.c  2.12    11/16/87";
        !             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(),
        !           730:         *fullaabet(), *multfull();
        !           731: 
        !           732:    getfield("F", field, ref);
        !           733:    if (field[0] != 0)
        !           734:       for (p = field; *p; p++)
        !           735:          *cp++ = *p;
        !           736:    else {
        !           737:       p = citetemplate;
        !           738:       field[0] = 0;
        !           739:       while (c = *p++) {
        !           740:          if (isalpha(c)) {                      /* field name   */
        !           741:             q = getfield(p-1, field, ref);
        !           742:             if (q != 0) {
        !           743:                p = q;
        !           744:                for (fp = field; *fp; )
        !           745:                   *cp++ = *fp++;
        !           746:                }
        !           747:             }
        !           748:          else if (c == '1') {                   /* numeric  order */
        !           749:             sprintf(field,"%d",1 + i);
        !           750:             for (fp = field; *fp; )
        !           751:                *cp++ = *fp++;
        !           752:             }
        !           753:          else if (c == '2')                     /* alternate alphabetic */
        !           754:             cp = aabet(cp, ref);
        !           755:          else if (c == '3')                     /* Astrophysical Journal style*/
        !           756:             cp = multfull(cp, ref, 3);
        !           757:          else if (c == '4')                     /* Computing Surveys style*/
        !           758:             cp = multfull(cp, ref, 2);
        !           759:         else if (c == '8')                     /* Full alphabetic */
        !           760:            cp = fullaabet(cp, ref);
        !           761:          else if (c == '9')                     /* Last name of Senior Author*/
        !           762:             cp = aabetlast(cp, ref);
        !           763:         else if (c == '0') {                   /* print nothing */
        !           764:             for (fp = field; *fp; )
        !           765:                *cp++ = *fp++;
        !           766:             }
        !           767: /*       else if (c == '4')          here is how to add new styles */
        !           768:          else if (c == '{') {                   /* other information   */
        !           769:             while (*p != '}')
        !           770:                if (*p == 0)
        !           771:                   error("unexpected end of citation template");
        !           772:                else
        !           773:                   *cp++ = *p++;
        !           774:             p++;
        !           775:             }
        !           776:          else if (c == '<') {
        !           777:             while (*p != '>') {
        !           778:                if (*p == 0)
        !           779:                   error("unexpected end of citation template");
        !           780:                else
        !           781:                   *cp++ = *p++;
        !           782:                }
        !           783:             p++;
        !           784:             }
        !           785:          else if (c != '@')
        !           786:             *cp++ = c;
        !           787:          }
        !           788:       }
        !           789:    *cp++ = 0;
        !           790: }
        !           791: 
        !           792: /* alternate alphabetic citation style -
        !           793:         if 1 author - first three letters of last name
        !           794:         if 2 authors - first two letters of first, followed by first letter of
        !           795:                                 seond
        !           796:         if 3 or more authors - first letter of first three authors */
        !           797:    char *aabet(cp, ref)
        !           798:    char *cp, ref[];
        !           799: {  char field[REFSIZE], temp[100];
        !           800:    reg char *np, *fp;
        !           801:    int j, getname();
        !           802: 
        !           803:    if (getname(1, field, temp, ref)) {
        !           804:       np = cp;
        !           805:       fp = field;
        !           806:       for (j = 1; j <= 3; j++)
        !           807:          if (*fp != 0)
        !           808:             *cp++ = *fp++;
        !           809:       if (getname(2, field, temp, ref))
        !           810:          np[2] = field[0];
        !           811:       if (getname(3, field, temp, ref)) {
        !           812:          np[1] = np[2];
        !           813:          np[2] = field[0];
        !           814:          }
        !           815:       }
        !           816: return(cp);
        !           817: }
        !           818: 
        !           819: /* alternate alphabetic citation style -
        !           820:        first two characters of last names of all authors
        !           821:        up to max_klen characters.
        !           822: */
        !           823:    char *fullaabet(cp, ref)
        !           824:    char *cp, ref[];
        !           825: {  char field[REFSIZE], temp[100];
        !           826:    reg char    *fp;
        !           827:    char        *lastcp;
        !           828:    int getname();
        !           829:    int i;
        !           830: 
        !           831:    lastcp = cp + max_klen;
        !           832:    for (i= 1; getname(i, field, temp, ref); i++) {
        !           833:       for (fp = field; *fp && (fp < &(field[3])); )
        !           834:         if (cp > lastcp)
        !           835:             break;
        !           836:          else if (isalpha(*fp))
        !           837:             *cp++ = *fp++;
        !           838:         else
        !           839:             fp++;
        !           840:    }
        !           841:    return(cp);
        !           842: }
        !           843: 
        !           844: 
        !           845: /* alternate alphabetic citation style -
        !           846:        entire last name of senior author
        !           847: */
        !           848:    char *aabetlast(cp, ref)
        !           849:    char *cp, ref[];
        !           850: {  char field[REFSIZE], temp[100];
        !           851:    reg char    *fp;
        !           852:    int getname();
        !           853: 
        !           854:    if (getname(1, field, temp, ref)) {
        !           855:       for (fp = field; *fp; )
        !           856:          *cp++ = *fp++;
        !           857:    }
        !           858:    return(cp);
        !           859: }
        !           860: 
        !           861: /* 
        !           862:   Multiple full authors last names (1, 2 or 3 full names).
        !           863: 
        !           864:   If maxauthors<3
        !           865:         if 1 author - last name date
        !           866:         if 2 authors - last name and last name date
        !           867:         if 3 or more authors - last name et al. date
        !           868:   If maxauthors>=3
        !           869:         if 1 author - last name date
        !           870:         if 2 authors - last name and last name date
        !           871:         if 3 authors - last name, last name and last name date
        !           872:         if 4 or more authors - last name et al. date */
        !           873:    char *multfull(cp, ref, maxauthors)
        !           874:    char *cp, ref[];
        !           875:    int maxauthors;
        !           876: {  char name1[100], name2[100], name3[100], temp[100];
        !           877:    reg char *fp;
        !           878:    int getname();
        !           879: 
        !           880:    if (getname(1, name1, temp, ref)) {
        !           881:       for (fp = name1; *fp; )
        !           882:          *cp++ = *fp++;
        !           883:       if (((maxauthors >= 3) && (getname(4, name3, temp, ref)))
        !           884:          || ((maxauthors < 3) && (getname(3, name3, temp, ref)))) {
        !           885:          for (fp = " \\*(e]"; *fp; )
        !           886:             *cp++ = *fp++;
        !           887:          }
        !           888:       else if (getname(2, name2, temp, ref)) {
        !           889:          if (getname(3, name3, temp, ref)) {
        !           890:             for (fp = "\\*(c]"; *fp; )
        !           891:                *cp++ = *fp++;
        !           892:             for (fp = name2; *fp; )
        !           893:                *cp++ = *fp++;
        !           894:             for (fp = "\\*(m]"; *fp; )
        !           895:                *cp++ = *fp++;
        !           896:             for (fp = name3; *fp; )
        !           897:                *cp++ = *fp++;
        !           898:             }
        !           899:          else {
        !           900:             for (fp = "\\*(n]"; *fp; )
        !           901:                *cp++ = *fp++;
        !           902:             for (fp = name2; *fp; )
        !           903:                *cp++ = *fp++;
        !           904:             }
        !           905:          }
        !           906:     }
        !           907: return(cp);
        !           908: }
        !           909: 
        !           910: /* getfield - get a single field from reference */
        !           911:    char *getfield(ptr, field, ref)
        !           912:    char *ptr, field[], ref[];
        !           913: {  reg char *p, *q;
        !           914:    char        temp[100];
        !           915:    int  n, len, i, getname();
        !           916: 
        !           917:    field[0] = 0;
        !           918:    if (*ptr == 'A')
        !           919:       getname(1, field, temp, ref);
        !           920:    else
        !           921:       for (p = ref; *p; p++)
        !           922:          if (*p == '%' && *(p+1) == *ptr) {
        !           923:             for (p = p + 2; *p == ' '; p++)
        !           924:                ;
        !           925:             for (q = field; (*p != '\n') && (*p != '\0'); )
        !           926:                *q++ = *p++;
        !           927:             *q = 0;
        !           928:             break;
        !           929:             }
        !           930:    n = 0;
        !           931:    len = strlen(field);
        !           932:    if (*++ptr == '-') {
        !           933:       for (ptr++; isdigit(*ptr); ptr++)
        !           934:          n = 10 * n + (*ptr - '0');
        !           935:       if (n > len)
        !           936:          n = 0;
        !           937:       else
        !           938:          n = len - n;
        !           939:       for (i = 0; field[i] = field[i+n]; i++)
        !           940:          ;
        !           941:       }
        !           942:    else if (isdigit(*ptr)) {
        !           943:       for (; isdigit(*ptr); ptr++)
        !           944:          n = 10 * n + (*ptr - '0');
        !           945:       if (n > len)
        !           946:          n = len;
        !           947:       field[n] = 0;
        !           948:       }
        !           949: 
        !           950:    if (*ptr == 'u') {
        !           951:       ptr++;
        !           952:       for (p = field; *p; p++)
        !           953:          if (islower(*p))
        !           954:             *p = (*p - 'a') + 'A';
        !           955:       }
        !           956:    else if (*ptr == 'l') {
        !           957:       ptr++;
        !           958:       for (p = field; *p; p++)
        !           959:          if (isupper(*p))
        !           960:             *p = (*p - 'A') + 'a';
        !           961:       }
        !           962:    return(ptr);
        !           963: }
        !           964: 
        !           965: /* getname - get the nth name field from reference, breaking into
        !           966:              first and last names */
        !           967:    int getname(n, last, first, ref)
        !           968:    int  n;
        !           969:    char last[], first[], ref[];
        !           970: {  reg char *p;
        !           971:    int  m;
        !           972: 
        !           973:    m = n;
        !           974:    for (p = ref; *p; p++)
        !           975:       if (*p == '%' & *(p+1) == 'A') {
        !           976:          n--;
        !           977:          if (n == 0) {
        !           978:             for (p = p + 2; *p == ' '; p++) ;
        !           979:             breakname(p, first, last) ;
        !           980:             return(true);
        !           981:             }
        !           982:          }
        !           983: 
        !           984:    if (n == m)          /* no authors, try editors */
        !           985:       for (p = ref; *p; p++)
        !           986:          if (*p == '%' & *(p+1) == 'E') {
        !           987:             n--;
        !           988:             if (n == 0) {
        !           989:                for (p = p + 2; *p == ' '; p++) ;
        !           990:                breakname(p, first, last) ;
        !           991:                return(true);
        !           992:                }
        !           993:             }
        !           994: 
        !           995:    if (n == m) {        /* no editors, either, try institution */
        !           996:       first[0] = last[0] = '\0';
        !           997:       getfield("I", last, ref);
        !           998:       if (last[0] != '\0')
        !           999:          return(true);
        !          1000:       }
        !          1001: 
        !          1002:    return(false);
        !          1003: }
        !          1004: 
        !          1005: /* disambiguate - compare adjacent citation strings, and if equal, add
        !          1006:                   single character disambiguators */
        !          1007:    disambiguate()
        !          1008: {  reg int i, j;
        !          1009:        char adstr;
        !          1010: 
        !          1011:    for (i = 0; i < numrefs-1; i = j) {
        !          1012:       j = i + 1;
        !          1013:       if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) {
        !          1014:          adstr = 'a';
        !          1015:          for(j = i+1;
        !          1016:             j<numrefs && strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0;
        !          1017:             j++) {
        !          1018:             adstr = 'a' + (j-i);
        !          1019:            refinfo[j].ri_disambig[0] = adstr;
        !          1020:             }
        !          1021:         refinfo[i].ri_disambig[0] = 'a';
        !          1022:          }
        !          1023:      }
        !          1024:   for (i = 0; i < numrefs; i++){
        !          1025:        strcat(refinfo[i].ri_cite, refinfo[i].ri_disambig);
        !          1026:   }
        !          1027: }
        !          1028: 
        !          1029: 
        !          1030: /* bldname - build a name field
        !          1031:              doing abbreviations, reversals, and caps/small caps
        !          1032: */
        !          1033:    bldname(first, last, name, reverse)
        !          1034:    char *first, *last, name[];
        !          1035:    int reverse;
        !          1036: {
        !          1037:    char newfirst[120], newlast[120];
        !          1038:    reg char *p, *q, *f, *l;
        !          1039:    char *scopy();
        !          1040:    int  flag;
        !          1041: 
        !          1042:    if (abbrev) {
        !          1043:       p = first;
        !          1044:       q = newfirst;
        !          1045:       flag = false;
        !          1046:       while (*p) {
        !          1047:          while (*p == ' ')
        !          1048:             p++;
        !          1049:          if (*p == 0)
        !          1050:             break;
        !          1051:          if (isupper(*p)) {
        !          1052:             if (flag)           /* between initial gap */
        !          1053:                q = scopy(q, "\\*(a]");
        !          1054:             flag = true;
        !          1055:             *q++ = *p;
        !          1056:             q = scopy(q, "\\*(p]");
        !          1057:             }
        !          1058:          if (*++p == '.')
        !          1059:             p++;
        !          1060:          else while (*p != 0 && ! isspace(*p))
        !          1061:             p++;
        !          1062:          }
        !          1063:       *q = 0;
        !          1064:       f = newfirst;
        !          1065:       }
        !          1066:    else
        !          1067:       f = first;
        !          1068: 
        !          1069:    if (capsmcap) {
        !          1070:       p = last;
        !          1071:       q = newlast;
        !          1072:       flag = 0;  /* 1 - printing cap, 2 - printing small */
        !          1073:       while (*p)
        !          1074:          if (islower(*p)) {
        !          1075:             if (flag != 2)
        !          1076:                q = scopy(q, "\\s-2");
        !          1077:             flag = 2;
        !          1078:             *q++ = (*p++ - 'a') + 'A';
        !          1079:             }
        !          1080:          else {
        !          1081:             if (flag == 2)
        !          1082:                q = scopy(q,"\\s+2");
        !          1083:             flag = 1;
        !          1084:             *q++ = *p++;
        !          1085:             }
        !          1086:       if (flag == 2)
        !          1087:          q = scopy(q, "\\s+2");
        !          1088:       *q = 0;
        !          1089:       l = newlast;
        !          1090:       }
        !          1091:    else
        !          1092:       l = last;
        !          1093: 
        !          1094:    if (f[0] == 0)
        !          1095:       sprintf(name, "%s\n", l);
        !          1096:    else if (reverse)
        !          1097:       sprintf(name, "%s\\*(b]%s\n", l, f);
        !          1098:    else
        !          1099:       sprintf(name, "%s %s\n", f, l);
        !          1100: }
        !          1101: 
        !          1102: /* prtauth - print author or editor field */
        !          1103:    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
        !          1104:    char c, *line;
        !          1105:    int  num, max, abbrev, capsmcap, numrev;
        !          1106:    FILE *ofd;
        !          1107: {  char first[LINELENGTH], last[LINELENGTH];
        !          1108: 
        !          1109:    if (num <= numrev || abbrev || capsmcap) {
        !          1110:       breakname(line, first, last);
        !          1111:       bldname(first, last, line, num <= numrev);
        !          1112:       }
        !          1113:    if (num == 1)
        !          1114:       fprintf(ofd,".ds [%c %s", c, line);
        !          1115:    else if (num < max)
        !          1116:       fprintf(ofd,".as [%c \\*(c]%s", c, line);
        !          1117:    else if (max == 2)
        !          1118:       fprintf(ofd,".as [%c \\*(n]%s", c, line);
        !          1119:    else
        !          1120:       fprintf(ofd,".as [%c \\*(m]%s", c, line);
        !          1121:    if (num == max && index(trailstr, c))
        !          1122:       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
        !          1123: }
        !          1124: 
        !          1125: /* doline - actually print out a line of reference information */
        !          1126:    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
        !          1127:    char c, *line;
        !          1128:    int numauths, maxauths, numeds, maxeds;
        !          1129:    FILE *ofd;
        !          1130: {
        !          1131: 
        !          1132:    switch(c) {
        !          1133:       case 'A':
        !          1134:           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
        !          1135:           break;
        !          1136: 
        !          1137:        case 'E':
        !          1138:           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
        !          1139:           if (numeds == maxeds)
        !          1140:              fprintf(ofd,".nr [E %d\n", maxeds);
        !          1141:           break;
        !          1142: 
        !          1143:        case 'P':
        !          1144:           if (index(line, '-'))
        !          1145:              fprintf(ofd,".nr [P 1\n");
        !          1146:           else
        !          1147:              fprintf(ofd,".nr [P 0\n");
        !          1148:           fprintf(ofd,".ds [P %s",line);
        !          1149:           if (index(trailstr, 'P'))
        !          1150:              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
        !          1151:           break;
        !          1152: 
        !          1153:        case 'F':
        !          1154:        case 'K': break;
        !          1155: 
        !          1156:        default:
        !          1157:           fprintf(ofd,".ds [%c %s", c, line);
        !          1158:           if (index(trailstr, c))
        !          1159:              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
        !          1160:           }
        !          1161: }
        !          1162: 
        !          1163: /* dumpref - dump reference number i */
        !          1164:    dumpref(i, ofd)
        !          1165:    int i;
        !          1166:    FILE *ofd;
        !          1167: {  char ref[REFSIZE], line[REFSIZE];
        !          1168:    reg char *p, *q;
        !          1169:    char *from;
        !          1170:    int numauths, maxauths, numeds, maxeds;
        !          1171: 
        !          1172:    if ( i < 0 ) ref[0] = 0; /* ref not found */
        !          1173:    else {
        !          1174:           rdref(&refinfo[i], ref);
        !          1175:           maxauths = maxeds = 0;
        !          1176:           numauths = numeds = 0;
        !          1177:           for (p = ref; *p; p++)
        !          1178:              if (*p == '%')
        !          1179:                 if (*(p+1) == 'A') maxauths++;
        !          1180:                 else if (*(p+1) == 'E') maxeds++;
        !          1181:           fprintf(ofd, ".[-\n");
        !          1182:           fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite);
        !          1183: #ifndef INCORE
        !          1184:           fseek(rfd, (long)refinfo[i].ri_pos, 0);
        !          1185:           while (fgets(line, REFSIZE, rfd) != NULL) {
        !          1186: #else INCORE
        !          1187:           for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */
        !          1188:                if (*from == '\n'){
        !          1189:                        *q++ = '\n';
        !          1190:                        *q = 0;
        !          1191:                        q = line;
        !          1192:                        from++;
        !          1193:                } else {
        !          1194:                        *q++ = *from++;
        !          1195:                        continue;
        !          1196:                }
        !          1197: #endif INCORE
        !          1198:                switch(line[0]){
        !          1199:                case 0:
        !          1200:                        goto doneref;
        !          1201:                case '.':
        !          1202:                        fprintf(ofd, "%s", line);
        !          1203:                        break;
        !          1204:                case '%':
        !          1205:                        switch(line[1]){
        !          1206:                        case 'A':       numauths++;     break;
        !          1207:                        case 'E':       numeds++;       break;
        !          1208:                        }
        !          1209:                        for (p = &line[2]; *p == ' '; p++) /*VOID*/;
        !          1210:                        doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
        !          1211:                }
        !          1212:           }
        !          1213:           doneref:;
        !          1214:           fprintf(ofd,".][\n");
        !          1215:    }
        !          1216: }

unix.superglobalmegacorp.com

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