* added compilers lcc and bcc (linux86)
[mascara-docs.git] / compilers / linux86-0.16.17 / libc / stdio / scanf.c
bloba49174d08177af888a9c2407bd1572b47b22c045
1 /*
2 * This file based on scanf.c from 'Dlibs' on the atari ST (RdeBath)
4 * 19-OCT-88: Dale Schumacher
5 * > John Stanley has again been a great help in debugging, particularly
6 * > with the printf/scanf functions which are his creation.
8 * Dale Schumacher 399 Beacon Ave.
9 * (alias: Dalnefre') St. Paul, MN 55104
10 * dal@syntel.UUCP United States of America
11 * "It's not reality that's important, but how you perceive things."
15 #include <stdio.h>
16 #include <ctype.h>
17 #include <string.h>
19 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
20 #include <stdarg.h>
21 #define va_strt va_start
22 #else
23 #include <varargs.h>
24 #define va_strt(p,i) va_start(p)
25 #endif
27 #ifdef L_scanf
28 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
29 int scanf(const char * fmt, ...)
30 #else
31 int scanf(fmt, va_alist)
32 __const char *fmt;
33 va_dcl
34 #endif
36 va_list ptr;
37 int rv;
38 va_strt(ptr, fmt);
39 rv = vfscanf(stdin,fmt,ptr);
40 va_end(ptr);
41 return rv;
43 #endif
45 #ifdef L_sscanf
46 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
47 int sscanf(char * sp, const char * fmt, ...)
48 #else
49 int sscanf(sp, fmt, va_alist)
50 char * sp;
51 __const char *fmt;
52 va_dcl
53 #endif
55 static FILE string[1] =
57 {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
58 _IOFBF | __MODE_READ}
61 va_list ptr;
62 int rv;
63 va_strt(ptr, fmt);
64 string->bufpos = sp;
65 rv = vfscanf(string,fmt,ptr);
66 va_end(ptr);
67 return rv;
69 #endif
71 #ifdef L_fscanf
72 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
73 int fscanf(FILE * fp, const char * fmt, ...)
74 #else
75 int fscanf(fp, fmt, va_alist)
76 FILE * fp;
77 __const char *fmt;
78 va_dcl
79 #endif
81 va_list ptr;
82 int rv;
83 va_strt(ptr, fmt);
84 rv = vfscanf(fp,fmt,ptr);
85 va_end(ptr);
86 return rv;
88 #endif
90 #ifdef L_vscanf
91 int vscanf(fmt, ap)
92 __const char *fmt;
93 va_list ap;
95 return vfscanf(stdin,fmt,ap);
97 #endif
99 #ifdef L_vsscanf
100 int vsscanf(sp, fmt, ap)
101 char * sp;
102 __const char *fmt;
104 static FILE string[1] =
106 {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
107 _IOFBF | __MODE_READ}
110 string->bufpos = sp;
111 return vfscanf(string,fmt,ap);
113 #endif
115 #ifdef L_vfscanf
116 /* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/
118 #define skip() while(isspace(c)) { if ((c=getc(fp))<1) goto done; }
120 #if FLOATS
121 /* fp scan actions */
122 #define F_NADA 0 /* just change state */
123 #define F_SIGN 1 /* set sign */
124 #define F_ESIGN 2 /* set exponent's sign */
125 #define F_INT 3 /* adjust integer part */
126 #define F_FRAC 4 /* adjust fraction part */
127 #define F_EXP 5 /* adjust exponent part */
128 #define F_QUIT 6
130 #define NSTATE 8
131 #define FS_INIT 0 /* initial state */
132 #define FS_SIGNED 1 /* saw sign */
133 #define FS_DIGS 2 /* saw digits, no . */
134 #define FS_DOT 3 /* saw ., no digits */
135 #define FS_DD 4 /* saw digits and . */
136 #define FS_E 5 /* saw 'e' */
137 #define FS_ESIGN 6 /* saw exp's sign */
138 #define FS_EDIGS 7 /* saw exp's digits */
140 #define FC_DIG 0
141 #define FC_DOT 1
142 #define FC_E 2
143 #define FC_SIGN 3
145 /* given transition,state do what action? */
146 int fp_do[][NSTATE] = {
147 {F_INT,F_INT,F_INT,
148 F_FRAC,F_FRAC,
149 F_EXP,F_EXP,F_EXP}, /* see digit */
150 {F_NADA,F_NADA,F_NADA,
151 F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT}, /* see '.' */
152 {F_QUIT,F_QUIT,
153 F_NADA,F_QUIT,F_NADA,
154 F_QUIT,F_QUIT,F_QUIT}, /* see e/E */
155 {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT,
156 F_ESIGN,F_QUIT,F_QUIT}, /* see sign */
158 /* given transition,state what is new state? */
159 int fp_ns[][NSTATE] = {
160 {FS_DIGS,FS_DIGS,FS_DIGS,
161 FS_DD,FS_DD,
162 FS_EDIGS,FS_EDIGS,FS_EDIGS}, /* see digit */
163 {FS_DOT,FS_DOT,FS_DD,
164 }, /* see '.' */
165 {0,0,
166 FS_E,0,FS_E,
167 }, /* see e/E */
168 {FS_SIGNED,0,0,0,0,
169 FS_ESIGN,0,0}, /* see sign */
171 /* which states are valid terminators? */
172 int fp_sval[NSTATE] = {
173 0,0,1,0,1,0,0,1
175 #endif
177 vfscanf(fp, fmt, ap)
178 register FILE *fp;
179 register char *fmt;
180 va_list ap;
183 register long n;
184 register int c, width, lval, cnt = 0;
185 int store, neg, base, wide1, endnull, rngflag, c2;
186 register unsigned char *p;
187 unsigned char delim[128], digits[17], *q;
188 #if FLOATS
189 long frac, expo;
190 int eneg, fraclen, fstate, trans;
191 double fx, fp_scan();
192 #endif
194 if (!*fmt)
195 return (0);
197 c = getc(fp);
198 while (c > 0)
200 store = 0;
201 if (*fmt == '%')
203 n = 0;
204 width = -1;
205 wide1 = 1;
206 base = 10;
207 lval = (sizeof(long) == sizeof(int));
208 store = 1;
209 endnull = 1;
210 neg = -1;
212 strcpy(delim, "\011\012\013\014\015 ");
213 strcpy(digits, "0123456789ABCDEF");
215 if (fmt[1] == '*')
217 endnull = store = 0;
218 ++fmt;
221 while (isdigit(*++fmt))/* width digit(s) */
223 if (width == -1)
224 width = 0;
225 wide1 = width = (width * 10) + (*fmt - '0');
227 --fmt;
228 fmtnxt:
229 ++fmt;
230 switch (tolower(*fmt)) /* tolower() is a MACRO! */
232 case '*':
233 endnull = store = 0;
234 goto fmtnxt;
236 case 'l': /* long data */
237 lval = 1;
238 goto fmtnxt;
239 case 'h': /* short data */
240 lval = 0;
241 goto fmtnxt;
243 case 'i': /* any-base numeric */
244 base = 0;
245 goto numfmt;
247 case 'b': /* unsigned binary */
248 base = 2;
249 goto numfmt;
251 case 'o': /* unsigned octal */
252 base = 8;
253 goto numfmt;
255 case 'x': /* unsigned hexadecimal */
256 base = 16;
257 goto numfmt;
259 case 'd': /* SIGNED decimal */
260 neg = 0;
261 /* FALL-THRU */
263 case 'u': /* unsigned decimal */
264 numfmt:skip();
266 if (isupper(*fmt))
267 lval = 1;
269 if (!base)
271 base = 10;
272 neg = 0;
273 if (c == '%')
275 base = 2;
276 goto skip1;
278 else if (c == '0')
280 c = getc(fp);
281 if (c < 1)
282 goto savnum;
283 if ((c != 'x')
284 && (c != 'X'))
286 base = 8;
287 digits[8] = '\0';
288 goto zeroin;
290 base = 16;
291 goto skip1;
295 if ((neg == 0) && (base == 10)
296 && ((neg = (c == '-')) || (c == '+')))
298 skip1:
299 c = getc(fp);
300 if (c < 1)
301 goto done;
304 digits[base] = '\0';
305 p = ((unsigned char *)
306 strchr(digits, toupper(c)));
308 if ((!c || !p) && width)
309 goto done;
311 while (p && width-- && c)
313 n = (n * base) + (p - digits);
314 c = getc(fp);
315 zeroin:
316 p = ((unsigned char *)
317 strchr(digits, toupper(c)));
319 savnum:
320 if (store)
322 if (neg == 1)
323 n = -n;
324 if (lval)
325 *va_arg(ap, long*) = n;
326 else
327 *va_arg(ap, short*) = n;
328 ++cnt;
330 break;
332 #if FLOATS
333 case 'e': /* float */
334 case 'f':
335 case 'g':
336 skip();
338 if (isupper(*fmt))
339 lval = 1;
341 fstate = FS_INIT;
342 neg = 0;
343 eneg = 0;
344 n = 0;
345 frac = 0;
346 expo = 0;
347 fraclen = 0;
349 while (c && width--)
351 if (c >= '0' && c <= '9')
352 trans = FC_DIG;
353 else if (c == '.')
354 trans = FC_DOT;
355 else if (c == '+' || c == '-')
356 trans = FC_SIGN;
357 else if (tolower(c) == 'e')
358 trans = FC_E;
359 else
360 goto fdone;
362 switch (fp_do[trans][fstate])
364 case F_SIGN:
365 neg = (c == '-');
366 break;
367 case F_ESIGN:
368 eneg = (c == '-');
369 break;
370 case F_INT:
371 n = 10 * n + (c - '0');
372 break;
373 case F_FRAC:
374 frac = 10 * frac + (c - '0');
375 fraclen++;
376 break;
377 case F_EXP:
378 expo = 10 * expo + (c - '0');
379 break;
380 case F_QUIT:
381 goto fdone;
383 fstate = fp_ns[trans][fstate];
384 c = getc(fp);
387 fdone:
388 if (!fp_sval[fstate])
389 goto done;
390 if (store)
392 fx = fp_scan(neg, eneg, n, frac, expo, fraclen);
393 if (lval)
394 *va_arg(ap, double *) = fx;
395 else
396 *va_arg(ap, float *) = fx;
397 ++cnt;
399 break;
400 #endif
402 case 'c': /* character data */
403 width = wide1;
404 lval = endnull = 0;
405 delim[0] = '\0';
406 goto strproc;
408 case '[': /* string w/ delimiter set */
410 /* get delimiters */
411 p = delim;
413 if (*++fmt == '^')
415 fmt++;
416 lval = 0;
418 else
419 lval = 1;
421 rngflag = 2;
422 if ((*fmt == ']') || (*fmt == '-'))
424 *p++ = *fmt++;
425 rngflag = 0;
428 while (*fmt != ']')
430 if (*fmt == '\0')
431 goto done;
432 switch (rngflag)
434 case 1:
435 c2 = *(p - 2);
436 if (c2 <= *fmt)
438 p -= 2;
439 while (c2 < *fmt)
440 *p++ = c2++;
441 rngflag = 2;
442 break;
444 /* fall thru intentional */
446 case 0:
447 rngflag = (*fmt == '-');
448 break;
450 case 2:
451 rngflag = 0;
454 *p++ = *fmt++;
457 *p = '\0';
458 goto strproc;
460 case 's': /* string data */
461 lval = 0;
462 skip();
463 strproc:
464 /* process string */
465 p = va_arg(ap, unsigned char *);
467 /* if the 1st char fails, match fails */
468 if (width)
470 q = ((unsigned char *)
471 strchr(delim, c));
472 if ((c < 1) || lval == (q==0))
474 if (endnull)
475 *p = '\0';
476 goto done;
480 for (;;) /* FOREVER */
482 if (store)
483 *p++ = c;
484 if (((c = getc(fp)) < 1) ||
485 (--width == 0))
486 break;
488 q = ((unsigned char *)
489 strchr(delim, c));
490 if (lval == (q==0))
491 break;
494 if (store)
496 if (endnull)
497 *p = '\0';
498 ++cnt;
500 break;
502 case '\0': /* early EOS */
503 --fmt;
504 /* FALL THRU */
506 default:
507 goto cmatch;
510 else if (isspace(*fmt)) /* skip whitespace */
512 skip();
514 else
515 { /* normal match char */
516 cmatch:
517 if (c != *fmt)
518 break;
519 c = getc(fp);
522 if (!*++fmt)
523 break;
526 done: /* end of scan */
527 if ((c == EOF) && (cnt == 0))
528 return (EOF);
530 if( c != EOF )
531 ungetc(c, fp);
532 return (cnt);
535 #endif