10 #include "stdio_impl.h"
13 #include "floatscan.h"
22 static void store_int(void *dest
, int size
, unsigned long long i
)
39 *(long long *)dest
= i
;
44 static void *arg_n(va_list ap
, unsigned int n
)
50 for (i
=n
; i
>1; i
--) va_arg(ap2
, void *);
51 p
= va_arg(ap2
, void *);
56 int vfscanf(FILE *restrict f
, const char *restrict fmt
, va_list ap
)
62 const unsigned char *p
;
73 unsigned char scanset
[257];
79 for (p
=(const unsigned char *)fmt
; *p
; p
++) {
84 while (isspace(p
[1])) p
++;
86 while (isspace(shgetc(f
)));
91 if (*p
!= '%' || p
[1] == '%') {
95 while (isspace((c
=shgetc(f
))));
101 if (c
<0) goto input_fail
;
111 } else if (isdigit(*p
) && p
[1]=='$') {
112 dest
= arg_n(ap
, *p
-'0'); p
+=2;
114 dest
= va_arg(ap
, void *);
117 for (width
=0; isdigit(*p
); p
++) {
118 width
= 10*width
+ *p
- '0';
133 if (*p
== 'h') p
++, size
= SIZE_hh
;
137 if (*p
== 'l') p
++, size
= SIZE_ll
;
150 case 'd': case 'i': case 'o': case 'u': case 'x':
151 case 'a': case 'e': case 'f': case 'g':
152 case 'A': case 'E': case 'F': case 'G': case 'X':
153 case 's': case 'c': case '[':
172 if (width
< 1) width
= 1;
176 store_int(dest
, size
, pos
);
177 /* do not increment match count, etc! */
181 while (isspace(shgetc(f
)));
187 if (shgetc(f
) < 0) goto input_fail
;
194 if (t
== 'c' || t
== 's') {
195 memset(scanset
, -1, sizeof scanset
);
206 if (*++p
== '^') p
++, invert
= 1;
208 memset(scanset
, invert
, sizeof scanset
);
210 if (*p
== '-') p
++, scanset
[1+'-'] = 1-invert
;
211 else if (*p
== ']') p
++, scanset
[1+']'] = 1-invert
;
212 for (; *p
!= ']'; p
++) {
213 if (!*p
) goto fmt_fail
;
214 if (*p
=='-' && p
[1] && p
[1] != ']')
215 for (c
=p
++[-1]; c
<*p
; c
++)
216 scanset
[1+c
] = 1-invert
;
217 scanset
[1+*p
] = 1-invert
;
223 k
= t
=='c' ? width
+1U : 31;
224 if (size
== SIZE_l
) {
226 wcs
= malloc(k
*sizeof(wchar_t));
227 if (!wcs
) goto alloc_fail
;
232 while (scanset
[(c
=shgetc(f
))+1]) {
233 switch (mbrtowc(&wc
, &(char){c
}, 1, &st
)) {
239 if (wcs
) wcs
[i
++] = wc
;
242 wchar_t *tmp
= realloc(wcs
, k
*sizeof(wchar_t));
243 if (!tmp
) goto alloc_fail
;
247 if (!mbsinit(&st
)) goto input_fail
;
250 if (!s
) goto alloc_fail
;
251 while (scanset
[(c
=shgetc(f
))+1]) {
255 char *tmp
= realloc(s
, k
);
256 if (!tmp
) goto alloc_fail
;
260 } else if ((s
= dest
)) {
261 while (scanset
[(c
=shgetc(f
))+1])
264 while (scanset
[(c
=shgetc(f
))+1]);
267 if (!shcnt(f
)) goto match_fail
;
268 if (t
== 'c' && shcnt(f
) != width
) goto match_fail
;
270 if (size
== SIZE_l
) *(wchar_t **)dest
= wcs
;
271 else *(char **)dest
= s
;
293 x
= __intscan(f
, base
, 0, ULLONG_MAX
);
294 if (!shcnt(f
)) goto match_fail
;
295 if (t
=='p' && dest
) *(void **)dest
= (void *)(uintptr_t)x
;
296 else store_int(dest
, size
, x
);
302 y
= __floatscan(f
, size
, 0);
303 if (!shcnt(f
)) goto match_fail
;
304 if (dest
) switch (size
) {
312 *(long double *)dest
= y
;
325 if (!matches
) matches
--;
336 weak_alias(vfscanf
,__isoc99_vfscanf
);