113110Srrh #ifndef lint
2*60507Sbostic static char sccsid[] = "@(#)bibargs.c 2.13 05/27/93";
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
14*60507Sbostic version 8/23/1988
15*60507Sbostic
16*60507Sbostic Adapted to use TiB style macro calls (i.e. |macro|)
17*60507Sbostic A. Dain Samples
1815061Sgarrison
1915061Sgarrison
20*60507Sbostic
21*60507Sbostic
2212910Sgarrison read argument strings for bib and listrefs
2312910Sgarrison do name formatting, printing lines, other actions common to both
2412910Sgarrison */
2512910Sgarrison # include <stdio.h>
2612910Sgarrison # include <ctype.h>
2712910Sgarrison # include "bib.h"
2812910Sgarrison # define LINELENGTH 1024
2912910Sgarrison # define MAXDEFS 500 /* maximum number of defined words */
3012910Sgarrison
3112910Sgarrison /* global variables */
3215061Sgarrison char bibfname[120]; /* file name currently being read */
3315061Sgarrison int biblineno; /* line number currently being referenced */
3412910Sgarrison int abbrev = false; /* automatically abbreviate names */
3512910Sgarrison int capsmcap = false; /* print names in caps small caps (CACM form)*/
36*60507Sbostic int TibOption = false; /* expect files in TiB format */
37*60507Sbostic int TibxOption = false; /* to create files for bib2tib */
3812910Sgarrison int numrev = 0; /* number of authors names to reverse */
3912910Sgarrison int edabbrev = false; /* abbreviate editors names ? */
4012910Sgarrison int edcapsmcap = false; /* print editors in cap small caps */
4112910Sgarrison int ednumrev = 0; /* number of editors to reverse */
4223485Sgarrison int max_klen = 6; /* max size of key */
4312910Sgarrison int sort = false; /* sort references ? (default no) */
4412910Sgarrison int foot = false; /* footnoted references ? (default endnotes) */
45*60507Sbostic int doacite = true; /* place citations ? */
46*60507Sbostic int redefWarning = false; /* warnings on attempted redefs ? */
4712910Sgarrison int hyphen = false; /* hypenate contiguous references */
4812910Sgarrison int ordcite = true; /* order multiple citations */
4912910Sgarrison char sortstr[80] = "1"; /* sorting template */
5012910Sgarrison char trailstr[80] = ""; /* trailing characters to output */
5125528Sgarrison char pfile[400]; /* private file name */
5212910Sgarrison int personal = false; /* personal file given ? (default no) */
5312910Sgarrison char citetemplate[80] = "1"; /* citation template */
5415903Srrh struct wordinfo words[MAXDEFS]; /* defined words */
5515903Srrh struct wordinfo *wordhash[HASHSIZE];
5615903Srrh struct wordinfo *wordsearch();
5715903Srrh int wordtop = 0; /* number of defined words */
58*60507Sbostic char letterSeen[128]; /* keeps track of keyletters
59*60507Sbostic * so we know whether to emit a .ds
60*60507Sbostic * or a .as
61*60507Sbostic /* */
6212910Sgarrison
6312910Sgarrison /* where output goes */
6412910Sgarrison extern FILE *tfd;
6515061Sgarrison /* reference file information */
6615903Srrh extern struct refinfo refinfo[];
6715061Sgarrison extern char reffile[];
6815903Srrh #ifndef INCORE
6915061Sgarrison extern FILE *rfd;
7015903Srrh #endif not INCORE
7115061Sgarrison extern int numrefs;
72*60507Sbostic extern char *programName;
7312910Sgarrison
74*60507Sbostic char *usageArr[] = {
75*60507Sbostic "-aa abbreviate authors' first names",
76*60507Sbostic "-arN reverse first N authors' names; no N, do all",
77*60507Sbostic "-ax print authors' last names in Caps-Small",
78*60507Sbostic "-cS use template S for citations",
79*60507Sbostic "-d change the default directory",
80*60507Sbostic "-ea abbreviate editors' first names",
81*60507Sbostic "-ex print editors' last names in Caps-Small",
82*60507Sbostic "-erN reverse first N editors' names; no N, do all",
83*60507Sbostic "-f dump reference after citation for footnotes",
84*60507Sbostic "-iFILE process FILE (e.g. a file of definitions)",
85*60507Sbostic "-h hyphenate sequences of citations (turns on -o)",
86*60507Sbostic "-nS turn off options; S is composed of the option letters 'afhosx'",
87*60507Sbostic "-pFILE search these FILEs (comma separated list) instead of INDEX",
88*60507Sbostic "-R print warnings when duplicate definitions of names are ignored",
89*60507Sbostic "-sS sort references according to template S",
90*60507Sbostic "-tTYPE use the style TYPE",
91*60507Sbostic "-Tib expect files to be in TiB format (which see)",
92*60507Sbostic "-Tibx write a file for converting bib to TiB-style |macros|",
93*60507Sbostic "",
94*60507Sbostic 0
95*60507Sbostic };
96*60507Sbostic
97*60507Sbostic void
usageErr(argv0,opt,str)98*60507Sbostic usageErr(argv0, opt, str)
99*60507Sbostic char *argv0;
100*60507Sbostic char *opt;
101*60507Sbostic char *str;
102*60507Sbostic {
103*60507Sbostic char **p;
104*60507Sbostic fprintf(stderr, "Illegal invocation of %s. Acceptable options:\n",
105*60507Sbostic argv0);
106*60507Sbostic fprintf(stderr, "Argument: %s\n", opt);
107*60507Sbostic fprintf(stderr, "Problem: %s\n", str);
108*60507Sbostic for (p = usageArr; *p != 0; p++) {
109*60507Sbostic fprintf(stderr, " %s\n", *p);
110*60507Sbostic }
111*60507Sbostic }
112*60507Sbostic
113*60507Sbostic /* bibwarning - print out a warning message */
114*60507Sbostic /*VARARGS1*/
bibwarning(msg,a1,a2)115*60507Sbostic bibwarning(msg, a1, a2)
116*60507Sbostic char *msg;
117*60507Sbostic {
118*60507Sbostic fprintf(stderr,"%s: `%s', line %d: ", programName, bibfname, biblineno);
119*60507Sbostic fprintf(stderr, msg, a1, a2);
120*60507Sbostic fprintf(stderr, "\n");
121*60507Sbostic }
122*60507Sbostic
123*60507Sbostic
124*60507Sbostic
12512910Sgarrison /* doargs - read command argument line for both bib and listrefs
12612910Sgarrison set switch values
12712910Sgarrison call rdtext on file arguments, after dumping
12812910Sgarrison default style file if no alternative style is given
12912910Sgarrison */
130*60507Sbostic
doargs(argc,argv,defstyle)13112910Sgarrison int doargs(argc, argv, defstyle)
13212910Sgarrison int argc;
13312910Sgarrison char **argv, defstyle[];
13412910Sgarrison { int numfiles, i, style;
13512910Sgarrison char *p, *q, *walloc();
13612910Sgarrison FILE *fd;
13712910Sgarrison
13812910Sgarrison numfiles = 0;
13912910Sgarrison style = true;
140*60507Sbostic TibxOption = false;
14117248Srrh newbibdir(BMACLIB);
14212910Sgarrison
143*60507Sbostic programName = argv[0];
14412910Sgarrison for (i = 1; i < argc; i++)
14512910Sgarrison if (argv[i][0] == '-')
14612910Sgarrison switch(argv[i][1]) {
14715061Sgarrison case 'a': for (p = &argv[i][2]; *p; p++)
14815061Sgarrison if (*p == 'a' || *p == 0)
14912961Sgarrison abbrev = true;
15012961Sgarrison else if (*p == 'x')
15112961Sgarrison capsmcap = true;
15212961Sgarrison else if (*p == 'r') {
15312961Sgarrison if (*(p+1))
15412961Sgarrison numrev = atoi(p+1);
15512961Sgarrison else
15612961Sgarrison numrev = 1000;
15712961Sgarrison break;
15812961Sgarrison }
15912910Sgarrison break;
16012910Sgarrison
16112910Sgarrison case 'c': if (argv[i][2] == 0)
16215903Srrh error("citation string expected for 'c'");
16312910Sgarrison else
16412910Sgarrison for (p = citetemplate,q = &argv[i][2]; *p++ = *q++; );
16512910Sgarrison break;
16612910Sgarrison
167*60507Sbostic case 'd': if (argv[i][2])
168*60507Sbostic p = &argv[i][2];
169*60507Sbostic else { /* take next arg */
170*60507Sbostic i++;
171*60507Sbostic p = argv[i];
172*60507Sbostic }
173*60507Sbostic newbibdir(p);
174*60507Sbostic break;
175*60507Sbostic
17612910Sgarrison case 'e': for (p = &argv[i][2]; *p; p++)
17712910Sgarrison if (*p == 'a')
17812910Sgarrison edabbrev = true;
17912910Sgarrison else if (*p == 'x')
18012910Sgarrison edcapsmcap = true;
18112910Sgarrison else if (*p == 'r') {
18212910Sgarrison if (*(p+1))
18312910Sgarrison ednumrev = atoi(p+1);
18412910Sgarrison else
18512910Sgarrison ednumrev = 1000;
18612910Sgarrison break;
18712910Sgarrison }
18812910Sgarrison break;
18912910Sgarrison
190*60507Sbostic case 'f': CASE_f:
191*60507Sbostic foot = true;
192*60507Sbostic hyphen = false;
193*60507Sbostic break;
194*60507Sbostic
195*60507Sbostic case 'i': CASE_i:
196*60507Sbostic if (argv[i][2])
197*60507Sbostic p = &argv[i][2];
198*60507Sbostic else { /* take next arg */
199*60507Sbostic i++;
200*60507Sbostic p = argv[i];
201*60507Sbostic }
202*60507Sbostic incfile(p);
203*60507Sbostic break;
204*60507Sbostic
20523485Sgarrison case 'l': if (argv[i][2]){
20623485Sgarrison max_klen = atoi(&argv[i][2]);
20723485Sgarrison if (max_klen > REFSIZE)
20823485Sgarrison error("too long key size");
20923485Sgarrison } else {
21023485Sgarrison error("-l needs a numeric value");
21123485Sgarrison }
21223485Sgarrison break;
21323485Sgarrison
21412910Sgarrison case 'h': hyphen = ordcite = true;
21512910Sgarrison break;
21612910Sgarrison
21712910Sgarrison case 'n': for (p = &argv[i][2]; *p; p++)
21812910Sgarrison if (*p == 'a')
21912910Sgarrison abbrev = false;
22012910Sgarrison else if (*p == 'f')
22112910Sgarrison foot = false;
22212910Sgarrison else if (*p == 'h')
22312910Sgarrison hyphen = false;
22412910Sgarrison else if (*p == 'o')
22512910Sgarrison ordcite = false;
226*60507Sbostic else if (*p == 'R')
227*60507Sbostic redefWarning = false;
22812910Sgarrison else if (*p == 'r')
22912910Sgarrison numrev = 0;
23012910Sgarrison else if (*p == 's')
23112910Sgarrison sort = false;
23212910Sgarrison else if (*p == 'x')
23312910Sgarrison capsmcap = false;
234*60507Sbostic else if (*p == 'v')
235*60507Sbostic doacite = true;
23612910Sgarrison break;
23712910Sgarrison
23812910Sgarrison case 'o': ordcite = true;
23912910Sgarrison break;
24012910Sgarrison
24112910Sgarrison case 'p': if (argv[i][2])
24212910Sgarrison p = &argv[i][2];
24312910Sgarrison else { /* take next arg */
24412910Sgarrison i++;
24512910Sgarrison p = argv[i];
24612910Sgarrison }
24712910Sgarrison strcpy(pfile, p);
24812910Sgarrison personal = true;
24912910Sgarrison break;
25012910Sgarrison
251*60507Sbostic case 'R': redefWarning = true;
252*60507Sbostic break;
253*60507Sbostic
254*60507Sbostic case 'r': if (argv[i][2] == 0) /* synonym -ar */
25512910Sgarrison numrev = 1000;
25612910Sgarrison else
25712910Sgarrison numrev = atoi(&argv[i][2]);
25812910Sgarrison break;
25912910Sgarrison
26012910Sgarrison case 's': sort = true;
26112910Sgarrison if (argv[i][2])
26212910Sgarrison for (p = sortstr,q = &argv[i][2]; *p++ = *q++; );
26312910Sgarrison break;
26412910Sgarrison
265*60507Sbostic case 't': style = false;
266*60507Sbostic goto CASE_i;
26712910Sgarrison
268*60507Sbostic case 'T': if (strcmp("Tib", &(argv[i][1])) == 0)
269*60507Sbostic TibOption = true;
270*60507Sbostic else if (strcmp("Tibx",&(argv[i][1])) == 0)
271*60507Sbostic TibxOption = true;
272*60507Sbostic else {
273*60507Sbostic usageErr(argv[0], argv[i],
274*60507Sbostic "Did you want the Tib option?");
275*60507Sbostic error("'%s' invalid switch", argv[i]);
276*60507Sbostic }
277*60507Sbostic break;
278*60507Sbostic
279*60507Sbostic case 'v': doacite = false;
280*60507Sbostic goto CASE_f;
281*60507Sbostic
282*60507Sbostic case 'x': capsmcap = true; /* synonym for -ax */
28312910Sgarrison break;
28412910Sgarrison
28512910Sgarrison case 0: if (style) { /* no style command given, take default */
28612910Sgarrison style = false;
28712910Sgarrison incfile( defstyle );
28812910Sgarrison }
28915061Sgarrison strcpy(bibfname,"<stdin>");
29012910Sgarrison rdtext(stdin);
29112910Sgarrison numfiles++;
29212910Sgarrison break;
29312910Sgarrison
294*60507Sbostic default: usageErr(argv[0], argv[i], "Invalid switch");
29515903Srrh error("'%c' invalid switch", argv[i][1]);
29612910Sgarrison }
29712910Sgarrison else { /* file name */
29812910Sgarrison numfiles++;
29912910Sgarrison if (style) {
30012910Sgarrison style = false;
30112910Sgarrison incfile( defstyle );
30212910Sgarrison }
30312910Sgarrison fd = fopen(argv[i], "r");
30412910Sgarrison if (fd == NULL) {
30515903Srrh error("can't open file %s", argv[i]);
30612910Sgarrison }
30712910Sgarrison else {
30815061Sgarrison strcpy(bibfname, argv[i]);
30912910Sgarrison rdtext(fd);
31012910Sgarrison fclose(fd);
31112910Sgarrison }
31212910Sgarrison }
31312910Sgarrison
31412910Sgarrison if (style) incfile( defstyle );
315*60507Sbostic if (TibxOption) {
316*60507Sbostic /*
317*60507Sbostic Emits m4 macros that allow easy transformation of old bib-style
318*60507Sbostic bibliographic databases into tib-style. The primary problem
319*60507Sbostic (although not the only one) is the change of |macro| calls.
320*60507Sbostic */
321*60507Sbostic reg struct wordinfo *wp;
322*60507Sbostic FILE *outf;
323*60507Sbostic outf = fopen("bib.m4.in","w");
324*60507Sbostic for (i=0; i<HASHSIZE; i++) {
325*60507Sbostic for (wp = wordhash[i]; wp != NULL; wp = wp->wi_hp) {
326*60507Sbostic fprintf(outf,"define(%s,|%s__m4_|)dnl\n",wp->wi_word,wp->wi_word);
327*60507Sbostic }
328*60507Sbostic }
329*60507Sbostic fclose(outf);
330*60507Sbostic }
33112910Sgarrison return(numfiles);
33212910Sgarrison
33312910Sgarrison }
33412910Sgarrison
newbibdir(name)33517248Srrh newbibdir(name)
33617248Srrh char *name;
33717248Srrh {
338*60507Sbostic strreplace(COMFILE, BMACLIB, name);
339*60507Sbostic strreplace(DEFSTYLE, BMACLIB, name);
340*60507Sbostic strcpy(BMACLIB, name);
341*60507Sbostic wordrestuff("BMACLIB", BMACLIB);
342*60507Sbostic fprintf(tfd, ".ds l] %s\n", BMACLIB);
34317248Srrh }
34417248Srrh
34512910Sgarrison /* incfile - read in an included file */
incfile(np)34612910Sgarrison incfile(np)
34712910Sgarrison char *np;
34812910Sgarrison { char name[120];
34912910Sgarrison FILE *fd;
35015061Sgarrison char *p, line[LINELENGTH], dline[LINELENGTH], word[80], *tfgets();
35116244Srrh int i, getwrd();
35212910Sgarrison
353*60507Sbostic strcpy(line, bibfname); /* temporary save in case of errors */
354*60507Sbostic /* first try ./<yourfile> */
355*60507Sbostic strcpy(bibfname, np);
356*60507Sbostic fd = fopen(bibfname, "r");
357*60507Sbostic /* try BMACLIB/<yourfile> */
35812910Sgarrison if (fd == NULL && *np != '/') {
359*60507Sbostic strcpy(name, BMACLIB); strcat(name, "/"); strcat(name, np);
36015061Sgarrison strcpy(bibfname, name);
361*60507Sbostic fd = fopen(bibfname, "r");
36212910Sgarrison }
363*60507Sbostic /* try BMACLIB/tibmacs/<yourfile> */
364*60507Sbostic if (TibOption && fd == NULL && *np != '/') {
365*60507Sbostic strcpy(name, BMACLIB); strcat(name, "/tibmacs/"); strcat(name, np);
366*60507Sbostic strcpy(bibfname, name);
367*60507Sbostic fd = fopen(bibfname, "r");
368*60507Sbostic }
369*60507Sbostic /* try BMACLIB/bibmacs/<yourfile> */
370*60507Sbostic if (!TibOption && fd == NULL && *np != '/') {
371*60507Sbostic strcpy(name, BMACLIB); strcat(name, "/bibmacs/"); strcat(name, np);
372*60507Sbostic strcpy(bibfname, name);
373*60507Sbostic fd = fopen(bibfname, "r");
374*60507Sbostic }
375*60507Sbostic /* try ./bib.<yourfile> */
37612910Sgarrison if (fd == NULL && *np != '/') {
377*60507Sbostic strcpy(name, "bib."); strcat(name, np);
37815061Sgarrison strcpy(bibfname, name);
379*60507Sbostic fd = fopen(bibfname, "r");
38012910Sgarrison }
381*60507Sbostic /* try BMACLIB/bib.<yourfile> */
382*60507Sbostic if (fd == NULL && *np != '/') {
383*60507Sbostic strcpy(name,BMACLIB); strcat(name, "/bib."); strcat(name, np);
384*60507Sbostic strcpy(bibfname, name);
385*60507Sbostic fd = fopen(bibfname, "r");
386*60507Sbostic }
38712910Sgarrison if (fd == NULL) {
388*60507Sbostic /* unsave old name */
389*60507Sbostic strcpy(bibfname, line);
390*60507Sbostic bibwarning("%s: can't find", np);
39115061Sgarrison exit(1);
39212910Sgarrison }
39312910Sgarrison
39415061Sgarrison /* now go off and process file */
39515061Sgarrison biblineno = 1;
39615061Sgarrison while (tfgets(line, LINELENGTH, fd) != NULL) {
39715061Sgarrison biblineno++;
39812910Sgarrison switch(line[0]) {
39912910Sgarrison
40012910Sgarrison case '#': break;
40112910Sgarrison
40212961Sgarrison case 'A': for (p = &line[1]; *p; p++)
40315061Sgarrison if (*p == 'A' || *p == '\0')
40412961Sgarrison abbrev = true;
40512961Sgarrison else if (*p == 'X')
40612961Sgarrison capsmcap = true;
40712961Sgarrison else if (*p == 'R') {
40812961Sgarrison if (*(p+1))
40912961Sgarrison numrev = atoi(p+1);
41012961Sgarrison else
41112961Sgarrison numrev = 1000;
41212961Sgarrison break;
41312961Sgarrison }
41412910Sgarrison break;
41512910Sgarrison
41612910Sgarrison case 'C': for (p = &line[1]; *p == ' '; p++) ;
41712910Sgarrison strcpy(citetemplate, p);
41812910Sgarrison break;
41912910Sgarrison
42012910Sgarrison case 'D': if ((i = getwrd(line, 1, word)) == 0)
42112910Sgarrison error("word expected in definition");
42223492Sgarrison if (wordsearch(word)) { /* already there-toss rest of def.*/
423*60507Sbostic if (redefWarning)
424*60507Sbostic bibwarning("Attempted redefine of %s ignored.",word);
42523492Sgarrison while(line[strlen(line)-1] == '\\' ) {
42623492Sgarrison if (tfgets(line, LINELENGTH, fd) == NULL) break;
42723492Sgarrison }
42815903Srrh break;
42923492Sgarrison }
430*60507Sbostic for (p = &line[i]; isspace(*p); p++) ;
43112910Sgarrison for (strcpy(dline, p); dline[strlen(dline)-1] == '\\'; ){
43212910Sgarrison dline[strlen(dline)-1] = '\n';
43315061Sgarrison if (tfgets(line, LINELENGTH, fd) == NULL) break;
43412910Sgarrison strcat(dline, line);
43512910Sgarrison }
43615903Srrh wordstuff(word, dline);
43712910Sgarrison break;
43812910Sgarrison
43912910Sgarrison case 'E': for (p = &line[1]; *p; p++)
44012910Sgarrison if (*p == 'A')
44112910Sgarrison edabbrev = true;
44212910Sgarrison else if (*p == 'X')
44312910Sgarrison edcapsmcap = true;
44412910Sgarrison else if (*p == 'R') {
44512910Sgarrison if (*(p+1))
44612910Sgarrison ednumrev = atoi(p+1);
44712910Sgarrison else
44812910Sgarrison ednumrev = 1000;
44912910Sgarrison break;
45012910Sgarrison }
45112910Sgarrison break;
45212910Sgarrison
45312910Sgarrison case 'F': foot = true;
45412910Sgarrison hyphen = false;
45512910Sgarrison break;
45612910Sgarrison
45712910Sgarrison case 'I': for (p = &line[1]; *p == ' '; p++);
45812910Sgarrison expand(p);
45912910Sgarrison incfile(p);
46012910Sgarrison break;
46112910Sgarrison
46212910Sgarrison case 'H': hyphen = ordcite = true;
46312910Sgarrison break;
46412910Sgarrison
46512910Sgarrison case 'O': ordcite = true;
46612910Sgarrison break;
46712910Sgarrison
46815061Sgarrison case 'R': if (line[1] == 0) /* this is now replaced by AR */
46912910Sgarrison numrev = 1000;
47012910Sgarrison else
47112910Sgarrison numrev = atoi(&line[1]);
47212910Sgarrison break;
47312910Sgarrison
47412910Sgarrison case 'S': sort = true;
47512910Sgarrison for (p = &line[1]; *p == ' '; p++) ;
47612910Sgarrison strcpy(sortstr, p);
47712910Sgarrison break;
47812910Sgarrison
47912910Sgarrison case 'T': for (p = &line[1]; *p == ' '; p++) ;
48012910Sgarrison strcpy(trailstr, p);
48112910Sgarrison break;
48212910Sgarrison
48315061Sgarrison case 'X': capsmcap = true; /* this is now replace by AX */
48412910Sgarrison break;
48512910Sgarrison
48612910Sgarrison default: fprintf(tfd,"%s\n",line);
48715061Sgarrison while (fgets(line, LINELENGTH, fd) != NULL)
48812910Sgarrison fputs(line, tfd);
48912910Sgarrison return;
49012910Sgarrison }
49115061Sgarrison
49215061Sgarrison }
49315061Sgarrison /* close up */
49415061Sgarrison fclose(fd);
49512910Sgarrison }
49612910Sgarrison
49715061Sgarrison /* error - report unrecoverable error message */
49815903Srrh /*VARARGS1*/
error(str,a1,a2)49915903Srrh error(str, a1, a2)
50015903Srrh char *str;
50115061Sgarrison {
50215903Srrh bibwarning(str, a1, a2);
50315903Srrh /*
50415903Srrh * clean up temp files and exit
50515903Srrh */
50615903Srrh cleanup(1);
50715061Sgarrison }
50815061Sgarrison
50915903Srrh #ifndef INCORE
51015061Sgarrison #ifdef READWRITE
51115061Sgarrison /*
51215061Sgarrison ** fixrfd( mode ) -- re-opens the rfd file to be read or write,
51315061Sgarrison ** depending on the mode. Uses a static int to save the current mode
51415061Sgarrison ** and avoid unnecessary re-openings.
51515061Sgarrison */
fixrfd(mode)51615061Sgarrison fixrfd( mode )
51715061Sgarrison register int mode;
51815061Sgarrison {
51915061Sgarrison static int cur_mode = WRITE; /* rfd open for writing initially */
52015061Sgarrison
52115061Sgarrison if (mode != cur_mode)
52215061Sgarrison {
52315061Sgarrison rfd = freopen(reffile, ((mode == READ)? "r" : "a"), rfd);
52415061Sgarrison cur_mode = mode;
52515061Sgarrison if (rfd == NULL)
52615903Srrh error("Hell! Couldn't re-open reference file %s",
52715903Srrh reffile);
52815061Sgarrison }
52915061Sgarrison }
53015061Sgarrison #endif
53115903Srrh #endif not INCORE
53215061Sgarrison
53315061Sgarrison
53415061Sgarrison /* tfgets - fgets which trims off newline */
tfgets(line,n,ptr)53515061Sgarrison char *tfgets(line, n, ptr)
53615061Sgarrison char line[];
53715061Sgarrison int n;
53815061Sgarrison FILE *ptr;
53915903Srrh { reg char *p;
54015061Sgarrison
54115061Sgarrison p = fgets(line, n, ptr);
54215061Sgarrison if (p == NULL)
54315061Sgarrison return(NULL);
54415061Sgarrison else
54515061Sgarrison for (p = line; *p; p++)
54615061Sgarrison if (*p == '\n')
54715061Sgarrison *p = 0;
54815061Sgarrison return(line);
54915061Sgarrison }
55015061Sgarrison
55115061Sgarrison /* getwrd - place next word from in[i] into out */
getwrd(in,i,out)55215061Sgarrison int getwrd(in, i, out)
55315903Srrh reg char in[], out[];
55415903Srrh reg int i;
55515061Sgarrison { int j;
55615061Sgarrison
55715061Sgarrison j = 0;
558*60507Sbostic while (isspace(in[i]))
55915061Sgarrison i++;
560*60507Sbostic if (in[i] != '\0')
561*60507Sbostic while (in[i] != '\0' && !isspace(in[i]))
56215061Sgarrison out[j++] = in[i++];
56315061Sgarrison else
56415061Sgarrison i = 0; /* signals end of in[i..] */
56515061Sgarrison out[j] = 0;
56615061Sgarrison return (i);
56715061Sgarrison }
56815061Sgarrison
56915061Sgarrison /* walloc - allocate enough space for a word */
walloc(word)57015061Sgarrison char *walloc(word)
57115061Sgarrison char *word;
57215061Sgarrison { char *i, *malloc();
57315061Sgarrison i = malloc(1 + strlen(word));
57415061Sgarrison if (i == NULL)
57515061Sgarrison error("out of storage");
57615061Sgarrison strcpy(i, word);
57715061Sgarrison return(i);
57815061Sgarrison }
57915061Sgarrison
58012910Sgarrison /* isword - see if character is legit word char */
581*60507Sbostic #define iswordc(c) (isalnum(c) || c == '&' || c == '_')
582*60507Sbostic
expand(line)58312910Sgarrison expand(line)
58412910Sgarrison char *line;
585*60507Sbostic { char line2[REFSIZE], word[REFSIZE];
58615903Srrh reg struct wordinfo *wp;
58715903Srrh reg char *p, *q, *w;
58812910Sgarrison
589*60507Sbostic q = line2;
590*60507Sbostic if (TibOption) {
591*60507Sbostic /* expand only macro names in |name| vertical bars; name must exist */
592*60507Sbostic for (p = line; *p != '\0'; /* VOID */ ) {
593*60507Sbostic if (*p == '|') {
594*60507Sbostic p++;
595*60507Sbostic w = word;
596*60507Sbostic while (*p != '|' && *p != '\0' && !isspace(*p)) { *w++ = *p++; }
597*60507Sbostic *w = '\0';
598*60507Sbostic /* skip second '|', if present */
599*60507Sbostic if (*p++ != '|') {
600*60507Sbostic --p;
601*60507Sbostic bibwarning("Unbalanced |macro| bars\n");
602*60507Sbostic }
603*60507Sbostic else if ((wp = wordsearch(word)) != 0) {
604*60507Sbostic strcpy(word, wp->wi_def);
605*60507Sbostic if (wp->wi_expanding) {
606*60507Sbostic bibwarning("Recursive definition for |%s|\n", word);
607*60507Sbostic }
608*60507Sbostic else {
609*60507Sbostic wp->wi_expanding = true;
610*60507Sbostic expand(word);
611*60507Sbostic wp->wi_expanding = false;
612*60507Sbostic }
613*60507Sbostic }
614*60507Sbostic else {
615*60507Sbostic char errword[REFSIZE];
616*60507Sbostic bibwarning("word |%s| not defined\n", word);
617*60507Sbostic strcpy(errword, "?");
618*60507Sbostic strcat(errword, word);
619*60507Sbostic strcat(errword, "?");
620*60507Sbostic wordstuff(word, errword);
621*60507Sbostic strcpy(word, errword);
622*60507Sbostic }
623*60507Sbostic for (w = word; *w != '\0'; *q++ = *w++);
624*60507Sbostic }
625*60507Sbostic else {
626*60507Sbostic *q++ = *p++;
627*60507Sbostic }
628*60507Sbostic }
629*60507Sbostic }
630*60507Sbostic else {
631*60507Sbostic for (p = line; *p != '\0'; /*VOID*/){
632*60507Sbostic if (isalnum(*p)) {
633*60507Sbostic for (w = word; *p && iswordc(*p); ) *w++ = *p++;
634*60507Sbostic *w = 0;
635*60507Sbostic if (wp = wordsearch(word)){
636*60507Sbostic if (wp->wi_expanding)
637*60507Sbostic bibwarning("Recursive definition for %s\n", word);
638*60507Sbostic else {
639*60507Sbostic strcpy(word, wp->wi_def);
640*60507Sbostic wp->wi_expanding = true;
641*60507Sbostic expand(word);
642*60507Sbostic wp->wi_expanding = false;
643*60507Sbostic }
644*60507Sbostic }
645*60507Sbostic for (w = word; *w != '\0'; *q++ = *w++);
646*60507Sbostic }
647*60507Sbostic else if (*p == '\\' && *(p+1) != '\0') {
648*60507Sbostic *q++ = *p++;
649*60507Sbostic *q++ = *p++;
650*60507Sbostic }
651*60507Sbostic else {
652*60507Sbostic *q++ = *p++;
653*60507Sbostic }
654*60507Sbostic }
655*60507Sbostic }
656*60507Sbostic *q = 0;
657*60507Sbostic strcpy(line, line2);
65812910Sgarrison }
65912910Sgarrison
66015903Srrh /* wordstuff- save a word and its definition, building a hash table */
wordstuff(word,def)66115903Srrh wordstuff(word, def)
66215903Srrh char *word, *def;
66315903Srrh {
66415903Srrh int i;
66515903Srrh if (wordtop >= MAXDEFS)
66615903Srrh error("too many definitions, max of %d", MAXDEFS);
66715903Srrh words[wordtop].wi_length = strlen(word);
668*60507Sbostic words[wordtop].wi_word = word ? walloc(word) : NULL;
669*60507Sbostic words[wordtop].wi_def = def ? walloc(def) : NULL;
67015903Srrh i = strhash(word);
671*60507Sbostic words[wordtop].wi_expanding = false;
67215903Srrh words[wordtop].wi_hp = wordhash[i];
67315903Srrh wordhash[i] = &words[wordtop];
67415903Srrh wordtop++;
67515903Srrh }
wordsearch(word)67615903Srrh struct wordinfo *wordsearch(word)
67715903Srrh char *word;
67815903Srrh {
67915903Srrh reg int lg;
68015903Srrh reg struct wordinfo *wp;
68115903Srrh lg = strlen(word);
68215903Srrh for (wp = wordhash[strhash(word)]; wp; wp = wp->wi_hp){
68315903Srrh if (wp->wi_length == lg && (strcmp(wp->wi_word, word) == 0)){
68415903Srrh return(wp);
68515903Srrh }
68615903Srrh }
68715903Srrh return(0);
68815903Srrh }
689*60507Sbostic /* wordrestuff - save a word and its definition, but replace any existing
690*60507Sbostic * definition; this could be more efficient, but it is only used to
691*60507Sbostic * redefine BMACLIB at the present. -ads 8/88
692*60507Sbostic */
wordrestuff(word,def)693*60507Sbostic wordrestuff(word, def)
694*60507Sbostic char *word, *def;
695*60507Sbostic {
696*60507Sbostic struct wordinfo *wp = wordsearch(word);
697*60507Sbostic if (wp == NULL) wordstuff(word, def);
698*60507Sbostic else {
699*60507Sbostic if (wp->wi_word != NULL) free(wp->wi_word);
700*60507Sbostic if (wp->wi_def != NULL) free(wp->wi_def);
701*60507Sbostic wp->wi_length = strlen(word);
702*60507Sbostic wp->wi_word = word ? walloc(word) : NULL;
703*60507Sbostic wp->wi_def = def ? walloc(def) : NULL;
704*60507Sbostic wp->wi_expanding = false;
705*60507Sbostic }
706*60507Sbostic }
70715903Srrh
strhash(str)70815903Srrh int strhash(str)
70915903Srrh reg char *str;
71015903Srrh {
71115903Srrh reg int value = 0;
71215903Srrh for (value = 0; *str; value <<= 2, value += *str++)/*VOID*/;
71315903Srrh value %= HASHSIZE;
71415903Srrh if (value < 0)
71515903Srrh value += HASHSIZE;
71615903Srrh return(value);
71715903Srrh }
71815903Srrh
71915061Sgarrison /* rdref - read text for an already cited reference */
72015903Srrh rdref(p, ref)
72115903Srrh struct refinfo *p;
72215061Sgarrison char ref[REFSIZE];
72315061Sgarrison {
72415061Sgarrison ref[0] = 0;
72515903Srrh #ifndef INCORE
72615061Sgarrison #ifdef READWRITE
72715061Sgarrison fixrfd( READ ); /* fix access mode of rfd, if nec. */
72815061Sgarrison #endif
72915903Srrh fseek(rfd, p->ri_pos, 0);
73015903Srrh fread(ref, p->ri_length, 1, rfd);
73115903Srrh #else INCORE
73215903Srrh strcpy(ref, p->ri_ref);
73315903Srrh #endif INCORE
73415061Sgarrison }
73515061Sgarrison
73615903Srrh /* wrref - write text for a new reference */
73715903Srrh wrref(p, ref)
73815903Srrh struct refinfo *p;
73915903Srrh char ref[REFSIZE];
74015903Srrh {
74115903Srrh #ifndef INCORE
74215903Srrh #ifdef READWRITE
74315903Srrh fixrfd( WRITE ); /* fix access mode of rfd, if nec. */
74415903Srrh #else
74515903Srrh fseek(rfd, p->ri_pos, 0); /* go to end of rfd */
74615903Srrh #endif
74715903Srrh fwrite(ref, p->ri_length, 1, rfd);
74815903Srrh #else INCORE
74915903Srrh p->ri_ref = walloc(ref);
75015903Srrh #endif INCORE
75115903Srrh }
75215903Srrh
75312910Sgarrison /* breakname - break a name into first and last name */
breakname(line,first,last)75412910Sgarrison breakname(line, first, last)
75512910Sgarrison char line[], first[], last[];
75615903Srrh { reg char *t, *f, *q, *r, *p;
75712910Sgarrison
75812910Sgarrison for (t = line; *t != '\n'; t++);
75912910Sgarrison for (t--; isspace(*t); t--);
76012910Sgarrison
76112910Sgarrison /* now strip off last name */
76212910Sgarrison for (q = t; isspace(*q) == 0 || ((*q == ' ') & (*(q-1) == '\\')); q--)
76312910Sgarrison if (q == line)
76412910Sgarrison break;
76512910Sgarrison f = q;
76615061Sgarrison if (q != line) {
76712910Sgarrison q++;
76815061Sgarrison for (; isspace(*f); f--);
76915061Sgarrison f++;
77015061Sgarrison }
77112910Sgarrison
77212910Sgarrison /* first name is start to f, last name is q to t */
77312910Sgarrison
77415061Sgarrison for (r = first, p = line; p != f; )
77512910Sgarrison *r++ = *p++;
77612910Sgarrison *r = 0;
77712910Sgarrison for (r = last, p = q, t++; q != t; )
77812910Sgarrison *r++ = *q++;
77912910Sgarrison *r = 0;
78015061Sgarrison
78112910Sgarrison }
78212910Sgarrison
78312910Sgarrison /* match - see if string1 is a substring of string2 (case independent)*/
match(str1,str2)78412910Sgarrison int match(str1, str2)
78515903Srrh reg char str1[], str2[];
78615903Srrh { reg int j, i;
78712910Sgarrison char a, b;
78812910Sgarrison
78912910Sgarrison for (i = 0; str2[i]; i++) {
79012910Sgarrison for (j = 0; str1[j]; j++) {
79112910Sgarrison if (isupper(a = str2[i+j]))
79212910Sgarrison a = (a - 'A') + 'a';
79312910Sgarrison if (isupper(b = str1[j]))
79412910Sgarrison b = (b - 'A') + 'a';
79512910Sgarrison if (a != b)
79612910Sgarrison break;
79712910Sgarrison }
79812910Sgarrison if (str1[j] == 0)
79912910Sgarrison return(true);
80012910Sgarrison }
80112910Sgarrison return(false);
80212910Sgarrison }
80312910Sgarrison
80412910Sgarrison /* scopy - append a copy of one string to another */
scopy(p,q)80512910Sgarrison char *scopy(p, q)
80615903Srrh reg char *p, *q;
80712910Sgarrison {
80812910Sgarrison while (*p++ = *q++)
80912910Sgarrison ;
81012910Sgarrison return(--p);
81112910Sgarrison }
81212910Sgarrison
81315061Sgarrison /* rcomp - reference comparison routine for qsort utility */
rcomp(ap,bp)81415061Sgarrison int rcomp(ap, bp)
81515903Srrh struct refinfo *ap, *bp;
81615061Sgarrison { char ref1[REFSIZE], ref2[REFSIZE], field1[MAXFIELD], field2[MAXFIELD];
81715903Srrh reg char *p, *q;
81815903Srrh char *getfield();
81915061Sgarrison int neg, res;
82015061Sgarrison int fields_found;
82115061Sgarrison
82215903Srrh rdref(ap, ref1);
82315903Srrh rdref(bp, ref2);
82415061Sgarrison for (p = sortstr; *p; p = q) {
82515061Sgarrison if (*p == '-') {
82615061Sgarrison p++;
82715061Sgarrison neg = true;
82815061Sgarrison }
82915061Sgarrison else
83015061Sgarrison neg = false;
83115061Sgarrison q = getfield(p, field1, ref1);
83215061Sgarrison fields_found = true;
83315061Sgarrison if (q == 0) {
83415061Sgarrison res = 1;
83515061Sgarrison fields_found = false;
83615061Sgarrison } else if (strcmp (field1, "") == 0) { /* field not found */
83715061Sgarrison if (*p == 'A') {
83815061Sgarrison getfield("F", field1, ref1);
83915061Sgarrison if (strcmp (field1, "") == 0) {
84015061Sgarrison getfield("I", field1, ref1);
84115061Sgarrison if (strcmp (field1, "") == 0) {
84215061Sgarrison res = 1;
84315061Sgarrison fields_found = false;
84415061Sgarrison }
84515061Sgarrison }
84615061Sgarrison } else {
84715061Sgarrison res = 1;
84815061Sgarrison fields_found = false;
84915061Sgarrison }
85015061Sgarrison }
85115061Sgarrison
85215061Sgarrison if (getfield(p, field2, ref2) == 0) {
85315061Sgarrison res = -1;
85415061Sgarrison fields_found = false;
85515061Sgarrison } else if (strcmp (field2, "") == 0) { /* field not found */
85615061Sgarrison if (*p == 'A') {
85715061Sgarrison getfield("F", field2, ref2);
85815061Sgarrison if (strcmp (field2, "") == 0) {
85915061Sgarrison getfield("I", field2, ref2);
86015061Sgarrison if (strcmp (field2, "") == 0) {
86115061Sgarrison res = -1;
86215061Sgarrison fields_found = false;
86315061Sgarrison }
86415061Sgarrison }
86515061Sgarrison } else {
86615061Sgarrison res = -1;
86715061Sgarrison fields_found = false;
86815061Sgarrison }
86915061Sgarrison }
87015061Sgarrison if (fields_found) {
87115061Sgarrison if (*p == 'A') {
87215061Sgarrison if (isupper(field1[0]))
87315061Sgarrison field1[0] -= 'A' - 'a';
87415061Sgarrison if (isupper(field2[0]))
87515061Sgarrison field2[0] -= 'A' - 'a';
87615061Sgarrison }
87715061Sgarrison res = strcmp(field1, field2);
87815061Sgarrison }
87915061Sgarrison if (neg)
88015061Sgarrison res = - res;
88115061Sgarrison if (res != 0)
88215061Sgarrison break;
88315061Sgarrison }
88415061Sgarrison if (res == 0)
88515061Sgarrison if (ap < bp)
88615061Sgarrison res = -1;
88715061Sgarrison else
88815061Sgarrison res = 1;
88915061Sgarrison return(res);
89015061Sgarrison }
89115061Sgarrison
89216244Srrh /* makecites - make standard citation strings, using citetemplate currently in effect */
makecites()89315903Srrh makecites()
89415061Sgarrison { char ref[REFSIZE], tempcite[100], *malloc();
89515903Srrh reg int i;
89615061Sgarrison
89715903Srrh for (i = 0; i < numrefs; i++) {
89815903Srrh rdref(&refinfo[i], ref);
89915061Sgarrison bldcite(tempcite, i, ref);
90016244Srrh refinfo[i].ri_cite = malloc(2 + strlen(tempcite));
90115903Srrh if (refinfo[i].ri_cite == NULL)
90215061Sgarrison error("out of storage");
90315903Srrh strcpy(refinfo[i].ri_cite, tempcite);
90415061Sgarrison }
90515061Sgarrison }
90615061Sgarrison
90715061Sgarrison /* bldcite - build a single citation string */
bldcite(cp,i,ref)90815061Sgarrison bldcite(cp, i, ref)
90915061Sgarrison char *cp, ref[];
91015061Sgarrison int i;
91115903Srrh { reg char *p, *q, *fp;
91215903Srrh char c;
91315903Srrh char field[REFSIZE];
91431947Sbostic char *getfield(), *aabet(), *aabetlast(),
91531947Sbostic *fullaabet(), *multfull();
91615061Sgarrison
91715061Sgarrison getfield("F", field, ref);
91815061Sgarrison if (field[0] != 0)
91915061Sgarrison for (p = field; *p; p++)
92015061Sgarrison *cp++ = *p;
92115061Sgarrison else {
92215061Sgarrison p = citetemplate;
92315061Sgarrison field[0] = 0;
92415061Sgarrison while (c = *p++) {
92515061Sgarrison if (isalpha(c)) { /* field name */
92615061Sgarrison q = getfield(p-1, field, ref);
92715061Sgarrison if (q != 0) {
92815061Sgarrison p = q;
92915061Sgarrison for (fp = field; *fp; )
93015061Sgarrison *cp++ = *fp++;
93115061Sgarrison }
93215061Sgarrison }
93315061Sgarrison else if (c == '1') { /* numeric order */
93415061Sgarrison sprintf(field,"%d",1 + i);
93515061Sgarrison for (fp = field; *fp; )
93615061Sgarrison *cp++ = *fp++;
93715061Sgarrison }
93815061Sgarrison else if (c == '2') /* alternate alphabetic */
93915061Sgarrison cp = aabet(cp, ref);
94015061Sgarrison else if (c == '3') /* Astrophysical Journal style*/
94131947Sbostic cp = multfull(cp, ref, 3);
94231947Sbostic else if (c == '4') /* Computing Surveys style*/
94331947Sbostic cp = multfull(cp, ref, 2);
94423485Sgarrison else if (c == '8') /* Full alphabetic */
94523485Sgarrison cp = fullaabet(cp, ref);
94615890Srrh else if (c == '9') /* Last name of Senior Author*/
94715890Srrh cp = aabetlast(cp, ref);
94817246Srrh else if (c == '0') { /* print nothing */
94917246Srrh for (fp = field; *fp; )
95017246Srrh *cp++ = *fp++;
95117246Srrh }
95215061Sgarrison else if (c == '{') { /* other information */
95315061Sgarrison while (*p != '}')
95415061Sgarrison if (*p == 0)
95515061Sgarrison error("unexpected end of citation template");
95615061Sgarrison else
95715061Sgarrison *cp++ = *p++;
95815061Sgarrison p++;
95915061Sgarrison }
96015061Sgarrison else if (c == '<') {
96115061Sgarrison while (*p != '>') {
96215061Sgarrison if (*p == 0)
96315061Sgarrison error("unexpected end of citation template");
96415061Sgarrison else
96515061Sgarrison *cp++ = *p++;
96615061Sgarrison }
96715061Sgarrison p++;
96815061Sgarrison }
96915061Sgarrison else if (c != '@')
97015061Sgarrison *cp++ = c;
97115061Sgarrison }
97215061Sgarrison }
97315061Sgarrison *cp++ = 0;
97415061Sgarrison }
97515061Sgarrison
97615061Sgarrison /* alternate alphabetic citation style -
97715061Sgarrison if 1 author - first three letters of last name
97815061Sgarrison if 2 authors - first two letters of first, followed by first letter of
97915061Sgarrison seond
98015061Sgarrison if 3 or more authors - first letter of first three authors */
aabet(cp,ref)98115061Sgarrison char *aabet(cp, ref)
98215061Sgarrison char *cp, ref[];
98315903Srrh { char field[REFSIZE], temp[100];
98415903Srrh reg char *np, *fp;
98515061Sgarrison int j, getname();
98615061Sgarrison
98715061Sgarrison if (getname(1, field, temp, ref)) {
98815061Sgarrison np = cp;
98915061Sgarrison fp = field;
99015061Sgarrison for (j = 1; j <= 3; j++)
99115061Sgarrison if (*fp != 0)
99215061Sgarrison *cp++ = *fp++;
99315061Sgarrison if (getname(2, field, temp, ref))
99415061Sgarrison np[2] = field[0];
99515061Sgarrison if (getname(3, field, temp, ref)) {
99615061Sgarrison np[1] = np[2];
99715061Sgarrison np[2] = field[0];
99815061Sgarrison }
99915061Sgarrison }
100015061Sgarrison return(cp);
100115061Sgarrison }
100215061Sgarrison
100315890Srrh /* alternate alphabetic citation style -
100423485Sgarrison first two characters of last names of all authors
100523485Sgarrison up to max_klen characters.
100623485Sgarrison */
fullaabet(cp,ref)100723485Sgarrison char *fullaabet(cp, ref)
100823485Sgarrison char *cp, ref[];
100923485Sgarrison { char field[REFSIZE], temp[100];
101023485Sgarrison reg char *fp;
101123485Sgarrison char *lastcp;
101223485Sgarrison int getname();
101323485Sgarrison int i;
101423485Sgarrison
101523485Sgarrison lastcp = cp + max_klen;
101623485Sgarrison for (i= 1; getname(i, field, temp, ref); i++) {
101723485Sgarrison for (fp = field; *fp && (fp < &(field[3])); )
101823485Sgarrison if (cp > lastcp)
101923485Sgarrison break;
102023485Sgarrison else if (isalpha(*fp))
102123485Sgarrison *cp++ = *fp++;
102223485Sgarrison else
102323485Sgarrison fp++;
102423485Sgarrison }
102523485Sgarrison return(cp);
102623485Sgarrison }
102723485Sgarrison
102823485Sgarrison
102923485Sgarrison /* alternate alphabetic citation style -
103015890Srrh entire last name of senior author
103115890Srrh */
aabetlast(cp,ref)103215890Srrh char *aabetlast(cp, ref)
103315890Srrh char *cp, ref[];
103415890Srrh { char field[REFSIZE], temp[100];
103515903Srrh reg char *fp;
103615890Srrh int getname();
103715890Srrh
103815890Srrh if (getname(1, field, temp, ref)) {
103915890Srrh for (fp = field; *fp; )
104015890Srrh *cp++ = *fp++;
104115890Srrh }
104215890Srrh return(cp);
104315890Srrh }
104415890Srrh
104531947Sbostic /*
104631947Sbostic Multiple full authors last names (1, 2 or 3 full names).
104731947Sbostic
104831947Sbostic If maxauthors<3
104915061Sgarrison if 1 author - last name date
105015061Sgarrison if 2 authors - last name and last name date
105131947Sbostic if 3 or more authors - last name et al. date
105231947Sbostic If maxauthors>=3
105331947Sbostic if 1 author - last name date
105431947Sbostic if 2 authors - last name and last name date
105515061Sgarrison if 3 authors - last name, last name and last name date
105615061Sgarrison if 4 or more authors - last name et al. date */
multfull(cp,ref,maxauthors)105731947Sbostic char *multfull(cp, ref, maxauthors)
105815061Sgarrison char *cp, ref[];
105931947Sbostic int maxauthors;
106015903Srrh { char name1[100], name2[100], name3[100], temp[100];
106115903Srrh reg char *fp;
106215061Sgarrison int getname();
106315061Sgarrison
106415061Sgarrison if (getname(1, name1, temp, ref)) {
106515061Sgarrison for (fp = name1; *fp; )
106615061Sgarrison *cp++ = *fp++;
106732623Sgarrison if (((maxauthors >= 3) && (getname(4, name3, temp, ref)))
106832623Sgarrison || ((maxauthors < 3) && (getname(3, name3, temp, ref)))) {
106931947Sbostic for (fp = " \\*(e]"; *fp; )
107015061Sgarrison *cp++ = *fp++;
107115061Sgarrison }
107215061Sgarrison else if (getname(2, name2, temp, ref)) {
107315061Sgarrison if (getname(3, name3, temp, ref)) {
107415061Sgarrison for (fp = "\\*(c]"; *fp; )
107515061Sgarrison *cp++ = *fp++;
107615061Sgarrison for (fp = name2; *fp; )
107715061Sgarrison *cp++ = *fp++;
107815061Sgarrison for (fp = "\\*(m]"; *fp; )
107915061Sgarrison *cp++ = *fp++;
108015061Sgarrison for (fp = name3; *fp; )
108115061Sgarrison *cp++ = *fp++;
108215061Sgarrison }
108315061Sgarrison else {
108415061Sgarrison for (fp = "\\*(n]"; *fp; )
108515061Sgarrison *cp++ = *fp++;
108615061Sgarrison for (fp = name2; *fp; )
108715061Sgarrison *cp++ = *fp++;
108815061Sgarrison }
108915061Sgarrison }
109015061Sgarrison }
109115061Sgarrison return(cp);
109215061Sgarrison }
109315061Sgarrison
109415061Sgarrison /* getfield - get a single field from reference */
getfield(ptr,field,ref)109515061Sgarrison char *getfield(ptr, field, ref)
109615061Sgarrison char *ptr, field[], ref[];
109715903Srrh { reg char *p, *q;
109815903Srrh char temp[100];
109915061Sgarrison int n, len, i, getname();
110015061Sgarrison
110115061Sgarrison field[0] = 0;
110215061Sgarrison if (*ptr == 'A')
110315061Sgarrison getname(1, field, temp, ref);
110415061Sgarrison else
1105*60507Sbostic for (p = ref; *p != '\0'; p++)
110615061Sgarrison if (*p == '%' && *(p+1) == *ptr) {
1107*60507Sbostic for (p = p + 2; isspace(*p); p++)
110815061Sgarrison ;
110915061Sgarrison for (q = field; (*p != '\n') && (*p != '\0'); )
111015061Sgarrison *q++ = *p++;
111115061Sgarrison *q = 0;
111215061Sgarrison break;
111315061Sgarrison }
111415061Sgarrison n = 0;
111515061Sgarrison len = strlen(field);
111615061Sgarrison if (*++ptr == '-') {
111715061Sgarrison for (ptr++; isdigit(*ptr); ptr++)
111815061Sgarrison n = 10 * n + (*ptr - '0');
111915061Sgarrison if (n > len)
112015061Sgarrison n = 0;
112115061Sgarrison else
112215061Sgarrison n = len - n;
112315061Sgarrison for (i = 0; field[i] = field[i+n]; i++)
112415061Sgarrison ;
112515061Sgarrison }
112615061Sgarrison else if (isdigit(*ptr)) {
112715061Sgarrison for (; isdigit(*ptr); ptr++)
112815061Sgarrison n = 10 * n + (*ptr - '0');
112915061Sgarrison if (n > len)
113015061Sgarrison n = len;
113115061Sgarrison field[n] = 0;
113215061Sgarrison }
113315061Sgarrison
113415061Sgarrison if (*ptr == 'u') {
113515061Sgarrison ptr++;
113615061Sgarrison for (p = field; *p; p++)
113715061Sgarrison if (islower(*p))
113815061Sgarrison *p = (*p - 'a') + 'A';
113915061Sgarrison }
114015061Sgarrison else if (*ptr == 'l') {
114115061Sgarrison ptr++;
114215061Sgarrison for (p = field; *p; p++)
114315061Sgarrison if (isupper(*p))
114415061Sgarrison *p = (*p - 'A') + 'a';
114515061Sgarrison }
114615061Sgarrison return(ptr);
114715061Sgarrison }
114815061Sgarrison
114915061Sgarrison /* getname - get the nth name field from reference, breaking into
115015061Sgarrison first and last names */
getname(n,last,first,ref)115115061Sgarrison int getname(n, last, first, ref)
115215061Sgarrison int n;
115315061Sgarrison char last[], first[], ref[];
115415903Srrh { reg char *p;
115515061Sgarrison int m;
115615061Sgarrison
115715061Sgarrison m = n;
115815061Sgarrison for (p = ref; *p; p++)
115915061Sgarrison if (*p == '%' & *(p+1) == 'A') {
116015061Sgarrison n--;
116115061Sgarrison if (n == 0) {
116215061Sgarrison for (p = p + 2; *p == ' '; p++) ;
116315061Sgarrison breakname(p, first, last) ;
116415061Sgarrison return(true);
116515061Sgarrison }
116615061Sgarrison }
116715061Sgarrison
116815061Sgarrison if (n == m) /* no authors, try editors */
116915061Sgarrison for (p = ref; *p; p++)
117015061Sgarrison if (*p == '%' & *(p+1) == 'E') {
117115061Sgarrison n--;
117215061Sgarrison if (n == 0) {
117315061Sgarrison for (p = p + 2; *p == ' '; p++) ;
117415061Sgarrison breakname(p, first, last) ;
117515061Sgarrison return(true);
117615061Sgarrison }
117715061Sgarrison }
117815061Sgarrison
117915061Sgarrison if (n == m) { /* no editors, either, try institution */
118015061Sgarrison first[0] = last[0] = '\0';
118115061Sgarrison getfield("I", last, ref);
118215061Sgarrison if (last[0] != '\0')
118315061Sgarrison return(true);
118415061Sgarrison }
118515061Sgarrison
118615061Sgarrison return(false);
118715061Sgarrison }
118815061Sgarrison
118915061Sgarrison /* disambiguate - compare adjacent citation strings, and if equal, add
119015061Sgarrison single character disambiguators */
disambiguate()119115061Sgarrison disambiguate()
119215903Srrh { reg int i, j;
119316244Srrh char adstr;
119415061Sgarrison
119523492Sgarrison for (i = 0; i < numrefs-1; i = j) {
119615061Sgarrison j = i + 1;
119715903Srrh if (strcmp(refinfo[i].ri_cite, refinfo[j].ri_cite)==0) {
119816244Srrh adstr = 'a';
119923492Sgarrison for(j = i+1;
120023492Sgarrison j<numrefs && strcmp(refinfo[i].ri_cite,refinfo[j].ri_cite) == 0;
120123492Sgarrison j++) {
120216244Srrh adstr = 'a' + (j-i);
120316244Srrh refinfo[j].ri_disambig[0] = adstr;
120415061Sgarrison }
120516244Srrh refinfo[i].ri_disambig[0] = 'a';
120615061Sgarrison }
120715061Sgarrison }
120816244Srrh for (i = 0; i < numrefs; i++){
120916244Srrh strcat(refinfo[i].ri_cite, refinfo[i].ri_disambig);
121016244Srrh }
121115061Sgarrison }
121215061Sgarrison
121315061Sgarrison
121412910Sgarrison /* bldname - build a name field
121512910Sgarrison doing abbreviations, reversals, and caps/small caps
121612910Sgarrison */
bldname(first,last,name,reverse)121712910Sgarrison bldname(first, last, name, reverse)
121812910Sgarrison char *first, *last, name[];
121912910Sgarrison int reverse;
122012910Sgarrison {
122115903Srrh char newfirst[120], newlast[120];
122215903Srrh reg char *p, *q, *f, *l;
122315903Srrh char *scopy();
122412910Sgarrison int flag;
122512910Sgarrison
122612910Sgarrison if (abbrev) {
122712910Sgarrison p = first;
122812910Sgarrison q = newfirst;
122912910Sgarrison flag = false;
123012910Sgarrison while (*p) {
123112910Sgarrison while (*p == ' ')
123212910Sgarrison p++;
123312910Sgarrison if (*p == 0)
123412910Sgarrison break;
123512910Sgarrison if (isupper(*p)) {
123615061Sgarrison if (flag) /* between initial gap */
123712910Sgarrison q = scopy(q, "\\*(a]");
123812910Sgarrison flag = true;
123912910Sgarrison *q++ = *p;
124015061Sgarrison q = scopy(q, "\\*(p]");
124112910Sgarrison }
124212910Sgarrison if (*++p == '.')
124312910Sgarrison p++;
124412910Sgarrison else while (*p != 0 && ! isspace(*p))
124512910Sgarrison p++;
124612910Sgarrison }
124712910Sgarrison *q = 0;
124812910Sgarrison f = newfirst;
124912910Sgarrison }
125012910Sgarrison else
125112910Sgarrison f = first;
125212910Sgarrison
125312910Sgarrison if (capsmcap) {
125412910Sgarrison p = last;
125512910Sgarrison q = newlast;
125612910Sgarrison flag = 0; /* 1 - printing cap, 2 - printing small */
125712910Sgarrison while (*p)
125812910Sgarrison if (islower(*p)) {
125912910Sgarrison if (flag != 2)
126012910Sgarrison q = scopy(q, "\\s-2");
126112910Sgarrison flag = 2;
126212910Sgarrison *q++ = (*p++ - 'a') + 'A';
126312910Sgarrison }
126412910Sgarrison else {
126512910Sgarrison if (flag == 2)
126612910Sgarrison q = scopy(q,"\\s+2");
126712910Sgarrison flag = 1;
126812910Sgarrison *q++ = *p++;
126912910Sgarrison }
127012910Sgarrison if (flag == 2)
127112910Sgarrison q = scopy(q, "\\s+2");
127212910Sgarrison *q = 0;
127312910Sgarrison l = newlast;
127412910Sgarrison }
127512910Sgarrison else
127612910Sgarrison l = last;
127712910Sgarrison
127815061Sgarrison if (f[0] == 0)
127915061Sgarrison sprintf(name, "%s\n", l);
128015061Sgarrison else if (reverse)
128115061Sgarrison sprintf(name, "%s\\*(b]%s\n", l, f);
128212910Sgarrison else
128312910Sgarrison sprintf(name, "%s %s\n", f, l);
128412910Sgarrison }
128512910Sgarrison
128612910Sgarrison /* prtauth - print author or editor field */
prtauth(c,line,num,max,ofd,abbrev,capsmcap,numrev)128712910Sgarrison prtauth(c, line, num, max, ofd, abbrev, capsmcap, numrev)
128812910Sgarrison char c, *line;
128912910Sgarrison int num, max, abbrev, capsmcap, numrev;
129012910Sgarrison FILE *ofd;
129112910Sgarrison { char first[LINELENGTH], last[LINELENGTH];
129212910Sgarrison
129312910Sgarrison if (num <= numrev || abbrev || capsmcap) {
129412910Sgarrison breakname(line, first, last);
129512910Sgarrison bldname(first, last, line, num <= numrev);
129612910Sgarrison }
129712910Sgarrison if (num == 1)
129812910Sgarrison fprintf(ofd,".ds [%c %s", c, line);
129912910Sgarrison else if (num < max)
130012910Sgarrison fprintf(ofd,".as [%c \\*(c]%s", c, line);
130112910Sgarrison else if (max == 2)
130212910Sgarrison fprintf(ofd,".as [%c \\*(n]%s", c, line);
130312910Sgarrison else
130412910Sgarrison fprintf(ofd,".as [%c \\*(m]%s", c, line);
130512910Sgarrison if (num == max && index(trailstr, c))
130612910Sgarrison fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
130712910Sgarrison }
130812910Sgarrison
130912910Sgarrison /* doline - actually print out a line of reference information */
doline(c,line,numauths,maxauths,numeds,maxeds,ofd)131012910Sgarrison doline(c, line, numauths, maxauths, numeds, maxeds, ofd)
131112910Sgarrison char c, *line;
131212910Sgarrison int numauths, maxauths, numeds, maxeds;
131312910Sgarrison FILE *ofd;
131412910Sgarrison {
1315*60507Sbostic int appending;
131612910Sgarrison
131712910Sgarrison switch(c) {
131812910Sgarrison case 'A':
131912910Sgarrison prtauth(c, line, numauths, maxauths, ofd, abbrev, capsmcap, numrev);
132012910Sgarrison break;
132112910Sgarrison
1322*60507Sbostic case 'E':
132312910Sgarrison prtauth(c, line, numeds, maxeds, ofd, edabbrev, edcapsmcap, ednumrev);
132412910Sgarrison if (numeds == maxeds)
132512910Sgarrison fprintf(ofd,".nr [E %d\n", maxeds);
132612910Sgarrison break;
132712910Sgarrison
1328*60507Sbostic case 'P':
132912910Sgarrison if (index(line, '-'))
133012910Sgarrison fprintf(ofd,".nr [P 1\n");
133112910Sgarrison else
133212910Sgarrison fprintf(ofd,".nr [P 0\n");
133312910Sgarrison fprintf(ofd,".ds [P %s",line);
133412910Sgarrison if (index(trailstr, 'P'))
133512910Sgarrison fprintf(ofd,".ds ]P %c\n",line[strlen(line)-2]);
133612910Sgarrison break;
133712910Sgarrison
1338*60507Sbostic case 'F': break;
133912910Sgarrison
1340*60507Sbostic /* these now accumulate their entries */
1341*60507Sbostic /* defined by official bib documentation */
1342*60507Sbostic case 'K': case 'O': case 'W':
1343*60507Sbostic /* not defined by official bib documentation */
1344*60507Sbostic case 'H': case 'L': case 'M': case 'Q': case 'U': case 'X': case 'Y':
1345*60507Sbostic case 'Z':
1346*60507Sbostic appending = letterSeen[c];
1347*60507Sbostic letterSeen[c] = true;
1348*60507Sbostic if (appending)
1349*60507Sbostic fprintf(ofd, ".as [%c , %s", c, line);
1350*60507Sbostic else
1351*60507Sbostic fprintf(ofd, ".ds [%c %s", c, line);
1352*60507Sbostic if (index(trailstr, c))
1353*60507Sbostic fprintf(ofd, ".ds ]%c %c\n", c, line[strlen(line) - 2]);
1354*60507Sbostic break;
1355*60507Sbostic
1356*60507Sbostic default:
1357*60507Sbostic if (!isupper(c)) break; /* ignore what you don't understand */
135812910Sgarrison fprintf(ofd,".ds [%c %s", c, line);
135912910Sgarrison if (index(trailstr, c))
136012910Sgarrison fprintf(ofd,".ds ]%c %c\n", c, line[strlen(line)-2]);
136112910Sgarrison }
136212910Sgarrison }
136312910Sgarrison
136415061Sgarrison /* dumpref - dump reference number i */
dumpref(i,ofd)136515061Sgarrison dumpref(i, ofd)
136615061Sgarrison int i;
136715061Sgarrison FILE *ofd;
136815903Srrh { char ref[REFSIZE], line[REFSIZE];
136915903Srrh reg char *p, *q;
137015903Srrh char *from;
137115061Sgarrison int numauths, maxauths, numeds, maxeds;
1372*60507Sbostic int j;
137315061Sgarrison
137431947Sbostic if ( i < 0 ) ref[0] = 0; /* ref not found */
137531947Sbostic else {
137631947Sbostic rdref(&refinfo[i], ref);
137731947Sbostic maxauths = maxeds = 0;
137831947Sbostic numauths = numeds = 0;
1379*60507Sbostic for (j=0; j < 128; j++) letterSeen[j] = 0;
138031947Sbostic for (p = ref; *p; p++)
138131947Sbostic if (*p == '%')
138231947Sbostic if (*(p+1) == 'A') maxauths++;
138331947Sbostic else if (*(p+1) == 'E') maxeds++;
138431947Sbostic fprintf(ofd, ".[-\n");
138531947Sbostic fprintf(ofd, ".ds [F %s\n", refinfo[i].ri_cite);
138615903Srrh #ifndef INCORE
138731947Sbostic fseek(rfd, (long)refinfo[i].ri_pos, 0);
138831947Sbostic while (fgets(line, REFSIZE, rfd) != NULL) {
138915903Srrh #else INCORE
139031947Sbostic for (q = line, from = refinfo[i].ri_ref; *from; /*VOID*/) { /*} */
139131947Sbostic if (*from == '\n'){
139231947Sbostic *q++ = '\n';
139331947Sbostic *q = 0;
139431947Sbostic q = line;
139531947Sbostic from++;
139631947Sbostic } else {
139731947Sbostic *q++ = *from++;
139831947Sbostic continue;
139931947Sbostic }
140015903Srrh #endif INCORE
140131947Sbostic switch(line[0]){
140231947Sbostic case 0:
140331947Sbostic goto doneref;
140431947Sbostic case '.':
140531947Sbostic fprintf(ofd, "%s", line);
140631947Sbostic break;
140731947Sbostic case '%':
140831947Sbostic switch(line[1]){
140931947Sbostic case 'A': numauths++; break;
141031947Sbostic case 'E': numeds++; break;
141131947Sbostic }
141231947Sbostic for (p = &line[2]; *p == ' '; p++) /*VOID*/;
141331947Sbostic doline(line[1], p, numauths, maxauths, numeds, maxeds, ofd);
141415903Srrh }
141531947Sbostic }
141631947Sbostic doneref:;
141731947Sbostic fprintf(ofd,".][\n");
141815903Srrh }
141915061Sgarrison }
1420