source: buchla-68k/libcio/scan.c@ 9519422

Last change on this file since 9519422 was 7258c6a, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Use standard integer types.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/*
2 =============================================================================
3 scan.c -- input scan conversion for the portable C I/O Library
4 Version 3 -- 1989-01-16 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#include "stdio.h"
9#include "stddefs.h"
10#include "ctype.h"
11
12static int16_t maxwide;
13static int16_t (*gsub)();
14
15extern int8_t *index(int8_t *str, int8_t c);
16
17static int8_t *scnstr;
18static int8_t quit;
19
20/*
21
22*/
23
24static int32_t getnum(int8_t *list, int8_t *values, int16_t base)
25{
26 register int32_t val;
27 register int8_t *cp;
28 int16_t c;
29 int16_t sign;
30
31 if (maxwide LE 0)
32 return(0L);
33
34 val = sign = 0;
35
36 if ((c = (*gsub)(0)) EQ '-') {
37
38 sign = 1;
39 --maxwide;
40
41 } else if (c EQ '+')
42 --maxwide;
43 else
44 (*gsub)(1);
45
46 while (maxwide--) {
47
48 if ((cp = index(list, (*gsub)(0))) EQ NULL) {
49
50 (*gsub)(1);
51 break;
52 }
53
54 val *= base;
55 val += values[(int32_t)cp - (int32_t)list];
56 }
57
58 if (sign)
59 val = -val;
60
61 return(val);
62}
63
64/*
65
66*/
67
68static int16_t skipblk(void)
69{
70 while (isspace((*gsub)(0)))
71 ;
72
73 if ((*gsub)(1) EQ EOF)
74 return(EOF);
75
76 return(0);
77}
78
79static int16_t sgetc(int16_t what)
80{
81 if (what EQ 0) {
82
83 if (*scnstr)
84 return(*scnstr++ & 0x00FF);
85
86 quit = TRUE;
87
88 } else {
89
90 if (!quit)
91 return(*--scnstr & 0x00FF);
92 }
93
94 return(EOF);
95}
96
97/*
98
99*/
100
101int16_t scanfmt(int16_t (*getsub)(), int8_t *fmt, int16_t **args)
102{
103
104#ifdef FLOAT
105 double getflt(), d;
106#endif
107
108 int32_t lv;
109 int16_t c, count, dontdo, lflag, base;
110 int8_t *cp;
111 int8_t tlist[130];
112
113 static int8_t list[] = "ABCDEFabcdef9876543210";
114
115 static int8_t vals[] = {
116
117 10,11,12,13,14,15,10,11,12,13,14,15,9,8,7,6,5,4,3,2,1,0
118 };
119
120/*
121
122*/
123 count = 0;
124 gsub = getsub;
125
126 while (c = *fmt++) {
127
128 if (c EQ '%') {
129
130 lflag = dontdo = FALSE;
131 maxwide = 127;
132
133 if (*fmt EQ '*') {
134 ++fmt;
135 dontdo = 1;
136 }
137
138 if (isdigit(*fmt)) {
139
140 maxwide = 0;
141
142 do {
143
144 maxwide = maxwide*10 + *fmt - '0';
145
146 } while (isdigit(*++fmt));
147 }
148
149 if (*fmt EQ 'l') {
150
151 lflag = TRUE;
152 ++fmt;
153 }
154
155/*
156
157*/
158 switch (*fmt++) {
159
160 case '%':
161 c = '%';
162 goto matchit;
163
164 case 'h': /* specify short (for compatibility) */
165 lflag = FALSE;
166 goto decimal;
167
168 case 'D':
169 lflag = TRUE;
170
171 case 'd':
172 decimal:
173 c = 12;
174 base = 10;
175 goto getval;
176
177 case 'X':
178 lflag = TRUE;
179
180 case 'x':
181 c = 0;
182 base = 16;
183 goto getval;
184
185 case 'O':
186 lflag = TRUE;
187
188 case 'o':
189 c = 14;
190 base = 8;
191 getval:
192 if (skipblk())
193 goto ateof;
194
195 lv = getnum(&list[c], &vals[c], base);
196
197 if (!dontdo) {
198
199 if (lflag)
200 *(int32_t *)(*args++) = lv;
201 else
202 **args++ = lv;
203 ++count;
204 }
205
206 break;
207/*
208
209*/
210
211#ifdef FLOAT
212 case 'E':
213 case 'F':
214 lflag = TRUE;
215
216 case 'e':
217 case 'f':
218 if (skipblk())
219 goto ateof;
220
221 d = getflt(tlist);
222
223 if (!dontdo) {
224
225 if (lflag)
226 *(double *)(*args++) = d;
227 else
228 *(float *)(*args++) = d;
229 ++count;
230 }
231
232 break;
233#endif
234
235/*
236
237*/
238
239 case '[':
240 lflag = FALSE;
241
242 if (*fmt EQ '^' || *fmt EQ '~') {
243
244 ++fmt;
245 lflag = TRUE;
246 }
247
248 for (cp = tlist ; (c = *fmt++) != ']' ; )
249 *cp++ = c;
250
251 *cp = 0;
252 goto string;
253
254 case 's':
255 lflag = TRUE;
256 tlist[0] = ' ';
257 tlist[1] = '\t';
258 tlist[2] = '\n';
259 tlist[3] = 0;
260 string:
261 if (skipblk())
262 goto ateof;
263
264 if (!dontdo)
265 cp = *args++;
266
267 while (maxwide--) {
268
269 if ((c = (*gsub)(0)) EQ EOF)
270 break;
271
272 if (lflag ?
273 (index(tlist, c) NE 0) :
274 (index(tlist, c) EQ 0)) {
275
276 (*gsub)(1); /* unget last character */
277 break;
278 }
279
280 if (!dontdo)
281 *cp++ = c;
282 }
283
284 if (!dontdo) {
285
286 *cp = 0;
287 ++count;
288 }
289
290 break;
291/*
292
293*/
294 case 'c':
295 if ((c = (*gsub)(0)) EQ EOF)
296 goto ateof;
297
298 if (!dontdo) {
299
300 *(int8_t *)(*args++) = c;
301 ++count;
302 }
303
304 break;
305 }
306
307 } else if (isspace(c)) {
308
309 if (skipblk()) {
310ateof:
311 if (count EQ 0)
312 return(EOF);
313
314 return(count);
315 }
316
317 } else {
318
319matchit:
320 if (skipblk())
321 goto ateof;
322
323 if ((*gsub)(0) != c)
324 return(count);
325 }
326 }
327
328 return(count);
329}
330
331/*
332
333*/
334
335#ifdef FLOAT
336
337double
338getflt(buffer)
339char *buffer;
340{
341 register int c;
342 char decpt, sign, exp;
343 register char *cp;
344 double atof();
345
346 cp = buffer;
347 sign = exp = decpt = 0;
348
349 while (maxwide--) {
350
351 c = (*gsub)(0);
352
353 if (!sign AND (c EQ '-' OR c EQ '+'))
354 sign = 1;
355 else if (!decpt AND c EQ '.')
356 decpt = 1;
357 else if (!exp AND (c EQ 'e' OR c EQ 'E')) {
358
359 sign = 0;
360 exp = decpt = 1;
361
362 } else if (!isdigit(c)) {
363
364 (*gsub)(1);
365 break;
366 }
367
368 *cp++ = c;
369 }
370
371 *cp = 0;
372 return(atof(buffer));
373}
374
375#endif
376
377/*
378
379*/
380
381int16_t sscanf(int8_t *string, int8_t *fmt, int16_t *args)
382{
383 scnstr = string;
384 quit = FALSE;
385 return(scanfmt(sgetc, fmt, &args));
386}
387
Note: See TracBrowser for help on using the repository browser.