source: buchla-68k/orig/IOLIB/SCAN.C@ f40a309

Last change on this file since f40a309 was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Imported original source code.

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