1 /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
2 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
3 /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
4 #include <crtdll/stdio.h>
5 #include <crtdll/stdlib.h>
6 #include <crtdll/ctype.h>
7 #include <crtdll/internal/file.h>
13 //static int _fltused = 0;
16 _doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
17 const char *fmt, va_list argp);
19 //#include <crtdll/local.h>
33 static int _innum(int **ptr, int type, int len, int size, FILE *iop,
34 int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
36 static int _instr(char *ptr, int type, int len, FILE *iop,
37 int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
39 static const char *_getccl(const unsigned char *s);
41 static char _sctab[256] = {
43 0,SPC,SPC,SPC,SPC,SPC,0,0,
52 static int nchars = 0;
55 _doscan(FILE *iop, const char *fmt, va_list argp)
57 return(_doscan_low(iop, fgetc, ungetc, fmt, argp));
61 _dowscan(FILE *iop, const wchar_t *fmt, va_list argp)
63 return(_doscan_low(iop, fgetwc, ((void *)ungetwc), ((void *)fmt), argp));
67 _doscan_low(FILE *iop, int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *),
68 const char *fmt, va_list argp)
72 int **ptr, fileended, size;
77 for (;;) switch (ch = *fmt++) {
81 if ((ch = *fmt++) == '%')
85 ptr = va_arg(argp, int **);
91 len = len*10 + ch - '0';
103 size = LONGDOUBLE; /* for long long 'll' format */
110 } else if (ch=='L') {
114 fmt = _getccl((const unsigned char *)fmt);
117 gcc gives warning: ANSI C forbids braced
118 groups within expressions */
122 else if (size != LONGDOUBLE)
133 **(long**)ptr = nchars;
134 else if (size==SHORT)
135 **(short**)ptr = nchars;
136 else if (size==LONGDOUBLE)
137 **(long**)ptr = nchars;
139 **(int**)ptr = nchars;
143 if (_innum(ptr, ch, len, size, iop, scan_getc, scan_ungetc,
151 if (fileended && nmatch==0)
162 while (((nchars++, ch1 = scan_getc(iop))!=EOF) && (_sctab[ch1] & SPC))
166 scan_ungetc(ch1, iop);
173 ch1 = scan_getc(iop);
174 if (ch1 != EOF) nchars++;
177 return(nmatch? nmatch: -1);
178 scan_ungetc(ch1, iop);
186 _innum(int **ptr, int type, int len, int size, FILE *iop,
187 int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *), int *eofptr)
191 register int c, base;
192 int expseen, scale, negflg, c1, ndigit;
196 if (type=='c' || type=='s' || type=='[')
197 return(_instr(ptr? *(char **)ptr: (char *)NULL, type, len,
198 iop, scan_getc, scan_ungetc, eofptr));
202 if (type=='e'||type=='f'||type=='g')
212 while (((nchars++, c = scan_getc(iop)) != EOF) && (_sctab[c] & SPC) )
214 if (c == EOF) nchars--;
227 for ( ; --len>=0; *np++ = c, c = scan_getc(iop), nchars++) {
229 if (c == '0' && cpos == 1 && type == 'i')
231 if ((c == 'x' || c == 'X') && (type == 'i' || type == 'x')
232 && cpos == 2 && lcval == 0)
238 || (base==16 && (('a'<=c && c<='f') || ('A'<=c && c<='F')))) {
243 lcval = ((lcval<<2) + lcval)<<1;
249 else if ('a'<=c && c<='f')
257 if (base!=10 || scale==INT)
261 } else if ((c=='e'||c=='E') && expseen==0) {
262 if (base!=10 || scale==INT || ndigit==0)
268 if (c!='+'&&c!='-'&&('0'>c||c>'9'))
281 if (np==numbuf || (negflg && np==numbuf+1) ) /* gene dykes*/
286 switch((scale<<4) | size) {
288 case (FLOAT<<4) | SHORT:
289 case (FLOAT<<4) | REGULAR:
290 **(float **)ptr = (float)atof(numbuf);
293 case (FLOAT<<4) | LONG:
294 **(double **)ptr = atof(numbuf);
297 case (FLOAT<<4) | LONGDOUBLE:
298 **(long double **)ptr = atold(numbuf);
301 case (INT<<4) | SHORT:
302 **(short **)ptr = (short)lcval;
305 case (INT<<4) | REGULAR:
306 **(int **)ptr = (int)lcval;
309 case (INT<<4) | LONG:
310 **(long **)ptr = lcval;
313 case (INT<<4) | LONGDOUBLE:
314 **(long **)ptr = lcval;
321 _instr(char *ptr, int type, int len, FILE *iop,
322 int (*scan_getc)(FILE *), int (*scan_ungetc)(int, FILE *), int *eofptr)
330 if (type=='c' && len==30000)
335 while ((nchars++, ch = scan_getc(iop)) != EOF && _sctab[ch] & ignstp)
342 while (ch!=EOF && (_sctab[ch]&ignstp)==0) {
353 scan_ungetc(ch, iop);
373 _getccl(const unsigned char *s)
382 for (c = 0; c < (sizeof _sctab / sizeof _sctab[0]); c++)
387 if ((c = *s) == ']' || c == '-') { /* first char is special */
394 while ((c = *s++) != ']') {
396 return((const char *)--s);
397 else if (c == '-' && *s != ']' && s[-2] < *s) {
398 for (c = s[-2] + 1; c < *s; c++)
408 return((const char *)s);