1 /*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley software License Agreement
12 * specifies the terms and conditions for redistribution.
13 */
14
15 #include "refer..c"
16 #define SAME 0
17 #define NFLAB 3000 /* number of bytes to record all labels */
18 #define NLABC 1000 /* max number of labels */
19
20 static char sig[MXSIG];
21 static char bflab[NFLAB];
22 static char *labtab[NLABC];
23 static char *lbp = bflab;
24 static char labc[NLABC];
25 static char stbuff[50];
26 static int prevsig;
27
28 extern void addch();
29 extern void append();
30 extern void err();
31 extern void flout();
32 extern int prefix();
33
34 char keylet(char *, int);
35 static void initadd(char *, char *, char *);
36 static void mycpy(char *, char *);
37 static void mycpy2(char *, char *, int);
38 void tokeytab(char *, int);
39
40 /* choose signal style */
41 void
putsig(int nf,char * flds[],int nref,char * nstline,char * endline,int toindex)42 putsig(int nf, char *flds[], int nref, char *nstline,
43 char *endline, int toindex)
44 {
45 char t[100], t1[MXSIG], t2[100], format[10], *sd, *stline;
46 int addon, another = 0;
47 static FILE *fhide = 0;
48 int i;
49 char tag;
50
51 if (labels) {
52 if (nf == 0) /* old */
53 sprintf(t, "%s%c", labtab[nref], labc[nref]);
54 else {
55 *t = 0;
56 if (keywant)
57 fpar(nf, flds, t, keywant, 1, 0);
58 if (science && t[0] == 0) {
59 if (fpar(nf, flds, t, 'A', 1, 0) != 0) {
60 if (fpar(nf, flds, t2, 'D',
61 1, 0) != 0) {
62 strcat(t, ", ");
63 strcat(t, t2);
64 }
65 }
66 } else if (t[0] == 0) {
67 sprintf(format,
68 nmlen > 0 ? "%%.%ds%%s" : "%%s%%s",
69 nmlen);
70 /* format is %s%s for default labels */
71 /* or %.3s%s eg if wanted */
72 if (fpar(nf, flds, t2, 'D', 1, 0)) {
73 sd = t2;
74 if (dtlen > 0) {
75 int n = strlen(sd) - dtlen;
76 if (n > 0)
77 sd += n;
78 }
79 } else {
80 sd = "";
81 }
82 t1[0] = 0;
83 fpar(nf, flds, t1, 'A', 1, 0);
84 sprintf(t, format, t1, sd);
85 }
86 if (keywant) {
87 addon = 0;
88 for (sd = t; *sd; sd++)
89 ;
90 if (*--sd == '-') {
91 addon = 1;
92 *sd = 0;
93 }
94 }
95 if ((!keywant || addon) && !science) {
96 addch(t, keylet(t, nref));
97 } else {
98 tokeytab(t, nref);
99 }
100 }
101 } else {
102 if (sort)
103 sprintf(t, "%c%d%c", FLAG, nref, FLAG);
104 else
105 sprintf(t, "%d", nref);
106 }
107 another = (sd = lookat()) ? prefix(".[", sd) : 0;
108 if (another && (strcmp(".[\n", sd) != SAME))
109 fprintf(stderr, (char *)gettext(
110 "File %s line %d: punctuation ignored from: %s"),
111 Ifile, Iline, sd);
112 if ((strlen(sig) + strlen(t)) > MXSIG)
113 err(gettext("sig overflow (%d)"), MXSIG);
114 strcat(sig, t);
115 #if EBUG
116 fprintf(stderr, "sig is now %s leng %d\n", sig, strlen(sig));
117 #endif
118 trimnl(nstline);
119 trimnl(endline);
120 stline = stbuff;
121 if (prevsig == 0) {
122 strcpy(stline, nstline);
123 prevsig = 1;
124 }
125 if (stline[2] || endline[2]) {
126 stline += 2;
127 endline += 2;
128 } else {
129 stline = "\\*([.";
130 endline = "\\*(.]";
131 }
132 if (science) {
133 stline = " (";
134 endline = ")";
135 }
136 if (bare == 0) {
137 if (!another) {
138 sprintf(t1, "%s%s%s\n", stline, sig, endline);
139 if (strlen(t1) > MXSIG)
140 err(gettext("t1 overflow (%d)"), MXSIG);
141 append(t1);
142 flout();
143 sig[0] = 0;
144 prevsig = 0;
145 if (fo == fhide) {
146 int ch;
147 fclose(fhide);
148 fhide = fopen(hidenam, "r");
149 fo = ftemp;
150 while ((ch = getc(fhide)) != EOF)
151 putc(ch, fo);
152 fclose(fhide);
153 unlink(hidenam);
154 }
155 } else {
156 if (labels) {
157 strcat(sig, ",\\|");
158 } else {
159 /*
160 * Seperate reference numbers with AFLAG
161 * for later sorting and condensing.
162 */
163 t1[0] = AFLAG;
164 t1[1] = '\0';
165 strcat(sig, t1);
166 }
167 if (fo == ftemp) { /* hide if need be */
168 sprintf(hidenam, "/tmp/rj%dc", getpid());
169 #if EBUG
170 fprintf(stderr, "hiding in %s\n", hidenam);
171 #endif
172 fhide = fopen(hidenam, "w");
173 if (fhide == NULL)
174 err(gettext(
175 "Can't get scratch file %s"),
176 hidenam);
177 fo = fhide;
178 }
179 }
180 }
181 if (bare < 2)
182 if (nf > 0 && toindex)
183 fprintf(fo, ".ds [F %s%c", t, sep);
184 if (bare > 0)
185 flout();
186 #if EBUG
187 fprintf(stderr, "sig is now %s\n", sig);
188 #endif
189 }
190
191 char *
fpar(int nf,char * flds[],char * out,int c,int seq,int prepend)192 fpar(int nf, char *flds[], char *out, int c, int seq, int prepend)
193 {
194 char *p, *s;
195 int i, fnd = 0;
196
197 for (i = 0; i < nf; i++)
198 if (flds[i][1] == c && ++fnd >= seq) {
199 /* for titles use first word otherwise last */
200 if (c == 'T' || c == 'J') {
201 p = flds[i]+3;
202 if (prefix("A ", p))
203 p += 2;
204 if (prefix("An ", p))
205 p += 3;
206 if (prefix("The ", p))
207 p += 4;
208 mycpy2(out, p, 20);
209 return (out);
210 }
211 /* if its not 'L' then use just the last word */
212 s = p = flds[i]+2;
213 if (c != 'L') {
214 for (; *p; p++)
215 ;
216 while (p > s && *p != ' ')
217 p--;
218 }
219 /* special wart for authors */
220 if (c == 'A' && (p[-1] == ',' || p[1] == '(')) {
221 p--;
222 while (p > s && *p != ' ')
223 p--;
224 mycpy(out, p+1);
225 } else
226 strcpy(out, p+1);
227 if (c == 'A' && prepend)
228 initadd(out, flds[i]+2, p);
229 return (out);
230 }
231 return (0);
232 }
233
234 void
putkey(int nf,char * flds[],int nref,char * keystr)235 putkey(int nf, char *flds[], int nref, char *keystr)
236 {
237 char t1[50], *sf;
238 int ctype, i, count;
239
240 fprintf(fo, ".\\\"");
241 if (nf <= 0)
242 fprintf(fo, "%s%c%c", labtab[nref], labc[nref], sep);
243 else {
244 while (ctype = *keystr++) {
245 count = atoi(keystr);
246 if (*keystr == '+')
247 count = 999;
248 if (count <= 0)
249 count = 1;
250 for (i = 1; i <= count; i++) {
251 sf = fpar(nf, flds, t1, ctype, i, 1);
252 if (sf == 0)
253 break;
254 sf = artskp(sf);
255 fprintf(fo, "%s%c", sf, '-');
256 }
257 }
258 fprintf(fo, "%c%d%c%c", FLAG, nref, FLAG, sep);
259 }
260 }
261
262
263 void
tokeytab(char * t,int nref)264 tokeytab(char *t, int nref)
265 {
266 strcpy(labtab[nref] = lbp, t);
267 while (*lbp++)
268 ;
269 }
270
271 char
keylet(char * t,int nref)272 keylet(char *t, int nref)
273 {
274 int i;
275 int x = 'a' - 1;
276
277 for (i = 1; i < nref; i++) {
278 if (strcmp(labtab[i], t) == 0)
279 x = labc[i];
280 }
281 tokeytab(t, nref);
282 if (lbp-bflab > NFLAB)
283 err(gettext("bflab overflow (%d)"), NFLAB);
284 if (nref > NLABC)
285 err(gettext("nref in labc overflow (%d)"), NLABC);
286 #if EBUG
287 fprintf(stderr, "lbp up to %d of %d\n", lbp-bflab, NFLAB);
288 #endif
289 return (labc[nref] = x+1);
290 }
291
292 static void
mycpy(char * s,char * t)293 mycpy(char *s, char *t)
294 {
295 while (*t && *t != ',' && *t != ' ')
296 *s++ = *t++;
297 *s = 0;
298 }
299
300 static void
mycpy2(char * s,char * t,int n)301 mycpy2(char *s, char *t, int n)
302 {
303 int c;
304
305 while (n-- && (c = *t++) > 0) {
306 if (c == ' ')
307 c = '-';
308 *s++ = c;
309 }
310 *s = 0;
311 }
312
313 static void
initadd(char * to,char * from,char * stop)314 initadd(char *to, char *from, char *stop)
315 {
316 int c, nalph = 1;
317
318 while (*to)
319 to++;
320 while (from < stop) {
321 c = *from++;
322 if (!isalpha(c)) {
323 if (nalph)
324 *to++ = '.';
325 nalph = 0;
326 continue;
327 }
328 if (nalph++ == 0)
329 *to++ = c;
330 }
331 *to = 0;
332 }
333
334 static char *articles[] = {
335 "the ", "an ", "a ", 0
336 };
337
338 char *
artskp(s)339 artskp(s) /* skips over initial "a ", "an ", "the " in s */
340 char *s;
341 {
342
343 char **p, *r1, *r2;
344
345 for (p = articles; *p; p++) {
346 r2 = s;
347 for (r1 = *p; ((*r1 ^ *r2) & ~040) == 0; r1++)
348 r2++;
349 if (*r1 == 0 && *r2 != 0)
350 return (r2);
351 }
352 return (s);
353 }
354