Annotation of 43BSD/contrib/bib/src/bibargs.c, revision 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.