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
doref(char * line1)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
newline(char * s)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
choices(char * buff)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
control(char c)218 control(char c)
219 {
220 if (c == '.')
221 return (1);
222 if (c == '%')
223 return (1);
224 return (0);
225 }
226