xref: /csrg-svn/contrib/bib/src/bibargs.c (revision 23485)
113110Srrh #ifndef lint
2*23485Sgarrison static char sccsid[] = "@(#)bibargs.c	2.8	06/10/85";
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              */
34*23485Sgarrison    int	max_klen     = 6;	/* max size of key			     */
3512910Sgarrison    int  sort         = false;   /* sort references ? (default no)            */
3612910Sgarrison    int  foot         = false;   /* footnoted references ? (default endnotes) */
3717246Srrh    int  doacite      = true;    /* place citations ? */
3812910Sgarrison    int  hyphen       = false;   /* hypenate contiguous references            */
3912910Sgarrison    int  ordcite      = true;    /* order multiple citations                  */
4012910Sgarrison    char sortstr[80]  = "1";     /* sorting template                          */
4112910Sgarrison    char trailstr[80] = "";      /* trailing characters to output             */
4212910Sgarrison    char pfile[120];             /* private file name                         */
4312910Sgarrison    int  personal = false;       /* personal file given ? (default no)        */
4412910Sgarrison    char citetemplate[80] = "1"; /* citation template                         */
4515903Srrh    struct wordinfo words[MAXDEFS];     /* defined words */
4615903Srrh    struct wordinfo *wordhash[HASHSIZE];
4715903Srrh    struct wordinfo *wordsearch();
4815903Srrh    int  wordtop = 0;           /* number of defined words         */
4912910Sgarrison 
5012910Sgarrison /* where output goes */
5112910Sgarrison    extern FILE *tfd;
5215061Sgarrison /* reference file information */
5315903Srrh    extern struct refinfo refinfo[];
5415061Sgarrison    extern char reffile[];
5515903Srrh #ifndef INCORE
5615061Sgarrison    extern FILE *rfd;
5715903Srrh #endif not INCORE
5815061Sgarrison    extern int numrefs;
5912910Sgarrison 
6012910Sgarrison /* doargs - read command argument line for both bib and listrefs
6112910Sgarrison             set switch values
6212910Sgarrison             call rdtext on file arguments, after dumping
6312910Sgarrison             default style file if no alternative style is given
6412910Sgarrison */
6512910Sgarrison    int doargs(argc, argv, defstyle)
6612910Sgarrison    int argc;
6712910Sgarrison    char **argv, defstyle[];
6812910Sgarrison {  int numfiles, i, style;
6912910Sgarrison    char *p, *q, *walloc();
7012910Sgarrison    FILE *fd;
7112910Sgarrison 
7212910Sgarrison    numfiles = 0;
7312910Sgarrison    style = true;
7417248Srrh    newbibdir(BMACLIB);
7512910Sgarrison 
7612910Sgarrison    for (i = 1; i < argc; i++)
7712910Sgarrison       if (argv[i][0] == '-')
7812910Sgarrison          switch(argv[i][1]) {
7917248Srrh 			case 'd':
8017248Srrh 				if (argv[i][2])
8117248Srrh 					p = &argv[i][2];
8217248Srrh 				else {  /* take next arg */
8317248Srrh 					i++;
8417248Srrh 					p = argv[i];
8517248Srrh 			}
8617248Srrh 			newbibdir(p);
8715061Sgarrison             case 'a':  for (p = &argv[i][2]; *p; p++)
8815061Sgarrison                           if (*p == 'a' || *p == 0)
8912961Sgarrison                              abbrev = true;
9012961Sgarrison                            else if (*p == 'x')
9112961Sgarrison                              capsmcap = true;
9212961Sgarrison                            else if (*p == 'r') {
9312961Sgarrison                              if (*(p+1))
9412961Sgarrison                                 numrev = atoi(p+1);
9512961Sgarrison                               else
9612961Sgarrison                                 numrev = 1000;
9712961Sgarrison                               break;
9812961Sgarrison                               }
9912910Sgarrison                        break;
10012910Sgarrison 
10112910Sgarrison             case 'c':  if (argv[i][2] == 0)
10215903Srrh                           error("citation string expected for 'c'");
10312910Sgarrison                        else
10412910Sgarrison                           for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
10512910Sgarrison                        break;
10612910Sgarrison 
10712910Sgarrison             case 'e':  for (p = &argv[i][2]; *p; p++)
10812910Sgarrison                           if (*p == 'a')
10912910Sgarrison                              edabbrev = true;
11012910Sgarrison                            else if (*p == 'x')
11112910Sgarrison                              edcapsmcap = true;
11212910Sgarrison                            else if (*p == 'r') {
11312910Sgarrison                              if (*(p+1))
11412910Sgarrison                                 ednumrev = atoi(p+1);
11512910Sgarrison                               else
11612910Sgarrison                                 ednumrev = 1000;
11712910Sgarrison                               break;
11812910Sgarrison                               }
11912910Sgarrison                        break;
12012910Sgarrison 
121*23485Sgarrison 	    case 'l':  if (argv[i][2]){
122*23485Sgarrison                           max_klen  = atoi(&argv[i][2]);
123*23485Sgarrison 			  if (max_klen > REFSIZE)
124*23485Sgarrison 			      error("too long key size");
125*23485Sgarrison 		       } else {
126*23485Sgarrison 			  error("-l needs a numeric value");
127*23485Sgarrison 		       }
128*23485Sgarrison 		       break;
129*23485Sgarrison 
13017246Srrh             case 'v':  doacite = false;
13117246Srrh 			/*FALLTHROUGH*/
13212910Sgarrison             case 'f':  foot = true;
13312910Sgarrison                        hyphen = false;
13412910Sgarrison                        break;
13512910Sgarrison 
13612910Sgarrison             case 'h':  hyphen = ordcite = true;
13712910Sgarrison                        break;
13812910Sgarrison 
13912910Sgarrison             case 'n':  for (p = &argv[i][2]; *p; p++)
14012910Sgarrison                           if (*p == 'a')
14112910Sgarrison                              abbrev = false;
14217246Srrh                           else if (*p == 'v')
14317246Srrh                              doacite = true;
14412910Sgarrison                           else if (*p == 'f')
14512910Sgarrison                              foot = false;
14612910Sgarrison                           else if (*p == 'h')
14712910Sgarrison                              hyphen = false;
14812910Sgarrison                           else if (*p == 'o')
14912910Sgarrison                              ordcite = false;
15012910Sgarrison                           else if (*p == 'r')
15112910Sgarrison                              numrev = 0;
15212910Sgarrison                           else if (*p == 's')
15312910Sgarrison                              sort = false;
15412910Sgarrison                           else if (*p == 'x')
15512910Sgarrison                              capsmcap = false;
15612910Sgarrison                        break;
15712910Sgarrison 
15812910Sgarrison             case 'o':  ordcite = true;
15912910Sgarrison                        break;
16012910Sgarrison 
16112910Sgarrison             case 'p':  if (argv[i][2])
16212910Sgarrison                           p = &argv[i][2];
16312910Sgarrison                        else {  /* take next arg */
16412910Sgarrison                           i++;
16512910Sgarrison                           p = argv[i];
16612910Sgarrison                           }
16712910Sgarrison                        strcpy(pfile, p);
16812910Sgarrison                        personal = true;
16912910Sgarrison                        break;
17012910Sgarrison 
17115061Sgarrison             case 'r':  if (argv[i][2] == 0)  /* this is now replaced by -ar */
17212910Sgarrison                           numrev = 1000;
17312910Sgarrison                        else
17412910Sgarrison                           numrev = atoi(&argv[i][2]);
17512910Sgarrison                        break;
17612910Sgarrison 
17712910Sgarrison             case 's':  sort = true;
17812910Sgarrison                        if (argv[i][2])
17912910Sgarrison                           for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
18012910Sgarrison                        break;
18112910Sgarrison 
18215061Sgarrison             case 't':  style = false;           /* fall through */
18315061Sgarrison             case 'i':  if (argv[i][2])
18412910Sgarrison                           p = &argv[i][2];
18512910Sgarrison                        else { /* take next arg */
18612910Sgarrison                           i++;
18712910Sgarrison                           p = argv[i];
18812910Sgarrison                           }
18912910Sgarrison                        incfile(p);
19012910Sgarrison                        break;
19112910Sgarrison 
19215061Sgarrison             case 'x':  capsmcap = true; /* this is now replaced by -ax */
19312910Sgarrison                        break;
19412910Sgarrison 
19512910Sgarrison             case 0:    if (style) {  /* no style command given, take default */
19612910Sgarrison                           style = false;
19712910Sgarrison                           incfile( defstyle );
19812910Sgarrison                           }
19915061Sgarrison                        strcpy(bibfname,"<stdin>");
20012910Sgarrison                        rdtext(stdin);
20112910Sgarrison                        numfiles++;
20212910Sgarrison                        break;
20312910Sgarrison 
20412910Sgarrison             default:   fputs(argv[i], stderr);
20515903Srrh                        error("'%c' invalid switch", argv[i][1]);
20612910Sgarrison             }
20712910Sgarrison       else { /* file name */
20812910Sgarrison          numfiles++;
20912910Sgarrison          if (style) {
21012910Sgarrison             style = false;
21112910Sgarrison             incfile( defstyle );
21212910Sgarrison             }
21312910Sgarrison          fd = fopen(argv[i], "r");
21412910Sgarrison          if (fd == NULL) {
21515903Srrh             error("can't open file %s", argv[i]);
21612910Sgarrison             }
21712910Sgarrison          else {
21815061Sgarrison             strcpy(bibfname, argv[i]);
21912910Sgarrison             rdtext(fd);
22012910Sgarrison             fclose(fd);
22112910Sgarrison             }
22212910Sgarrison          }
22312910Sgarrison 
22412910Sgarrison    if (style) incfile( defstyle );
22512910Sgarrison    return(numfiles);
22612910Sgarrison 
22712910Sgarrison }
22812910Sgarrison 
22917248Srrh newbibdir(name)
23017248Srrh 	char *name;
23117248Srrh {
23217248Srrh 	strreplace(COMFILE, BMACLIB, name);
23317248Srrh 	strreplace(DEFSTYLE, BMACLIB, name);
23417248Srrh 	strcpy(BMACLIB, name);
23517248Srrh 	wordstuff("BMACLIB", BMACLIB);
23617248Srrh 	fprintf(tfd, ".ds l] %s\n", BMACLIB);
23717248Srrh }
23817248Srrh 
23912910Sgarrison /* incfile - read in an included file  */
24012910Sgarrison incfile(np)
24112910Sgarrison    char *np;
24212910Sgarrison {  char name[120];
24312910Sgarrison    FILE *fd;
24415061Sgarrison    char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
24516244Srrh    int  i, getwrd();
24612910Sgarrison 
24715061Sgarrison    strcpy(bibfname, np);
24812910Sgarrison    fd = fopen(np, "r");
24912910Sgarrison    if (fd == NULL && *np != '/') {
25012910Sgarrison       strcpy(name, "bib.");
25112910Sgarrison       strcat(name, np);
25215061Sgarrison       strcpy(bibfname, name);
25312910Sgarrison       fd = fopen(name, "r");
25412910Sgarrison       }
25512910Sgarrison    if (fd == NULL && *np != '/') {
25612910Sgarrison       strcpy(name,BMACLIB);
25712910Sgarrison       strcat(name, "/bib.");
25812910Sgarrison       strcat(name, np);
25915061Sgarrison       strcpy(bibfname, name);
26012910Sgarrison       fd = fopen(name, "r");
26112910Sgarrison       }
26212910Sgarrison    if (fd == NULL) {
26315061Sgarrison       bibwarning("%s: can't open", np);
26415061Sgarrison       exit(1);
26512910Sgarrison       }
26612910Sgarrison 
26715061Sgarrison    /* now go off and process file */
26815061Sgarrison    biblineno = 1;
26915061Sgarrison    while (tfgets(line, LINELENGTH, fd) != NULL) {
27015061Sgarrison       biblineno++;
27112910Sgarrison       switch(line[0]) {
27212910Sgarrison 
27312910Sgarrison          case '#': break;
27412910Sgarrison 
27512961Sgarrison          case 'A': for (p = &line[1]; *p; p++)
27615061Sgarrison                       if (*p == 'A' || *p == '\0')
27712961Sgarrison                          abbrev = true;
27812961Sgarrison                       else if (*p == 'X')
27912961Sgarrison                          capsmcap = true;
28012961Sgarrison                       else if (*p == 'R') {
28112961Sgarrison                          if (*(p+1))
28212961Sgarrison                             numrev = atoi(p+1);
28312961Sgarrison                          else
28412961Sgarrison                             numrev = 1000;
28512961Sgarrison                          break;
28612961Sgarrison                          }
28712910Sgarrison                    break;
28812910Sgarrison 
28912910Sgarrison          case 'C': for (p = &line[1]; *p == ' '; p++) ;
29012910Sgarrison                    strcpy(citetemplate, p);
29112910Sgarrison                    break;
29212910Sgarrison 
29312910Sgarrison          case 'D': if ((i = getwrd(line, 1, word)) == 0)
29412910Sgarrison                       error("word expected in definition");
29515903Srrh 		   if (wordsearch(word))
29615903Srrh 			break;
29712910Sgarrison                    for (p = &line[i]; *p == ' '; p++) ;
29812910Sgarrison                    for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
29912910Sgarrison                        dline[strlen(dline)-1] = '\n';
30015061Sgarrison                        if (tfgets(line, LINELENGTH, fd) == NULL) break;
30112910Sgarrison                        strcat(dline, line);
30212910Sgarrison                        }
30315903Srrh 		   wordstuff(word, dline);
30412910Sgarrison                    break;
30512910Sgarrison 
30612910Sgarrison          case 'E': for (p = &line[1]; *p; p++)
30712910Sgarrison                       if (*p == 'A')
30812910Sgarrison                          edabbrev = true;
30912910Sgarrison                       else if (*p == 'X')
31012910Sgarrison                          edcapsmcap = true;
31112910Sgarrison                       else if (*p == 'R') {
31212910Sgarrison                          if (*(p+1))
31312910Sgarrison                             ednumrev = atoi(p+1);
31412910Sgarrison                          else
31512910Sgarrison                             ednumrev = 1000;
31612910Sgarrison                          break;
31712910Sgarrison                          }
31812910Sgarrison                    break;
31912910Sgarrison 
32012910Sgarrison          case 'F': foot = true;
32112910Sgarrison                    hyphen = false;
32212910Sgarrison                    break;
32312910Sgarrison 
32412910Sgarrison          case 'I': for (p = &line[1]; *p == ' '; p++);
32512910Sgarrison                    expand(p);
32612910Sgarrison                    incfile(p);
32712910Sgarrison                    break;
32812910Sgarrison 
32912910Sgarrison          case 'H': hyphen = ordcite = true;
33012910Sgarrison                    break;
33112910Sgarrison 
33212910Sgarrison          case 'O': ordcite = true;
33312910Sgarrison                    break;
33412910Sgarrison 
33515061Sgarrison          case 'R': if (line[1] == 0)  /* this is now replaced by AR */
33612910Sgarrison                       numrev = 1000;
33712910Sgarrison                    else
33812910Sgarrison                       numrev = atoi(&line[1]);
33912910Sgarrison                    break;
34012910Sgarrison 
34112910Sgarrison          case 'S': sort = true;
34212910Sgarrison                    for (p = &line[1]; *p == ' '; p++) ;
34312910Sgarrison                    strcpy(sortstr, p);
34412910Sgarrison                    break;
34512910Sgarrison 
34612910Sgarrison          case 'T': for (p = &line[1]; *p == ' '; p++) ;
34712910Sgarrison                    strcpy(trailstr, p);
34812910Sgarrison                    break;
34912910Sgarrison 
35015061Sgarrison          case 'X': capsmcap = true;     /* this is now replace by AX */
35112910Sgarrison                    break;
35212910Sgarrison 
35312910Sgarrison          default:  fprintf(tfd,"%s\n",line);
35415061Sgarrison                    while (fgets(line, LINELENGTH, fd) != NULL)
35512910Sgarrison                       fputs(line, tfd);
35612910Sgarrison                    return;
35712910Sgarrison          }
35815061Sgarrison 
35915061Sgarrison    }
36015061Sgarrison    /* close up */
36115061Sgarrison    fclose(fd);
36212910Sgarrison }
36312910Sgarrison 
36415061Sgarrison /* bibwarning - print out a warning message */
36515903Srrh   /*VARARGS1*/
36615903Srrh   bibwarning(msg, a1, a2)
36715903Srrh   char *msg;
36815061Sgarrison {
36915061Sgarrison   fprintf(stderr,"`%s', line %d: ", bibfname, biblineno);
37015903Srrh   fprintf(stderr, msg, a1, a2);
37117248Srrh   fprintf(stderr, "\n");
37215061Sgarrison }
37315061Sgarrison 
37415061Sgarrison /* error - report unrecoverable error message */
37515903Srrh   /*VARARGS1*/
37615903Srrh   error(str, a1, a2)
37715903Srrh   char *str;
37815061Sgarrison {
37915903Srrh   bibwarning(str, a1, a2);
38015903Srrh   /*
38115903Srrh    *	clean up temp files and exit
38215903Srrh    */
38315903Srrh   cleanup(1);
38415061Sgarrison }
38515061Sgarrison 
38615903Srrh #ifndef INCORE
38715061Sgarrison #ifdef READWRITE
38815061Sgarrison /*
38915061Sgarrison ** fixrfd( mode ) -- re-opens the rfd file to be read or write,
39015061Sgarrison **      depending on the mode.  Uses a static int to save the current mode
39115061Sgarrison **      and avoid unnecessary re-openings.
39215061Sgarrison */
39315061Sgarrison fixrfd( mode )
39415061Sgarrison register int mode;
39515061Sgarrison {
39615061Sgarrison 	static int cur_mode = WRITE;    /* rfd open for writing initially */
39715061Sgarrison 
39815061Sgarrison 	if (mode != cur_mode)
39915061Sgarrison 	{
40015061Sgarrison 		rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
40115061Sgarrison 		cur_mode = mode;
40215061Sgarrison 		if (rfd == NULL)
40315903Srrh 		      error("Hell!  Couldn't re-open reference file %s",
40415903Srrh 			reffile);
40515061Sgarrison 	}
40615061Sgarrison }
40715061Sgarrison #endif
40815903Srrh #endif not INCORE
40915061Sgarrison 
41015061Sgarrison 
41115061Sgarrison /* tfgets - fgets which trims off newline */
41215061Sgarrison    char *tfgets(line, n, ptr)
41315061Sgarrison    char line[];
41415061Sgarrison    int  n;
41515061Sgarrison    FILE *ptr;
41615903Srrh {  reg char *p;
41715061Sgarrison 
41815061Sgarrison    p = fgets(line, n, ptr);
41915061Sgarrison    if (p == NULL)
42015061Sgarrison       return(NULL);
42115061Sgarrison    else
42215061Sgarrison       for (p = line; *p; p++)
42315061Sgarrison          if (*p == '\n')
42415061Sgarrison             *p = 0;
42515061Sgarrison    return(line);
42615061Sgarrison }
42715061Sgarrison 
42815061Sgarrison /* getwrd - place next word from in[i] into out */
42915061Sgarrison int getwrd(in, i, out)
43015903Srrh    reg char in[], out[];
43115903Srrh    reg int i;
43215061Sgarrison {  int j;
43315061Sgarrison 
43415061Sgarrison    j = 0;
43515061Sgarrison    while (in[i] == ' ' || in[i] == '\n' || in[i] == '\t')
43615061Sgarrison       i++;
43715061Sgarrison    if (in[i])
43815061Sgarrison       while (in[i] && in[i] != ' ' && in[i] != '\t' && in[i] != '\n')
43915061Sgarrison          out[j++] = in[i++];
44015061Sgarrison    else
44115061Sgarrison       i = 0;    /* signals end of in[i..]   */
44215061Sgarrison    out[j] = 0;
44315061Sgarrison    return (i);
44415061Sgarrison }
44515061Sgarrison 
44615061Sgarrison /* walloc - allocate enough space for a word */
44715061Sgarrison char *walloc(word)
44815061Sgarrison    char *word;
44915061Sgarrison {  char *i, *malloc();
45015061Sgarrison    i = malloc(1 + strlen(word));
45115061Sgarrison    if (i == NULL)
45215061Sgarrison       error("out of storage");
45315061Sgarrison    strcpy(i, word);
45415061Sgarrison    return(i);
45515061Sgarrison }
45615061Sgarrison 
45712910Sgarrison /* isword - see if character is legit word char */
45812910Sgarrison int iswordc(c)
45912910Sgarrison char c;
46012910Sgarrison {
46112910Sgarrison    if (isalnum(c) || c == '&' || c == '_')
46212910Sgarrison       return(true);
46312910Sgarrison    return(false);
46412910Sgarrison }
46512910Sgarrison    expand(line)
46612910Sgarrison    char *line;
46715903Srrh {  char line2[REFSIZE], word[LINELENGTH];
46815903Srrh    reg	struct wordinfo *wp;
46915903Srrh    reg	char *p, *q, *w;
47012910Sgarrison 
47115903Srrh 	q = line2;
47215903Srrh 	for (p = line; *p; /*VOID*/){
47315903Srrh 		if (isalnum(*p)) {
47415903Srrh 			for (w = word; *p && iswordc(*p); ) *w++ = *p++;
47515903Srrh 			*w = 0;
47615903Srrh 			if (wp = wordsearch(word)){
47715903Srrh 				strcpy(word, wp->wi_def);
47815903Srrh 				expand(word);
47915903Srrh 			}
48015903Srrh 			strcpy(q, word);
48115903Srrh 			q += strlen(q);
48215903Srrh 		} else {
48315903Srrh 			*q++ = *p++;
48415903Srrh 		}
48515903Srrh 	}
48615903Srrh 	*q = 0;
48715903Srrh 	strcpy(line, line2);
48812910Sgarrison }
48912910Sgarrison 
49015903Srrh /* wordstuff- save a word and its definition, building a hash table */
49115903Srrh    wordstuff(word, def)
49215903Srrh    char *word, *def;
49315903Srrh {
49415903Srrh    int i;
49515903Srrh    if (wordtop >= MAXDEFS)
49615903Srrh 	error("too many definitions, max of %d", MAXDEFS);
49715903Srrh    words[wordtop].wi_length = strlen(word);
49815903Srrh    words[wordtop].wi_word = word ? walloc(word) : 0;
49915903Srrh    words[wordtop].wi_def = def ? walloc(def) : 0;
50015903Srrh    i = strhash(word);
50115903Srrh    words[wordtop].wi_hp = wordhash[i];
50215903Srrh    wordhash[i] = &words[wordtop];
50315903Srrh    wordtop++;
50415903Srrh }
50515903Srrh    struct wordinfo *wordsearch(word)
50615903Srrh    char *word;
50715903Srrh {
50815903Srrh    reg int lg;
50915903Srrh    reg struct wordinfo *wp;
51015903Srrh    lg = strlen(word);
51115903Srrh    for (wp = wordhash[strhash(word)]; wp; wp = wp->wi_hp){
51215903Srrh 	if (wp->wi_length == lg && (strcmp(wp->wi_word, word) == 0)){
51315903Srrh 		return(wp);
51415903Srrh 	}
51515903Srrh    }
51615903Srrh    return(0);
51715903Srrh }
51815903Srrh 
51915903Srrh    int strhash(str)
52015903Srrh    reg char *str;
52115903Srrh {
52215903Srrh    reg int value = 0;
52315903Srrh    for (value = 0; *str; value <<= 2, value += *str++)/*VOID*/;
52415903Srrh    value %= HASHSIZE;
52515903Srrh    if (value < 0)
52615903Srrh 	value += HASHSIZE;
52715903Srrh    return(value);
52815903Srrh }
52915903Srrh 
53015061Sgarrison /* rdref - read text for an already cited reference */
53115903Srrh    rdref(p, ref)
53215903Srrh    struct refinfo *p;
53315061Sgarrison    char ref[REFSIZE];
53415061Sgarrison {
53515061Sgarrison    ref[0] = 0;
53615903Srrh #ifndef INCORE
53715061Sgarrison #ifdef READWRITE
53815061Sgarrison    fixrfd( READ );                      /* fix access mode of rfd, if nec. */
53915061Sgarrison #endif
54015903Srrh    fseek(rfd, p->ri_pos, 0);
54115903Srrh    fread(ref, p->ri_length, 1, rfd);
54215903Srrh #else INCORE
54315903Srrh    strcpy(ref, p->ri_ref);
54415903Srrh #endif INCORE
54515061Sgarrison }
54615061Sgarrison 
54715903Srrh /* wrref - write text for a new reference */
54815903Srrh    wrref(p, ref)
54915903Srrh    struct refinfo *p;
55015903Srrh    char ref[REFSIZE];
55115903Srrh {
55215903Srrh #ifndef INCORE
55315903Srrh #ifdef READWRITE
55415903Srrh     fixrfd( WRITE );                 /* fix access mode of rfd, if nec. */
55515903Srrh #else
55615903Srrh     fseek(rfd, p->ri_pos, 0);        /* go to end of rfd */
55715903Srrh #endif
55815903Srrh     fwrite(ref, p->ri_length, 1, rfd);
55915903Srrh #else INCORE
56015903Srrh    p->ri_ref = walloc(ref);
56115903Srrh #endif INCORE
56215903Srrh }
56315903Srrh 
56412910Sgarrison /* breakname - break a name into first and last name */
56512910Sgarrison    breakname(line, first, last)
56612910Sgarrison    char line[], first[], last[];
56715903Srrh {  reg char *t, *f, *q, *r, *p;
56812910Sgarrison 
56912910Sgarrison    for (t = line; *t != '\n'; t++);
57012910Sgarrison    for (t--; isspace(*t); t--);
57112910Sgarrison 
57212910Sgarrison    /* now strip off last name */
57312910Sgarrison    for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
57412910Sgarrison       if (q == line)
57512910Sgarrison          break;
57612910Sgarrison    f = q;
57715061Sgarrison    if (q != line) {
57812910Sgarrison       q++;
57915061Sgarrison       for (; isspace(*f); f--);
58015061Sgarrison       f++;
58115061Sgarrison       }
58212910Sgarrison 
58312910Sgarrison    /* first name is start to f, last name is q to t */
58412910Sgarrison 
58515061Sgarrison    for (r = first, p = line; p != f; )
58612910Sgarrison       *r++ = *p++;
58712910Sgarrison    *r = 0;
58812910Sgarrison    for (r = last, p = q, t++; q != t; )
58912910Sgarrison       *r++ = *q++;
59012910Sgarrison    *r = 0;
59115061Sgarrison 
59212910Sgarrison }
59312910Sgarrison 
59412910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
59512910Sgarrison    int match(str1, str2)
59615903Srrh    reg char str1[], str2[];
59715903Srrh {  reg int  j, i;
59812910Sgarrison    char a, b;
59912910Sgarrison 
60012910Sgarrison    for (i = 0; str2[i]; i++) {
60112910Sgarrison       for (j = 0; str1[j]; j++) {
60212910Sgarrison          if (isupper(a = str2[i+j]))
60312910Sgarrison             a = (a - 'A') + 'a';
60412910Sgarrison          if (isupper(b = str1[j]))
60512910Sgarrison             b = (b - 'A') + 'a';
60612910Sgarrison          if (a != b)
60712910Sgarrison             break;
60812910Sgarrison          }
60912910Sgarrison       if (str1[j] == 0)
61012910Sgarrison          return(true);
61112910Sgarrison       }
61212910Sgarrison    return(false);
61312910Sgarrison }
61412910Sgarrison 
61512910Sgarrison /* scopy - append a copy of one string to another */
61612910Sgarrison    char *scopy(p, q)
61715903Srrh    reg char *p, *q;
61812910Sgarrison {
61912910Sgarrison    while (*p++ = *q++)
62012910Sgarrison       ;
62112910Sgarrison    return(--p);
62212910Sgarrison }
62312910Sgarrison 
62415061Sgarrison /* rcomp - reference comparison routine for qsort utility */
62515061Sgarrison    int rcomp(ap, bp)
62615903Srrh    struct refinfo *ap, *bp;
62715061Sgarrison {  char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
62815903Srrh    reg	char *p, *q;
62915903Srrh    char *getfield();
63015061Sgarrison    int  neg, res;
63115061Sgarrison    int  fields_found;
63215061Sgarrison 
63315903Srrh    rdref(ap, ref1);
63415903Srrh    rdref(bp, ref2);
63515061Sgarrison    for (p = sortstr; *p; p = q) {
63615061Sgarrison       if (*p == '-') {
63715061Sgarrison          p++;
63815061Sgarrison          neg = true;
63915061Sgarrison          }
64015061Sgarrison       else
64115061Sgarrison          neg = false;
64215061Sgarrison       q = getfield(p, field1, ref1);
64315061Sgarrison       fields_found = true;
64415061Sgarrison       if (q == 0) {
64515061Sgarrison 	 res = 1;
64615061Sgarrison 	 fields_found = false;
64715061Sgarrison       } else if (strcmp (field1, "") == 0) {	/* field not found */
64815061Sgarrison          if (*p == 'A') {
64915061Sgarrison             getfield("F", field1, ref1);
65015061Sgarrison 	    if (strcmp (field1, "") == 0) {
65115061Sgarrison                getfield("I", field1, ref1);
65215061Sgarrison 	       if (strcmp (field1, "") == 0) {
65315061Sgarrison 	          res = 1;
65415061Sgarrison 		  fields_found = false;
65515061Sgarrison 	       }
65615061Sgarrison 	    }
65715061Sgarrison 	 } else {
65815061Sgarrison 	    res = 1;
65915061Sgarrison 	    fields_found = false;
66015061Sgarrison 	 }
66115061Sgarrison       }
66215061Sgarrison 
66315061Sgarrison       if (getfield(p, field2, ref2) == 0) {
66415061Sgarrison 	 res = -1;
66515061Sgarrison 	 fields_found = false;
66615061Sgarrison       } else if (strcmp (field2, "") == 0) {	/* field not found */
66715061Sgarrison          if (*p == 'A') {
66815061Sgarrison             getfield("F", field2, ref2);
66915061Sgarrison 	    if (strcmp (field2, "") == 0) {
67015061Sgarrison                getfield("I", field2, ref2);
67115061Sgarrison 	       if (strcmp (field2, "") == 0) {
67215061Sgarrison 	          res = -1;
67315061Sgarrison 		  fields_found = false;
67415061Sgarrison 	       }
67515061Sgarrison 	    }
67615061Sgarrison 	 } else {
67715061Sgarrison 	    res = -1;
67815061Sgarrison 	    fields_found = false;
67915061Sgarrison 	 }
68015061Sgarrison       }
68115061Sgarrison       if (fields_found) {
68215061Sgarrison          if (*p == 'A') {
68315061Sgarrison             if (isupper(field1[0]))
68415061Sgarrison                field1[0] -= 'A' - 'a';
68515061Sgarrison             if (isupper(field2[0]))
68615061Sgarrison                field2[0] -= 'A' - 'a';
68715061Sgarrison             }
68815061Sgarrison          res = strcmp(field1, field2);
68915061Sgarrison          }
69015061Sgarrison       if (neg)
69115061Sgarrison          res = - res;
69215061Sgarrison       if (res != 0)
69315061Sgarrison          break;
69415061Sgarrison       }
69515061Sgarrison    if (res == 0)
69615061Sgarrison       if (ap < bp)
69715061Sgarrison          res = -1;
69815061Sgarrison       else
69915061Sgarrison          res = 1;
70015061Sgarrison    return(res);
70115061Sgarrison }
70215061Sgarrison 
70316244Srrh /* makecites - make standard citation strings, using citetemplate currently in effect */
70415903Srrh    makecites()
70515061Sgarrison {  char ref[REFSIZE], tempcite[100], *malloc();
70615903Srrh    reg int  i;
70715061Sgarrison 
70815903Srrh    for (i = 0; i < numrefs; i++) {
70915903Srrh       rdref(&refinfo[i], ref);
71015061Sgarrison       bldcite(tempcite, i, ref);
71116244Srrh       refinfo[i].ri_cite = malloc(2 + strlen(tempcite));
71215903Srrh       if (refinfo[i].ri_cite == NULL)
71315061Sgarrison          error("out of storage");
71415903Srrh       strcpy(refinfo[i].ri_cite, tempcite);
71515061Sgarrison       }
71615061Sgarrison }
71715061Sgarrison 
71815061Sgarrison /* bldcite - build a single citation string */
71915061Sgarrison    bldcite(cp, i, ref)
72015061Sgarrison    char *cp, ref[];
72115061Sgarrison    int  i;
72215903Srrh {  reg char *p, *q, *fp;
72315903Srrh    char c;
72415903Srrh    char field[REFSIZE];
725*23485Sgarrison    char *getfield(), *aabet(), *aabetlast(), *fullaabet(), *astro();
72615061Sgarrison 
72715061Sgarrison    getfield("F", field, ref);
72815061Sgarrison    if (field[0] != 0)
72915061Sgarrison       for (p = field; *p; p++)
73015061Sgarrison          *cp++ = *p;
73115061Sgarrison    else {
73215061Sgarrison       p = citetemplate;
73315061Sgarrison       field[0] = 0;
73415061Sgarrison       while (c = *p++) {
73515061Sgarrison          if (isalpha(c)) {                      /* field name   */
73615061Sgarrison             q = getfield(p-1, field, ref);
73715061Sgarrison             if (q != 0) {
73815061Sgarrison                p = q;
73915061Sgarrison                for (fp = field; *fp; )
74015061Sgarrison                   *cp++ = *fp++;
74115061Sgarrison                }
74215061Sgarrison             }
74315061Sgarrison          else if (c == '1') {                   /* numeric  order */
74415061Sgarrison             sprintf(field,"%d",1 + i);
74515061Sgarrison             for (fp = field; *fp; )
74615061Sgarrison                *cp++ = *fp++;
74715061Sgarrison             }
74815061Sgarrison          else if (c == '2')                     /* alternate alphabetic */
74915061Sgarrison             cp = aabet(cp, ref);
75015061Sgarrison          else if (c == '3')                     /* Astrophysical Journal style*/
75115061Sgarrison             cp = astro(cp, ref);
752*23485Sgarrison 	 else if (c == '8')			/* Full alphabetic */
753*23485Sgarrison 	    cp = fullaabet(cp, ref);
75415890Srrh          else if (c == '9')                     /* Last name of Senior Author*/
75515890Srrh             cp = aabetlast(cp, ref);
75617246Srrh 	 else if (c == '0') {			/* print nothing */
75717246Srrh             for (fp = field; *fp; )
75817246Srrh                *cp++ = *fp++;
75917246Srrh             }
76015061Sgarrison /*       else if (c == '4')          here is how to add new styles */
76115061Sgarrison          else if (c == '{') {                   /* other information   */
76215061Sgarrison             while (*p != '}')
76315061Sgarrison                if (*p == 0)
76415061Sgarrison                   error("unexpected end of citation template");
76515061Sgarrison                else
76615061Sgarrison                   *cp++ = *p++;
76715061Sgarrison             p++;
76815061Sgarrison             }
76915061Sgarrison          else if (c == '<') {
77015061Sgarrison             while (*p != '>') {
77115061Sgarrison                if (*p == 0)
77215061Sgarrison                   error("unexpected end of citation template");
77315061Sgarrison                else
77415061Sgarrison                   *cp++ = *p++;
77515061Sgarrison                }
77615061Sgarrison             p++;
77715061Sgarrison             }
77815061Sgarrison          else if (c != '@')
77915061Sgarrison             *cp++ = c;
78015061Sgarrison          }
78115061Sgarrison       }
78215061Sgarrison    *cp++ = 0;
78315061Sgarrison }
78415061Sgarrison 
78515061Sgarrison /* alternate alphabetic citation style -
78615061Sgarrison         if 1 author - first three letters of last name
78715061Sgarrison         if 2 authors - first two letters of first, followed by first letter of
78815061Sgarrison                                 seond
78915061Sgarrison         if 3 or more authors - first letter of first three authors */
79015061Sgarrison    char *aabet(cp, ref)
79115061Sgarrison    char *cp, ref[];
79215903Srrh {  char field[REFSIZE], temp[100];
79315903Srrh    reg char *np, *fp;
79415061Sgarrison    int j, getname();
79515061Sgarrison 
79615061Sgarrison    if (getname(1, field, temp, ref)) {
79715061Sgarrison       np = cp;
79815061Sgarrison       fp = field;
79915061Sgarrison       for (j = 1; j <= 3; j++)
80015061Sgarrison          if (*fp != 0)
80115061Sgarrison             *cp++ = *fp++;
80215061Sgarrison       if (getname(2, field, temp, ref))
80315061Sgarrison          np[2] = field[0];
80415061Sgarrison       if (getname(3, field, temp, ref)) {
80515061Sgarrison          np[1] = np[2];
80615061Sgarrison          np[2] = field[0];
80715061Sgarrison          }
80815061Sgarrison       }
80915061Sgarrison return(cp);
81015061Sgarrison }
81115061Sgarrison 
81215890Srrh /* alternate alphabetic citation style -
813*23485Sgarrison 	first two characters of last names of all authors
814*23485Sgarrison 	up to max_klen characters.
815*23485Sgarrison */
816*23485Sgarrison    char *fullaabet(cp, ref)
817*23485Sgarrison    char *cp, ref[];
818*23485Sgarrison {  char field[REFSIZE], temp[100];
819*23485Sgarrison    reg char	*fp;
820*23485Sgarrison    char	*lastcp;
821*23485Sgarrison    int getname();
822*23485Sgarrison    int i;
823*23485Sgarrison 
824*23485Sgarrison    lastcp = cp + max_klen;
825*23485Sgarrison    for (i= 1; getname(i, field, temp, ref); i++) {
826*23485Sgarrison       for (fp = field; *fp && (fp < &(field[3])); )
827*23485Sgarrison 	 if (cp > lastcp)
828*23485Sgarrison 	     break;
829*23485Sgarrison          else if (isalpha(*fp))
830*23485Sgarrison 	     *cp++ = *fp++;
831*23485Sgarrison 	 else
832*23485Sgarrison 	     fp++;
833*23485Sgarrison    }
834*23485Sgarrison    return(cp);
835*23485Sgarrison }
836*23485Sgarrison 
837*23485Sgarrison 
838*23485Sgarrison /* alternate alphabetic citation style -
83915890Srrh 	entire last name of senior author
84015890Srrh */
84115890Srrh    char *aabetlast(cp, ref)
84215890Srrh    char *cp, ref[];
84315890Srrh {  char field[REFSIZE], temp[100];
84415903Srrh    reg char	*fp;
84515890Srrh    int getname();
84615890Srrh 
84715890Srrh    if (getname(1, field, temp, ref)) {
84815890Srrh       for (fp = field; *fp; )
84915890Srrh          *cp++ = *fp++;
85015890Srrh    }
85115890Srrh    return(cp);
85215890Srrh }
85315890Srrh 
85415061Sgarrison /* Astrophysical Journal style
85515061Sgarrison         if 1 author - last name date
85615061Sgarrison         if 2 authors - last name and last name date
85715061Sgarrison         if 3 authors - last name, last name and last name date
85815061Sgarrison         if 4 or more authors - last name et al. date */
85915061Sgarrison    char *astro(cp, ref)
86015061Sgarrison    char *cp, ref[];
86115903Srrh {  char name1[100], name2[100], name3[100], temp[100];
86215903Srrh    reg char *fp;
86315061Sgarrison    int getname();
86415061Sgarrison 
86515061Sgarrison    if (getname(1, name1, temp, ref)) {
86615061Sgarrison       for (fp = name1; *fp; )
86715061Sgarrison          *cp++ = *fp++;
86815061Sgarrison       if (getname(4, name3, temp, ref)) {
86915061Sgarrison          for (fp = " et al."; *fp; )
87015061Sgarrison             *cp++ = *fp++;
87115061Sgarrison          }
87215061Sgarrison       else if (getname(2, name2, temp, ref)) {
87315061Sgarrison          if (getname(3, name3, temp, ref)) {
87415061Sgarrison             for (fp = "\\*(c]"; *fp; )
87515061Sgarrison                *cp++ = *fp++;
87615061Sgarrison             for (fp = name2; *fp; )
87715061Sgarrison                *cp++ = *fp++;
87815061Sgarrison             for (fp = "\\*(m]"; *fp; )
87915061Sgarrison                *cp++ = *fp++;
88015061Sgarrison             for (fp = name3; *fp; )
88115061Sgarrison                *cp++ = *fp++;
88215061Sgarrison             }
88315061Sgarrison          else {
88415061Sgarrison             for (fp = "\\*(n]"; *fp; )
88515061Sgarrison                *cp++ = *fp++;
88615061Sgarrison             for (fp = name2; *fp; )
88715061Sgarrison                *cp++ = *fp++;
88815061Sgarrison             }
88915061Sgarrison          }
89015061Sgarrison     }
89115061Sgarrison return(cp);
89215061Sgarrison }
89315061Sgarrison 
89415061Sgarrison /* getfield - get a single field from reference */
89515061Sgarrison    char *getfield(ptr, field, ref)
89615061Sgarrison    char *ptr, field[], ref[];
89715903Srrh {  reg	char *p, *q;
89815903Srrh    char	temp[100];
89915061Sgarrison    int  n, len, i, getname();
90015061Sgarrison 
90115061Sgarrison    field[0] = 0;
90215061Sgarrison    if (*ptr == 'A')
90315061Sgarrison       getname(1, field, temp, ref);
90415061Sgarrison    else
90515061Sgarrison       for (p = ref; *p; p++)
90615061Sgarrison          if (*p == '%' && *(p+1) == *ptr) {
90715061Sgarrison             for (p = p + 2; *p == ' '; p++)
90815061Sgarrison                ;
90915061Sgarrison             for (q = field; (*p != '\n') && (*p != '\0'); )
91015061Sgarrison                *q++ = *p++;
91115061Sgarrison             *q = 0;
91215061Sgarrison             break;
91315061Sgarrison             }
91415061Sgarrison    n = 0;
91515061Sgarrison    len = strlen(field);
91615061Sgarrison    if (*++ptr == '-') {
91715061Sgarrison       for (ptr++; isdigit(*ptr); ptr++)
91815061Sgarrison          n = 10 * n + (*ptr - '0');
91915061Sgarrison       if (n > len)
92015061Sgarrison          n = 0;
92115061Sgarrison       else
92215061Sgarrison          n = len - n;
92315061Sgarrison       for (i = 0; field[i] = field[i+n]; i++)
92415061Sgarrison          ;
92515061Sgarrison       }
92615061Sgarrison    else if (isdigit(*ptr)) {
92715061Sgarrison       for (; isdigit(*ptr); ptr++)
92815061Sgarrison          n = 10 * n + (*ptr - '0');
92915061Sgarrison       if (n > len)
93015061Sgarrison          n = len;
93115061Sgarrison       field[n] = 0;
93215061Sgarrison       }
93315061Sgarrison 
93415061Sgarrison    if (*ptr == 'u') {
93515061Sgarrison       ptr++;
93615061Sgarrison       for (p = field; *p; p++)
93715061Sgarrison          if (islower(*p))
93815061Sgarrison             *p = (*p - 'a') + 'A';
93915061Sgarrison       }
94015061Sgarrison    else if (*ptr == 'l') {
94115061Sgarrison       ptr++;
94215061Sgarrison       for (p = field; *p; p++)
94315061Sgarrison          if (isupper(*p))
94415061Sgarrison             *p = (*p - 'A') + 'a';
94515061Sgarrison       }
94615061Sgarrison    return(ptr);
94715061Sgarrison }
94815061Sgarrison 
94915061Sgarrison /* getname - get the nth name field from reference, breaking into
95015061Sgarrison              first and last names */
95115061Sgarrison    int getname(n, last, first, ref)
95215061Sgarrison    int  n;
95315061Sgarrison    char last[], first[], ref[];
95415903Srrh {  reg char *p;
95515061Sgarrison    int  m;
95615061Sgarrison 
95715061Sgarrison    m = n;
95815061Sgarrison    for (p = ref; *p; p++)
95915061Sgarrison       if (*p == '%' & *(p+1) == 'A') {
96015061Sgarrison          n--;
96115061Sgarrison          if (n == 0) {
96215061Sgarrison             for (p = p + 2; *p == ' '; p++) ;
96315061Sgarrison             breakname(p, first, last) ;
96415061Sgarrison             return(true);
96515061Sgarrison             }
96615061Sgarrison          }
96715061Sgarrison 
96815061Sgarrison    if (n == m)          /* no authors, try editors */
96915061Sgarrison       for (p = ref; *p; p++)
97015061Sgarrison          if (*p == '%' & *(p+1) == 'E') {
97115061Sgarrison             n--;
97215061Sgarrison             if (n == 0) {
97315061Sgarrison                for (p = p + 2; *p == ' '; p++) ;
97415061Sgarrison                breakname(p, first, last) ;
97515061Sgarrison                return(true);
97615061Sgarrison                }
97715061Sgarrison             }
97815061Sgarrison 
97915061Sgarrison    if (n == m) {        /* no editors, either, try institution */
98015061Sgarrison       first[0] = last[0] = '\0';
98115061Sgarrison       getfield("I", last, ref);
98215061Sgarrison       if (last[0] != '\0')
98315061Sgarrison          return(true);
98415061Sgarrison       }
98515061Sgarrison 
98615061Sgarrison    return(false);
98715061Sgarrison }
98815061Sgarrison 
98915061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
99015061Sgarrison                   single character disambiguators */
99115061Sgarrison    disambiguate()
99215903Srrh {  reg int i, j;
99316244Srrh 	char adstr;
99415061Sgarrison 
99515061Sgarrison    for (i = 0; i < numrefs; i = j) {
99615061Sgarrison       j = i + 1;
99715903Srrh       if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) {
99816244Srrh          adstr = 'a';
99915903Srrh          for(j = i+1; strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0; j++) {
100016244Srrh             adstr = 'a' + (j-i);
100115061Sgarrison             if (j == numrefs)
100215061Sgarrison                break;
100316244Srrh 	    refinfo[j].ri_disambig[0] = adstr;
100415061Sgarrison             }
100516244Srrh 	 refinfo[i].ri_disambig[0] = 'a';
100615061Sgarrison          }
100715061Sgarrison      }
100816244Srrh   for (i = 0; i < numrefs; i++){
100916244Srrh 	strcat(refinfo[i].ri_cite, refinfo[i].ri_disambig);
101016244Srrh   }
101115061Sgarrison }
101215061Sgarrison 
101315061Sgarrison 
101412910Sgarrison /* bldname - build a name field
101512910Sgarrison              doing abbreviations, reversals, and caps/small caps
101612910Sgarrison */
101712910Sgarrison    bldname(first, last, name, reverse)
101812910Sgarrison    char *first, *last, name[];
101912910Sgarrison    int reverse;
102012910Sgarrison {
102115903Srrh    char newfirst[120], newlast[120];
102215903Srrh    reg char *p, *q, *f, *l;
102315903Srrh    char *scopy();
102412910Sgarrison    int  flag;
102512910Sgarrison 
102612910Sgarrison    if (abbrev) {
102712910Sgarrison       p = first;
102812910Sgarrison       q = newfirst;
102912910Sgarrison       flag = false;
103012910Sgarrison       while (*p) {
103112910Sgarrison          while (*p == ' ')
103212910Sgarrison             p++;
103312910Sgarrison          if (*p == 0)
103412910Sgarrison             break;
103512910Sgarrison          if (isupper(*p)) {
103615061Sgarrison             if (flag)           /* between initial gap */
103712910Sgarrison                q = scopy(q, "\\*(a]");
103812910Sgarrison             flag = true;
103912910Sgarrison             *q++ = *p;
104015061Sgarrison             q = scopy(q, "\\*(p]");
104112910Sgarrison             }
104212910Sgarrison          if (*++p == '.')
104312910Sgarrison             p++;
104412910Sgarrison          else while (*p != 0 && ! isspace(*p))
104512910Sgarrison             p++;
104612910Sgarrison          }
104712910Sgarrison       *q = 0;
104812910Sgarrison       f = newfirst;
104912910Sgarrison       }
105012910Sgarrison    else
105112910Sgarrison       f = first;
105212910Sgarrison 
105312910Sgarrison    if (capsmcap) {
105412910Sgarrison       p = last;
105512910Sgarrison       q = newlast;
105612910Sgarrison       flag = 0;  /* 1 - printing cap, 2 - printing small */
105712910Sgarrison       while (*p)
105812910Sgarrison          if (islower(*p)) {
105912910Sgarrison             if (flag != 2)
106012910Sgarrison                q = scopy(q, "\\s-2");
106112910Sgarrison             flag = 2;
106212910Sgarrison             *q++ = (*p++ - 'a') + 'A';
106312910Sgarrison             }
106412910Sgarrison          else {
106512910Sgarrison             if (flag == 2)
106612910Sgarrison                q = scopy(q,"\\s+2");
106712910Sgarrison             flag = 1;
106812910Sgarrison             *q++ = *p++;
106912910Sgarrison             }
107012910Sgarrison       if (flag == 2)
107112910Sgarrison          q = scopy(q, "\\s+2");
107212910Sgarrison       *q = 0;
107312910Sgarrison       l = newlast;
107412910Sgarrison       }
107512910Sgarrison    else
107612910Sgarrison       l = last;
107712910Sgarrison 
107815061Sgarrison    if (f[0] == 0)
107915061Sgarrison       sprintf(name, "%s\n", l);
108015061Sgarrison    else if (reverse)
108115061Sgarrison       sprintf(name, "%s\\*(b]%s\n", l, f);
108212910Sgarrison    else
108312910Sgarrison       sprintf(name, "%s %s\n", f, l);
108412910Sgarrison }
108512910Sgarrison 
108612910Sgarrison /* prtauth - print author or editor field */
108712910Sgarrison    prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
108812910Sgarrison    char c, *line;
108912910Sgarrison    int  num, max, abbrev, capsmcap, numrev;
109012910Sgarrison    FILE *ofd;
109112910Sgarrison {  char first[LINELENGTH], last[LINELENGTH];
109212910Sgarrison 
109312910Sgarrison    if (num <= numrev || abbrev || capsmcap) {
109412910Sgarrison       breakname(line, first, last);
109512910Sgarrison       bldname(first, last, line, num <= numrev);
109612910Sgarrison       }
109712910Sgarrison    if (num == 1)
109812910Sgarrison       fprintf(ofd,".ds [%c %s", c, line);
109912910Sgarrison    else if (num < max)
110012910Sgarrison       fprintf(ofd,".as [%c \\*(c]%s", c, line);
110112910Sgarrison    else if (max == 2)
110212910Sgarrison       fprintf(ofd,".as [%c \\*(n]%s", c, line);
110312910Sgarrison    else
110412910Sgarrison       fprintf(ofd,".as [%c \\*(m]%s", c, line);
110512910Sgarrison    if (num == max && index(trailstr, c))
110612910Sgarrison       fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
110712910Sgarrison }
110812910Sgarrison 
110912910Sgarrison /* doline - actually print out a line of reference information */
111012910Sgarrison    doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
111112910Sgarrison    char c, *line;
111212910Sgarrison    int numauths, maxauths, numeds, maxeds;
111312910Sgarrison    FILE *ofd;
111412910Sgarrison {
111512910Sgarrison 
111612910Sgarrison    switch(c) {
111712910Sgarrison       case 'A':
111812910Sgarrison           prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
111912910Sgarrison           break;
112012910Sgarrison 
112112910Sgarrison        case 'E':
112212910Sgarrison           prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
112312910Sgarrison           if (numeds == maxeds)
112412910Sgarrison              fprintf(ofd,".nr [E %d\n", maxeds);
112512910Sgarrison           break;
112612910Sgarrison 
112712910Sgarrison        case 'P':
112812910Sgarrison           if (index(line, '-'))
112912910Sgarrison              fprintf(ofd,".nr [P 1\n");
113012910Sgarrison           else
113112910Sgarrison              fprintf(ofd,".nr [P 0\n");
113212910Sgarrison           fprintf(ofd,".ds [P %s",line);
113312910Sgarrison           if (index(trailstr, 'P'))
113412910Sgarrison              fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
113512910Sgarrison           break;
113612910Sgarrison 
113712910Sgarrison        case 'F':
113812910Sgarrison        case 'K': break;
113912910Sgarrison 
114012910Sgarrison        default:
114112910Sgarrison           fprintf(ofd,".ds [%c %s", c, line);
114212910Sgarrison           if (index(trailstr, c))
114312910Sgarrison              fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
114412910Sgarrison           }
114512910Sgarrison }
114612910Sgarrison 
114715061Sgarrison /* dumpref - dump reference number i */
114815061Sgarrison    dumpref(i, ofd)
114915061Sgarrison    int i;
115015061Sgarrison    FILE *ofd;
115115903Srrh {  char ref[REFSIZE], line[REFSIZE];
115215903Srrh    reg char *p, *q;
115315903Srrh    char *from;
115415061Sgarrison    int numauths, maxauths, numeds, maxeds;
115515061Sgarrison 
115615903Srrh    rdref(&refinfo[i], ref);
115715061Sgarrison    maxauths = maxeds = 0;
115815061Sgarrison    numauths = numeds = 0;
115915061Sgarrison    for (p = ref; *p; p++)
116015061Sgarrison       if (*p == '%')
116115061Sgarrison          if (*(p+1) == 'A') maxauths++;
116215061Sgarrison          else if (*(p+1) == 'E') maxeds++;
116315061Sgarrison    fprintf(ofd, ".[-\n");
116415903Srrh    fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite);
116515903Srrh #ifndef INCORE
116615903Srrh    fseek(rfd, (long)refinfo[i].ri_pos, 0);
116715061Sgarrison    while (fgets(line, REFSIZE, rfd) != NULL) {
116815903Srrh #else INCORE
116915903Srrh    for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */
117015903Srrh 	if (*from == '\n'){
117115903Srrh 		*q++ = '\n';
117215903Srrh 		*q = 0;
117315903Srrh 		q = line;
117415903Srrh 		from++;
117515903Srrh 	} else {
117615903Srrh 		*q++ = *from++;
117715903Srrh 		continue;
117815903Srrh 	}
117915903Srrh #endif INCORE
118015903Srrh 	switch(line[0]){
118115903Srrh 	case 0:
118215903Srrh 		goto doneref;
118315903Srrh 	case '.':
118415903Srrh 		fprintf(ofd, "%s", line);
118515903Srrh 		break;
118615903Srrh 	case '%':
118715903Srrh 		switch(line[1]){
118815903Srrh 		case 'A':	numauths++;	break;
118915903Srrh 		case 'E':	numeds++;	break;
119015903Srrh 		}
119115903Srrh 		for (p = &line[2]; *p == ' '; p++) /*VOID*/;
119215903Srrh 		doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
119315903Srrh 	}
119415903Srrh    }
119515903Srrh    doneref:;
119615061Sgarrison    fprintf(ofd,".][\n");
119715061Sgarrison }
1198