xref: /illumos-gate/usr/src/cmd/refer/refer2.c (revision d8109ce4330e1b8ad6c29f9fccacec969066bb9d)
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 #include <locale.h>
17 #define	NFLD 30
18 #define	TLEN 512
19 
20 extern FILE *in;
21 char one[ANSLEN];
22 int onelen = ANSLEN;
23 static char dr [100] = "";
24 
25 extern int prefix();
26 extern int common();
27 extern void dumpold();
28 extern void putref();
29 extern void flout();
30 extern int tabs();
31 extern int chkdup();
32 extern void putsig();
33 extern void putkey();
34 extern void err();
35 extern int corout();
36 
37 void choices(char *);
38 int control(char);
39 static int newline(char *);
40 
41 void
42 doref(char *line1)
43 {
44 	char buff[QLEN], dbuff[3*QLEN];
45 	char answer[ANSLEN], temp[TLEN], line[BUFSIZ];
46 	char *p, **sr, *flds[NFLD], *r;
47 	int stat, nf, nr, query = 0, alph, digs;
48 
49 again:
50 	buff[0] = dbuff[0] = '\0';
51 	if (biblio && Iline == 1 && line1[0] == '%')
52 		strcat(dbuff, line1);
53 	while (input(line)) {		/* get query */
54 		Iline++;
55 		if (prefix(".]", line))
56 			break;
57 		if (biblio && line[0] == '\n')
58 			break;
59 		if (biblio && line[0] == '%' && line[1] == *convert)
60 			break;
61 		if (control(line[0]))
62 			query = 1;
63 		strcat(query ? dbuff : buff, line);
64 		if (strlen(buff) > QLEN)
65 			err(gettext("query too long (%d)"), strlen(buff));
66 		if (strlen(dbuff) > 3 * QLEN)
67 			err(gettext("record at line %d too long"), Iline-1);
68 	}
69 	if (biblio && line[0] == '\n' && feof(in))
70 		return;
71 	if (strcmp(buff, "$LIST$\n") == 0) {
72 		assert(dbuff[0] == 0);
73 		dumpold();
74 		return;
75 	}
76 	answer[0] = 0;
77 	for (p = buff; *p; p++) {
78 		if (isupper(*p))
79 			*p |= 040;
80 	}
81 	alph = digs = 0;
82 	for (p = buff; *p; p++) {
83 		if (isalpha(*p))
84 			alph++;
85 		else
86 			if (isdigit(*p))
87 				digs++;
88 			else {
89 				*p = 0;
90 				if ((alph+digs < 3) || common(p-alph)) {
91 					r = p-alph;
92 					while (r < p)
93 						*r++ = ' ';
94 				}
95 				if (alph == 0 && digs > 0) {
96 					r = p-digs;
97 					if (digs != 4 || atoi(r)/100 != 19) {
98 						while (r < p)
99 							*r++ = ' ';
100 					}
101 				}
102 				*p = ' ';
103 				alph = digs = 0;
104 			}
105 	}
106 	one[0] = 0;
107 	if (buff[0]) {	/* do not search if no query */
108 		for (sr = rdata; sr < search; sr++) {
109 			temp[0] = 0;
110 			corout(buff, temp, "hunt", *sr, TLEN);
111 			assert(strlen(temp) < TLEN);
112 			if (strlen(temp)+strlen(answer) > BUFSIZ)
113 				err(gettext(
114 				    "Accumulated answers too large"), 0);
115 			strcat(answer, temp);
116 			if (strlen(answer) > BUFSIZ)
117 				err(gettext("answer too long (%d)"),
118 				    strlen(answer));
119 			if (newline(answer) > 0)
120 				break;
121 		}
122 	}
123 	assert(strlen(one) < ANSLEN);
124 	assert(strlen(answer) < ANSLEN);
125 	if (buff[0])
126 		switch (newline(answer)) {
127 		case 0:
128 			fprintf(stderr, gettext("No such paper: %s\n"), buff);
129 			return;
130 		default:
131 			fprintf(stderr, gettext(
132 			    "Too many hits: %s\n"), trimnl(buff));
133 			choices(answer);
134 			p = buff;
135 			while (*p != '\n')
136 				p++;
137 			*++p = 0;
138 			/* FALLTHROUGH */
139 
140 		case 1:
141 			if (endpush)
142 				if (nr = chkdup(answer)) {
143 					if (bare < 2) {
144 						nf = tabs(flds, one);
145 						nf += tabs(flds+nf, dbuff);
146 						assert(nf < NFLD);
147 						putsig(nf, flds, nr, line1,
148 						    line, 0);
149 					}
150 					return;
151 				}
152 			if (one[0] == 0)
153 				corout(answer, one, "deliv", dr, QLEN);
154 			break;
155 		}
156 	assert(strlen(buff) < QLEN);
157 	assert(strlen(one) < ANSLEN);
158 	nf = tabs(flds, one);
159 	nf += tabs(flds+nf, dbuff);
160 	assert(nf < NFLD);
161 	refnum++;
162 	if (sort)
163 		putkey(nf, flds, refnum, keystr);
164 	if (bare < 2)
165 		putsig(nf, flds, refnum, line1, line, 1);
166 	else
167 		flout();
168 	putref(nf, flds);
169 	if (biblio && line[0] == '\n')
170 		goto again;
171 	if (biblio && line[0] == '%' && line[1] == *convert)
172 		fprintf(fo, "%s%c%s", convert+1, sep, line+3);
173 }
174 
175 static int
176 newline(char *s)
177 {
178 	int k = 0, c;
179 
180 	while (c = *s++)
181 		if (c == '\n')
182 		k++;
183 	return (k);
184 }
185 
186 void
187 choices(char *buff)
188 {
189 	char ob[BUFSIZ], *p, *r, *q, *t;
190 	int nl;
191 
192 	for (r = p = buff; *p; p++) {
193 		if (*p == '\n') {
194 			*p++ = 0;
195 		corout(r, ob, "deliv", dr, BUFSIZ);
196 			nl = 1;
197 			for (q = ob; *q; q++) {
198 				if (nl && (q[0] == '.' || q[0] == '%') &&
199 				    q[1] == 'T') {
200 					q += 3;
201 					for (t = q; *t && *t != '\n'; t++)
202 						;
203 					*t = 0;
204 					fprintf(stderr, "%.70s\n", q);
205 					q = 0;
206 					break;
207 				}
208 				nl = *q == '\n';
209 			}
210 			if (q)
211 				fprintf(stderr, gettext("??? at %s\n"), r);
212 			r = p;
213 		}
214 	}
215 }
216 
217 int
218 control(char c)
219 {
220 	if (c == '.')
221 		return (1);
222 	if (c == '%')
223 		return (1);
224 	return (0);
225 }
226