xref: /illumos-gate/usr/src/cmd/refer/refer2.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 #include <locale.h>
19 #define	NFLD 30
20 #define	TLEN 512
21 
22 extern FILE *in;
23 char one[ANSLEN];
24 int onelen = ANSLEN;
25 static char dr [100] = "";
26 
27 extern int prefix();
28 extern int common();
29 extern void dumpold();
30 extern void putref();
31 extern void flout();
32 extern int tabs();
33 extern int chkdup();
34 extern void putsig();
35 extern void putkey();
36 extern void err();
37 extern int corout();
38 
39 void choices(char *);
40 int control(char);
41 static int newline(char *);
42 
43 void
44 doref(char *line1)
45 {
46 	char buff[QLEN], dbuff[3*QLEN];
47 	char answer[ANSLEN], temp[TLEN], line[BUFSIZ];
48 	char *p, **sr, *flds[NFLD], *r;
49 	int stat, nf, nr, query = 0, alph, digs;
50 
51 again:
52 	buff[0] = dbuff[0] = NULL;
53 	if (biblio && Iline == 1 && line1[0] == '%')
54 		strcat(dbuff, line1);
55 	while (input(line)) {		/* get query */
56 		Iline++;
57 		if (prefix(".]", line))
58 			break;
59 		if (biblio && line[0] == '\n')
60 			break;
61 		if (biblio && line[0] == '%' && line[1] == *convert)
62 			break;
63 		if (control(line[0]))
64 			query = 1;
65 		strcat(query ? dbuff : buff, line);
66 		if (strlen(buff) > QLEN)
67 			err(gettext("query too long (%d)"), strlen(buff));
68 		if (strlen(dbuff) > 3 * QLEN)
69 			err(gettext("record at line %d too long"), Iline-1);
70 	}
71 	if (biblio && line[0] == '\n' && feof(in))
72 		return;
73 	if (strcmp(buff, "$LIST$\n") == 0) {
74 		assert(dbuff[0] == 0);
75 		dumpold();
76 		return;
77 	}
78 	answer[0] = 0;
79 	for (p = buff; *p; p++) {
80 		if (isupper(*p))
81 			*p |= 040;
82 	}
83 	alph = digs = 0;
84 	for (p = buff; *p; p++) {
85 		if (isalpha(*p))
86 			alph++;
87 		else
88 			if (isdigit(*p))
89 				digs++;
90 			else {
91 				*p = 0;
92 				if ((alph+digs < 3) || common(p-alph)) {
93 					r = p-alph;
94 					while (r < p)
95 						*r++ = ' ';
96 				}
97 				if (alph == 0 && digs > 0) {
98 					r = p-digs;
99 					if (digs != 4 || atoi(r)/100 != 19) {
100 						while (r < p)
101 							*r++ = ' ';
102 					}
103 				}
104 				*p = ' ';
105 				alph = digs = 0;
106 			}
107 	}
108 	one[0] = 0;
109 	if (buff[0]) {	/* do not search if no query */
110 		for (sr = rdata; sr < search; sr++) {
111 			temp[0] = 0;
112 			corout(buff, temp, "hunt", *sr, TLEN);
113 			assert(strlen(temp) < TLEN);
114 			if (strlen(temp)+strlen(answer) > BUFSIZ)
115 				err(gettext(
116 				    "Accumulated answers too large"), 0);
117 			strcat(answer, temp);
118 			if (strlen(answer) > BUFSIZ)
119 				err(gettext("answer too long (%d)"),
120 				    strlen(answer));
121 			if (newline(answer) > 0)
122 				break;
123 		}
124 	}
125 	assert(strlen(one) < ANSLEN);
126 	assert(strlen(answer) < ANSLEN);
127 	if (buff[0])
128 		switch (newline(answer)) {
129 		case 0:
130 			fprintf(stderr, gettext("No such paper: %s\n"), buff);
131 			return;
132 		default:
133 			fprintf(stderr, gettext(
134 			    "Too many hits: %s\n"), trimnl(buff));
135 			choices(answer);
136 			p = buff;
137 			while (*p != '\n')
138 				p++;
139 			*++p = 0;
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