xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 17246)
113110Srrh #ifndef lint
2*17246Srrh static char sccsid[] = "@(#)bibargs.c	2.6	10/12/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) */
36*17246Srrh    int  doacite      = true;    /* place citations ? */
3712910Sgarrison    int  hyphen       = false;   /* hypenate contiguous references            */
3812910Sgarrison    int  ordcite      = true;    /* order multiple citations                  */
3912910Sgarrison    char sortstr[80]  = "1";     /* sorting template                          */
4012910Sgarrison    char trailstr[80] = "";      /* trailing characters to output             */
4112910Sgarrison    char pfile[120];             /* private file name                         */
4212910Sgarrison    int  personal = false;       /* personal file given ? (default no)        */
4312910Sgarrison    char citetemplate[80] = "1"; /* citation template                         */
4415903Srrh    struct wordinfo words[MAXDEFS];     /* defined words */
4515903Srrh    struct wordinfo *wordhash[HASHSIZE];
4615903Srrh    struct wordinfo *wordsearch();
4715903Srrh    int  wordtop = 0;           /* number of defined words         */
4812910Sgarrison 
4912910Sgarrison /* where output goes */
5012910Sgarrison    extern FILE *tfd;
5115061Sgarrison /* reference file information */
5215903Srrh    extern struct refinfo refinfo[];
5315061Sgarrison    extern char reffile[];
5415903Srrh #ifndef INCORE
5515061Sgarrison    extern FILE *rfd;
5615903Srrh #endif not INCORE
5715061Sgarrison    extern int numrefs;
5812910Sgarrison 
5912910Sgarrison /* doargs - read command argument line for both bib and listrefs
6012910Sgarrison             set switch values
6112910Sgarrison             call rdtext on file arguments, after dumping
6212910Sgarrison             default style file if no alternative style is given
6312910Sgarrison */
6412910Sgarrison    int doargs(argc, argv, defstyle)
6512910Sgarrison    int argc;
6612910Sgarrison    char **argv, defstyle[];
6712910Sgarrison {  int numfiles, i, style;
6812910Sgarrison    char *p, *q, *walloc();
6912910Sgarrison    FILE *fd;
7012910Sgarrison 
7112910Sgarrison    numfiles = 0;
7212910Sgarrison    style = true;
7315903Srrh    wordstuff("BMACLIB", BMACLIB);
7412910Sgarrison    fputs(".ds l] ",tfd);
7512910Sgarrison    fputs(BMACLIB, tfd);
7612910Sgarrison    fputs("\n", tfd);
7712910Sgarrison 
7812910Sgarrison    for (i = 1; i < argc; i++)
7912910Sgarrison       if (argv[i][0] == '-')
8012910Sgarrison          switch(argv[i][1]) {
8112910Sgarrison 
8215061Sgarrison             case 'a':  for (p = &argv[i][2]; *p; p++)
8315061Sgarrison                           if (*p == 'a' || *p == 0)
8412961Sgarrison                              abbrev = true;
8512961Sgarrison                            else if (*p == 'x')
8612961Sgarrison                              capsmcap = true;
8712961Sgarrison                            else if (*p == 'r') {
8812961Sgarrison                              if (*(p+1))
8912961Sgarrison                                 numrev = atoi(p+1);
9012961Sgarrison                               else
9112961Sgarrison                                 numrev = 1000;
9212961Sgarrison                               break;
9312961Sgarrison                               }
9412910Sgarrison                        break;
9512910Sgarrison 
9612910Sgarrison             case 'c':  if (argv[i][2] == 0)
9715903Srrh                           error("citation string expected for 'c'");
9812910Sgarrison                        else
9912910Sgarrison                           for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
10012910Sgarrison                        break;
10112910Sgarrison 
10212910Sgarrison             case 'e':  for (p = &argv[i][2]; *p; p++)
10312910Sgarrison                           if (*p == 'a')
10412910Sgarrison                              edabbrev = true;
10512910Sgarrison                            else if (*p == 'x')
10612910Sgarrison                              edcapsmcap = true;
10712910Sgarrison                            else if (*p == 'r') {
10812910Sgarrison                              if (*(p+1))
10912910Sgarrison                                 ednumrev = atoi(p+1);
11012910Sgarrison                               else
11112910Sgarrison                                 ednumrev = 1000;
11212910Sgarrison                               break;
11312910Sgarrison                               }
11412910Sgarrison                        break;
11512910Sgarrison 
116*17246Srrh             case 'v':  doacite = false;
117*17246Srrh 			/*FALLTHROUGH*/
11812910Sgarrison             case 'f':  foot = true;
11912910Sgarrison                        hyphen = false;
12012910Sgarrison                        break;
12112910Sgarrison 
12212910Sgarrison             case 'h':  hyphen = ordcite = true;
12312910Sgarrison                        break;
12412910Sgarrison 
12512910Sgarrison             case 'n':  for (p = &argv[i][2]; *p; p++)
12612910Sgarrison                           if (*p == 'a')
12712910Sgarrison                              abbrev = false;
128*17246Srrh                           else if (*p == 'v')
129*17246Srrh                              doacite = true;
13012910Sgarrison                           else if (*p == 'f')
13112910Sgarrison                              foot = false;
13212910Sgarrison                           else if (*p == 'h')
13312910Sgarrison                              hyphen = false;
13412910Sgarrison                           else if (*p == 'o')
13512910Sgarrison                              ordcite = false;
13612910Sgarrison                           else if (*p == 'r')
13712910Sgarrison                              numrev = 0;
13812910Sgarrison                           else if (*p == 's')
13912910Sgarrison                              sort = false;
14012910Sgarrison                           else if (*p == 'x')
14112910Sgarrison                              capsmcap = false;
14212910Sgarrison                        break;
14312910Sgarrison 
14412910Sgarrison             case 'o':  ordcite = true;
14512910Sgarrison                        break;
14612910Sgarrison 
14712910Sgarrison             case 'p':  if (argv[i][2])
14812910Sgarrison                           p = &argv[i][2];
14912910Sgarrison                        else {  /* take next arg */
15012910Sgarrison                           i++;
15112910Sgarrison                           p = argv[i];
15212910Sgarrison                           }
15312910Sgarrison                        strcpy(pfile, p);
15412910Sgarrison                        personal = true;
15512910Sgarrison                        break;
15612910Sgarrison 
15715061Sgarrison             case 'r':  if (argv[i][2] == 0)  /* this is now replaced by -ar */
15812910Sgarrison                           numrev = 1000;
15912910Sgarrison                        else
16012910Sgarrison                           numrev = atoi(&argv[i][2]);
16112910Sgarrison                        break;
16212910Sgarrison 
16312910Sgarrison             case 's':  sort = true;
16412910Sgarrison                        if (argv[i][2])
16512910Sgarrison                           for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
16612910Sgarrison                        break;
16712910Sgarrison 
16815061Sgarrison             case 't':  style = false;           /* fall through */
16915061Sgarrison             case 'i':  if (argv[i][2])
17012910Sgarrison                           p = &argv[i][2];
17112910Sgarrison                        else { /* take next arg */
17212910Sgarrison                           i++;
17312910Sgarrison                           p = argv[i];
17412910Sgarrison                           }
17512910Sgarrison                        incfile(p);
17612910Sgarrison                        break;
17712910Sgarrison 
17815061Sgarrison             case 'x':  capsmcap = true; /* this is now replaced by -ax */
17912910Sgarrison                        break;
18012910Sgarrison 
18112910Sgarrison             case 0:    if (style) {  /* no style command given, take default */
18212910Sgarrison                           style = false;
18312910Sgarrison                           incfile( defstyle );
18412910Sgarrison                           }
18515061Sgarrison                        strcpy(bibfname,"<stdin>");
18612910Sgarrison                        rdtext(stdin);
18712910Sgarrison                        numfiles++;
18812910Sgarrison                        break;
18912910Sgarrison 
19012910Sgarrison             default:   fputs(argv[i], stderr);
19115903Srrh                        error("'%c' invalid switch", argv[i][1]);
19212910Sgarrison             }
19312910Sgarrison       else { /* file name */
19412910Sgarrison          numfiles++;
19512910Sgarrison          if (style) {
19612910Sgarrison             style = false;
19712910Sgarrison             incfile( defstyle );
19812910Sgarrison             }
19912910Sgarrison          fd = fopen(argv[i], "r");
20012910Sgarrison          if (fd == NULL) {
20115903Srrh             error("can't open file %s", argv[i]);
20212910Sgarrison             }
20312910Sgarrison          else {
20415061Sgarrison             strcpy(bibfname, argv[i]);
20512910Sgarrison             rdtext(fd);
20612910Sgarrison             fclose(fd);
20712910Sgarrison             }
20812910Sgarrison          }
20912910Sgarrison 
21012910Sgarrison    if (style) incfile( defstyle );
21112910Sgarrison    return(numfiles);
21212910Sgarrison 
21312910Sgarrison }
21412910Sgarrison 
21512910Sgarrison /* incfile - read in an included file  */
21612910Sgarrison incfile(np)
21712910Sgarrison    char *np;
21812910Sgarrison {  char name[120];
21912910Sgarrison    FILE *fd;
22015061Sgarrison    char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
22116244Srrh    int  i, getwrd();
22212910Sgarrison 
22315061Sgarrison    strcpy(bibfname, np);
22412910Sgarrison    fd = fopen(np, "r");
22512910Sgarrison    if (fd == NULL && *np != '/') {
22612910Sgarrison       strcpy(name, "bib.");
22712910Sgarrison       strcat(name, np);
22815061Sgarrison       strcpy(bibfname, name);
22912910Sgarrison       fd = fopen(name, "r");
23012910Sgarrison       }
23112910Sgarrison    if (fd == NULL && *np != '/') {
23212910Sgarrison       strcpy(name,BMACLIB);
23312910Sgarrison       strcat(name, "/bib.");
23412910Sgarrison       strcat(name, np);
23515061Sgarrison       strcpy(bibfname, name);
23612910Sgarrison       fd = fopen(name, "r");
23712910Sgarrison       }
23812910Sgarrison    if (fd == NULL) {
23915061Sgarrison       bibwarning("%s: can't open", np);
24015061Sgarrison       exit(1);
24112910Sgarrison       }
24212910Sgarrison 
24315061Sgarrison    /* now go off and process file */
24415061Sgarrison    biblineno = 1;
24515061Sgarrison    while (tfgets(line, LINELENGTH, fd) != NULL) {
24615061Sgarrison       biblineno++;
24712910Sgarrison       switch(line[0]) {
24812910Sgarrison 
24912910Sgarrison          case '#': break;
25012910Sgarrison 
25112961Sgarrison          case 'A': for (p = &line[1]; *p; p++)
25215061Sgarrison                       if (*p == 'A' || *p == '\0')
25312961Sgarrison                          abbrev = true;
25412961Sgarrison                       else if (*p == 'X')
25512961Sgarrison                          capsmcap = true;
25612961Sgarrison                       else if (*p == 'R') {
25712961Sgarrison                          if (*(p+1))
25812961Sgarrison                             numrev = atoi(p+1);
25912961Sgarrison                          else
26012961Sgarrison                             numrev = 1000;
26112961Sgarrison                          break;
26212961Sgarrison                          }
26312910Sgarrison                    break;
26412910Sgarrison 
26512910Sgarrison          case 'C': for (p = &line[1]; *p == ' '; p++) ;
26612910Sgarrison                    strcpy(citetemplate, p);
26712910Sgarrison                    break;
26812910Sgarrison 
26912910Sgarrison          case 'D': if ((i = getwrd(line, 1, word)) == 0)
27012910Sgarrison                       error("word expected in definition");
27115903Srrh 		   if (wordsearch(word))
27215903Srrh 			break;
27312910Sgarrison                    for (p = &line[i]; *p == ' '; p++) ;
27412910Sgarrison                    for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
27512910Sgarrison                        dline[strlen(dline)-1] = '\n';
27615061Sgarrison                        if (tfgets(line, LINELENGTH, fd) == NULL) break;
27712910Sgarrison                        strcat(dline, line);
27812910Sgarrison                        }
27915903Srrh 		   wordstuff(word, dline);
28012910Sgarrison                    break;
28112910Sgarrison 
28212910Sgarrison          case 'E': for (p = &line[1]; *p; p++)
28312910Sgarrison                       if (*p == 'A')
28412910Sgarrison                          edabbrev = true;
28512910Sgarrison                       else if (*p == 'X')
28612910Sgarrison                          edcapsmcap = true;
28712910Sgarrison                       else if (*p == 'R') {
28812910Sgarrison                          if (*(p+1))
28912910Sgarrison                             ednumrev = atoi(p+1);
29012910Sgarrison                          else
29112910Sgarrison                             ednumrev = 1000;
29212910Sgarrison                          break;
29312910Sgarrison                          }
29412910Sgarrison                    break;
29512910Sgarrison 
29612910Sgarrison          case 'F': foot = true;
29712910Sgarrison                    hyphen = false;
29812910Sgarrison                    break;
29912910Sgarrison 
30012910Sgarrison          case 'I': for (p = &line[1]; *p == ' '; p++);
30112910Sgarrison                    expand(p);
30212910Sgarrison                    incfile(p);
30312910Sgarrison                    break;
30412910Sgarrison 
30512910Sgarrison          case 'H': hyphen = ordcite = true;
30612910Sgarrison                    break;
30712910Sgarrison 
30812910Sgarrison          case 'O': ordcite = true;
30912910Sgarrison                    break;
31012910Sgarrison 
31115061Sgarrison          case 'R': if (line[1] == 0)  /* this is now replaced by AR */
31212910Sgarrison                       numrev = 1000;
31312910Sgarrison                    else
31412910Sgarrison                       numrev = atoi(&line[1]);
31512910Sgarrison                    break;
31612910Sgarrison 
31712910Sgarrison          case 'S': sort = true;
31812910Sgarrison                    for (p = &line[1]; *p == ' '; p++) ;
31912910Sgarrison                    strcpy(sortstr, p);
32012910Sgarrison                    break;
32112910Sgarrison 
32212910Sgarrison          case 'T': for (p = &line[1]; *p == ' '; p++) ;
32312910Sgarrison                    strcpy(trailstr, p);
32412910Sgarrison                    break;
32512910Sgarrison 
32615061Sgarrison          case 'X': capsmcap = true;     /* this is now replace by AX */
32712910Sgarrison                    break;
32812910Sgarrison 
32912910Sgarrison          default:  fprintf(tfd,"%s\n",line);
33015061Sgarrison                    while (fgets(line, LINELENGTH, fd) != NULL)
33112910Sgarrison                       fputs(line, tfd);
33212910Sgarrison                    return;
33312910Sgarrison          }
33415061Sgarrison 
33515061Sgarrison    }
33615061Sgarrison    /* close up */
33715061Sgarrison    fclose(fd);
33812910Sgarrison }
33912910Sgarrison 
34015061Sgarrison /* bibwarning - print out a warning message */
34115903Srrh   /*VARARGS1*/
34215903Srrh   bibwarning(msg, a1, a2)
34315903Srrh   char *msg;
34415061Sgarrison {
34515061Sgarrison   fprintf(stderr,"`%s', line %d: ", bibfname, biblineno);
34615903Srrh   fprintf(stderr, msg, a1, a2);
34715061Sgarrison }
34815061Sgarrison 
34915061Sgarrison /* error - report unrecoverable error message */
35015903Srrh   /*VARARGS1*/
35115903Srrh   error(str, a1, a2)
35215903Srrh   char *str;
35315061Sgarrison {
35415903Srrh   bibwarning(str, a1, a2);
35515903Srrh   /*
35615903Srrh    *	clean up temp files and exit
35715903Srrh    */
35815903Srrh   cleanup(1);
35915061Sgarrison }
36015061Sgarrison 
36115903Srrh #ifndef INCORE
36215061Sgarrison #ifdef READWRITE
36315061Sgarrison /*
36415061Sgarrison ** fixrfd( mode ) -- re-opens the rfd file to be read or write,
36515061Sgarrison **      depending on the mode.  Uses a static int to save the current mode
36615061Sgarrison **      and avoid unnecessary re-openings.
36715061Sgarrison */
36815061Sgarrison fixrfd( mode )
36915061Sgarrison register int mode;
37015061Sgarrison {
37115061Sgarrison 	static int cur_mode = WRITE;    /* rfd open for writing initially */
37215061Sgarrison 
37315061Sgarrison 	if (mode != cur_mode)
37415061Sgarrison 	{
37515061Sgarrison 		rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
37615061Sgarrison 		cur_mode = mode;
37715061Sgarrison 		if (rfd == NULL)
37815903Srrh 		      error("Hell!  Couldn't re-open reference file %s",
37915903Srrh 			reffile);
38015061Sgarrison 	}
38115061Sgarrison }
38215061Sgarrison #endif
38315903Srrh #endif not INCORE
38415061Sgarrison 
38515061Sgarrison 
38615061Sgarrison /* tfgets - fgets which trims off newline */
38715061Sgarrison    char *tfgets(line, n, ptr)
38815061Sgarrison    char line[];
38915061Sgarrison    int  n;
39015061Sgarrison    FILE *ptr;
39115903Srrh {  reg char *p;
39215061Sgarrison 
39315061Sgarrison    p = fgets(line, n, ptr);
39415061Sgarrison    if (p == NULL)
39515061Sgarrison       return(NULL);
39615061Sgarrison    else
39715061Sgarrison       for (p = line; *p; p++)
39815061Sgarrison          if (*p == '\n')
39915061Sgarrison             *p = 0;
40015061Sgarrison    return(line);
40115061Sgarrison }
40215061Sgarrison 
40315061Sgarrison /* getwrd - place next word from in[i] into out */
40415061Sgarrison int getwrd(in, i, out)
40515903Srrh    reg char in[], out[];
40615903Srrh    reg int i;
40715061Sgarrison {  int j;
40815061Sgarrison 
40915061Sgarrison    j = 0;
41015061Sgarrison    while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
41115061Sgarrison       i++;
41215061Sgarrison    if (in[i])
41315061Sgarrison       while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
41415061Sgarrison          out[j++] = in[i++];
41515061Sgarrison    else
41615061Sgarrison       i = 0;    /* signals end of in[i..]   */
41715061Sgarrison    out[j] = 0;
41815061Sgarrison    return (i);
41915061Sgarrison }
42015061Sgarrison 
42115061Sgarrison /* walloc - allocate enough space for a word */
42215061Sgarrison char *walloc(word)
42315061Sgarrison    char *word;
42415061Sgarrison {  char *i, *malloc();
42515061Sgarrison    i = malloc(1 + strlen(word));
42615061Sgarrison    if (i == NULL)
42715061Sgarrison       error("out of storage");
42815061Sgarrison    strcpy(i, word);
42915061Sgarrison    return(i);
43015061Sgarrison }
43115061Sgarrison 
43212910Sgarrison /* isword - see if character is legit word char */
43312910Sgarrison int iswordc(c)
43412910Sgarrison char c;
43512910Sgarrison {
43612910Sgarrison    if (isalnum(c) || c == '&' || c == '_')
43712910Sgarrison       return(true);
43812910Sgarrison    return(false);
43912910Sgarrison }
44012910Sgarrison    expand(line)
44112910Sgarrison    char *line;
44215903Srrh {  char line2[REFSIZE], word[LINELENGTH];
44315903Srrh    reg	struct wordinfo *wp;
44415903Srrh    reg	char *p, *q, *w;
44512910Sgarrison 
44615903Srrh 	q = line2;
44715903Srrh 	for (p = line; *p; /*VOID*/){
44815903Srrh 		if (isalnum(*p)) {
44915903Srrh 			for (w = word; *p && iswordc(*p); ) *w++ = *p++;
45015903Srrh 			*w = 0;
45115903Srrh 			if (wp = wordsearch(word)){
45215903Srrh 				strcpy(word, wp->wi_def);
45315903Srrh 				expand(word);
45415903Srrh 			}
45515903Srrh 			strcpy(q, word);
45615903Srrh 			q += strlen(q);
45715903Srrh 		} else {
45815903Srrh 			*q++ = *p++;
45915903Srrh 		}
46015903Srrh 	}
46115903Srrh 	*q = 0;
46215903Srrh 	strcpy(line, line2);
46312910Sgarrison }
46412910Sgarrison 
46515903Srrh /* wordstuff- save a word and its definition, building a hash table */
46615903Srrh    wordstuff(word, def)
46715903Srrh    char *word, *def;
46815903Srrh {
46915903Srrh    int i;
47015903Srrh    if (wordtop >= MAXDEFS)
47115903Srrh 	error("too many definitions, max of %d", MAXDEFS);
47215903Srrh    words[wordtop].wi_length = strlen(word);
47315903Srrh    words[wordtop].wi_word = word ? walloc(word) : 0;
47415903Srrh    words[wordtop].wi_def = def ? walloc(def) : 0;
47515903Srrh    i = strhash(word);
47615903Srrh    words[wordtop].wi_hp = wordhash[i];
47715903Srrh    wordhash[i] = &words[wordtop];
47815903Srrh    wordtop++;
47915903Srrh }
48015903Srrh    struct wordinfo *wordsearch(word)
48115903Srrh    char *word;
48215903Srrh {
48315903Srrh    reg int lg;
48415903Srrh    reg struct wordinfo *wp;
48515903Srrh    lg = strlen(word);
48615903Srrh    for (wp = wordhash[strhash(word)]; wp; wp = wp->wi_hp){
48715903Srrh 	if (wp->wi_length == lg && (strcmp(wp->wi_word, word) == 0)){
48815903Srrh 		return(wp);
48915903Srrh 	}
49015903Srrh    }
49115903Srrh    return(0);
49215903Srrh }
49315903Srrh 
49415903Srrh    int strhash(str)
49515903Srrh    reg char *str;
49615903Srrh {
49715903Srrh    reg int value = 0;
49815903Srrh    for (value = 0; *str; value <<= 2, value += *str++)/*VOID*/;
49915903Srrh    value %= HASHSIZE;
50015903Srrh    if (value < 0)
50115903Srrh 	value += HASHSIZE;
50215903Srrh    return(value);
50315903Srrh }
50415903Srrh 
50515061Sgarrison /* rdref - read text for an already cited reference */
50615903Srrh    rdref(p, ref)
50715903Srrh    struct refinfo *p;
50815061Sgarrison    char ref[REFSIZE];
50915061Sgarrison {
51015061Sgarrison    ref[0] = 0;
51115903Srrh #ifndef INCORE
51215061Sgarrison #ifdef READWRITE
51315061Sgarrison    fixrfd( READ );                      /* fix access mode of rfd, if nec. */
51415061Sgarrison #endif
51515903Srrh    fseek(rfd, p->ri_pos, 0);
51615903Srrh    fread(ref, p->ri_length, 1, rfd);
51715903Srrh #else INCORE
51815903Srrh    strcpy(ref, p->ri_ref);
51915903Srrh #endif INCORE
52015061Sgarrison }
52115061Sgarrison 
52215903Srrh /* wrref - write text for a new reference */
52315903Srrh    wrref(p, ref)
52415903Srrh    struct refinfo *p;
52515903Srrh    char ref[REFSIZE];
52615903Srrh {
52715903Srrh #ifndef INCORE
52815903Srrh #ifdef READWRITE
52915903Srrh     fixrfd( WRITE );                 /* fix access mode of rfd, if nec. */
53015903Srrh #else
53115903Srrh     fseek(rfd, p->ri_pos, 0);        /* go to end of rfd */
53215903Srrh #endif
53315903Srrh     fwrite(ref, p->ri_length, 1, rfd);
53415903Srrh #else INCORE
53515903Srrh    p->ri_ref = walloc(ref);
53615903Srrh #endif INCORE
53715903Srrh }
53815903Srrh 
53912910Sgarrison /* breakname - break a name into first and last name */
54012910Sgarrison    breakname(line, first, last)
54112910Sgarrison    char line[], first[], last[];
54215903Srrh {  reg char *t, *f, *q, *r, *p;
54312910Sgarrison 
54412910Sgarrison    for (t = line; *t != '\n'; t++);
54512910Sgarrison    for (t--; isspace(*t); t--);
54612910Sgarrison 
54712910Sgarrison    /* now strip off last name */
54812910Sgarrison    for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
54912910Sgarrison       if (q == line)
55012910Sgarrison          break;
55112910Sgarrison    f = q;
55215061Sgarrison    if (q != line) {
55312910Sgarrison       q++;
55415061Sgarrison       for (; isspace(*f); f--);
55515061Sgarrison       f++;
55615061Sgarrison       }
55712910Sgarrison 
55812910Sgarrison    /* first name is start to f, last name is q to t */
55912910Sgarrison 
56015061Sgarrison    for (r = first, p = line; p != f; )
56112910Sgarrison       *r++ = *p++;
56212910Sgarrison    *r = 0;
56312910Sgarrison    for (r = last, p = q, t++; q != t; )
56412910Sgarrison       *r++ = *q++;
56512910Sgarrison    *r = 0;
56615061Sgarrison 
56712910Sgarrison }
56812910Sgarrison 
56912910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
57012910Sgarrison    int match(str1, str2)
57115903Srrh    reg char str1[], str2[];
57215903Srrh {  reg int  j, i;
57312910Sgarrison    char a, b;
57412910Sgarrison 
57512910Sgarrison    for (i = 0; str2[i]; i++) {
57612910Sgarrison       for (j = 0; str1[j]; j++) {
57712910Sgarrison          if (isupper(a = str2[i+j]))
57812910Sgarrison             a = (a - 'A') + 'a';
57912910Sgarrison          if (isupper(b = str1[j]))
58012910Sgarrison             b = (b - 'A') + 'a';
58112910Sgarrison          if (a != b)
58212910Sgarrison             break;
58312910Sgarrison          }
58412910Sgarrison       if (str1[j] == 0)
58512910Sgarrison          return(true);
58612910Sgarrison       }
58712910Sgarrison    return(false);
58812910Sgarrison }
58912910Sgarrison 
59012910Sgarrison /* scopy - append a copy of one string to another */
59112910Sgarrison    char *scopy(p, q)
59215903Srrh    reg char *p, *q;
59312910Sgarrison {
59412910Sgarrison    while (*p++ = *q++)
59512910Sgarrison       ;
59612910Sgarrison    return(--p);
59712910Sgarrison }
59812910Sgarrison 
59915061Sgarrison /* rcomp - reference comparison routine for qsort utility */
60015061Sgarrison    int rcomp(ap, bp)
60115903Srrh    struct refinfo *ap, *bp;
60215061Sgarrison {  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
60315903Srrh    reg	char *p, *q;
60415903Srrh    char *getfield();
60515061Sgarrison    int  neg, res;
60615061Sgarrison    int  fields_found;
60715061Sgarrison 
60815903Srrh    rdref(ap, ref1);
60915903Srrh    rdref(bp, ref2);
61015061Sgarrison    for (p = sortstr; *p; p = q) {
61115061Sgarrison       if (*p == '-') {
61215061Sgarrison          p++;
61315061Sgarrison          neg = true;
61415061Sgarrison          }
61515061Sgarrison       else
61615061Sgarrison          neg = false;
61715061Sgarrison       q = getfield(p, field1, ref1);
61815061Sgarrison       fields_found = true;
61915061Sgarrison       if (q == 0) {
62015061Sgarrison 	 res = 1;
62115061Sgarrison 	 fields_found = false;
62215061Sgarrison       } else if (strcmp (field1, "") == 0) {	/* field not found */
62315061Sgarrison          if (*p == 'A') {
62415061Sgarrison             getfield("F", field1, ref1);
62515061Sgarrison 	    if (strcmp (field1, "") == 0) {
62615061Sgarrison                getfield("I", field1, ref1);
62715061Sgarrison 	       if (strcmp (field1, "") == 0) {
62815061Sgarrison 	          res = 1;
62915061Sgarrison 		  fields_found = false;
63015061Sgarrison 	       }
63115061Sgarrison 	    }
63215061Sgarrison 	 } else {
63315061Sgarrison 	    res = 1;
63415061Sgarrison 	    fields_found = false;
63515061Sgarrison 	 }
63615061Sgarrison       }
63715061Sgarrison 
63815061Sgarrison       if (getfield(p, field2, ref2) == 0) {
63915061Sgarrison 	 res = -1;
64015061Sgarrison 	 fields_found = false;
64115061Sgarrison       } else if (strcmp (field2, "") == 0) {	/* field not found */
64215061Sgarrison          if (*p == 'A') {
64315061Sgarrison             getfield("F", field2, ref2);
64415061Sgarrison 	    if (strcmp (field2, "") == 0) {
64515061Sgarrison                getfield("I", field2, ref2);
64615061Sgarrison 	       if (strcmp (field2, "") == 0) {
64715061Sgarrison 	          res = -1;
64815061Sgarrison 		  fields_found = false;
64915061Sgarrison 	       }
65015061Sgarrison 	    }
65115061Sgarrison 	 } else {
65215061Sgarrison 	    res = -1;
65315061Sgarrison 	    fields_found = false;
65415061Sgarrison 	 }
65515061Sgarrison       }
65615061Sgarrison       if (fields_found) {
65715061Sgarrison          if (*p == 'A') {
65815061Sgarrison             if (isupper(field1[0]))
65915061Sgarrison                field1[0] -= 'A' - 'a';
66015061Sgarrison             if (isupper(field2[0]))
66115061Sgarrison                field2[0] -= 'A' - 'a';
66215061Sgarrison             }
66315061Sgarrison          res = strcmp(field1, field2);
66415061Sgarrison          }
66515061Sgarrison       if (neg)
66615061Sgarrison          res = - res;
66715061Sgarrison       if (res != 0)
66815061Sgarrison          break;
66915061Sgarrison       }
67015061Sgarrison    if (res == 0)
67115061Sgarrison       if (ap < bp)
67215061Sgarrison          res = -1;
67315061Sgarrison       else
67415061Sgarrison          res = 1;
67515061Sgarrison    return(res);
67615061Sgarrison }
67715061Sgarrison 
67816244Srrh /* makecites - make standard citation strings, using citetemplate currently in effect */
67915903Srrh    makecites()
68015061Sgarrison {  char ref[REFSIZE], tempcite[100], *malloc();
68115903Srrh    reg int  i;
68215061Sgarrison 
68315903Srrh    for (i = 0; i < numrefs; i++) {
68415903Srrh       rdref(&refinfo[i], ref);
68515061Sgarrison       bldcite(tempcite, i, ref);
68616244Srrh       refinfo[i].ri_cite = malloc(2 + strlen(tempcite));
68715903Srrh       if (refinfo[i].ri_cite == NULL)
68815061Sgarrison          error("out of storage");
68915903Srrh       strcpy(refinfo[i].ri_cite, tempcite);
69015061Sgarrison       }
69115061Sgarrison }
69215061Sgarrison 
69315061Sgarrison /* bldcite - build a single citation string */
69415061Sgarrison    bldcite(cp, i, ref)
69515061Sgarrison    char *cp, ref[];
69615061Sgarrison    int  i;
69715903Srrh {  reg char *p, *q, *fp;
69815903Srrh    char c;
69915903Srrh    char field[REFSIZE];
70015890Srrh    char *getfield(), *aabet(), *aabetlast(), *astro();
70115061Sgarrison 
70215061Sgarrison    getfield("F", field, ref);
70315061Sgarrison    if (field[0] != 0)
70415061Sgarrison       for (p = field; *p; p++)
70515061Sgarrison          *cp++ = *p;
70615061Sgarrison    else {
70715061Sgarrison       p = citetemplate;
70815061Sgarrison       field[0] = 0;
70915061Sgarrison       while (c = *p++) {
71015061Sgarrison          if (isalpha(c)) {                      /* field name   */
71115061Sgarrison             q = getfield(p-1, field, ref);
71215061Sgarrison             if (q != 0) {
71315061Sgarrison                p = q;
71415061Sgarrison                for (fp = field; *fp; )
71515061Sgarrison                   *cp++ = *fp++;
71615061Sgarrison                }
71715061Sgarrison             }
71815061Sgarrison          else if (c == '1') {                   /* numeric  order */
71915061Sgarrison             sprintf(field,"%d",1 + i);
72015061Sgarrison             for (fp = field; *fp; )
72115061Sgarrison                *cp++ = *fp++;
72215061Sgarrison             }
72315061Sgarrison          else if (c == '2')                     /* alternate alphabetic */
72415061Sgarrison             cp = aabet(cp, ref);
72515061Sgarrison          else if (c == '3')                     /* Astrophysical Journal style*/
72615061Sgarrison             cp = astro(cp, ref);
72715890Srrh          else if (c == '9')                     /* Last name of Senior Author*/
72815890Srrh             cp = aabetlast(cp, ref);
729*17246Srrh 	 else if (c == '0') {			/* print nothing */
730*17246Srrh             for (fp = field; *fp; )
731*17246Srrh                *cp++ = *fp++;
732*17246Srrh             }
73315061Sgarrison /*       else if (c == '4')          here is how to add new styles */
73415061Sgarrison          else if (c == '{') {                   /* other information   */
73515061Sgarrison             while (*p != '}')
73615061Sgarrison                if (*p == 0)
73715061Sgarrison                   error("unexpected end of citation template");
73815061Sgarrison                else
73915061Sgarrison                   *cp++ = *p++;
74015061Sgarrison             p++;
74115061Sgarrison             }
74215061Sgarrison          else if (c == '<') {
74315061Sgarrison             while (*p != '>') {
74415061Sgarrison                if (*p == 0)
74515061Sgarrison                   error("unexpected end of citation template");
74615061Sgarrison                else
74715061Sgarrison                   *cp++ = *p++;
74815061Sgarrison                }
74915061Sgarrison             p++;
75015061Sgarrison             }
75115061Sgarrison          else if (c != '@')
75215061Sgarrison             *cp++ = c;
75315061Sgarrison          }
75415061Sgarrison       }
75515061Sgarrison    *cp++ = 0;
75615061Sgarrison }
75715061Sgarrison 
75815061Sgarrison /* alternate alphabetic citation style -
75915061Sgarrison         if 1 author - first three letters of last name
76015061Sgarrison         if 2 authors - first two letters of first, followed by first letter of
76115061Sgarrison                                 seond
76215061Sgarrison         if 3 or more authors - first letter of first three authors */
76315061Sgarrison    char *aabet(cp, ref)
76415061Sgarrison    char *cp, ref[];
76515903Srrh {  char field[REFSIZE], temp[100];
76615903Srrh    reg char *np, *fp;
76715061Sgarrison    int j, getname();
76815061Sgarrison 
76915061Sgarrison    if (getname(1, field, temp, ref)) {
77015061Sgarrison       np = cp;
77115061Sgarrison       fp = field;
77215061Sgarrison       for (j = 1; j <= 3; j++)
77315061Sgarrison          if (*fp != 0)
77415061Sgarrison             *cp++ = *fp++;
77515061Sgarrison       if (getname(2, field, temp, ref))
77615061Sgarrison          np[2] = field[0];
77715061Sgarrison       if (getname(3, field, temp, ref)) {
77815061Sgarrison          np[1] = np[2];
77915061Sgarrison          np[2] = field[0];
78015061Sgarrison          }
78115061Sgarrison       }
78215061Sgarrison return(cp);
78315061Sgarrison }
78415061Sgarrison 
78515890Srrh /* alternate alphabetic citation style -
78615890Srrh 	entire last name of senior author
78715890Srrh */
78815890Srrh    char *aabetlast(cp, ref)
78915890Srrh    char *cp, ref[];
79015890Srrh {  char field[REFSIZE], temp[100];
79115903Srrh    reg char	*fp;
79215890Srrh    int getname();
79315890Srrh 
79415890Srrh    if (getname(1, field, temp, ref)) {
79515890Srrh       for (fp = field; *fp; )
79615890Srrh          *cp++ = *fp++;
79715890Srrh    }
79815890Srrh    return(cp);
79915890Srrh }
80015890Srrh 
80115061Sgarrison /* Astrophysical Journal style
80215061Sgarrison         if 1 author - last name date
80315061Sgarrison         if 2 authors - last name and last name date
80415061Sgarrison         if 3 authors - last name, last name and last name date
80515061Sgarrison         if 4 or more authors - last name et al. date */
80615061Sgarrison    char *astro(cp, ref)
80715061Sgarrison    char *cp, ref[];
80815903Srrh {  char name1[100], name2[100], name3[100], temp[100];
80915903Srrh    reg char *fp;
81015061Sgarrison    int getname();
81115061Sgarrison 
81215061Sgarrison    if (getname(1, name1, temp, ref)) {
81315061Sgarrison       for (fp = name1; *fp; )
81415061Sgarrison          *cp++ = *fp++;
81515061Sgarrison       if (getname(4, name3, temp, ref)) {
81615061Sgarrison          for (fp = " et al."; *fp; )
81715061Sgarrison             *cp++ = *fp++;
81815061Sgarrison          }
81915061Sgarrison       else if (getname(2, name2, temp, ref)) {
82015061Sgarrison          if (getname(3, name3, temp, ref)) {
82115061Sgarrison             for (fp = "\\*(c]"; *fp; )
82215061Sgarrison                *cp++ = *fp++;
82315061Sgarrison             for (fp = name2; *fp; )
82415061Sgarrison                *cp++ = *fp++;
82515061Sgarrison             for (fp = "\\*(m]"; *fp; )
82615061Sgarrison                *cp++ = *fp++;
82715061Sgarrison             for (fp = name3; *fp; )
82815061Sgarrison                *cp++ = *fp++;
82915061Sgarrison             }
83015061Sgarrison          else {
83115061Sgarrison             for (fp = "\\*(n]"; *fp; )
83215061Sgarrison                *cp++ = *fp++;
83315061Sgarrison             for (fp = name2; *fp; )
83415061Sgarrison                *cp++ = *fp++;
83515061Sgarrison             }
83615061Sgarrison          }
83715061Sgarrison     }
83815061Sgarrison return(cp);
83915061Sgarrison }
84015061Sgarrison 
84115061Sgarrison /* getfield - get a single field from reference */
84215061Sgarrison    char *getfield(ptr, field, ref)
84315061Sgarrison    char *ptr, field[], ref[];
84415903Srrh {  reg	char *p, *q;
84515903Srrh    char	temp[100];
84615061Sgarrison    int  n, len, i, getname();
84715061Sgarrison 
84815061Sgarrison    field[0] = 0;
84915061Sgarrison    if (*ptr == 'A')
85015061Sgarrison       getname(1, field, temp, ref);
85115061Sgarrison    else
85215061Sgarrison       for (p = ref; *p; p++)
85315061Sgarrison          if (*p == '%' && *(p+1) == *ptr) {
85415061Sgarrison             for (p = p + 2; *p == ' '; p++)
85515061Sgarrison                ;
85615061Sgarrison             for (q = field; (*p != '\n') && (*p != '\0'); )
85715061Sgarrison                *q++ = *p++;
85815061Sgarrison             *q = 0;
85915061Sgarrison             break;
86015061Sgarrison             }
86115061Sgarrison    n = 0;
86215061Sgarrison    len = strlen(field);
86315061Sgarrison    if (*++ptr == '-') {
86415061Sgarrison       for (ptr++; isdigit(*ptr); ptr++)
86515061Sgarrison          n = 10 * n + (*ptr - '0');
86615061Sgarrison       if (n > len)
86715061Sgarrison          n = 0;
86815061Sgarrison       else
86915061Sgarrison          n = len - n;
87015061Sgarrison       for (i = 0; field[i] = field[i+n]; i++)
87115061Sgarrison          ;
87215061Sgarrison       }
87315061Sgarrison    else if (isdigit(*ptr)) {
87415061Sgarrison       for (; isdigit(*ptr); ptr++)
87515061Sgarrison          n = 10 * n + (*ptr - '0');
87615061Sgarrison       if (n > len)
87715061Sgarrison          n = len;
87815061Sgarrison       field[n] = 0;
87915061Sgarrison       }
88015061Sgarrison 
88115061Sgarrison    if (*ptr == 'u') {
88215061Sgarrison       ptr++;
88315061Sgarrison       for (p = field; *p; p++)
88415061Sgarrison          if (islower(*p))
88515061Sgarrison             *p = (*p - 'a') + 'A';
88615061Sgarrison       }
88715061Sgarrison    else if (*ptr == 'l') {
88815061Sgarrison       ptr++;
88915061Sgarrison       for (p = field; *p; p++)
89015061Sgarrison          if (isupper(*p))
89115061Sgarrison             *p = (*p - 'A') + 'a';
89215061Sgarrison       }
89315061Sgarrison    return(ptr);
89415061Sgarrison }
89515061Sgarrison 
89615061Sgarrison /* getname - get the nth name field from reference, breaking into
89715061Sgarrison              first and last names */
89815061Sgarrison    int getname(n, last, first, ref)
89915061Sgarrison    int  n;
90015061Sgarrison    char last[], first[], ref[];
90115903Srrh {  reg char *p;
90215061Sgarrison    int  m;
90315061Sgarrison 
90415061Sgarrison    m = n;
90515061Sgarrison    for (p = ref; *p; p++)
90615061Sgarrison       if (*p == '%' & *(p+1) == 'A') {
90715061Sgarrison          n--;
90815061Sgarrison          if (n == 0) {
90915061Sgarrison             for (p = p + 2; *p == ' '; p++) ;
91015061Sgarrison             breakname(p, first, last) ;
91115061Sgarrison             return(true);
91215061Sgarrison             }
91315061Sgarrison          }
91415061Sgarrison 
91515061Sgarrison    if (n == m)          /* no authors, try editors */
91615061Sgarrison       for (p = ref; *p; p++)
91715061Sgarrison          if (*p == '%' & *(p+1) == 'E') {
91815061Sgarrison             n--;
91915061Sgarrison             if (n == 0) {
92015061Sgarrison                for (p = p + 2; *p == ' '; p++) ;
92115061Sgarrison                breakname(p, first, last) ;
92215061Sgarrison                return(true);
92315061Sgarrison                }
92415061Sgarrison             }
92515061Sgarrison 
92615061Sgarrison    if (n == m) {        /* no editors, either, try institution */
92715061Sgarrison       first[0] = last[0] = '\0';
92815061Sgarrison       getfield("I", last, ref);
92915061Sgarrison       if (last[0] != '\0')
93015061Sgarrison          return(true);
93115061Sgarrison       }
93215061Sgarrison 
93315061Sgarrison    return(false);
93415061Sgarrison }
93515061Sgarrison 
93615061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
93715061Sgarrison                   single character disambiguators */
93815061Sgarrison    disambiguate()
93915903Srrh {  reg int i, j;
94016244Srrh 	char adstr;
94115061Sgarrison 
94215061Sgarrison    for (i = 0; i < numrefs; i = j) {
94315061Sgarrison       j = i + 1;
94415903Srrh       if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) {
94516244Srrh          adstr = 'a';
94615903Srrh          for(j = i+1; strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0; j++) {
94716244Srrh             adstr = 'a' + (j-i);
94815061Sgarrison             if (j == numrefs)
94915061Sgarrison                break;
95016244Srrh 	    refinfo[j].ri_disambig[0] = adstr;
95115061Sgarrison             }
95216244Srrh 	 refinfo[i].ri_disambig[0] = 'a';
95315061Sgarrison          }
95415061Sgarrison      }
95516244Srrh   for (i = 0; i < numrefs; i++){
95616244Srrh 	strcat(refinfo[i].ri_cite, refinfo[i].ri_disambig);
95716244Srrh   }
95815061Sgarrison }
95915061Sgarrison 
96015061Sgarrison 
96112910Sgarrison /* bldname - build a name field
96212910Sgarrison              doing abbreviations, reversals, and caps/small caps
96312910Sgarrison */
96412910Sgarrison    bldname(first, last, name, reverse)
96512910Sgarrison    char *first, *last, name[];
96612910Sgarrison    int reverse;
96712910Sgarrison {
96815903Srrh    char newfirst[120], newlast[120];
96915903Srrh    reg char *p, *q, *f, *l;
97015903Srrh    char *scopy();
97112910Sgarrison    int  flag;
97212910Sgarrison 
97312910Sgarrison    if (abbrev) {
97412910Sgarrison       p = first;
97512910Sgarrison       q = newfirst;
97612910Sgarrison       flag = false;
97712910Sgarrison       while (*p) {
97812910Sgarrison          while (*p == ' ')
97912910Sgarrison             p++;
98012910Sgarrison          if (*p == 0)
98112910Sgarrison             break;
98212910Sgarrison          if (isupper(*p)) {
98315061Sgarrison             if (flag)           /* between initial gap */
98412910Sgarrison                q = scopy(q, "\\*(a]");
98512910Sgarrison             flag = true;
98612910Sgarrison             *q++ = *p;
98715061Sgarrison             q = scopy(q, "\\*(p]");
98812910Sgarrison             }
98912910Sgarrison          if (*++p == '.')
99012910Sgarrison             p++;
99112910Sgarrison          else while (*p != 0 && ! isspace(*p))
99212910Sgarrison             p++;
99312910Sgarrison          }
99412910Sgarrison       *q = 0;
99512910Sgarrison       f = newfirst;
99612910Sgarrison       }
99712910Sgarrison    else
99812910Sgarrison       f = first;
99912910Sgarrison 
100012910Sgarrison    if (capsmcap) {
100112910Sgarrison       p = last;
100212910Sgarrison       q = newlast;
100312910Sgarrison       flag = 0;  /* 1 - printing cap, 2 - printing small */
100412910Sgarrison       while (*p)
100512910Sgarrison          if (islower(*p)) {
100612910Sgarrison             if (flag != 2)
100712910Sgarrison                q = scopy(q, "\\s-2");
100812910Sgarrison             flag = 2;
100912910Sgarrison             *q++ = (*p++ - 'a') + 'A';
101012910Sgarrison             }
101112910Sgarrison          else {
101212910Sgarrison             if (flag == 2)
101312910Sgarrison                q = scopy(q,"\\s+2");
101412910Sgarrison             flag = 1;
101512910Sgarrison             *q++ = *p++;
101612910Sgarrison             }
101712910Sgarrison       if (flag == 2)
101812910Sgarrison          q = scopy(q, "\\s+2");
101912910Sgarrison       *q = 0;
102012910Sgarrison       l = newlast;
102112910Sgarrison       }
102212910Sgarrison    else
102312910Sgarrison       l = last;
102412910Sgarrison 
102515061Sgarrison    if (f[0] == 0)
102615061Sgarrison       sprintf(name, "%s\n", l);
102715061Sgarrison    else if (reverse)
102815061Sgarrison       sprintf(name, "%s\\*(b]%s\n", l, f);
102912910Sgarrison    else
103012910Sgarrison       sprintf(name, "%s %s\n", f, l);
103112910Sgarrison }
103212910Sgarrison 
103312910Sgarrison /* prtauth - print author or editor field */
103412910Sgarrison    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
103512910Sgarrison    char c, *line;
103612910Sgarrison    int  num, max, abbrev, capsmcap, numrev;
103712910Sgarrison    FILE *ofd;
103812910Sgarrison {  char first[LINELENGTH], last[LINELENGTH];
103912910Sgarrison 
104012910Sgarrison    if (num <= numrev || abbrev || capsmcap) {
104112910Sgarrison       breakname(line, first, last);
104212910Sgarrison       bldname(first, last, line, num <= numrev);
104312910Sgarrison       }
104412910Sgarrison    if (num == 1)
104512910Sgarrison       fprintf(ofd,".ds [%c %s", c, line);
104612910Sgarrison    else if (num < max)
104712910Sgarrison       fprintf(ofd,".as [%c \\*(c]%s", c, line);
104812910Sgarrison    else if (max == 2)
104912910Sgarrison       fprintf(ofd,".as [%c \\*(n]%s", c, line);
105012910Sgarrison    else
105112910Sgarrison       fprintf(ofd,".as [%c \\*(m]%s", c, line);
105212910Sgarrison    if (num == max && index(trailstr, c))
105312910Sgarrison       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
105412910Sgarrison }
105512910Sgarrison 
105612910Sgarrison /* doline - actually print out a line of reference information */
105712910Sgarrison    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
105812910Sgarrison    char c, *line;
105912910Sgarrison    int numauths, maxauths, numeds, maxeds;
106012910Sgarrison    FILE *ofd;
106112910Sgarrison {
106212910Sgarrison 
106312910Sgarrison    switch(c) {
106412910Sgarrison       case 'A':
106512910Sgarrison           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
106612910Sgarrison           break;
106712910Sgarrison 
106812910Sgarrison        case 'E':
106912910Sgarrison           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
107012910Sgarrison           if (numeds == maxeds)
107112910Sgarrison              fprintf(ofd,".nr [E %d\n", maxeds);
107212910Sgarrison           break;
107312910Sgarrison 
107412910Sgarrison        case 'P':
107512910Sgarrison           if (index(line, '-'))
107612910Sgarrison              fprintf(ofd,".nr [P 1\n");
107712910Sgarrison           else
107812910Sgarrison              fprintf(ofd,".nr [P 0\n");
107912910Sgarrison           fprintf(ofd,".ds [P %s",line);
108012910Sgarrison           if (index(trailstr, 'P'))
108112910Sgarrison              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
108212910Sgarrison           break;
108312910Sgarrison 
108412910Sgarrison        case 'F':
108512910Sgarrison        case 'K': break;
108612910Sgarrison 
108712910Sgarrison        default:
108812910Sgarrison           fprintf(ofd,".ds [%c %s", c, line);
108912910Sgarrison           if (index(trailstr, c))
109012910Sgarrison              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
109112910Sgarrison           }
109212910Sgarrison }
109312910Sgarrison 
109415061Sgarrison /* dumpref - dump reference number i */
109515061Sgarrison    dumpref(i, ofd)
109615061Sgarrison    int i;
109715061Sgarrison    FILE *ofd;
109815903Srrh {  char ref[REFSIZE], line[REFSIZE];
109915903Srrh    reg char *p, *q;
110015903Srrh    char *from;
110115061Sgarrison    int numauths, maxauths, numeds, maxeds;
110215061Sgarrison 
110315903Srrh    rdref(&refinfo[i], ref);
110415061Sgarrison    maxauths = maxeds = 0;
110515061Sgarrison    numauths = numeds = 0;
110615061Sgarrison    for (p = ref; *p; p++)
110715061Sgarrison       if (*p == '%')
110815061Sgarrison          if (*(p+1) == 'A') maxauths++;
110915061Sgarrison          else if (*(p+1) == 'E') maxeds++;
111015061Sgarrison    fprintf(ofd, ".[-\n");
111115903Srrh    fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite);
111215903Srrh #ifndef INCORE
111315903Srrh    fseek(rfd, (long)refinfo[i].ri_pos, 0);
111415061Sgarrison    while (fgets(line, REFSIZE, rfd) != NULL) {
111515903Srrh #else INCORE
111615903Srrh    for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */
111715903Srrh 	if (*from == '\n'){
111815903Srrh 		*q++ = '\n';
111915903Srrh 		*q = 0;
112015903Srrh 		q = line;
112115903Srrh 		from++;
112215903Srrh 	} else {
112315903Srrh 		*q++ = *from++;
112415903Srrh 		continue;
112515903Srrh 	}
112615903Srrh #endif INCORE
112715903Srrh 	switch(line[0]){
112815903Srrh 	case 0:
112915903Srrh 		goto doneref;
113015903Srrh 	case '.':
113115903Srrh 		fprintf(ofd, "%s", line);
113215903Srrh 		break;
113315903Srrh 	case '%':
113415903Srrh 		switch(line[1]){
113515903Srrh 		case 'A':	numauths++;	break;
113615903Srrh 		case 'E':	numeds++;	break;
113715903Srrh 		}
113815903Srrh 		for (p = &line[2]; *p == ' '; p++) /*VOID*/;
113915903Srrh 		doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
114015903Srrh 	}
114115903Srrh    }
114215903Srrh    doneref:;
114315061Sgarrison    fprintf(ofd,".][\n");
114415061Sgarrison }
1145