xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 16244)
113110Srrh #ifndef lint
2*16244Srrh static char sccsid[] = "@(#)bibargs.c	2.5	03/27/84";
313110Srrh #endif not lint
415061Sgarrison /*
515061Sgarrison         Authored by: Tim Budd, University of Arizona, 1983.
615061Sgarrison                 version 7/4/83
713110Srrh 
815061Sgarrison         Various modifications suggested by:
915061Sgarrison                 David Cherveny - Duke University Medical Center
1015061Sgarrison                 Phil Garrison - UC Berkeley
1115061Sgarrison                 M. J. Hawley - Yale University
1215061Sgarrison 
1315061Sgarrison 
1415061Sgarrison 
1515061Sgarrison 
1612910Sgarrison         read argument strings for bib and listrefs
1712910Sgarrison         do name formatting, printing lines, other actions common to both
1812910Sgarrison                                                         */
1912910Sgarrison # include <stdio.h>
2012910Sgarrison # include <ctype.h>
2112910Sgarrison # include "bib.h"
2212910Sgarrison # define LINELENGTH 1024
2312910Sgarrison # define MAXDEFS     500             /* maximum number of defined words */
2412910Sgarrison 
2512910Sgarrison /* global variables */
2615061Sgarrison    char bibfname[120];          /* file name currently being read            */
2715061Sgarrison    int  biblineno;              /* line number currently being referenced    */
2812910Sgarrison    int  abbrev       = false;   /* automatically abbreviate names            */
2912910Sgarrison    int  capsmcap     = false;   /* print names in caps small caps (CACM form)*/
3012910Sgarrison    int  numrev       = 0;       /* number of authors names to reverse        */
3112910Sgarrison    int  edabbrev     = false;   /* abbreviate editors names ?                */
3212910Sgarrison    int  edcapsmcap   = false;   /* print editors in cap small caps           */
3312910Sgarrison    int  ednumrev     = 0;       /* number of editors to reverse              */
3412910Sgarrison    int  sort         = false;   /* sort references ? (default no)            */
3512910Sgarrison    int  foot         = false;   /* footnoted references ? (default endnotes) */
3612910Sgarrison    int  hyphen       = false;   /* hypenate contiguous references            */
3712910Sgarrison    int  ordcite      = true;    /* order multiple citations                  */
3812910Sgarrison    char sortstr[80]  = "1";     /* sorting template                          */
3912910Sgarrison    char trailstr[80] = "";      /* trailing characters to output             */
4012910Sgarrison    char pfile[120];             /* private file name                         */
4112910Sgarrison    int  personal = false;       /* personal file given ? (default no)        */
4212910Sgarrison    char citetemplate[80] = "1"; /* citation template                         */
4315903Srrh    struct wordinfo words[MAXDEFS];     /* defined words */
4415903Srrh    struct wordinfo *wordhash[HASHSIZE];
4515903Srrh    struct wordinfo *wordsearch();
4615903Srrh    int  wordtop = 0;           /* number of defined words         */
4712910Sgarrison 
4812910Sgarrison /* where output goes */
4912910Sgarrison    extern FILE *tfd;
5015061Sgarrison /* reference file information */
5115903Srrh    extern struct refinfo refinfo[];
5215061Sgarrison    extern char reffile[];
5315903Srrh #ifndef INCORE
5415061Sgarrison    extern FILE *rfd;
5515903Srrh #endif not INCORE
5615061Sgarrison    extern int numrefs;
5712910Sgarrison 
5812910Sgarrison /* doargs - read command argument line for both bib and listrefs
5912910Sgarrison             set switch values
6012910Sgarrison             call rdtext on file arguments, after dumping
6112910Sgarrison             default style file if no alternative style is given
6212910Sgarrison */
6312910Sgarrison    int doargs(argc, argv, defstyle)
6412910Sgarrison    int argc;
6512910Sgarrison    char **argv, defstyle[];
6612910Sgarrison {  int numfiles, i, style;
6712910Sgarrison    char *p, *q, *walloc();
6812910Sgarrison    FILE *fd;
6912910Sgarrison 
7012910Sgarrison    numfiles = 0;
7112910Sgarrison    style = true;
7215903Srrh    wordstuff("BMACLIB", BMACLIB);
7312910Sgarrison    fputs(".ds l] ",tfd);
7412910Sgarrison    fputs(BMACLIB, tfd);
7512910Sgarrison    fputs("\n", tfd);
7612910Sgarrison 
7712910Sgarrison    for (i = 1; i < argc; i++)
7812910Sgarrison       if (argv[i][0] == '-')
7912910Sgarrison          switch(argv[i][1]) {
8012910Sgarrison 
8115061Sgarrison             case 'a':  for (p = &argv[i][2]; *p; p++)
8215061Sgarrison                           if (*p == 'a' || *p == 0)
8312961Sgarrison                              abbrev = true;
8412961Sgarrison                            else if (*p == 'x')
8512961Sgarrison                              capsmcap = true;
8612961Sgarrison                            else if (*p == 'r') {
8712961Sgarrison                              if (*(p+1))
8812961Sgarrison                                 numrev = atoi(p+1);
8912961Sgarrison                               else
9012961Sgarrison                                 numrev = 1000;
9112961Sgarrison                               break;
9212961Sgarrison                               }
9312910Sgarrison                        break;
9412910Sgarrison 
9512910Sgarrison             case 'c':  if (argv[i][2] == 0)
9615903Srrh                           error("citation string expected for 'c'");
9712910Sgarrison                        else
9812910Sgarrison                           for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
9912910Sgarrison                        break;
10012910Sgarrison 
10112910Sgarrison             case 'e':  for (p = &argv[i][2]; *p; p++)
10212910Sgarrison                           if (*p == 'a')
10312910Sgarrison                              edabbrev = true;
10412910Sgarrison                            else if (*p == 'x')
10512910Sgarrison                              edcapsmcap = true;
10612910Sgarrison                            else if (*p == 'r') {
10712910Sgarrison                              if (*(p+1))
10812910Sgarrison                                 ednumrev = atoi(p+1);
10912910Sgarrison                               else
11012910Sgarrison                                 ednumrev = 1000;
11112910Sgarrison                               break;
11212910Sgarrison                               }
11312910Sgarrison                        break;
11412910Sgarrison 
11512910Sgarrison             case 'f':  foot = true;
11612910Sgarrison                        hyphen = false;
11712910Sgarrison                        break;
11812910Sgarrison 
11912910Sgarrison             case 'h':  hyphen = ordcite = true;
12012910Sgarrison                        break;
12112910Sgarrison 
12212910Sgarrison             case 'n':  for (p = &argv[i][2]; *p; p++)
12312910Sgarrison                           if (*p == 'a')
12412910Sgarrison                              abbrev = false;
12512910Sgarrison                           else if (*p == 'f')
12612910Sgarrison                              foot = false;
12712910Sgarrison                           else if (*p == 'h')
12812910Sgarrison                              hyphen = false;
12912910Sgarrison                           else if (*p == 'o')
13012910Sgarrison                              ordcite = false;
13112910Sgarrison                           else if (*p == 'r')
13212910Sgarrison                              numrev = 0;
13312910Sgarrison                           else if (*p == 's')
13412910Sgarrison                              sort = false;
13512910Sgarrison                           else if (*p == 'x')
13612910Sgarrison                              capsmcap = false;
13712910Sgarrison                        break;
13812910Sgarrison 
13912910Sgarrison             case 'o':  ordcite = true;
14012910Sgarrison                        break;
14112910Sgarrison 
14212910Sgarrison             case 'p':  if (argv[i][2])
14312910Sgarrison                           p = &argv[i][2];
14412910Sgarrison                        else {  /* take next arg */
14512910Sgarrison                           i++;
14612910Sgarrison                           p = argv[i];
14712910Sgarrison                           }
14812910Sgarrison                        strcpy(pfile, p);
14912910Sgarrison                        personal = true;
15012910Sgarrison                        break;
15112910Sgarrison 
15215061Sgarrison             case 'r':  if (argv[i][2] == 0)  /* this is now replaced by -ar */
15312910Sgarrison                           numrev = 1000;
15412910Sgarrison                        else
15512910Sgarrison                           numrev = atoi(&argv[i][2]);
15612910Sgarrison                        break;
15712910Sgarrison 
15812910Sgarrison             case 's':  sort = true;
15912910Sgarrison                        if (argv[i][2])
16012910Sgarrison                           for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
16112910Sgarrison                        break;
16212910Sgarrison 
16315061Sgarrison             case 't':  style = false;           /* fall through */
16415061Sgarrison             case 'i':  if (argv[i][2])
16512910Sgarrison                           p = &argv[i][2];
16612910Sgarrison                        else { /* take next arg */
16712910Sgarrison                           i++;
16812910Sgarrison                           p = argv[i];
16912910Sgarrison                           }
17012910Sgarrison                        incfile(p);
17112910Sgarrison                        break;
17212910Sgarrison 
17315061Sgarrison             case 'x':  capsmcap = true; /* this is now replaced by -ax */
17412910Sgarrison                        break;
17512910Sgarrison 
17612910Sgarrison             case 0:    if (style) {  /* no style command given, take default */
17712910Sgarrison                           style = false;
17812910Sgarrison                           incfile( defstyle );
17912910Sgarrison                           }
18015061Sgarrison                        strcpy(bibfname,"<stdin>");
18112910Sgarrison                        rdtext(stdin);
18212910Sgarrison                        numfiles++;
18312910Sgarrison                        break;
18412910Sgarrison 
18512910Sgarrison             default:   fputs(argv[i], stderr);
18615903Srrh                        error("'%c' invalid switch", argv[i][1]);
18712910Sgarrison             }
18812910Sgarrison       else { /* file name */
18912910Sgarrison          numfiles++;
19012910Sgarrison          if (style) {
19112910Sgarrison             style = false;
19212910Sgarrison             incfile( defstyle );
19312910Sgarrison             }
19412910Sgarrison          fd = fopen(argv[i], "r");
19512910Sgarrison          if (fd == NULL) {
19615903Srrh             error("can't open file %s", argv[i]);
19712910Sgarrison             }
19812910Sgarrison          else {
19915061Sgarrison             strcpy(bibfname, argv[i]);
20012910Sgarrison             rdtext(fd);
20112910Sgarrison             fclose(fd);
20212910Sgarrison             }
20312910Sgarrison          }
20412910Sgarrison 
20512910Sgarrison    if (style) incfile( defstyle );
20612910Sgarrison    return(numfiles);
20712910Sgarrison 
20812910Sgarrison }
20912910Sgarrison 
21012910Sgarrison /* incfile - read in an included file  */
21112910Sgarrison incfile(np)
21212910Sgarrison    char *np;
21312910Sgarrison {  char name[120];
21412910Sgarrison    FILE *fd;
21515061Sgarrison    char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
216*16244Srrh    int  i, getwrd();
21712910Sgarrison 
21815061Sgarrison    strcpy(bibfname, np);
21912910Sgarrison    fd = fopen(np, "r");
22012910Sgarrison    if (fd == NULL && *np != '/') {
22112910Sgarrison       strcpy(name, "bib.");
22212910Sgarrison       strcat(name, np);
22315061Sgarrison       strcpy(bibfname, name);
22412910Sgarrison       fd = fopen(name, "r");
22512910Sgarrison       }
22612910Sgarrison    if (fd == NULL && *np != '/') {
22712910Sgarrison       strcpy(name,BMACLIB);
22812910Sgarrison       strcat(name, "/bib.");
22912910Sgarrison       strcat(name, np);
23015061Sgarrison       strcpy(bibfname, name);
23112910Sgarrison       fd = fopen(name, "r");
23212910Sgarrison       }
23312910Sgarrison    if (fd == NULL) {
23415061Sgarrison       bibwarning("%s: can't open", np);
23515061Sgarrison       exit(1);
23612910Sgarrison       }
23712910Sgarrison 
23815061Sgarrison    /* now go off and process file */
23915061Sgarrison    biblineno = 1;
24015061Sgarrison    while (tfgets(line, LINELENGTH, fd) != NULL) {
24115061Sgarrison       biblineno++;
24212910Sgarrison       switch(line[0]) {
24312910Sgarrison 
24412910Sgarrison          case '#': break;
24512910Sgarrison 
24612961Sgarrison          case 'A': for (p = &line[1]; *p; p++)
24715061Sgarrison                       if (*p == 'A' || *p == '\0')
24812961Sgarrison                          abbrev = true;
24912961Sgarrison                       else if (*p == 'X')
25012961Sgarrison                          capsmcap = true;
25112961Sgarrison                       else if (*p == 'R') {
25212961Sgarrison                          if (*(p+1))
25312961Sgarrison                             numrev = atoi(p+1);
25412961Sgarrison                          else
25512961Sgarrison                             numrev = 1000;
25612961Sgarrison                          break;
25712961Sgarrison                          }
25812910Sgarrison                    break;
25912910Sgarrison 
26012910Sgarrison          case 'C': for (p = &line[1]; *p == ' '; p++) ;
26112910Sgarrison                    strcpy(citetemplate, p);
26212910Sgarrison                    break;
26312910Sgarrison 
26412910Sgarrison          case 'D': if ((i = getwrd(line, 1, word)) == 0)
26512910Sgarrison                       error("word expected in definition");
26615903Srrh 		   if (wordsearch(word))
26715903Srrh 			break;
26812910Sgarrison                    for (p = &line[i]; *p == ' '; p++) ;
26912910Sgarrison                    for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
27012910Sgarrison                        dline[strlen(dline)-1] = '\n';
27115061Sgarrison                        if (tfgets(line, LINELENGTH, fd) == NULL) break;
27212910Sgarrison                        strcat(dline, line);
27312910Sgarrison                        }
27415903Srrh 		   wordstuff(word, dline);
27512910Sgarrison                    break;
27612910Sgarrison 
27712910Sgarrison          case 'E': for (p = &line[1]; *p; p++)
27812910Sgarrison                       if (*p == 'A')
27912910Sgarrison                          edabbrev = true;
28012910Sgarrison                       else if (*p == 'X')
28112910Sgarrison                          edcapsmcap = true;
28212910Sgarrison                       else if (*p == 'R') {
28312910Sgarrison                          if (*(p+1))
28412910Sgarrison                             ednumrev = atoi(p+1);
28512910Sgarrison                          else
28612910Sgarrison                             ednumrev = 1000;
28712910Sgarrison                          break;
28812910Sgarrison                          }
28912910Sgarrison                    break;
29012910Sgarrison 
29112910Sgarrison          case 'F': foot = true;
29212910Sgarrison                    hyphen = false;
29312910Sgarrison                    break;
29412910Sgarrison 
29512910Sgarrison          case 'I': for (p = &line[1]; *p == ' '; p++);
29612910Sgarrison                    expand(p);
29712910Sgarrison                    incfile(p);
29812910Sgarrison                    break;
29912910Sgarrison 
30012910Sgarrison          case 'H': hyphen = ordcite = true;
30112910Sgarrison                    break;
30212910Sgarrison 
30312910Sgarrison          case 'O': ordcite = true;
30412910Sgarrison                    break;
30512910Sgarrison 
30615061Sgarrison          case 'R': if (line[1] == 0)  /* this is now replaced by AR */
30712910Sgarrison                       numrev = 1000;
30812910Sgarrison                    else
30912910Sgarrison                       numrev = atoi(&line[1]);
31012910Sgarrison                    break;
31112910Sgarrison 
31212910Sgarrison          case 'S': sort = true;
31312910Sgarrison                    for (p = &line[1]; *p == ' '; p++) ;
31412910Sgarrison                    strcpy(sortstr, p);
31512910Sgarrison                    break;
31612910Sgarrison 
31712910Sgarrison          case 'T': for (p = &line[1]; *p == ' '; p++) ;
31812910Sgarrison                    strcpy(trailstr, p);
31912910Sgarrison                    break;
32012910Sgarrison 
32115061Sgarrison          case 'X': capsmcap = true;     /* this is now replace by AX */
32212910Sgarrison                    break;
32312910Sgarrison 
32412910Sgarrison          default:  fprintf(tfd,"%s\n",line);
32515061Sgarrison                    while (fgets(line, LINELENGTH, fd) != NULL)
32612910Sgarrison                       fputs(line, tfd);
32712910Sgarrison                    return;
32812910Sgarrison          }
32915061Sgarrison 
33015061Sgarrison    }
33115061Sgarrison    /* close up */
33215061Sgarrison    fclose(fd);
33312910Sgarrison }
33412910Sgarrison 
33515061Sgarrison /* bibwarning - print out a warning message */
33615903Srrh   /*VARARGS1*/
33715903Srrh   bibwarning(msg, a1, a2)
33815903Srrh   char *msg;
33915061Sgarrison {
34015061Sgarrison   fprintf(stderr,"`%s', line %d: ", bibfname, biblineno);
34115903Srrh   fprintf(stderr, msg, a1, a2);
34215061Sgarrison }
34315061Sgarrison 
34415061Sgarrison /* error - report unrecoverable error message */
34515903Srrh   /*VARARGS1*/
34615903Srrh   error(str, a1, a2)
34715903Srrh   char *str;
34815061Sgarrison {
34915903Srrh   bibwarning(str, a1, a2);
35015903Srrh   /*
35115903Srrh    *	clean up temp files and exit
35215903Srrh    */
35315903Srrh   cleanup(1);
35415061Sgarrison }
35515061Sgarrison 
35615903Srrh #ifndef INCORE
35715061Sgarrison #ifdef READWRITE
35815061Sgarrison /*
35915061Sgarrison ** fixrfd( mode ) -- re-opens the rfd file to be read or write,
36015061Sgarrison **      depending on the mode.  Uses a static int to save the current mode
36115061Sgarrison **      and avoid unnecessary re-openings.
36215061Sgarrison */
36315061Sgarrison fixrfd( mode )
36415061Sgarrison register int mode;
36515061Sgarrison {
36615061Sgarrison 	static int cur_mode = WRITE;    /* rfd open for writing initially */
36715061Sgarrison 
36815061Sgarrison 	if (mode != cur_mode)
36915061Sgarrison 	{
37015061Sgarrison 		rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
37115061Sgarrison 		cur_mode = mode;
37215061Sgarrison 		if (rfd == NULL)
37315903Srrh 		      error("Hell!  Couldn't re-open reference file %s",
37415903Srrh 			reffile);
37515061Sgarrison 	}
37615061Sgarrison }
37715061Sgarrison #endif
37815903Srrh #endif not INCORE
37915061Sgarrison 
38015061Sgarrison 
38115061Sgarrison /* tfgets - fgets which trims off newline */
38215061Sgarrison    char *tfgets(line, n, ptr)
38315061Sgarrison    char line[];
38415061Sgarrison    int  n;
38515061Sgarrison    FILE *ptr;
38615903Srrh {  reg char *p;
38715061Sgarrison 
38815061Sgarrison    p = fgets(line, n, ptr);
38915061Sgarrison    if (p == NULL)
39015061Sgarrison       return(NULL);
39115061Sgarrison    else
39215061Sgarrison       for (p = line; *p; p++)
39315061Sgarrison          if (*p == '\n')
39415061Sgarrison             *p = 0;
39515061Sgarrison    return(line);
39615061Sgarrison }
39715061Sgarrison 
39815061Sgarrison /* getwrd - place next word from in[i] into out */
39915061Sgarrison int getwrd(in, i, out)
40015903Srrh    reg char in[], out[];
40115903Srrh    reg int i;
40215061Sgarrison {  int j;
40315061Sgarrison 
40415061Sgarrison    j = 0;
40515061Sgarrison    while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
40615061Sgarrison       i++;
40715061Sgarrison    if (in[i])
40815061Sgarrison       while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
40915061Sgarrison          out[j++] = in[i++];
41015061Sgarrison    else
41115061Sgarrison       i = 0;    /* signals end of in[i..]   */
41215061Sgarrison    out[j] = 0;
41315061Sgarrison    return (i);
41415061Sgarrison }
41515061Sgarrison 
41615061Sgarrison /* walloc - allocate enough space for a word */
41715061Sgarrison char *walloc(word)
41815061Sgarrison    char *word;
41915061Sgarrison {  char *i, *malloc();
42015061Sgarrison    i = malloc(1 + strlen(word));
42115061Sgarrison    if (i == NULL)
42215061Sgarrison       error("out of storage");
42315061Sgarrison    strcpy(i, word);
42415061Sgarrison    return(i);
42515061Sgarrison }
42615061Sgarrison 
42712910Sgarrison /* isword - see if character is legit word char */
42812910Sgarrison int iswordc(c)
42912910Sgarrison char c;
43012910Sgarrison {
43112910Sgarrison    if (isalnum(c) || c == '&' || c == '_')
43212910Sgarrison       return(true);
43312910Sgarrison    return(false);
43412910Sgarrison }
43512910Sgarrison    expand(line)
43612910Sgarrison    char *line;
43715903Srrh {  char line2[REFSIZE], word[LINELENGTH];
43815903Srrh    reg	struct wordinfo *wp;
43915903Srrh    reg	char *p, *q, *w;
44012910Sgarrison 
44115903Srrh 	q = line2;
44215903Srrh 	for (p = line; *p; /*VOID*/){
44315903Srrh 		if (isalnum(*p)) {
44415903Srrh 			for (w = word; *p && iswordc(*p); ) *w++ = *p++;
44515903Srrh 			*w = 0;
44615903Srrh 			if (wp = wordsearch(word)){
44715903Srrh 				strcpy(word, wp->wi_def);
44815903Srrh 				expand(word);
44915903Srrh 			}
45015903Srrh 			strcpy(q, word);
45115903Srrh 			q += strlen(q);
45215903Srrh 		} else {
45315903Srrh 			*q++ = *p++;
45415903Srrh 		}
45515903Srrh 	}
45615903Srrh 	*q = 0;
45715903Srrh 	strcpy(line, line2);
45812910Sgarrison }
45912910Sgarrison 
46015903Srrh /* wordstuff- save a word and its definition, building a hash table */
46115903Srrh    wordstuff(word, def)
46215903Srrh    char *word, *def;
46315903Srrh {
46415903Srrh    int i;
46515903Srrh    if (wordtop >= MAXDEFS)
46615903Srrh 	error("too many definitions, max of %d", MAXDEFS);
46715903Srrh    words[wordtop].wi_length = strlen(word);
46815903Srrh    words[wordtop].wi_word = word ? walloc(word) : 0;
46915903Srrh    words[wordtop].wi_def = def ? walloc(def) : 0;
47015903Srrh    i = strhash(word);
47115903Srrh    words[wordtop].wi_hp = wordhash[i];
47215903Srrh    wordhash[i] = &words[wordtop];
47315903Srrh    wordtop++;
47415903Srrh }
47515903Srrh    struct wordinfo *wordsearch(word)
47615903Srrh    char *word;
47715903Srrh {
47815903Srrh    reg int lg;
47915903Srrh    reg struct wordinfo *wp;
48015903Srrh    lg = strlen(word);
48115903Srrh    for (wp = wordhash[strhash(word)]; wp; wp = wp->wi_hp){
48215903Srrh 	if (wp->wi_length == lg && (strcmp(wp->wi_word, word) == 0)){
48315903Srrh 		return(wp);
48415903Srrh 	}
48515903Srrh    }
48615903Srrh    return(0);
48715903Srrh }
48815903Srrh 
48915903Srrh    int strhash(str)
49015903Srrh    reg char *str;
49115903Srrh {
49215903Srrh    reg int value = 0;
49315903Srrh    for (value = 0; *str; value <<= 2, value += *str++)/*VOID*/;
49415903Srrh    value %= HASHSIZE;
49515903Srrh    if (value < 0)
49615903Srrh 	value += HASHSIZE;
49715903Srrh    return(value);
49815903Srrh }
49915903Srrh 
50015061Sgarrison /* rdref - read text for an already cited reference */
50115903Srrh    rdref(p, ref)
50215903Srrh    struct refinfo *p;
50315061Sgarrison    char ref[REFSIZE];
50415061Sgarrison {
50515061Sgarrison    ref[0] = 0;
50615903Srrh #ifndef INCORE
50715061Sgarrison #ifdef READWRITE
50815061Sgarrison    fixrfd( READ );                      /* fix access mode of rfd, if nec. */
50915061Sgarrison #endif
51015903Srrh    fseek(rfd, p->ri_pos, 0);
51115903Srrh    fread(ref, p->ri_length, 1, rfd);
51215903Srrh #else INCORE
51315903Srrh    strcpy(ref, p->ri_ref);
51415903Srrh #endif INCORE
51515061Sgarrison }
51615061Sgarrison 
51715903Srrh /* wrref - write text for a new reference */
51815903Srrh    wrref(p, ref)
51915903Srrh    struct refinfo *p;
52015903Srrh    char ref[REFSIZE];
52115903Srrh {
52215903Srrh #ifndef INCORE
52315903Srrh #ifdef READWRITE
52415903Srrh     fixrfd( WRITE );                 /* fix access mode of rfd, if nec. */
52515903Srrh #else
52615903Srrh     fseek(rfd, p->ri_pos, 0);        /* go to end of rfd */
52715903Srrh #endif
52815903Srrh     fwrite(ref, p->ri_length, 1, rfd);
52915903Srrh #else INCORE
53015903Srrh    p->ri_ref = walloc(ref);
53115903Srrh #endif INCORE
53215903Srrh }
53315903Srrh 
53412910Sgarrison /* breakname - break a name into first and last name */
53512910Sgarrison    breakname(line, first, last)
53612910Sgarrison    char line[], first[], last[];
53715903Srrh {  reg char *t, *f, *q, *r, *p;
53812910Sgarrison 
53912910Sgarrison    for (t = line; *t != '\n'; t++);
54012910Sgarrison    for (t--; isspace(*t); t--);
54112910Sgarrison 
54212910Sgarrison    /* now strip off last name */
54312910Sgarrison    for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
54412910Sgarrison       if (q == line)
54512910Sgarrison          break;
54612910Sgarrison    f = q;
54715061Sgarrison    if (q != line) {
54812910Sgarrison       q++;
54915061Sgarrison       for (; isspace(*f); f--);
55015061Sgarrison       f++;
55115061Sgarrison       }
55212910Sgarrison 
55312910Sgarrison    /* first name is start to f, last name is q to t */
55412910Sgarrison 
55515061Sgarrison    for (r = first, p = line; p != f; )
55612910Sgarrison       *r++ = *p++;
55712910Sgarrison    *r = 0;
55812910Sgarrison    for (r = last, p = q, t++; q != t; )
55912910Sgarrison       *r++ = *q++;
56012910Sgarrison    *r = 0;
56115061Sgarrison 
56212910Sgarrison }
56312910Sgarrison 
56412910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
56512910Sgarrison    int match(str1, str2)
56615903Srrh    reg char str1[], str2[];
56715903Srrh {  reg int  j, i;
56812910Sgarrison    char a, b;
56912910Sgarrison 
57012910Sgarrison    for (i = 0; str2[i]; i++) {
57112910Sgarrison       for (j = 0; str1[j]; j++) {
57212910Sgarrison          if (isupper(a = str2[i+j]))
57312910Sgarrison             a = (a - 'A') + 'a';
57412910Sgarrison          if (isupper(b = str1[j]))
57512910Sgarrison             b = (b - 'A') + 'a';
57612910Sgarrison          if (a != b)
57712910Sgarrison             break;
57812910Sgarrison          }
57912910Sgarrison       if (str1[j] == 0)
58012910Sgarrison          return(true);
58112910Sgarrison       }
58212910Sgarrison    return(false);
58312910Sgarrison }
58412910Sgarrison 
58512910Sgarrison /* scopy - append a copy of one string to another */
58612910Sgarrison    char *scopy(p, q)
58715903Srrh    reg char *p, *q;
58812910Sgarrison {
58912910Sgarrison    while (*p++ = *q++)
59012910Sgarrison       ;
59112910Sgarrison    return(--p);
59212910Sgarrison }
59312910Sgarrison 
59415061Sgarrison /* rcomp - reference comparison routine for qsort utility */
59515061Sgarrison    int rcomp(ap, bp)
59615903Srrh    struct refinfo *ap, *bp;
59715061Sgarrison {  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
59815903Srrh    reg	char *p, *q;
59915903Srrh    char *getfield();
60015061Sgarrison    int  neg, res;
60115061Sgarrison    int  fields_found;
60215061Sgarrison 
60315903Srrh    rdref(ap, ref1);
60415903Srrh    rdref(bp, ref2);
60515061Sgarrison    for (p = sortstr; *p; p = q) {
60615061Sgarrison       if (*p == '-') {
60715061Sgarrison          p++;
60815061Sgarrison          neg = true;
60915061Sgarrison          }
61015061Sgarrison       else
61115061Sgarrison          neg = false;
61215061Sgarrison       q = getfield(p, field1, ref1);
61315061Sgarrison       fields_found = true;
61415061Sgarrison       if (q == 0) {
61515061Sgarrison 	 res = 1;
61615061Sgarrison 	 fields_found = false;
61715061Sgarrison       } else if (strcmp (field1, "") == 0) {	/* field not found */
61815061Sgarrison          if (*p == 'A') {
61915061Sgarrison             getfield("F", field1, ref1);
62015061Sgarrison 	    if (strcmp (field1, "") == 0) {
62115061Sgarrison                getfield("I", field1, ref1);
62215061Sgarrison 	       if (strcmp (field1, "") == 0) {
62315061Sgarrison 	          res = 1;
62415061Sgarrison 		  fields_found = false;
62515061Sgarrison 	       }
62615061Sgarrison 	    }
62715061Sgarrison 	 } else {
62815061Sgarrison 	    res = 1;
62915061Sgarrison 	    fields_found = false;
63015061Sgarrison 	 }
63115061Sgarrison       }
63215061Sgarrison 
63315061Sgarrison       if (getfield(p, field2, ref2) == 0) {
63415061Sgarrison 	 res = -1;
63515061Sgarrison 	 fields_found = false;
63615061Sgarrison       } else if (strcmp (field2, "") == 0) {	/* field not found */
63715061Sgarrison          if (*p == 'A') {
63815061Sgarrison             getfield("F", field2, ref2);
63915061Sgarrison 	    if (strcmp (field2, "") == 0) {
64015061Sgarrison                getfield("I", field2, ref2);
64115061Sgarrison 	       if (strcmp (field2, "") == 0) {
64215061Sgarrison 	          res = -1;
64315061Sgarrison 		  fields_found = false;
64415061Sgarrison 	       }
64515061Sgarrison 	    }
64615061Sgarrison 	 } else {
64715061Sgarrison 	    res = -1;
64815061Sgarrison 	    fields_found = false;
64915061Sgarrison 	 }
65015061Sgarrison       }
65115061Sgarrison       if (fields_found) {
65215061Sgarrison          if (*p == 'A') {
65315061Sgarrison             if (isupper(field1[0]))
65415061Sgarrison                field1[0] -= 'A' - 'a';
65515061Sgarrison             if (isupper(field2[0]))
65615061Sgarrison                field2[0] -= 'A' - 'a';
65715061Sgarrison             }
65815061Sgarrison          res = strcmp(field1, field2);
65915061Sgarrison          }
66015061Sgarrison       if (neg)
66115061Sgarrison          res = - res;
66215061Sgarrison       if (res != 0)
66315061Sgarrison          break;
66415061Sgarrison       }
66515061Sgarrison    if (res == 0)
66615061Sgarrison       if (ap < bp)
66715061Sgarrison          res = -1;
66815061Sgarrison       else
66915061Sgarrison          res = 1;
67015061Sgarrison    return(res);
67115061Sgarrison }
67215061Sgarrison 
673*16244Srrh /* makecites - make standard citation strings, using citetemplate currently in effect */
67415903Srrh    makecites()
67515061Sgarrison {  char ref[REFSIZE], tempcite[100], *malloc();
67615903Srrh    reg int  i;
67715061Sgarrison 
67815903Srrh    for (i = 0; i < numrefs; i++) {
67915903Srrh       rdref(&refinfo[i], ref);
68015061Sgarrison       bldcite(tempcite, i, ref);
681*16244Srrh       refinfo[i].ri_cite = malloc(2 + strlen(tempcite));
68215903Srrh       if (refinfo[i].ri_cite == NULL)
68315061Sgarrison          error("out of storage");
68415903Srrh       strcpy(refinfo[i].ri_cite, tempcite);
68515061Sgarrison       }
68615061Sgarrison }
68715061Sgarrison 
68815061Sgarrison /* bldcite - build a single citation string */
68915061Sgarrison    bldcite(cp, i, ref)
69015061Sgarrison    char *cp, ref[];
69115061Sgarrison    int  i;
69215903Srrh {  reg char *p, *q, *fp;
69315903Srrh    char c;
69415903Srrh    char field[REFSIZE];
69515890Srrh    char *getfield(), *aabet(), *aabetlast(), *astro();
69615061Sgarrison 
69715061Sgarrison    getfield("F", field, ref);
69815061Sgarrison    if (field[0] != 0)
69915061Sgarrison       for (p = field; *p; p++)
70015061Sgarrison          *cp++ = *p;
70115061Sgarrison    else {
70215061Sgarrison       p = citetemplate;
70315061Sgarrison       field[0] = 0;
70415061Sgarrison       while (c = *p++) {
70515061Sgarrison          if (isalpha(c)) {                      /* field name   */
70615061Sgarrison             q = getfield(p-1, field, ref);
70715061Sgarrison             if (q != 0) {
70815061Sgarrison                p = q;
70915061Sgarrison                for (fp = field; *fp; )
71015061Sgarrison                   *cp++ = *fp++;
71115061Sgarrison                }
71215061Sgarrison             }
71315061Sgarrison          else if (c == '1') {                   /* numeric  order */
71415061Sgarrison             sprintf(field,"%d",1 + i);
71515061Sgarrison             for (fp = field; *fp; )
71615061Sgarrison                *cp++ = *fp++;
71715061Sgarrison             }
71815061Sgarrison          else if (c == '2')                     /* alternate alphabetic */
71915061Sgarrison             cp = aabet(cp, ref);
72015061Sgarrison          else if (c == '3')                     /* Astrophysical Journal style*/
72115061Sgarrison             cp = astro(cp, ref);
72215890Srrh          else if (c == '9')                     /* Last name of Senior Author*/
72315890Srrh             cp = aabetlast(cp, ref);
72415061Sgarrison /*       else if (c == '4')          here is how to add new styles */
72515061Sgarrison          else if (c == '{') {                   /* other information   */
72615061Sgarrison             while (*p != '}')
72715061Sgarrison                if (*p == 0)
72815061Sgarrison                   error("unexpected end of citation template");
72915061Sgarrison                else
73015061Sgarrison                   *cp++ = *p++;
73115061Sgarrison             p++;
73215061Sgarrison             }
73315061Sgarrison          else if (c == '<') {
73415061Sgarrison             while (*p != '>') {
73515061Sgarrison                if (*p == 0)
73615061Sgarrison                   error("unexpected end of citation template");
73715061Sgarrison                else
73815061Sgarrison                   *cp++ = *p++;
73915061Sgarrison                }
74015061Sgarrison             p++;
74115061Sgarrison             }
74215061Sgarrison          else if (c != '@')
74315061Sgarrison             *cp++ = c;
74415061Sgarrison          }
74515061Sgarrison       }
74615061Sgarrison    *cp++ = 0;
74715061Sgarrison }
74815061Sgarrison 
74915061Sgarrison /* alternate alphabetic citation style -
75015061Sgarrison         if 1 author - first three letters of last name
75115061Sgarrison         if 2 authors - first two letters of first, followed by first letter of
75215061Sgarrison                                 seond
75315061Sgarrison         if 3 or more authors - first letter of first three authors */
75415061Sgarrison    char *aabet(cp, ref)
75515061Sgarrison    char *cp, ref[];
75615903Srrh {  char field[REFSIZE], temp[100];
75715903Srrh    reg char *np, *fp;
75815061Sgarrison    int j, getname();
75915061Sgarrison 
76015061Sgarrison    if (getname(1, field, temp, ref)) {
76115061Sgarrison       np = cp;
76215061Sgarrison       fp = field;
76315061Sgarrison       for (j = 1; j <= 3; j++)
76415061Sgarrison          if (*fp != 0)
76515061Sgarrison             *cp++ = *fp++;
76615061Sgarrison       if (getname(2, field, temp, ref))
76715061Sgarrison          np[2] = field[0];
76815061Sgarrison       if (getname(3, field, temp, ref)) {
76915061Sgarrison          np[1] = np[2];
77015061Sgarrison          np[2] = field[0];
77115061Sgarrison          }
77215061Sgarrison       }
77315061Sgarrison return(cp);
77415061Sgarrison }
77515061Sgarrison 
77615890Srrh /* alternate alphabetic citation style -
77715890Srrh 	entire last name of senior author
77815890Srrh */
77915890Srrh    char *aabetlast(cp, ref)
78015890Srrh    char *cp, ref[];
78115890Srrh {  char field[REFSIZE], temp[100];
78215903Srrh    reg char	*fp;
78315890Srrh    int getname();
78415890Srrh 
78515890Srrh    if (getname(1, field, temp, ref)) {
78615890Srrh       for (fp = field; *fp; )
78715890Srrh          *cp++ = *fp++;
78815890Srrh    }
78915890Srrh    return(cp);
79015890Srrh }
79115890Srrh 
79215061Sgarrison /* Astrophysical Journal style
79315061Sgarrison         if 1 author - last name date
79415061Sgarrison         if 2 authors - last name and last name date
79515061Sgarrison         if 3 authors - last name, last name and last name date
79615061Sgarrison         if 4 or more authors - last name et al. date */
79715061Sgarrison    char *astro(cp, ref)
79815061Sgarrison    char *cp, ref[];
79915903Srrh {  char name1[100], name2[100], name3[100], temp[100];
80015903Srrh    reg char *fp;
80115061Sgarrison    int getname();
80215061Sgarrison 
80315061Sgarrison    if (getname(1, name1, temp, ref)) {
80415061Sgarrison       for (fp = name1; *fp; )
80515061Sgarrison          *cp++ = *fp++;
80615061Sgarrison       if (getname(4, name3, temp, ref)) {
80715061Sgarrison          for (fp = " et al."; *fp; )
80815061Sgarrison             *cp++ = *fp++;
80915061Sgarrison          }
81015061Sgarrison       else if (getname(2, name2, temp, ref)) {
81115061Sgarrison          if (getname(3, name3, temp, ref)) {
81215061Sgarrison             for (fp = "\\*(c]"; *fp; )
81315061Sgarrison                *cp++ = *fp++;
81415061Sgarrison             for (fp = name2; *fp; )
81515061Sgarrison                *cp++ = *fp++;
81615061Sgarrison             for (fp = "\\*(m]"; *fp; )
81715061Sgarrison                *cp++ = *fp++;
81815061Sgarrison             for (fp = name3; *fp; )
81915061Sgarrison                *cp++ = *fp++;
82015061Sgarrison             }
82115061Sgarrison          else {
82215061Sgarrison             for (fp = "\\*(n]"; *fp; )
82315061Sgarrison                *cp++ = *fp++;
82415061Sgarrison             for (fp = name2; *fp; )
82515061Sgarrison                *cp++ = *fp++;
82615061Sgarrison             }
82715061Sgarrison          }
82815061Sgarrison     }
82915061Sgarrison return(cp);
83015061Sgarrison }
83115061Sgarrison 
83215061Sgarrison /* getfield - get a single field from reference */
83315061Sgarrison    char *getfield(ptr, field, ref)
83415061Sgarrison    char *ptr, field[], ref[];
83515903Srrh {  reg	char *p, *q;
83615903Srrh    char	temp[100];
83715061Sgarrison    int  n, len, i, getname();
83815061Sgarrison 
83915061Sgarrison    field[0] = 0;
84015061Sgarrison    if (*ptr == 'A')
84115061Sgarrison       getname(1, field, temp, ref);
84215061Sgarrison    else
84315061Sgarrison       for (p = ref; *p; p++)
84415061Sgarrison          if (*p == '%' && *(p+1) == *ptr) {
84515061Sgarrison             for (p = p + 2; *p == ' '; p++)
84615061Sgarrison                ;
84715061Sgarrison             for (q = field; (*p != '\n') && (*p != '\0'); )
84815061Sgarrison                *q++ = *p++;
84915061Sgarrison             *q = 0;
85015061Sgarrison             break;
85115061Sgarrison             }
85215061Sgarrison    n = 0;
85315061Sgarrison    len = strlen(field);
85415061Sgarrison    if (*++ptr == '-') {
85515061Sgarrison       for (ptr++; isdigit(*ptr); ptr++)
85615061Sgarrison          n = 10 * n + (*ptr - '0');
85715061Sgarrison       if (n > len)
85815061Sgarrison          n = 0;
85915061Sgarrison       else
86015061Sgarrison          n = len - n;
86115061Sgarrison       for (i = 0; field[i] = field[i+n]; i++)
86215061Sgarrison          ;
86315061Sgarrison       }
86415061Sgarrison    else if (isdigit(*ptr)) {
86515061Sgarrison       for (; isdigit(*ptr); ptr++)
86615061Sgarrison          n = 10 * n + (*ptr - '0');
86715061Sgarrison       if (n > len)
86815061Sgarrison          n = len;
86915061Sgarrison       field[n] = 0;
87015061Sgarrison       }
87115061Sgarrison 
87215061Sgarrison    if (*ptr == 'u') {
87315061Sgarrison       ptr++;
87415061Sgarrison       for (p = field; *p; p++)
87515061Sgarrison          if (islower(*p))
87615061Sgarrison             *p = (*p - 'a') + 'A';
87715061Sgarrison       }
87815061Sgarrison    else if (*ptr == 'l') {
87915061Sgarrison       ptr++;
88015061Sgarrison       for (p = field; *p; p++)
88115061Sgarrison          if (isupper(*p))
88215061Sgarrison             *p = (*p - 'A') + 'a';
88315061Sgarrison       }
88415061Sgarrison    return(ptr);
88515061Sgarrison }
88615061Sgarrison 
88715061Sgarrison /* getname - get the nth name field from reference, breaking into
88815061Sgarrison              first and last names */
88915061Sgarrison    int getname(n, last, first, ref)
89015061Sgarrison    int  n;
89115061Sgarrison    char last[], first[], ref[];
89215903Srrh {  reg char *p;
89315061Sgarrison    int  m;
89415061Sgarrison 
89515061Sgarrison    m = n;
89615061Sgarrison    for (p = ref; *p; p++)
89715061Sgarrison       if (*p == '%' & *(p+1) == 'A') {
89815061Sgarrison          n--;
89915061Sgarrison          if (n == 0) {
90015061Sgarrison             for (p = p + 2; *p == ' '; p++) ;
90115061Sgarrison             breakname(p, first, last) ;
90215061Sgarrison             return(true);
90315061Sgarrison             }
90415061Sgarrison          }
90515061Sgarrison 
90615061Sgarrison    if (n == m)          /* no authors, try editors */
90715061Sgarrison       for (p = ref; *p; p++)
90815061Sgarrison          if (*p == '%' & *(p+1) == 'E') {
90915061Sgarrison             n--;
91015061Sgarrison             if (n == 0) {
91115061Sgarrison                for (p = p + 2; *p == ' '; p++) ;
91215061Sgarrison                breakname(p, first, last) ;
91315061Sgarrison                return(true);
91415061Sgarrison                }
91515061Sgarrison             }
91615061Sgarrison 
91715061Sgarrison    if (n == m) {        /* no editors, either, try institution */
91815061Sgarrison       first[0] = last[0] = '\0';
91915061Sgarrison       getfield("I", last, ref);
92015061Sgarrison       if (last[0] != '\0')
92115061Sgarrison          return(true);
92215061Sgarrison       }
92315061Sgarrison 
92415061Sgarrison    return(false);
92515061Sgarrison }
92615061Sgarrison 
92715061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
92815061Sgarrison                   single character disambiguators */
92915061Sgarrison    disambiguate()
93015903Srrh {  reg int i, j;
931*16244Srrh 	char adstr;
93215061Sgarrison 
93315061Sgarrison    for (i = 0; i < numrefs; i = j) {
93415061Sgarrison       j = i + 1;
93515903Srrh       if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) {
936*16244Srrh          adstr = 'a';
93715903Srrh          for(j = i+1; strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0; j++) {
938*16244Srrh             adstr = 'a' + (j-i);
93915061Sgarrison             if (j == numrefs)
94015061Sgarrison                break;
941*16244Srrh 	    refinfo[j].ri_disambig[0] = adstr;
94215061Sgarrison             }
943*16244Srrh 	 refinfo[i].ri_disambig[0] = 'a';
94415061Sgarrison          }
94515061Sgarrison      }
946*16244Srrh   for (i = 0; i < numrefs; i++){
947*16244Srrh 	strcat(refinfo[i].ri_cite, refinfo[i].ri_disambig);
948*16244Srrh   }
94915061Sgarrison }
95015061Sgarrison 
95115061Sgarrison 
95212910Sgarrison /* bldname - build a name field
95312910Sgarrison              doing abbreviations, reversals, and caps/small caps
95412910Sgarrison */
95512910Sgarrison    bldname(first, last, name, reverse)
95612910Sgarrison    char *first, *last, name[];
95712910Sgarrison    int reverse;
95812910Sgarrison {
95915903Srrh    char newfirst[120], newlast[120];
96015903Srrh    reg char *p, *q, *f, *l;
96115903Srrh    char *scopy();
96212910Sgarrison    int  flag;
96312910Sgarrison 
96412910Sgarrison    if (abbrev) {
96512910Sgarrison       p = first;
96612910Sgarrison       q = newfirst;
96712910Sgarrison       flag = false;
96812910Sgarrison       while (*p) {
96912910Sgarrison          while (*p == ' ')
97012910Sgarrison             p++;
97112910Sgarrison          if (*p == 0)
97212910Sgarrison             break;
97312910Sgarrison          if (isupper(*p)) {
97415061Sgarrison             if (flag)           /* between initial gap */
97512910Sgarrison                q = scopy(q, "\\*(a]");
97612910Sgarrison             flag = true;
97712910Sgarrison             *q++ = *p;
97815061Sgarrison             q = scopy(q, "\\*(p]");
97912910Sgarrison             }
98012910Sgarrison          if (*++p == '.')
98112910Sgarrison             p++;
98212910Sgarrison          else while (*p != 0 && ! isspace(*p))
98312910Sgarrison             p++;
98412910Sgarrison          }
98512910Sgarrison       *q = 0;
98612910Sgarrison       f = newfirst;
98712910Sgarrison       }
98812910Sgarrison    else
98912910Sgarrison       f = first;
99012910Sgarrison 
99112910Sgarrison    if (capsmcap) {
99212910Sgarrison       p = last;
99312910Sgarrison       q = newlast;
99412910Sgarrison       flag = 0;  /* 1 - printing cap, 2 - printing small */
99512910Sgarrison       while (*p)
99612910Sgarrison          if (islower(*p)) {
99712910Sgarrison             if (flag != 2)
99812910Sgarrison                q = scopy(q, "\\s-2");
99912910Sgarrison             flag = 2;
100012910Sgarrison             *q++ = (*p++ - 'a') + 'A';
100112910Sgarrison             }
100212910Sgarrison          else {
100312910Sgarrison             if (flag == 2)
100412910Sgarrison                q = scopy(q,"\\s+2");
100512910Sgarrison             flag = 1;
100612910Sgarrison             *q++ = *p++;
100712910Sgarrison             }
100812910Sgarrison       if (flag == 2)
100912910Sgarrison          q = scopy(q, "\\s+2");
101012910Sgarrison       *q = 0;
101112910Sgarrison       l = newlast;
101212910Sgarrison       }
101312910Sgarrison    else
101412910Sgarrison       l = last;
101512910Sgarrison 
101615061Sgarrison    if (f[0] == 0)
101715061Sgarrison       sprintf(name, "%s\n", l);
101815061Sgarrison    else if (reverse)
101915061Sgarrison       sprintf(name, "%s\\*(b]%s\n", l, f);
102012910Sgarrison    else
102112910Sgarrison       sprintf(name, "%s %s\n", f, l);
102212910Sgarrison }
102312910Sgarrison 
102412910Sgarrison /* prtauth - print author or editor field */
102512910Sgarrison    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
102612910Sgarrison    char c, *line;
102712910Sgarrison    int  num, max, abbrev, capsmcap, numrev;
102812910Sgarrison    FILE *ofd;
102912910Sgarrison {  char first[LINELENGTH], last[LINELENGTH];
103012910Sgarrison 
103112910Sgarrison    if (num <= numrev || abbrev || capsmcap) {
103212910Sgarrison       breakname(line, first, last);
103312910Sgarrison       bldname(first, last, line, num <= numrev);
103412910Sgarrison       }
103512910Sgarrison    if (num == 1)
103612910Sgarrison       fprintf(ofd,".ds [%c %s", c, line);
103712910Sgarrison    else if (num < max)
103812910Sgarrison       fprintf(ofd,".as [%c \\*(c]%s", c, line);
103912910Sgarrison    else if (max == 2)
104012910Sgarrison       fprintf(ofd,".as [%c \\*(n]%s", c, line);
104112910Sgarrison    else
104212910Sgarrison       fprintf(ofd,".as [%c \\*(m]%s", c, line);
104312910Sgarrison    if (num == max && index(trailstr, c))
104412910Sgarrison       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
104512910Sgarrison }
104612910Sgarrison 
104712910Sgarrison /* doline - actually print out a line of reference information */
104812910Sgarrison    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
104912910Sgarrison    char c, *line;
105012910Sgarrison    int numauths, maxauths, numeds, maxeds;
105112910Sgarrison    FILE *ofd;
105212910Sgarrison {
105312910Sgarrison 
105412910Sgarrison    switch(c) {
105512910Sgarrison       case 'A':
105612910Sgarrison           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
105712910Sgarrison           break;
105812910Sgarrison 
105912910Sgarrison        case 'E':
106012910Sgarrison           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
106112910Sgarrison           if (numeds == maxeds)
106212910Sgarrison              fprintf(ofd,".nr [E %d\n", maxeds);
106312910Sgarrison           break;
106412910Sgarrison 
106512910Sgarrison        case 'P':
106612910Sgarrison           if (index(line, '-'))
106712910Sgarrison              fprintf(ofd,".nr [P 1\n");
106812910Sgarrison           else
106912910Sgarrison              fprintf(ofd,".nr [P 0\n");
107012910Sgarrison           fprintf(ofd,".ds [P %s",line);
107112910Sgarrison           if (index(trailstr, 'P'))
107212910Sgarrison              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
107312910Sgarrison           break;
107412910Sgarrison 
107512910Sgarrison        case 'F':
107612910Sgarrison        case 'K': break;
107712910Sgarrison 
107812910Sgarrison        default:
107912910Sgarrison           fprintf(ofd,".ds [%c %s", c, line);
108012910Sgarrison           if (index(trailstr, c))
108112910Sgarrison              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
108212910Sgarrison           }
108312910Sgarrison }
108412910Sgarrison 
108515061Sgarrison /* dumpref - dump reference number i */
108615061Sgarrison    dumpref(i, ofd)
108715061Sgarrison    int i;
108815061Sgarrison    FILE *ofd;
108915903Srrh {  char ref[REFSIZE], line[REFSIZE];
109015903Srrh    reg char *p, *q;
109115903Srrh    char *from;
109215061Sgarrison    int numauths, maxauths, numeds, maxeds;
109315061Sgarrison 
109415903Srrh    rdref(&refinfo[i], ref);
109515061Sgarrison    maxauths = maxeds = 0;
109615061Sgarrison    numauths = numeds = 0;
109715061Sgarrison    for (p = ref; *p; p++)
109815061Sgarrison       if (*p == '%')
109915061Sgarrison          if (*(p+1) == 'A') maxauths++;
110015061Sgarrison          else if (*(p+1) == 'E') maxeds++;
110115061Sgarrison    fprintf(ofd, ".[-\n");
110215903Srrh    fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite);
110315903Srrh #ifndef INCORE
110415903Srrh    fseek(rfd, (long)refinfo[i].ri_pos, 0);
110515061Sgarrison    while (fgets(line, REFSIZE, rfd) != NULL) {
110615903Srrh #else INCORE
110715903Srrh    for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */
110815903Srrh 	if (*from == '\n'){
110915903Srrh 		*q++ = '\n';
111015903Srrh 		*q = 0;
111115903Srrh 		q = line;
111215903Srrh 		from++;
111315903Srrh 	} else {
111415903Srrh 		*q++ = *from++;
111515903Srrh 		continue;
111615903Srrh 	}
111715903Srrh #endif INCORE
111815903Srrh 	switch(line[0]){
111915903Srrh 	case 0:
112015903Srrh 		goto doneref;
112115903Srrh 	case '.':
112215903Srrh 		fprintf(ofd, "%s", line);
112315903Srrh 		break;
112415903Srrh 	case '%':
112515903Srrh 		switch(line[1]){
112615903Srrh 		case 'A':	numauths++;	break;
112715903Srrh 		case 'E':	numeds++;	break;
112815903Srrh 		}
112915903Srrh 		for (p = &line[2]; *p == ' '; p++) /*VOID*/;
113015903Srrh 		doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
113115903Srrh 	}
113215903Srrh    }
113315903Srrh    doneref:;
113415061Sgarrison    fprintf(ofd,".][\n");
113515061Sgarrison }
1136