xref: /illumos-gate/usr/src/cmd/refer/refer5.c (revision 1566bc3431383e39ac9bc7fb7f00feff9c06acda)
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
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 *
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
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
266 tokeytab(char *t, int nref)
267 {
268 	strcpy(labtab[nref] = lbp, t);
269 	while (*lbp++)
270 		;
271 }
272 
273 char
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
295 mycpy(char *s, char *t)
296 {
297 	while (*t && *t != ',' && *t != ' ')
298 		*s++ = *t++;
299 	*s = 0;
300 }
301 
302 static void
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
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 *
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