xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 15903)
113110Srrh #ifndef lint
2*15903Srrh static char sccsid[] = "@(#)bibargs.c	2.4	01/29/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                         */
43*15903Srrh    struct wordinfo words[MAXDEFS];     /* defined words */
44*15903Srrh    struct wordinfo *wordhash[HASHSIZE];
45*15903Srrh    struct wordinfo *wordsearch();
46*15903Srrh    int  wordtop = 0;           /* number of defined words         */
4712910Sgarrison 
4812910Sgarrison /* where output goes */
4912910Sgarrison    extern FILE *tfd;
5015061Sgarrison /* reference file information */
51*15903Srrh    extern struct refinfo refinfo[];
5215061Sgarrison    extern char reffile[];
53*15903Srrh #ifndef INCORE
5415061Sgarrison    extern FILE *rfd;
55*15903Srrh #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;
72*15903Srrh    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)
96*15903Srrh                           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);
186*15903Srrh                        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) {
196*15903Srrh             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();
21615061Sgarrison    int  i, j, 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");
266*15903Srrh 		   if (wordsearch(word))
267*15903Srrh 			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                        }
274*15903Srrh 		   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 */
336*15903Srrh   /*VARARGS1*/
337*15903Srrh   bibwarning(msg, a1, a2)
338*15903Srrh   char *msg;
33915061Sgarrison {
34015061Sgarrison   fprintf(stderr,"`%s', line %d: ", bibfname, biblineno);
341*15903Srrh   fprintf(stderr, msg, a1, a2);
34215061Sgarrison }
34315061Sgarrison 
34415061Sgarrison /* error - report unrecoverable error message */
345*15903Srrh   /*VARARGS1*/
346*15903Srrh   error(str, a1, a2)
347*15903Srrh   char *str;
34815061Sgarrison {
349*15903Srrh   bibwarning(str, a1, a2);
350*15903Srrh   /*
351*15903Srrh    *	clean up temp files and exit
352*15903Srrh    */
353*15903Srrh   cleanup(1);
35415061Sgarrison }
35515061Sgarrison 
356*15903Srrh #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)
373*15903Srrh 		      error("Hell!  Couldn't re-open reference file %s",
374*15903Srrh 			reffile);
37515061Sgarrison 	}
37615061Sgarrison }
37715061Sgarrison #endif
378*15903Srrh #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;
386*15903Srrh {  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)
400*15903Srrh    reg char in[], out[];
401*15903Srrh    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;
437*15903Srrh {  char line2[REFSIZE], word[LINELENGTH];
438*15903Srrh    reg	struct wordinfo *wp;
439*15903Srrh    reg	char *p, *q, *w;
440*15903Srrh    reg	int i;
44112910Sgarrison 
442*15903Srrh 	q = line2;
443*15903Srrh 	for (p = line; *p; /*VOID*/){
444*15903Srrh 		if (isalnum(*p)) {
445*15903Srrh 			for (w = word; *p && iswordc(*p); ) *w++ = *p++;
446*15903Srrh 			*w = 0;
447*15903Srrh 			if (wp = wordsearch(word)){
448*15903Srrh 				strcpy(word, wp->wi_def);
449*15903Srrh 				expand(word);
450*15903Srrh 			}
451*15903Srrh 			strcpy(q, word);
452*15903Srrh 			q += strlen(q);
453*15903Srrh 		} else {
454*15903Srrh 			*q++ = *p++;
455*15903Srrh 		}
456*15903Srrh 	}
457*15903Srrh 	*q = 0;
458*15903Srrh 	strcpy(line, line2);
45912910Sgarrison }
46012910Sgarrison 
461*15903Srrh /* wordstuff- save a word and its definition, building a hash table */
462*15903Srrh    wordstuff(word, def)
463*15903Srrh    char *word, *def;
464*15903Srrh {
465*15903Srrh    int i;
466*15903Srrh    if (wordtop >= MAXDEFS)
467*15903Srrh 	error("too many definitions, max of %d", MAXDEFS);
468*15903Srrh    words[wordtop].wi_length = strlen(word);
469*15903Srrh    words[wordtop].wi_word = word ? walloc(word) : 0;
470*15903Srrh    words[wordtop].wi_def = def ? walloc(def) : 0;
471*15903Srrh    i = strhash(word);
472*15903Srrh    words[wordtop].wi_hp = wordhash[i];
473*15903Srrh    wordhash[i] = &words[wordtop];
474*15903Srrh    wordtop++;
475*15903Srrh }
476*15903Srrh    struct wordinfo *wordsearch(word)
477*15903Srrh    char *word;
478*15903Srrh {
479*15903Srrh    reg int i;
480*15903Srrh    reg int lg;
481*15903Srrh    reg struct wordinfo *wp;
482*15903Srrh    lg = strlen(word);
483*15903Srrh    for (wp = wordhash[strhash(word)]; wp; wp = wp->wi_hp){
484*15903Srrh 	if (wp->wi_length == lg && (strcmp(wp->wi_word, word) == 0)){
485*15903Srrh 		return(wp);
486*15903Srrh 	}
487*15903Srrh    }
488*15903Srrh    return(0);
489*15903Srrh }
490*15903Srrh 
491*15903Srrh    int strhash(str)
492*15903Srrh    reg char *str;
493*15903Srrh {
494*15903Srrh    reg int value = 0;
495*15903Srrh    for (value = 0; *str; value <<= 2, value += *str++)/*VOID*/;
496*15903Srrh    value %= HASHSIZE;
497*15903Srrh    if (value < 0)
498*15903Srrh 	value += HASHSIZE;
499*15903Srrh    return(value);
500*15903Srrh }
501*15903Srrh 
50215061Sgarrison /* rdref - read text for an already cited reference */
503*15903Srrh    rdref(p, ref)
504*15903Srrh    struct refinfo *p;
50515061Sgarrison    char ref[REFSIZE];
50615061Sgarrison {
50715061Sgarrison    ref[0] = 0;
508*15903Srrh #ifndef INCORE
50915061Sgarrison #ifdef READWRITE
51015061Sgarrison    fixrfd( READ );                      /* fix access mode of rfd, if nec. */
51115061Sgarrison #endif
512*15903Srrh    fseek(rfd, p->ri_pos, 0);
513*15903Srrh    fread(ref, p->ri_length, 1, rfd);
514*15903Srrh #else INCORE
515*15903Srrh    strcpy(ref, p->ri_ref);
516*15903Srrh #endif INCORE
51715061Sgarrison }
51815061Sgarrison 
519*15903Srrh /* wrref - write text for a new reference */
520*15903Srrh    wrref(p, ref)
521*15903Srrh    struct refinfo *p;
522*15903Srrh    char ref[REFSIZE];
523*15903Srrh {
524*15903Srrh #ifndef INCORE
525*15903Srrh #ifdef READWRITE
526*15903Srrh     fixrfd( WRITE );                 /* fix access mode of rfd, if nec. */
527*15903Srrh #else
528*15903Srrh     fseek(rfd, p->ri_pos, 0);        /* go to end of rfd */
529*15903Srrh #endif
530*15903Srrh     fwrite(ref, p->ri_length, 1, rfd);
531*15903Srrh #else INCORE
532*15903Srrh    p->ri_ref = walloc(ref);
533*15903Srrh #endif INCORE
534*15903Srrh }
535*15903Srrh 
53612910Sgarrison /* breakname - break a name into first and last name */
53712910Sgarrison    breakname(line, first, last)
53812910Sgarrison    char line[], first[], last[];
539*15903Srrh {  reg char *t, *f, *q, *r, *p;
54012910Sgarrison 
54112910Sgarrison    for (t = line; *t != '\n'; t++);
54212910Sgarrison    for (t--; isspace(*t); t--);
54312910Sgarrison 
54412910Sgarrison    /* now strip off last name */
54512910Sgarrison    for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
54612910Sgarrison       if (q == line)
54712910Sgarrison          break;
54812910Sgarrison    f = q;
54915061Sgarrison    if (q != line) {
55012910Sgarrison       q++;
55115061Sgarrison       for (; isspace(*f); f--);
55215061Sgarrison       f++;
55315061Sgarrison       }
55412910Sgarrison 
55512910Sgarrison    /* first name is start to f, last name is q to t */
55612910Sgarrison 
55715061Sgarrison    for (r = first, p = line; p != f; )
55812910Sgarrison       *r++ = *p++;
55912910Sgarrison    *r = 0;
56012910Sgarrison    for (r = last, p = q, t++; q != t; )
56112910Sgarrison       *r++ = *q++;
56212910Sgarrison    *r = 0;
56315061Sgarrison 
56412910Sgarrison }
56512910Sgarrison 
56612910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
56712910Sgarrison    int match(str1, str2)
568*15903Srrh    reg char str1[], str2[];
569*15903Srrh {  reg int  j, i;
57012910Sgarrison    char a, b;
57112910Sgarrison 
57212910Sgarrison    for (i = 0; str2[i]; i++) {
57312910Sgarrison       for (j = 0; str1[j]; j++) {
57412910Sgarrison          if (isupper(a = str2[i+j]))
57512910Sgarrison             a = (a - 'A') + 'a';
57612910Sgarrison          if (isupper(b = str1[j]))
57712910Sgarrison             b = (b - 'A') + 'a';
57812910Sgarrison          if (a != b)
57912910Sgarrison             break;
58012910Sgarrison          }
58112910Sgarrison       if (str1[j] == 0)
58212910Sgarrison          return(true);
58312910Sgarrison       }
58412910Sgarrison    return(false);
58512910Sgarrison }
58612910Sgarrison 
58712910Sgarrison /* scopy - append a copy of one string to another */
58812910Sgarrison    char *scopy(p, q)
589*15903Srrh    reg char *p, *q;
59012910Sgarrison {
59112910Sgarrison    while (*p++ = *q++)
59212910Sgarrison       ;
59312910Sgarrison    return(--p);
59412910Sgarrison }
59512910Sgarrison 
59615061Sgarrison /* rcomp - reference comparison routine for qsort utility */
59715061Sgarrison    int rcomp(ap, bp)
598*15903Srrh    struct refinfo *ap, *bp;
59915061Sgarrison {  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
600*15903Srrh    reg	char *p, *q;
601*15903Srrh    char *getfield();
60215061Sgarrison    int  neg, res;
60315061Sgarrison    int  fields_found;
60415061Sgarrison 
605*15903Srrh    rdref(ap, ref1);
606*15903Srrh    rdref(bp, ref2);
60715061Sgarrison    for (p = sortstr; *p; p = q) {
60815061Sgarrison       if (*p == '-') {
60915061Sgarrison          p++;
61015061Sgarrison          neg = true;
61115061Sgarrison          }
61215061Sgarrison       else
61315061Sgarrison          neg = false;
61415061Sgarrison       q = getfield(p, field1, ref1);
61515061Sgarrison       fields_found = true;
61615061Sgarrison       if (q == 0) {
61715061Sgarrison 	 res = 1;
61815061Sgarrison 	 fields_found = false;
61915061Sgarrison       } else if (strcmp (field1, "") == 0) {	/* field not found */
62015061Sgarrison          if (*p == 'A') {
62115061Sgarrison             getfield("F", field1, ref1);
62215061Sgarrison 	    if (strcmp (field1, "") == 0) {
62315061Sgarrison                getfield("I", field1, ref1);
62415061Sgarrison 	       if (strcmp (field1, "") == 0) {
62515061Sgarrison 	          res = 1;
62615061Sgarrison 		  fields_found = false;
62715061Sgarrison 	       }
62815061Sgarrison 	    }
62915061Sgarrison 	 } else {
63015061Sgarrison 	    res = 1;
63115061Sgarrison 	    fields_found = false;
63215061Sgarrison 	 }
63315061Sgarrison       }
63415061Sgarrison 
63515061Sgarrison       if (getfield(p, field2, ref2) == 0) {
63615061Sgarrison 	 res = -1;
63715061Sgarrison 	 fields_found = false;
63815061Sgarrison       } else if (strcmp (field2, "") == 0) {	/* field not found */
63915061Sgarrison          if (*p == 'A') {
64015061Sgarrison             getfield("F", field2, ref2);
64115061Sgarrison 	    if (strcmp (field2, "") == 0) {
64215061Sgarrison                getfield("I", field2, ref2);
64315061Sgarrison 	       if (strcmp (field2, "") == 0) {
64415061Sgarrison 	          res = -1;
64515061Sgarrison 		  fields_found = false;
64615061Sgarrison 	       }
64715061Sgarrison 	    }
64815061Sgarrison 	 } else {
64915061Sgarrison 	    res = -1;
65015061Sgarrison 	    fields_found = false;
65115061Sgarrison 	 }
65215061Sgarrison       }
65315061Sgarrison       if (fields_found) {
65415061Sgarrison          if (*p == 'A') {
65515061Sgarrison             if (isupper(field1[0]))
65615061Sgarrison                field1[0] -= 'A' - 'a';
65715061Sgarrison             if (isupper(field2[0]))
65815061Sgarrison                field2[0] -= 'A' - 'a';
65915061Sgarrison             }
66015061Sgarrison          res = strcmp(field1, field2);
66115061Sgarrison          }
66215061Sgarrison       if (neg)
66315061Sgarrison          res = - res;
66415061Sgarrison       if (res != 0)
66515061Sgarrison          break;
66615061Sgarrison       }
66715061Sgarrison    if (res == 0)
66815061Sgarrison       if (ap < bp)
66915061Sgarrison          res = -1;
67015061Sgarrison       else
67115061Sgarrison          res = 1;
67215061Sgarrison    return(res);
67315061Sgarrison }
67415061Sgarrison 
67515061Sgarrison /* makecites - make citation strings */
676*15903Srrh    makecites()
67715061Sgarrison {  char ref[REFSIZE], tempcite[100], *malloc();
678*15903Srrh    reg int  i;
67915061Sgarrison 
680*15903Srrh    for (i = 0; i < numrefs; i++) {
681*15903Srrh       rdref(&refinfo[i], ref);
68215061Sgarrison       bldcite(tempcite, i, ref);
683*15903Srrh       refinfo[i].ri_cite = malloc(2 + strlen(tempcite)); /* leave room for disambig */
684*15903Srrh       if (refinfo[i].ri_cite == NULL)
68515061Sgarrison          error("out of storage");
686*15903Srrh       strcpy(refinfo[i].ri_cite, tempcite);
68715061Sgarrison       }
68815061Sgarrison }
68915061Sgarrison 
69015061Sgarrison /* bldcite - build a single citation string */
69115061Sgarrison    bldcite(cp, i, ref)
69215061Sgarrison    char *cp, ref[];
69315061Sgarrison    int  i;
694*15903Srrh {  reg char *p, *q, *fp;
695*15903Srrh    char c;
696*15903Srrh    char field[REFSIZE];
69715890Srrh    char *getfield(), *aabet(), *aabetlast(), *astro();
69815061Sgarrison 
69915061Sgarrison    getfield("F", field, ref);
70015061Sgarrison    if (field[0] != 0)
70115061Sgarrison       for (p = field; *p; p++)
70215061Sgarrison          *cp++ = *p;
70315061Sgarrison    else {
70415061Sgarrison       p = citetemplate;
70515061Sgarrison       field[0] = 0;
70615061Sgarrison       while (c = *p++) {
70715061Sgarrison          if (isalpha(c)) {                      /* field name   */
70815061Sgarrison             q = getfield(p-1, field, ref);
70915061Sgarrison             if (q != 0) {
71015061Sgarrison                p = q;
71115061Sgarrison                for (fp = field; *fp; )
71215061Sgarrison                   *cp++ = *fp++;
71315061Sgarrison                }
71415061Sgarrison             }
71515061Sgarrison          else if (c == '1') {                   /* numeric  order */
71615061Sgarrison             sprintf(field,"%d",1 + i);
71715061Sgarrison             for (fp = field; *fp; )
71815061Sgarrison                *cp++ = *fp++;
71915061Sgarrison             }
72015061Sgarrison          else if (c == '2')                     /* alternate alphabetic */
72115061Sgarrison             cp = aabet(cp, ref);
72215061Sgarrison          else if (c == '3')                     /* Astrophysical Journal style*/
72315061Sgarrison             cp = astro(cp, ref);
72415890Srrh          else if (c == '9')                     /* Last name of Senior Author*/
72515890Srrh             cp = aabetlast(cp, ref);
72615061Sgarrison /*       else if (c == '4')          here is how to add new styles */
72715061Sgarrison          else if (c == '{') {                   /* other information   */
72815061Sgarrison             while (*p != '}')
72915061Sgarrison                if (*p == 0)
73015061Sgarrison                   error("unexpected end of citation template");
73115061Sgarrison                else
73215061Sgarrison                   *cp++ = *p++;
73315061Sgarrison             p++;
73415061Sgarrison             }
73515061Sgarrison          else if (c == '<') {
73615061Sgarrison             while (*p != '>') {
73715061Sgarrison                if (*p == 0)
73815061Sgarrison                   error("unexpected end of citation template");
73915061Sgarrison                else
74015061Sgarrison                   *cp++ = *p++;
74115061Sgarrison                }
74215061Sgarrison             p++;
74315061Sgarrison             }
74415061Sgarrison          else if (c != '@')
74515061Sgarrison             *cp++ = c;
74615061Sgarrison          }
74715061Sgarrison       }
74815061Sgarrison    *cp++ = 0;
74915061Sgarrison }
75015061Sgarrison 
75115061Sgarrison /* alternate alphabetic citation style -
75215061Sgarrison         if 1 author - first three letters of last name
75315061Sgarrison         if 2 authors - first two letters of first, followed by first letter of
75415061Sgarrison                                 seond
75515061Sgarrison         if 3 or more authors - first letter of first three authors */
75615061Sgarrison    char *aabet(cp, ref)
75715061Sgarrison    char *cp, ref[];
758*15903Srrh {  char field[REFSIZE], temp[100];
759*15903Srrh    reg char *np, *fp;
76015061Sgarrison    int j, getname();
76115061Sgarrison 
76215061Sgarrison    if (getname(1, field, temp, ref)) {
76315061Sgarrison       np = cp;
76415061Sgarrison       fp = field;
76515061Sgarrison       for (j = 1; j <= 3; j++)
76615061Sgarrison          if (*fp != 0)
76715061Sgarrison             *cp++ = *fp++;
76815061Sgarrison       if (getname(2, field, temp, ref))
76915061Sgarrison          np[2] = field[0];
77015061Sgarrison       if (getname(3, field, temp, ref)) {
77115061Sgarrison          np[1] = np[2];
77215061Sgarrison          np[2] = field[0];
77315061Sgarrison          }
77415061Sgarrison       }
77515061Sgarrison return(cp);
77615061Sgarrison }
77715061Sgarrison 
77815890Srrh /* alternate alphabetic citation style -
77915890Srrh 	entire last name of senior author
78015890Srrh */
78115890Srrh    char *aabetlast(cp, ref)
78215890Srrh    char *cp, ref[];
78315890Srrh {  char field[REFSIZE], temp[100];
784*15903Srrh    reg char	*fp;
78515890Srrh    int getname();
78615890Srrh 
78715890Srrh    if (getname(1, field, temp, ref)) {
78815890Srrh       for (fp = field; *fp; )
78915890Srrh          *cp++ = *fp++;
79015890Srrh    }
79115890Srrh    return(cp);
79215890Srrh }
79315890Srrh 
79415061Sgarrison /* Astrophysical Journal style
79515061Sgarrison         if 1 author - last name date
79615061Sgarrison         if 2 authors - last name and last name date
79715061Sgarrison         if 3 authors - last name, last name and last name date
79815061Sgarrison         if 4 or more authors - last name et al. date */
79915061Sgarrison    char *astro(cp, ref)
80015061Sgarrison    char *cp, ref[];
801*15903Srrh {  char name1[100], name2[100], name3[100], temp[100];
802*15903Srrh    reg char *fp;
80315061Sgarrison    int getname();
80415061Sgarrison 
80515061Sgarrison    if (getname(1, name1, temp, ref)) {
80615061Sgarrison       for (fp = name1; *fp; )
80715061Sgarrison          *cp++ = *fp++;
80815061Sgarrison       if (getname(4, name3, temp, ref)) {
80915061Sgarrison          for (fp = " et al."; *fp; )
81015061Sgarrison             *cp++ = *fp++;
81115061Sgarrison          }
81215061Sgarrison       else if (getname(2, name2, temp, ref)) {
81315061Sgarrison          if (getname(3, name3, temp, ref)) {
81415061Sgarrison             for (fp = "\\*(c]"; *fp; )
81515061Sgarrison                *cp++ = *fp++;
81615061Sgarrison             for (fp = name2; *fp; )
81715061Sgarrison                *cp++ = *fp++;
81815061Sgarrison             for (fp = "\\*(m]"; *fp; )
81915061Sgarrison                *cp++ = *fp++;
82015061Sgarrison             for (fp = name3; *fp; )
82115061Sgarrison                *cp++ = *fp++;
82215061Sgarrison             }
82315061Sgarrison          else {
82415061Sgarrison             for (fp = "\\*(n]"; *fp; )
82515061Sgarrison                *cp++ = *fp++;
82615061Sgarrison             for (fp = name2; *fp; )
82715061Sgarrison                *cp++ = *fp++;
82815061Sgarrison             }
82915061Sgarrison          }
83015061Sgarrison     }
83115061Sgarrison return(cp);
83215061Sgarrison }
83315061Sgarrison 
83415061Sgarrison /* getfield - get a single field from reference */
83515061Sgarrison    char *getfield(ptr, field, ref)
83615061Sgarrison    char *ptr, field[], ref[];
837*15903Srrh {  reg	char *p, *q;
838*15903Srrh    char	temp[100];
83915061Sgarrison    int  n, len, i, getname();
84015061Sgarrison 
84115061Sgarrison    field[0] = 0;
84215061Sgarrison    if (*ptr == 'A')
84315061Sgarrison       getname(1, field, temp, ref);
84415061Sgarrison    else
84515061Sgarrison       for (p = ref; *p; p++)
84615061Sgarrison          if (*p == '%' && *(p+1) == *ptr) {
84715061Sgarrison             for (p = p + 2; *p == ' '; p++)
84815061Sgarrison                ;
84915061Sgarrison             for (q = field; (*p != '\n') && (*p != '\0'); )
85015061Sgarrison                *q++ = *p++;
85115061Sgarrison             *q = 0;
85215061Sgarrison             break;
85315061Sgarrison             }
85415061Sgarrison    n = 0;
85515061Sgarrison    len = strlen(field);
85615061Sgarrison    if (*++ptr == '-') {
85715061Sgarrison       for (ptr++; isdigit(*ptr); ptr++)
85815061Sgarrison          n = 10 * n + (*ptr - '0');
85915061Sgarrison       if (n > len)
86015061Sgarrison          n = 0;
86115061Sgarrison       else
86215061Sgarrison          n = len - n;
86315061Sgarrison       for (i = 0; field[i] = field[i+n]; i++)
86415061Sgarrison          ;
86515061Sgarrison       }
86615061Sgarrison    else if (isdigit(*ptr)) {
86715061Sgarrison       for (; isdigit(*ptr); ptr++)
86815061Sgarrison          n = 10 * n + (*ptr - '0');
86915061Sgarrison       if (n > len)
87015061Sgarrison          n = len;
87115061Sgarrison       field[n] = 0;
87215061Sgarrison       }
87315061Sgarrison 
87415061Sgarrison    if (*ptr == 'u') {
87515061Sgarrison       ptr++;
87615061Sgarrison       for (p = field; *p; p++)
87715061Sgarrison          if (islower(*p))
87815061Sgarrison             *p = (*p - 'a') + 'A';
87915061Sgarrison       }
88015061Sgarrison    else if (*ptr == 'l') {
88115061Sgarrison       ptr++;
88215061Sgarrison       for (p = field; *p; p++)
88315061Sgarrison          if (isupper(*p))
88415061Sgarrison             *p = (*p - 'A') + 'a';
88515061Sgarrison       }
88615061Sgarrison    return(ptr);
88715061Sgarrison }
88815061Sgarrison 
88915061Sgarrison /* getname - get the nth name field from reference, breaking into
89015061Sgarrison              first and last names */
89115061Sgarrison    int getname(n, last, first, ref)
89215061Sgarrison    int  n;
89315061Sgarrison    char last[], first[], ref[];
894*15903Srrh {  reg char *p;
89515061Sgarrison    int  m;
89615061Sgarrison 
89715061Sgarrison    m = n;
89815061Sgarrison    for (p = ref; *p; p++)
89915061Sgarrison       if (*p == '%' & *(p+1) == 'A') {
90015061Sgarrison          n--;
90115061Sgarrison          if (n == 0) {
90215061Sgarrison             for (p = p + 2; *p == ' '; p++) ;
90315061Sgarrison             breakname(p, first, last) ;
90415061Sgarrison             return(true);
90515061Sgarrison             }
90615061Sgarrison          }
90715061Sgarrison 
90815061Sgarrison    if (n == m)          /* no authors, try editors */
90915061Sgarrison       for (p = ref; *p; p++)
91015061Sgarrison          if (*p == '%' & *(p+1) == 'E') {
91115061Sgarrison             n--;
91215061Sgarrison             if (n == 0) {
91315061Sgarrison                for (p = p + 2; *p == ' '; p++) ;
91415061Sgarrison                breakname(p, first, last) ;
91515061Sgarrison                return(true);
91615061Sgarrison                }
91715061Sgarrison             }
91815061Sgarrison 
91915061Sgarrison    if (n == m) {        /* no editors, either, try institution */
92015061Sgarrison       first[0] = last[0] = '\0';
92115061Sgarrison       getfield("I", last, ref);
92215061Sgarrison       if (last[0] != '\0')
92315061Sgarrison          return(true);
92415061Sgarrison       }
92515061Sgarrison 
92615061Sgarrison    return(false);
92715061Sgarrison }
92815061Sgarrison 
92915061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
93015061Sgarrison                   single character disambiguators */
93115061Sgarrison    disambiguate()
932*15903Srrh {  reg int i, j;
93315061Sgarrison    char adstr[2];
93415061Sgarrison 
93515061Sgarrison    for (i = 0; i < numrefs; i = j) {
93615061Sgarrison       j = i + 1;
937*15903Srrh       if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) {
93815061Sgarrison          adstr[0] = 'a'; adstr[1] = 0;
939*15903Srrh          for(j = i+1; strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0; j++) {
94015061Sgarrison             adstr[0] = 'a' + (j-i);
94115061Sgarrison             if (j == numrefs)
94215061Sgarrison                break;
943*15903Srrh             strcat(refinfo[j].ri_cite, adstr);
94415061Sgarrison             }
94515061Sgarrison          adstr[0] = 'a';
946*15903Srrh          strcat(refinfo[i].ri_cite, adstr);
94715061Sgarrison          }
94815061Sgarrison      }
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 {
959*15903Srrh    char newfirst[120], newlast[120];
960*15903Srrh    reg char *p, *q, *f, *l;
961*15903Srrh    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;
1089*15903Srrh {  char ref[REFSIZE], line[REFSIZE];
1090*15903Srrh    reg char *p, *q;
1091*15903Srrh    char *from;
109215061Sgarrison    int numauths, maxauths, numeds, maxeds;
109315061Sgarrison 
1094*15903Srrh    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");
1102*15903Srrh    fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite);
1103*15903Srrh #ifndef INCORE
1104*15903Srrh    fseek(rfd, (long)refinfo[i].ri_pos, 0);
110515061Sgarrison    while (fgets(line, REFSIZE, rfd) != NULL) {
1106*15903Srrh #else INCORE
1107*15903Srrh    for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */
1108*15903Srrh 	if (*from == '\n'){
1109*15903Srrh 		*q++ = '\n';
1110*15903Srrh 		*q = 0;
1111*15903Srrh 		q = line;
1112*15903Srrh 		from++;
1113*15903Srrh 	} else {
1114*15903Srrh 		*q++ = *from++;
1115*15903Srrh 		continue;
1116*15903Srrh 	}
1117*15903Srrh #endif INCORE
1118*15903Srrh 	switch(line[0]){
1119*15903Srrh 	case 0:
1120*15903Srrh 		goto doneref;
1121*15903Srrh 	case '.':
1122*15903Srrh 		fprintf(ofd, "%s", line);
1123*15903Srrh 		break;
1124*15903Srrh 	case '%':
1125*15903Srrh 		switch(line[1]){
1126*15903Srrh 		case 'A':	numauths++;	break;
1127*15903Srrh 		case 'E':	numeds++;	break;
1128*15903Srrh 		}
1129*15903Srrh 		for (p = &line[2]; *p == ' '; p++) /*VOID*/;
1130*15903Srrh 		doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
1131*15903Srrh 	}
1132*15903Srrh    }
1133*15903Srrh    doneref:;
113415061Sgarrison    fprintf(ofd,".][\n");
113515061Sgarrison }
1136