Commit | Line | Data |
---|---|---|
520d5775 EA |
1 | # include "iodec.h" |
2 | ||
3 | /* | |
4 | ** formatted read routine | |
5 | ** | |
6 | ** based on scanf() in the portable C library | |
7 | */ | |
8 | ||
9 | ||
10 | int (*__getc)(), (*__ungc)(); | |
11 | int __input; | |
12 | ||
13 | scanf(paramlist) | |
14 | char *paramlist; | |
15 | { | |
16 | extern cgetc(), ungetc(); | |
17 | extern __gets(), __ungs(); | |
18 | register char **p; | |
19 | extern int cin; | |
20 | register int nmatch; | |
21 | char *format; | |
22 | register char ch; | |
23 | char match_ch; | |
24 | ||
25 | p = ¶mlist; | |
26 | __getc = cgetc; | |
27 | __ungc = ungetc; | |
28 | __input = cin; | |
29 | if (paramlist == -1) | |
30 | { | |
31 | p++; | |
32 | __getc = __gets; | |
33 | __ungc = __ungs; | |
34 | __input = p++; | |
35 | } | |
36 | else | |
37 | if (paramlist >= 0 && paramlist < MAXFILES) | |
38 | { | |
39 | __input = *p++; | |
40 | } | |
41 | nmatch = 0; | |
42 | format = *p++; | |
43 | while (1) | |
44 | { | |
45 | switch (ch = *format++) | |
46 | { | |
47 | ||
48 | case '\0': | |
49 | return (nmatch); | |
50 | ||
51 | case '%': | |
52 | if (*format != '%') | |
53 | { | |
54 | switch (__scan(&format, *p)) | |
55 | { | |
56 | ||
57 | case 1: /* good return */ | |
58 | p++; | |
59 | nmatch++; | |
60 | case 0: /* no return */ | |
61 | break; | |
62 | ||
63 | case -1: /* no match */ | |
64 | return (nmatch); | |
65 | ||
66 | case -2: /* end of file */ | |
67 | return (nmatch ? nmatch : -1); | |
68 | ||
69 | default: /* syntax error */ | |
70 | return (-1); | |
71 | ||
72 | } | |
73 | break; | |
74 | } | |
75 | format++; | |
76 | ||
77 | default: | |
78 | match_ch = __next(0); | |
79 | if (ch != match_ch) | |
80 | { | |
81 | (*__ungc)(match_ch, __input); | |
82 | return (nmatch ? nmatch : -2); | |
83 | } | |
84 | break; | |
85 | ||
86 | } | |
87 | } | |
88 | } | |
89 | ||
90 | ||
91 | __scan(spec, result) | |
92 | char **spec; | |
93 | char *result; | |
94 | { | |
95 | register int longf, length; | |
96 | register char ch; | |
97 | extern int __strend(), __splend(); | |
98 | ||
99 | longf = length = 0; | |
100 | while (1) | |
101 | { | |
102 | switch (ch = *(*spec)++) | |
103 | { | |
104 | case '*': | |
105 | result = 0; | |
106 | break; | |
107 | ||
108 | case '0': | |
109 | case '1': | |
110 | case '2': | |
111 | case '3': | |
112 | case '4': | |
113 | case '5': | |
114 | case '6': | |
115 | case '7': | |
116 | case '8': | |
117 | case '9': | |
118 | length = length * 10 + ch - '0'; | |
119 | break; | |
120 | ||
121 | case 'l': | |
122 | if (longf) | |
123 | return (-3); | |
124 | longf = 1; | |
125 | break; | |
126 | ||
127 | case 'h': /* short */ | |
128 | if (longf) | |
129 | return (-3); | |
130 | longf = -1; | |
131 | break; | |
132 | ||
133 | case 'o': | |
134 | case 'O': | |
135 | return (__dec(result, length ? length : 100, 8, longf)); | |
136 | ||
137 | case 'd': | |
138 | case 'D': | |
139 | return (__dec(result, length ? length : 100, 10, longf)); | |
140 | ||
141 | case 'x': | |
142 | case 'X': | |
143 | return (__dec(result, length ? length : 100, 16, longf)); | |
144 | ||
145 | case 'c': | |
146 | case 'C': | |
147 | if (longf) | |
148 | return (-3); | |
149 | return (__char(result, length ? length : 1)); | |
150 | ||
151 | case 's': | |
152 | case 'S': | |
153 | if (longf) | |
154 | return (-3); | |
155 | return (__str(result, length ? length : 100, __strend)); | |
156 | ||
157 | case 'e': | |
158 | case 'E': | |
159 | case 'f': | |
160 | case 'F': | |
161 | if (longf < 0) | |
162 | return (-3); | |
163 | return (__float(result, length ? length : 100, longf)); | |
164 | ||
165 | case '[': | |
166 | if (longf) | |
167 | return (-3); | |
168 | if (__inits(spec)) | |
169 | return (-3); | |
170 | return (__str(result, length ? length : 100, __splend)); | |
171 | ||
172 | default: | |
173 | return (-3); | |
174 | ||
175 | } | |
176 | } | |
177 | } | |
178 | ||
179 | ||
180 | __dec(result, length, base, longf) | |
181 | int *result; | |
182 | int length; | |
183 | int base; | |
184 | int longf; | |
185 | { | |
186 | register char ch; | |
187 | long n, *lresult; | |
188 | register int val; | |
189 | long lres; | |
190 | int ires; | |
191 | int minus, ok; | |
192 | register int ndigit; | |
193 | ||
194 | ires = 0; | |
195 | lres = 0; | |
196 | ndigit = minus = 0; | |
197 | switch (ch = __next(1)) | |
198 | { | |
199 | ||
200 | case '\0': | |
201 | return (-2); | |
202 | ||
203 | case '-': | |
204 | minus = 1; | |
205 | case '+': | |
206 | ndigit++; | |
207 | ch = __next(-1); | |
208 | } | |
209 | ok = 0; | |
210 | while ((val = __digit(ch, base)) >= 0 && ndigit++ < length) | |
211 | { | |
212 | ok++; | |
213 | if (longf) | |
214 | lres = lres * base + val; | |
215 | else | |
216 | ires = ires * base + val; | |
217 | ch = __next(0); | |
218 | } | |
219 | (*__ungc)(ch, __input); | |
220 | if (!ok) | |
221 | return (-1); | |
222 | if (!result) | |
223 | return (0); | |
224 | if (minus) | |
225 | if (longf) | |
226 | lres = -lres; | |
227 | else | |
228 | ires = -ires; | |
229 | if (longf) | |
230 | { | |
231 | lresult = result; | |
232 | *lresult = lres; | |
233 | } | |
234 | else | |
235 | *result = ires; | |
236 | return (1); | |
237 | } | |
238 | ||
239 | ||
240 | __next(mode) | |
241 | int mode; | |
242 | { | |
243 | /* | |
244 | * mode -1: get next non-space or non-tab | |
245 | * mode 0: get next character | |
246 | * mode 1: get next non-space, non-tab, or non-newline | |
247 | */ | |
248 | register int ch; | |
249 | ||
250 | ch = (*__getc)(__input); | |
251 | if (mode == 0) | |
252 | return (ch); | |
253 | while (ch == ' ' || ch == '\t' || ch == '\n') | |
254 | { | |
255 | if (ch == '\n' && mode < 0) | |
256 | break; | |
257 | ch = (*__getc)(__input); | |
258 | } | |
259 | return (ch); | |
260 | } | |
261 | ||
262 | ||
263 | __digit(ch, base) | |
264 | char ch; | |
265 | int base; | |
266 | { | |
267 | register int n; | |
268 | ||
269 | if (ch < '0') | |
270 | return (-1); | |
271 | if (ch <= '7') | |
272 | return (ch - '0'); | |
273 | if (base == 8) | |
274 | return (-1); | |
275 | if (ch <= '9') | |
276 | return (ch - '0'); | |
277 | if (base == 10 || ch < 'A') | |
278 | return (-1); | |
279 | if (ch <= 'F') | |
280 | return (ch - 'A' + 10); | |
281 | if (ch < 'a' || ch > 'f') | |
282 | return (-1); | |
283 | return (ch - 'a' + 10); | |
284 | } | |
285 | ||
286 | ||
287 | __fltend(cha) | |
288 | char cha; | |
289 | { | |
290 | register char ch; | |
291 | static char gote, gotpt, gotsn; | |
292 | ||
293 | ch = cha; | |
294 | if (ch < 0) | |
295 | return (gote = gotpt = gotsn = 0); | |
296 | if (ch >= '0' && ch <= '9') | |
297 | { | |
298 | gotsn = -1; | |
299 | return (0); | |
300 | } | |
301 | if (ch == '+' || ch == '-') | |
302 | { | |
303 | if (gotsn || gotpt) | |
304 | return (1); | |
305 | gotsn = 1; | |
306 | return (0); | |
307 | } | |
308 | if (ch == '.') | |
309 | { | |
310 | if (gote || gotpt) | |
311 | return (1); | |
312 | gotpt++; | |
313 | return (0); | |
314 | } | |
315 | if (ch != 'e' && ch != 'E') | |
316 | return (1); | |
317 | if (gote) | |
318 | return (1); | |
319 | gote++; | |
320 | gotsn = 0; | |
321 | return (0); | |
322 | } | |
323 | ||
324 | ||
325 | __strend(cha) | |
326 | char cha; | |
327 | { | |
328 | register char ch; | |
329 | ||
330 | ch = cha; | |
331 | if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0') | |
332 | return (1); | |
333 | return (0); | |
334 | } | |
335 | ||
336 | ||
337 | char __splset[128]; | |
338 | ||
339 | __splend(ch) | |
340 | char ch; | |
341 | { | |
342 | return (__splset[ch]); | |
343 | } | |
344 | ||
345 | ||
346 | __inits(spec) | |
347 | char **spec; | |
348 | { | |
349 | register char ch; | |
350 | register int i; | |
351 | register int val; | |
352 | ||
353 | ch = *(*spec)++; | |
354 | if (ch == '^') | |
355 | { | |
356 | val = 0; | |
357 | ch = *(*spec)++; | |
358 | } | |
359 | else | |
360 | val = 1; | |
361 | for (i = 1; i < 128; i++) | |
362 | __splset[i] = val; | |
363 | val = 1 - val; | |
364 | while (ch != ']') | |
365 | { | |
366 | if (ch == 0) | |
367 | return (-1); | |
368 | __splset[ch & 0177] = val; | |
369 | ch = *(*spec)++; | |
370 | } | |
371 | __splset[0] = 1; | |
372 | return (0); | |
373 | } | |
374 | ||
375 | ||
376 | __float(result, length, longf) | |
377 | double *result; | |
378 | int length; | |
379 | int longf; | |
380 | { | |
381 | extern int __fltend(); | |
382 | char temp[101]; | |
383 | float *fres; | |
384 | register int r; | |
385 | double x; | |
386 | extern double atof(); | |
387 | ||
388 | __fltend(-1); | |
389 | r = __str(temp, length, __fltend); | |
390 | if (r < 0) | |
391 | return (r); | |
392 | if (!result) | |
393 | return (0); | |
394 | x = atof(temp); | |
395 | if (longf) | |
396 | { | |
397 | *result = x; | |
398 | return (1); | |
399 | } | |
400 | fres = result; | |
401 | *fres = x; | |
402 | return (1); | |
403 | } | |
404 | ||
405 | ||
406 | __str(result, length, endfn) | |
407 | char *result; | |
408 | int length; | |
409 | int (*endfn)(); | |
410 | { | |
411 | register char ch; | |
412 | extern int __splend(); | |
413 | register int imode, notok; | |
414 | ||
415 | notok = 1; | |
416 | imode = (endfn != __splend); | |
417 | while (!(*endfn)(ch = __next(imode)) && length-- > 0) | |
418 | { | |
419 | if (result) | |
420 | *result++ = ch; | |
421 | imode = notok = 0; | |
422 | } | |
423 | (*__ungc)(ch, __input); | |
424 | if (notok) | |
425 | return (ch ? -1 : -2); | |
426 | if (!result) | |
427 | return (0); | |
428 | *result = 0; | |
429 | return (1); | |
430 | } | |
431 | ||
432 | ||
433 | __char(result, length) | |
434 | char *result; | |
435 | int length; | |
436 | { | |
437 | register char *r, ch; | |
438 | register int l; | |
439 | ||
440 | r = result; | |
441 | l = length; | |
442 | ||
443 | while (l--) | |
444 | { | |
445 | if ((ch = __next(0)) <= 0) | |
446 | if (l + 1 == length) | |
447 | return (ch ? -1 : -2); | |
448 | else | |
449 | return (result != 0); | |
450 | if (result) | |
451 | *result++ = ch; | |
452 | } | |
453 | return (result != 0); | |
454 | } | |
455 | ||
456 | ||
457 | __gets(s) | |
458 | char **s; | |
459 | { | |
460 | register char c; | |
461 | ||
462 | c = **s; | |
463 | if (c) | |
464 | (*s)++; | |
465 | return (c); | |
466 | } | |
467 | ||
468 | ||
469 | __ungs(c, s) | |
470 | char c; | |
471 | char **s; | |
472 | { | |
473 | if (c) | |
474 | (*s)--; | |
475 | } |