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
doref(char * line1)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
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