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