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