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."
19 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
21 #define va_strt va_start
24 #define va_strt(p,i) va_start(p)
28 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
29 int scanf(const char * fmt
, ...)
31 int scanf(fmt
, va_alist
)
39 rv
= vfscanf(stdin
,fmt
,ptr
);
46 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
47 int sscanf(char * sp
, const char * fmt
, ...)
49 int sscanf(sp
, fmt
, va_alist
)
55 static FILE string
[1] =
57 {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
65 rv
= vfscanf(string
,fmt
,ptr
);
72 #if defined(__STDC__) && !defined(__FIRST_ARG_IN_AX__)
73 int fscanf(FILE * fp
, const char * fmt
, ...)
75 int fscanf(fp
, fmt
, va_alist
)
84 rv
= vfscanf(fp
,fmt
,ptr
);
95 return vfscanf(stdin
,fmt
,ap
);
100 int vsscanf(sp
, fmt
, ap
)
104 static FILE string
[1] =
106 {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1,
107 _IOFBF
| __MODE_READ
}
111 return vfscanf(string
,fmt
,ap
);
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; }
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 */
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 */
145 /* given transition,state do what action? */
146 int fp_do
[][NSTATE
] = {
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 '.' */
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
,
162 FS_EDIGS
,FS_EDIGS
,FS_EDIGS
}, /* see digit */
163 {FS_DOT
,FS_DOT
,FS_DD
,
169 FS_ESIGN
,0,0}, /* see sign */
171 /* which states are valid terminators? */
172 int fp_sval
[NSTATE
] = {
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
;
190 int eneg
, fraclen
, fstate
, trans
;
191 double fx
, fp_scan();
207 lval
= (sizeof(long) == sizeof(int));
212 strcpy(delim
, "\011\012\013\014\015 ");
213 strcpy(digits
, "0123456789ABCDEF");
221 while (isdigit(*++fmt
))/* width digit(s) */
225 wide1
= width
= (width
* 10) + (*fmt
- '0');
230 switch (tolower(*fmt
)) /* tolower() is a MACRO! */
236 case 'l': /* long data */
239 case 'h': /* short data */
243 case 'i': /* any-base numeric */
247 case 'b': /* unsigned binary */
251 case 'o': /* unsigned octal */
255 case 'x': /* unsigned hexadecimal */
259 case 'd': /* SIGNED decimal */
263 case 'u': /* unsigned decimal */
295 if ((neg
== 0) && (base
== 10)
296 && ((neg
= (c
== '-')) || (c
== '+')))
305 p
= ((unsigned char *)
306 strchr(digits
, toupper(c
)));
308 if ((!c
|| !p
) && width
)
311 while (p
&& width
-- && c
)
313 n
= (n
* base
) + (p
- digits
);
316 p
= ((unsigned char *)
317 strchr(digits
, toupper(c
)));
325 *va_arg(ap
, long*) = n
;
327 *va_arg(ap
, short*) = n
;
333 case 'e': /* float */
351 if (c
>= '0' && c
<= '9')
355 else if (c
== '+' || c
== '-')
357 else if (tolower(c
) == 'e')
362 switch (fp_do
[trans
][fstate
])
371 n
= 10 * n
+ (c
- '0');
374 frac
= 10 * frac
+ (c
- '0');
378 expo
= 10 * expo
+ (c
- '0');
383 fstate
= fp_ns
[trans
][fstate
];
388 if (!fp_sval
[fstate
])
392 fx
= fp_scan(neg
, eneg
, n
, frac
, expo
, fraclen
);
394 *va_arg(ap
, double *) = fx
;
396 *va_arg(ap
, float *) = fx
;
402 case 'c': /* character data */
408 case '[': /* string w/ delimiter set */
422 if ((*fmt
== ']') || (*fmt
== '-'))
444 /* fall thru intentional */
447 rngflag
= (*fmt
== '-');
460 case 's': /* string data */
465 p
= va_arg(ap
, unsigned char *);
467 /* if the 1st char fails, match fails */
470 q
= ((unsigned char *)
472 if ((c
< 1) || lval
== (q
==0))
480 for (;;) /* FOREVER */
484 if (((c
= getc(fp
)) < 1) ||
488 q
= ((unsigned char *)
502 case '\0': /* early EOS */
510 else if (isspace(*fmt
)) /* skip whitespace */
515 { /* normal match char */
526 done
: /* end of scan */
527 if ((c
== EOF
) && (cnt
== 0))