1 /* Copyright (C) 1991-2002, 2003, 2004, 2005, 2006
2 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
31 #include <bits/libc-lock.h>
32 #include <locale/localeinfo.h>
35 # define HAVE_LONGLONG
36 # define LONGLONG long long
38 # define LONGLONG long
41 /* Determine whether we have to handle `long long' at all. */
42 #if LONG_MAX == LONG_LONG_MAX
43 # define need_longlong 0
45 # define need_longlong 1
48 /* Determine whether we have to handle `long'. */
49 #if INT_MAX == LONG_MAX
55 /* Those are flags in the conversion format. */
56 #define LONG 0x001 /* l: long or double */
57 #define LONGDBL 0x002 /* L: long long or long double */
58 #define SHORT 0x004 /* h: short */
59 #define SUPPRESS 0x008 /* *: suppress assignment */
60 #define POINTER 0x010 /* weird %p pointer (`fake hex') */
61 #define NOSKIP 0x020 /* do not skip blanks */
62 #define WIDTH 0x040 /* width was given */
63 #define GROUP 0x080 /* ': group numbers */
64 #define MALLOC 0x100 /* a: malloc strings */
65 #define CHAR 0x200 /* hh: char */
66 #define I18N 0x400 /* I: use locale's digits */
69 #include <locale/localeinfo.h>
74 #define va_list _IO_va_list
77 # define ungetc(c, s) ((void) (c == WEOF \
79 INTUSE(_IO_sputbackwc) (s, c))))
80 # define ungetc_not_eof(c, s) ((void) (--read_in, \
81 INTUSE(_IO_sputbackwc) (s, c)))
82 # define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
83 : ((c = _IO_getwc_unlocked (s)), \
86 : (size_t) (inchar_errno = errno)), c))
88 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
89 # define ISSPACE(Ch) iswspace (Ch)
90 # define ISDIGIT(Ch) iswdigit (Ch)
91 # define ISXDIGIT(Ch) iswxdigit (Ch)
92 # define TOLOWER(Ch) towlower (Ch)
93 # define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
94 # define __strtoll_internal __wcstoll_internal
95 # define __strtoull_internal __wcstoull_internal
96 # define __strtol_internal __wcstol_internal
97 # define __strtoul_internal __wcstoul_internal
98 # define __strtold_internal __wcstold_internal
99 # define __strtod_internal __wcstod_internal
100 # define __strtof_internal __wcstof_internal
102 # define L_(Str) L##Str
103 # define CHAR_T wchar_t
104 # define UCHAR_T unsigned int
105 # define WINT_T wint_t
109 # define ungetc(c, s) ((void) ((int) c == EOF \
111 INTUSE(_IO_sputbackc) (s, (unsigned char) c))))
112 # define ungetc_not_eof(c, s) ((void) (--read_in, \
113 INTUSE(_IO_sputbackc) (s, (unsigned char) c)))
114 # define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
115 : ((c = _IO_getc_unlocked (s)), \
118 : (size_t) (inchar_errno = errno)), c))
119 # define MEMCPY(d, s, n) memcpy (d, s, n)
120 # define ISSPACE(Ch) __isspace_l (Ch, loc)
121 # define ISDIGIT(Ch) __isdigit_l (Ch, loc)
122 # define ISXDIGIT(Ch) __isxdigit_l (Ch, loc)
123 # define TOLOWER(Ch) __tolower_l ((unsigned char) (Ch), loc)
124 # define ORIENT if (_IO_vtable_offset (s) == 0 \
125 && _IO_fwide (s, -1) != -1) \
130 # define UCHAR_T unsigned char
134 #define encode_error() do { \
136 __set_errno (EILSEQ); \
139 #define conv_error() do { \
143 #define input_error() do { \
145 if (done == 0) done = EOF; \
148 #define memory_error() do { \
149 __set_errno (ENOMEM); \
153 #define ARGCHECK(s, format) \
156 /* Check file argument for consistence. */ \
157 CHECK_FILE (s, EOF); \
158 if (s->_flags & _IO_NO_READS) \
160 __set_errno (EBADF); \
163 else if (format == NULL) \
169 #define LOCK_STREAM(S) \
170 __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
172 #define UNLOCK_STREAM(S) \
173 _IO_funlockfile (S); \
174 __libc_cleanup_region_end (0)
177 /* Read formatted input from S according to the format string
178 FORMAT, using the argument list in ARG.
179 Return the number of assignments made, or -1 for an input error. */
180 #ifdef COMPILE_WSCANF
182 _IO_vfwscanf (_IO_FILE
*s
, const wchar_t *format
, _IO_va_list argptr
,
186 _IO_vfscanf_internal (_IO_FILE
*s
, const char *format
, _IO_va_list argptr
,
191 register const CHAR_T
*f
= format
;
192 register UCHAR_T fc
; /* Current character of the format. */
193 register WINT_T done
= 0; /* Assignments done. */
194 register size_t read_in
= 0; /* Chars read in. */
195 register WINT_T c
= 0; /* Last char read. */
196 register int width
; /* Maximum field width. */
197 register int flags
; /* Modifiers for current format element. */
199 #ifndef COMPILE_WSCANF
200 __locale_t loc
= _NL_CURRENT_LOCALE
;
201 struct locale_data
*const curctype
= loc
->__locales
[LC_CTYPE
];
204 /* Errno of last failed inchar call. */
205 int inchar_errno
= 0;
206 /* Status for reading F-P nums. */
207 char got_dot
, got_e
, negative
;
208 /* If a [...] is a [^...]. */
210 #define exp_char not_in
211 /* Base for integral numbers. */
213 /* Signedness for integral numbers. */
215 #define is_hexa number_signed
216 /* Decimal point character. */
217 #ifdef COMPILE_WSCANF
222 /* The thousands character of the current locale. */
223 #ifdef COMPILE_WSCANF
226 const char *thousands
;
228 /* State for the conversions. */
230 /* Integral holding variables. */
234 unsigned long long int uq
;
236 unsigned long int ul
;
238 /* Character-buffer pointer. */
240 wchar_t *wstr
= NULL
;
241 char **strptr
= NULL
;
243 /* We must not react on white spaces immediately because they can
244 possibly be matched even if in the input stream no character is
245 available anymore. */
247 /* Nonzero if we are reading a pointer. */
250 CHAR_T
*tw
; /* Temporary pointer. */
251 CHAR_T
*wp
= NULL
; /* Workspace. */
252 size_t wpmax
= 0; /* Maximal size of workspace. */
253 size_t wpsize
; /* Currently used bytes in workspace. */
257 if (wpsize == wpmax) \
260 wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
261 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
263 MEMCPY (wp, old, wpsize); \
265 wp[wpsize++] = (Ch); \
270 __va_copy (arg
, argptr
);
272 arg
= (va_list) argptr
;
279 ARGCHECK (s
, format
);
282 #ifndef COMPILE_WSCANF
283 struct locale_data
*const curnumeric
= loc
->__locales
[LC_NUMERIC
];
286 /* Figure out the decimal point character. */
287 #ifdef COMPILE_WSCANF
288 decimal
= _NL_CURRENT_WORD (LC_NUMERIC
, _NL_NUMERIC_DECIMAL_POINT_WC
);
290 decimal
= curnumeric
->values
[_NL_ITEM_INDEX (DECIMAL_POINT
)].string
;
292 /* Figure out the thousands separator character. */
293 #ifdef COMPILE_WSCANF
294 thousands
= _NL_CURRENT_WORD (LC_NUMERIC
, _NL_NUMERIC_THOUSANDS_SEP_WC
);
296 thousands
= curnumeric
->values
[_NL_ITEM_INDEX (THOUSANDS_SEP
)].string
;
297 if (*thousands
== '\0')
302 /* Lock the stream. */
306 #ifndef COMPILE_WSCANF
307 /* From now on we use `state' to convert the format string. */
308 memset (&state
, '\0', sizeof (state
));
311 /* Run through the format string. */
315 /* Extract the next argument, which is of type TYPE.
316 For a %N$... spec, this is the Nth argument from the beginning;
317 otherwise it is the next argument after the state now in ARG. */
319 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
320 ({ unsigned int pos = argpos; \
322 __va_copy (arg, argptr); \
324 (void) va_arg (arg, void *); \
325 va_arg (arg, type); \
329 /* XXX Possible optimization. */
330 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
331 ({ va_list arg = (va_list) argptr; \
332 arg = (va_list) ((char *) arg \
334 * __va_rounded_size (void *)); \
335 va_arg (arg, type); \
338 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
339 ({ unsigned int pos = argpos; \
340 va_list arg = (va_list) argptr; \
342 (void) va_arg (arg, void *); \
343 va_arg (arg, type); \
348 #ifndef COMPILE_WSCANF
349 if (!isascii ((unsigned char) *f
))
351 /* Non-ASCII, may be a multibyte. */
352 int len
= __mbrlen (f
, strlen (f
), &state
);
360 else if (c
!= (unsigned char) *f
++)
362 ungetc_not_eof (c
, s
);
375 /* Remember to skip spaces. */
382 /* Read a character. */
385 /* Characters other than format specs must just match. */
389 /* We saw white space char as the last character in the format
390 string. Now it's time to skip all leading white space. */
394 if (inchar () == EOF
)
408 /* This is the start of the conversion string. */
411 /* Not yet decided whether we read a pointer or not. */
414 /* Initialize state of modifiers. */
417 /* Prepare temporary buffer. */
420 /* Check for a positional parameter specification. */
421 if (ISDIGIT ((UCHAR_T
) *f
))
423 argpos
= (UCHAR_T
) *f
++ - L_('0');
424 while (ISDIGIT ((UCHAR_T
) *f
))
425 argpos
= argpos
* 10 + ((UCHAR_T
) *f
++ - L_('0'));
430 /* Oops; that was actually the field width. */
438 /* Check for the assignment-suppressing, the number grouping flag,
439 and the signal to use the locale's digit representation. */
440 while (*f
== L_('*') || *f
== L_('\'') || *f
== L_('I'))
454 /* We have seen width. */
455 if (ISDIGIT ((UCHAR_T
) *f
))
458 /* Find the maximum field width. */
460 while (ISDIGIT ((UCHAR_T
) *f
))
463 width
+= (UCHAR_T
) *f
++ - L_('0');
469 /* Check for type modifiers. */
473 /* ints are short ints or chars. */
485 /* A double `l' is equivalent to an `L'. */
487 flags
|= LONGDBL
| LONG
;
490 /* ints are long ints. */
495 /* doubles are long doubles, and ints are long long ints. */
496 flags
|= LONGDBL
| LONG
;
499 /* The `a' is used as a flag only if followed by `s', `S' or
501 if (*f
!= L_('s') && *f
!= L_('S') && *f
!= L_('['))
506 /* String conversions (%s, %[) take a `char **'
507 arg and fill it in with a malloc'd pointer. */
511 if (need_longlong
&& sizeof (size_t) > sizeof (unsigned long int))
513 else if (sizeof (size_t) > sizeof (unsigned int))
517 if (need_longlong
&& sizeof (uintmax_t) > sizeof (unsigned long int))
519 else if (sizeof (uintmax_t) > sizeof (unsigned int))
523 if (need_longlong
&& sizeof (ptrdiff_t) > sizeof (long int))
525 else if (sizeof (ptrdiff_t) > sizeof (int))
529 /* Not a recognized modifier. Backup. */
534 /* End of the format string? */
538 /* Find the conversion specifier. */
540 if (skip_space
|| (fc
!= L_('[') && fc
!= L_('c')
541 && fc
!= L_('C') && fc
!= L_('n')))
543 /* Eat whitespace. */
544 int save_errno
= errno
;
547 if (inchar () == EOF
&& errno
== EINTR
)
557 case L_('%'): /* Must match a literal '%'. */
563 ungetc_not_eof (c
, s
);
568 case L_('n'): /* Answer number of assignments done. */
569 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
570 with the 'n' conversion specifier. */
571 if (!(flags
& SUPPRESS
))
573 /* Don't count the read-ahead. */
574 if (need_longlong
&& (flags
& LONGDBL
))
575 *ARG (long long int *) = read_in
;
576 else if (need_long
&& (flags
& LONG
))
577 *ARG (long int *) = read_in
;
578 else if (flags
& SHORT
)
579 *ARG (short int *) = read_in
;
580 else if (!(flags
& CHAR
))
581 *ARG (int *) = read_in
;
583 *ARG (char *) = read_in
;
585 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
586 /* We have a severe problem here. The ISO C standard
587 contradicts itself in explaining the effect of the %n
588 format in `scanf'. While in ISO C:1990 and the ISO C
589 Amendement 1:1995 the result is described as
591 Execution of a %n directive does not effect the
592 assignment count returned at the completion of
593 execution of the f(w)scanf function.
595 in ISO C Corrigendum 1:1994 the following was added:
598 Add the following fourth example:
601 int d1, d2, n1, n2, i;
602 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
603 the value 123 is assigned to d1 and the value3 to n1.
604 Because %n can never get an input failure the value
605 of 3 is also assigned to n2. The value of d2 is not
606 affected. The value 3 is assigned to i.
608 We go for now with the historically correct code from ISO C,
609 i.e., we don't count the %n assignments. When it ever
610 should proof to be wrong just remove the #ifdef above. */
616 case L_('c'): /* Match characters. */
617 if ((flags
& LONG
) == 0)
619 if (!(flags
& SUPPRESS
))
633 #ifdef COMPILE_WSCANF
634 /* We have to convert the wide character(s) into multibyte
635 characters and store the result. */
636 memset (&state
, '\0', sizeof (state
));
642 n
= __wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
643 if (n
== (size_t) -1)
644 /* No valid wide character. */
647 /* Increment the output pointer. Even if we don't
651 while (--width
> 0 && inchar () != EOF
);
653 if (!(flags
& SUPPRESS
))
657 while (--width
> 0 && inchar () != EOF
);
660 while (--width
> 0 && inchar () != EOF
);
663 if (!(flags
& SUPPRESS
))
670 if (!(flags
& SUPPRESS
))
672 wstr
= ARG (wchar_t *);
681 #ifdef COMPILE_WSCANF
682 /* Just store the incoming wide characters. */
683 if (!(flags
& SUPPRESS
))
687 while (--width
> 0 && inchar () != EOF
);
690 while (--width
> 0 && inchar () != EOF
);
693 /* We have to convert the multibyte input sequence to wide
698 memset (&cstate
, '\0', sizeof (cstate
));
702 /* This is what we present the mbrtowc function first. */
709 n
= __mbrtowc (!(flags
& SUPPRESS
) ? wstr
: NULL
,
712 if (n
== (size_t) -2)
714 /* Possibly correct character, just not enough
716 if (inchar () == EOF
)
726 /* We have a match. */
730 /* Advance the result pointer. */
733 while (--width
> 0 && inchar () != EOF
);
737 if (!(flags
& SUPPRESS
))
742 case L_('s'): /* Read a string. */
745 #define STRING_ARG(Str, Type) \
746 do if (!(flags & SUPPRESS)) \
748 if (flags & MALLOC) \
750 /* The string is to be stored in a malloc'd buffer. */ \
751 strptr = ARG (char **); \
752 if (strptr == NULL) \
754 /* Allocate an initial buffer. */ \
756 *strptr = (char *) malloc (strsize * sizeof (Type)); \
757 Str = (Type *) *strptr; \
760 Str = ARG (Type *); \
764 STRING_ARG (str
, char);
770 #ifdef COMPILE_WSCANF
771 memset (&state
, '\0', sizeof (state
));
778 ungetc_not_eof (c
, s
);
782 #ifdef COMPILE_WSCANF
783 /* This is quite complicated. We have to convert the
784 wide characters into multibyte characters and then
789 if (!(flags
& SUPPRESS
) && (flags
& MALLOC
)
790 && str
+ MB_CUR_MAX
>= *strptr
+ strsize
)
792 /* We have to enlarge the buffer if the `a' flag
794 size_t strleng
= str
- *strptr
;
797 newstr
= (char *) realloc (*strptr
, strsize
* 2);
800 /* Can't allocate that much. Last-ditch
802 newstr
= (char *) realloc (*strptr
,
803 strleng
+ MB_CUR_MAX
);
806 /* We lose. Oh well. Terminate the
807 string and stop converting,
808 so at least we don't skip any input. */
809 ((char *) (*strptr
))[strleng
] = '\0';
816 str
= newstr
+ strleng
;
817 strsize
= strleng
+ MB_CUR_MAX
;
823 str
= newstr
+ strleng
;
828 n
= __wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
,
830 if (n
== (size_t) -1)
833 assert (n
<= MB_CUR_MAX
);
838 if (!(flags
& SUPPRESS
))
842 && (char *) str
== *strptr
+ strsize
)
844 /* Enlarge the buffer. */
845 str
= (char *) realloc (*strptr
, 2 * strsize
);
848 /* Can't allocate that much. Last-ditch
850 str
= (char *) realloc (*strptr
, strsize
+ 1);
853 /* We lose. Oh well. Terminate the
854 string and stop converting,
855 so at least we don't skip any input. */
856 ((char *) (*strptr
))[strsize
- 1] = '\0';
862 *strptr
= (char *) str
;
869 *strptr
= (char *) str
;
877 while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
879 if (!(flags
& SUPPRESS
))
881 #ifdef COMPILE_WSCANF
882 /* We have to emit the code to get into the initial
884 char buf
[MB_LEN_MAX
];
885 size_t n
= __wcrtomb (buf
, L
'\0', &state
);
886 if (n
> 0 && (flags
& MALLOC
)
887 && str
+ n
>= *strptr
+ strsize
)
889 /* Enlarge the buffer. */
890 size_t strleng
= str
- *strptr
;
893 newstr
= (char *) realloc (*strptr
, strleng
+ n
+ 1);
896 /* We lose. Oh well. Terminate the string
897 and stop converting, so at least we don't
899 ((char *) (*strptr
))[strleng
] = '\0';
906 str
= newstr
+ strleng
;
907 strsize
= strleng
+ n
+ 1;
911 str
= __mempcpy (str
, buf
, n
);
915 if ((flags
& MALLOC
) && str
- *strptr
!= strsize
)
917 char *cp
= (char *) realloc (*strptr
, str
- *strptr
);
930 #ifndef COMPILE_WSCANF
934 /* Wide character string. */
935 STRING_ARG (wstr
, wchar_t);
941 #ifndef COMPILE_WSCANF
942 memset (&cstate
, '\0', sizeof (cstate
));
949 ungetc_not_eof (c
, s
);
953 #ifdef COMPILE_WSCANF
955 if (!(flags
& SUPPRESS
))
959 && wstr
== (wchar_t *) *strptr
+ strsize
)
961 /* Enlarge the buffer. */
962 wstr
= (wchar_t *) realloc (*strptr
,
967 /* Can't allocate that much. Last-ditch
969 wstr
= (wchar_t *) realloc (*strptr
,
974 /* We lose. Oh well. Terminate the string
975 and stop converting, so at least we don't
977 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
983 *strptr
= (char *) wstr
;
990 *strptr
= (char *) wstr
;
1006 n
= __mbrtowc (!(flags
& SUPPRESS
) ? wstr
: NULL
,
1009 if (n
== (size_t) -2)
1011 /* Possibly correct character, just not enough
1013 if (inchar () == EOF
)
1023 /* We have a match. */
1028 if (!(flags
& SUPPRESS
) && (flags
& MALLOC
)
1029 && wstr
== (wchar_t *) *strptr
+ strsize
)
1031 /* Enlarge the buffer. */
1032 wstr
= (wchar_t *) realloc (*strptr
,
1034 * sizeof (wchar_t)));
1037 /* Can't allocate that much. Last-ditch effort. */
1038 wstr
= (wchar_t *) realloc (*strptr
,
1040 * sizeof (wchar_t)));
1043 /* We lose. Oh well. Terminate the
1044 string and stop converting, so at
1045 least we don't skip any input. */
1046 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1052 *strptr
= (char *) wstr
;
1059 *strptr
= (char *) wstr
;
1067 while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
1069 if (!(flags
& SUPPRESS
))
1073 if ((flags
& MALLOC
) && wstr
- (wchar_t *) *strptr
!= strsize
)
1075 wchar_t *cp
= (wchar_t *) realloc (*strptr
,
1077 - (wchar_t *) *strptr
)
1078 * sizeof(wchar_t)));
1080 *strptr
= (char *) cp
;
1088 case L_('x'): /* Hexadecimal integer. */
1089 case L_('X'): /* Ditto. */
1094 case L_('o'): /* Octal integer. */
1099 case L_('u'): /* Unsigned decimal integer. */
1104 case L_('d'): /* Signed decimal integer. */
1109 case L_('i'): /* Generic number. */
1118 /* Check for a sign. */
1119 if (c
== L_('-') || c
== L_('+'))
1127 /* Look for a leading indication of base. */
1128 if (width
!= 0 && c
== L_('0'))
1136 if (width
!= 0 && TOLOWER (c
) == L_('x'))
1154 if (base
== 10 && (flags
& I18N
) != 0)
1159 #ifdef COMPILE_WSCANF
1160 const wchar_t *wcdigits
[10];
1161 const wchar_t *wcdigits_extended
[10];
1163 const char *mbdigits
[10];
1164 const char *mbdigits_extended
[10];
1166 /* "to_inpunct" is a map from ASCII digits to their
1167 equivalent in locale. This is defined for locales
1168 which use an extra digits set. */
1169 wctrans_t map
= __wctrans ("to_inpunct");
1173 #ifdef COMPILE_WSCANF
1174 to_level
= _NL_CURRENT_WORD (LC_CTYPE
,
1175 _NL_CTYPE_INDIGITS_WC_LEN
) - 1;
1177 to_level
= (uint32_t) curctype
->values
[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN
)].word
- 1;
1180 /* Get the alternative digit forms if there are any. */
1181 if (__builtin_expect (map
!= NULL
, 0))
1183 /* Adding new level for extra digits set in locale file. */
1186 for (n
= 0; n
< 10; ++n
)
1188 #ifdef COMPILE_WSCANF
1189 wcdigits
[n
] = (const wchar_t *)
1190 _NL_CURRENT (LC_CTYPE
, _NL_CTYPE_INDIGITS0_WC
+ n
);
1192 wchar_t *wc_extended
= (wchar_t *)
1193 alloca ((to_level
+ 2) * sizeof (wchar_t));
1194 __wmemcpy (wc_extended
, wcdigits
[n
], to_level
);
1195 wc_extended
[to_level
] = __towctrans (L
'0' + n
, map
);
1196 wc_extended
[to_level
+ 1] = '\0';
1197 wcdigits_extended
[n
] = wc_extended
;
1200 = curctype
->values
[_NL_CTYPE_INDIGITS0_MB
+ n
].string
;
1202 /* Get the equivalent wide char in map. */
1203 wint_t extra_wcdigit
= __towctrans (L
'0' + n
, map
);
1205 /* Convert it to multibyte representation. */
1207 memset (&state
, '\0', sizeof (state
));
1209 char extra_mbdigit
[MB_LEN_MAX
];
1211 = __wcrtomb (extra_mbdigit
, extra_wcdigit
, &state
);
1213 if (mblen
== (size_t) -1)
1215 /* Ignore this new level. */
1220 /* Calculate the length of mbdigits[n]. */
1221 const char *last_char
= mbdigits
[n
];
1222 for (level
= 0; level
< to_level
; ++level
)
1223 last_char
= strchr (last_char
, '\0') + 1;
1225 size_t mbdigits_len
= last_char
- mbdigits
[n
];
1227 /* Allocate memory for extended multibyte digit. */
1229 mb_extended
= (char *) alloca (mbdigits_len
+ mblen
+ 1);
1231 /* And get the mbdigits + extra_digit string. */
1232 *(char *) __mempcpy (__mempcpy (mb_extended
, mbdigits
[n
],
1234 extra_mbdigit
, mblen
) = '\0';
1235 mbdigits_extended
[n
] = mb_extended
;
1240 /* Read the number into workspace. */
1241 while (c
!= EOF
&& width
!= 0)
1243 /* In this round we get the pointer to the digit strings
1244 and also perform the first round of comparisons. */
1245 for (n
= 0; n
< 10; ++n
)
1247 /* Get the string for the digits with value N. */
1248 #ifdef COMPILE_WSCANF
1249 if (__builtin_expect (map
!= NULL
, 0))
1250 wcdigits
[n
] = wcdigits_extended
[n
];
1252 wcdigits
[n
] = (const wchar_t *)
1253 _NL_CURRENT (LC_CTYPE
, _NL_CTYPE_INDIGITS0_WC
+ n
);
1254 wcdigits
[n
] += from_level
;
1256 if (c
== (wint_t) *wcdigits
[n
])
1258 to_level
= from_level
;
1262 /* Advance the pointer to the next string. */
1266 int avail
= width
> 0 ? width
: INT_MAX
;
1268 if (__builtin_expect (map
!= NULL
, 0))
1269 mbdigits
[n
] = mbdigits_extended
[n
];
1272 = curctype
->values
[_NL_CTYPE_INDIGITS0_MB
+ n
].string
;
1274 for (level
= 0; level
< from_level
; level
++)
1275 mbdigits
[n
] = strchr (mbdigits
[n
], '\0') + 1;
1278 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1280 if (*++cmpp
== '\0')
1284 if ((c
= inchar ()) == EOF
)
1294 to_level
= from_level
;
1298 /* We are pushing all read characters back. */
1299 if (cmpp
> mbdigits
[n
])
1302 while (--cmpp
> mbdigits
[n
])
1303 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1304 c
= (unsigned char) *cmpp
;
1307 /* Advance the pointer to the next string. */
1308 mbdigits
[n
] = strchr (mbdigits
[n
], '\0') + 1;
1314 /* Have not yet found the digit. */
1315 for (level
= from_level
+ 1; level
<= to_level
; ++level
)
1317 /* Search all ten digits of this level. */
1318 for (n
= 0; n
< 10; ++n
)
1320 #ifdef COMPILE_WSCANF
1321 if (c
== (wint_t) *wcdigits
[n
])
1324 /* Advance the pointer to the next string. */
1328 int avail
= width
> 0 ? width
: INT_MAX
;
1331 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1333 if (*++cmpp
== '\0')
1337 if ((c
= inchar ()) == EOF
)
1350 /* We are pushing all read characters back. */
1351 if (cmpp
> mbdigits
[n
])
1354 while (--cmpp
> mbdigits
[n
])
1355 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1356 c
= (unsigned char) *cmpp
;
1359 /* Advance the pointer to the next string. */
1360 mbdigits
[n
] = strchr (mbdigits
[n
], '\0') + 1;
1376 else if ((flags
& GROUP
)
1377 #ifdef COMPILE_WSCANF
1378 && thousands
!= L
'\0'
1380 && thousands
!= NULL
1384 /* Try matching against the thousands separator. */
1385 #ifdef COMPILE_WSCANF
1389 const char *cmpp
= thousands
;
1390 int avail
= width
> 0 ? width
: INT_MAX
;
1392 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1395 if (*++cmpp
== '\0')
1399 if ((c
= inchar ()) == EOF
)
1407 /* We are pushing all read characters back. */
1408 if (cmpp
> thousands
)
1410 wpsize
-= cmpp
- thousands
;
1412 while (--cmpp
> thousands
)
1413 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1414 c
= (unsigned char) *cmpp
;
1422 /* The last thousands character will be added back by
1438 /* Read the number into workspace. */
1439 while (c
!= EOF
&& width
!= 0)
1446 else if (!ISDIGIT (c
) || (int) (c
- L_('0')) >= base
)
1448 if (base
== 10 && (flags
& GROUP
)
1449 #ifdef COMPILE_WSCANF
1450 && thousands
!= L
'\0'
1452 && thousands
!= NULL
1456 /* Try matching against the thousands separator. */
1457 #ifdef COMPILE_WSCANF
1461 const char *cmpp
= thousands
;
1462 int avail
= width
> 0 ? width
: INT_MAX
;
1464 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1467 if (*++cmpp
== '\0')
1471 if ((c
= inchar ()) == EOF
)
1479 /* We are pushing all read characters back. */
1480 if (cmpp
> thousands
)
1482 wpsize
-= cmpp
- thousands
;
1484 while (--cmpp
> thousands
)
1485 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1486 c
= (unsigned char) *cmpp
;
1494 /* The last thousands character will be added back by
1510 || (wpsize
== 1 && (wp
[0] == L_('+') || wp
[0] == L_('-'))))
1512 /* There was no number. If we are supposed to read a pointer
1513 we must recognize "(nil)" as well. */
1514 if (wpsize
== 0 && read_pointer
&& (width
< 0 || width
>= 0)
1516 && TOLOWER (inchar ()) == L_('n')
1517 && TOLOWER (inchar ()) == L_('i')
1518 && TOLOWER (inchar ()) == L_('l')
1519 && inchar () == L_(')'))
1520 /* We must produce the value of a NULL pointer. A single
1521 '0' digit is enough. */
1525 /* The last read character is not part of the number
1533 /* The just read character is not part of the number anymore. */
1536 /* Convert the number. */
1538 if (need_longlong
&& (flags
& LONGDBL
))
1541 num
.q
= __strtoll_internal (wp
, &tw
, base
, flags
& GROUP
);
1543 num
.uq
= __strtoull_internal (wp
, &tw
, base
, flags
& GROUP
);
1548 num
.l
= __strtol_internal (wp
, &tw
, base
, flags
& GROUP
);
1550 num
.ul
= __strtoul_internal (wp
, &tw
, base
, flags
& GROUP
);
1555 if (!(flags
& SUPPRESS
))
1557 if (! number_signed
)
1559 if (need_longlong
&& (flags
& LONGDBL
))
1560 *ARG (unsigned LONGLONG
int *) = num
.uq
;
1561 else if (need_long
&& (flags
& LONG
))
1562 *ARG (unsigned long int *) = num
.ul
;
1563 else if (flags
& SHORT
)
1564 *ARG (unsigned short int *)
1565 = (unsigned short int) num
.ul
;
1566 else if (!(flags
& CHAR
))
1567 *ARG (unsigned int *) = (unsigned int) num
.ul
;
1569 *ARG (unsigned char *) = (unsigned char) num
.ul
;
1573 if (need_longlong
&& (flags
& LONGDBL
))
1574 *ARG (LONGLONG
int *) = num
.q
;
1575 else if (need_long
&& (flags
& LONG
))
1576 *ARG (long int *) = num
.l
;
1577 else if (flags
& SHORT
)
1578 *ARG (short int *) = (short int) num
.l
;
1579 else if (!(flags
& CHAR
))
1580 *ARG (int *) = (int) num
.l
;
1582 *ARG (signed char *) = (signed char) num
.ul
;
1588 case L_('e'): /* Floating-point numbers. */
1600 got_dot
= got_e
= 0;
1602 /* Check for a sign. */
1603 if (c
== L_('-') || c
== L_('+'))
1605 negative
= c
== L_('-');
1606 if (width
== 0 || inchar () == EOF
)
1607 /* EOF is only an input error before we read any chars. */
1609 if (! ISDIGIT (c
) && TOLOWER (c
) != L_('i')
1610 && TOLOWER (c
) != L_('n'))
1612 #ifdef COMPILE_WSCANF
1615 /* This is no valid number. */
1620 /* Match against the decimal point. At this point
1621 we are taking advantage of the fact that we can
1622 push more than one character back. This is
1623 (almost) never necessary since the decimal point
1624 string hopefully never contains more than one
1626 const char *cmpp
= decimal
;
1627 int avail
= width
> 0 ? width
: INT_MAX
;
1629 while ((unsigned char) *cmpp
== c
&& avail
-- > 0)
1630 if (*++cmpp
== '\0')
1634 if (inchar () == EOF
)
1640 /* This is no valid number. */
1644 if (cmpp
== decimal
)
1646 c
= (unsigned char) *--cmpp
;
1653 /* Add all the characters. */
1654 for (cmpp
= decimal
; *cmpp
!= '\0'; ++cmpp
)
1655 ADDW ((unsigned char) *cmpp
);
1672 /* Take care for the special arguments "nan" and "inf". */
1673 if (TOLOWER (c
) == L_('n'))
1677 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('a'))
1682 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('n'))
1690 else if (TOLOWER (c
) == L_('i'))
1692 /* Maybe "inf" or "infinity". */
1694 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('n'))
1699 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('f'))
1704 /* It is as least "inf". */
1705 if (width
!= 0 && inchar () != EOF
)
1707 if (TOLOWER (c
) == L_('i'))
1711 /* Now we have to read the rest as well. */
1713 if (width
== 0 || inchar () == EOF
1714 || TOLOWER (c
) != L_('n'))
1719 if (width
== 0 || inchar () == EOF
1720 || TOLOWER (c
) != L_('i'))
1725 if (width
== 0 || inchar () == EOF
1726 || TOLOWER (c
) != L_('t'))
1731 if (width
== 0 || inchar () == EOF
1732 || TOLOWER (c
) != L_('y'))
1747 if (width
!= 0 && c
== L_('0'))
1753 if (width
!= 0 && TOLOWER (c
) == L_('x'))
1755 /* It is a number in hexadecimal format. */
1761 /* Grouping is not allowed. */
1773 else if (!got_e
&& is_hexa
&& ISXDIGIT (c
))
1775 else if (got_e
&& wp
[wpsize
- 1] == exp_char
1776 && (c
== L_('-') || c
== L_('+')))
1778 else if (wpsize
> 0 && !got_e
1779 && (CHAR_T
) TOLOWER (c
) == exp_char
)
1782 got_e
= got_dot
= 1;
1786 #ifdef COMPILE_WSCANF
1787 if (! got_dot
&& c
== decimal
)
1792 else if ((flags
& GROUP
) != 0 && thousands
!= L
'\0'
1793 && ! got_dot
&& c
== thousands
)
1797 /* The last read character is not part of the number
1803 const char *cmpp
= decimal
;
1804 int avail
= width
> 0 ? width
: INT_MAX
;
1808 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1809 if (*++cmpp
== '\0')
1813 if (inchar () == EOF
)
1821 /* Add all the characters. */
1822 for (cmpp
= decimal
; *cmpp
!= '\0'; ++cmpp
)
1823 ADDW ((unsigned char) *cmpp
);
1830 /* Figure out whether it is a thousands separator.
1831 There is one problem: we possibly read more than
1832 one character. We cannot push them back but since
1833 we know that parts of the `decimal' string matched,
1834 we can compare against it. */
1835 const char *cmp2p
= thousands
;
1837 if ((flags
& GROUP
) != 0 && thousands
!= NULL
1840 while (cmp2p
- thousands
< cmpp
- decimal
1841 && *cmp2p
== decimal
[cmp2p
- thousands
])
1843 if (cmp2p
- thousands
== cmpp
- decimal
)
1845 while ((unsigned char) *cmp2p
== c
&& avail
> 0)
1846 if (*++cmp2p
== '\0')
1850 if (inchar () == EOF
)
1857 if (cmp2p
!= NULL
&& *cmp2p
== '\0')
1859 /* Add all the characters. */
1860 for (cmpp
= thousands
; *cmpp
!= '\0'; ++cmpp
)
1861 ADDW ((unsigned char) *cmpp
);
1867 /* The last read character is not part of the number
1878 while (width
!= 0 && inchar () != EOF
);
1880 /* Have we read any character? If we try to read a number
1881 in hexadecimal notation and we have read only the `0x'
1882 prefix or no exponent this is an error. */
1883 if (wpsize
== 0 || (is_hexa
&& (wpsize
== 2 || ! got_e
)))
1887 /* Convert the number. */
1889 if ((flags
& LONGDBL
) && !__ldbl_is_dbl
)
1891 long double d
= __strtold_internal (wp
, &tw
, flags
& GROUP
);
1892 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1893 *ARG (long double *) = negative
? -d
: d
;
1895 else if (flags
& (LONG
| LONGDBL
))
1897 double d
= __strtod_internal (wp
, &tw
, flags
& GROUP
);
1898 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1899 *ARG (double *) = negative
? -d
: d
;
1903 float d
= __strtof_internal (wp
, &tw
, flags
& GROUP
);
1904 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1905 *ARG (float *) = negative
? -d
: d
;
1911 if (!(flags
& SUPPRESS
))
1915 case L_('['): /* Character class. */
1917 STRING_ARG (wstr
, wchar_t);
1919 STRING_ARG (str
, char);
1930 /* There is no width given so there is also no limit on the
1931 number of characters we read. Therefore we set width to
1932 a very high value to make the algorithm easier. */
1935 #ifdef COMPILE_WSCANF
1936 /* Find the beginning and the end of the scanlist. We are not
1937 creating a lookup table since it would have to be too large.
1938 Instead we search each time through the string. This is not
1939 a constant lookup time but who uses this feature deserves to
1941 tw
= (wchar_t *) f
; /* Marks the beginning. */
1946 while ((fc
= *f
++) != L
'\0' && fc
!= L
']');
1950 wp
= (wchar_t *) f
- 1;
1952 /* Fill WP with byte flags indexed by character.
1953 We will use this flag map for matching input characters. */
1954 if (wpmax
< UCHAR_MAX
+ 1)
1956 wpmax
= UCHAR_MAX
+ 1;
1957 wp
= (char *) alloca (wpmax
);
1959 memset (wp
, '\0', UCHAR_MAX
+ 1);
1962 if (fc
== ']' || fc
== '-')
1964 /* If ] or - appears before any char in the set, it is not
1965 the terminator or separator, but the first char in the
1971 while ((fc
= *f
++) != '\0' && fc
!= ']')
1972 if (fc
== '-' && *f
!= '\0' && *f
!= ']'
1973 && (unsigned char) f
[-2] <= (unsigned char) *f
)
1975 /* Add all characters from the one before the '-'
1976 up to (but not including) the next format char. */
1977 for (fc
= (unsigned char) f
[-2]; fc
< (unsigned char) *f
; ++fc
)
1981 /* Add the character to the flag map. */
1990 size_t now
= read_in
;
1991 #ifdef COMPILE_WSCANF
1992 if (inchar () == WEOF
)
1999 /* Test whether it's in the scanlist. */
2003 if (runp
[0] == L
'-' && runp
[1] != '\0' && runp
+ 1 != wp
2005 && (unsigned int) runp
[-1] <= (unsigned int) runp
[1])
2007 /* Match against all characters in between the
2008 first and last character of the sequence. */
2011 for (wc
= runp
[-1] + 1; wc
<= runp
[1]; ++wc
)
2012 if ((wint_t) wc
== c
)
2015 if (wc
<= runp
[1] && !not_in
)
2017 if (wc
<= runp
[1] && not_in
)
2019 /* The current character is not in the
2029 if ((wint_t) *runp
== c
&& !not_in
)
2031 if ((wint_t) *runp
== c
&& not_in
)
2041 if (runp
== wp
&& !not_in
)
2047 if (!(flags
& SUPPRESS
))
2051 if ((flags
& MALLOC
)
2052 && wstr
== (wchar_t *) *strptr
+ strsize
)
2054 /* Enlarge the buffer. */
2055 wstr
= (wchar_t *) realloc (*strptr
,
2057 * sizeof (wchar_t));
2060 /* Can't allocate that much. Last-ditch
2063 realloc (*strptr
, (strsize
+ 1)
2064 * sizeof (wchar_t));
2067 /* We lose. Oh well. Terminate the string
2068 and stop converting, so at least we don't
2070 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
2076 *strptr
= (char *) wstr
;
2083 *strptr
= (char *) wstr
;
2090 while (--width
> 0 && inchar () != WEOF
);
2093 char buf
[MB_LEN_MAX
];
2097 if (inchar () == EOF
)
2100 memset (&cstate
, '\0', sizeof (cstate
));
2104 if (wp
[c
] == not_in
)
2106 ungetc_not_eof (c
, s
);
2111 if (!(flags
& SUPPRESS
))
2115 /* Convert it into a wide character. */
2117 n
= __mbrtowc (wstr
, buf
, 1, &cstate
);
2119 if (n
== (size_t) -2)
2121 /* Possibly correct character, just not enough
2124 assert (cnt
< MB_CUR_MAX
);
2130 if ((flags
& MALLOC
)
2131 && wstr
== (wchar_t *) *strptr
+ strsize
)
2133 /* Enlarge the buffer. */
2134 wstr
= (wchar_t *) realloc (*strptr
,
2136 * sizeof (wchar_t)));
2139 /* Can't allocate that much. Last-ditch
2142 realloc (*strptr
, ((strsize
+ 1)
2143 * sizeof (wchar_t)));
2146 /* We lose. Oh well. Terminate the
2147 string and stop converting,
2148 so at least we don't skip any input. */
2149 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
2155 *strptr
= (char *) wstr
;
2162 *strptr
= (char *) wstr
;
2172 while (inchar () != EOF
);
2175 /* We stopped in the middle of recognizing another
2176 character. That's a problem. */
2181 /* We haven't succesfully read any character. */
2184 if (!(flags
& SUPPRESS
))
2188 if ((flags
& MALLOC
)
2189 && wstr
- (wchar_t *) *strptr
!= strsize
)
2191 wchar_t *cp
= (wchar_t *)
2192 realloc (*strptr
, ((wstr
- (wchar_t *) *strptr
)
2193 * sizeof(wchar_t)));
2195 *strptr
= (char *) cp
;
2203 size_t now
= read_in
;
2205 if (inchar () == EOF
)
2208 #ifdef COMPILE_WSCANF
2210 memset (&state
, '\0', sizeof (state
));
2217 /* Test whether it's in the scanlist. */
2221 if (runp
[0] == L
'-' && runp
[1] != '\0' && runp
+ 1 != wp
2223 && (unsigned int) runp
[-1] <= (unsigned int) runp
[1])
2225 /* Match against all characters in between the
2226 first and last character of the sequence. */
2229 for (wc
= runp
[-1] + 1; wc
<= runp
[1]; ++wc
)
2230 if ((wint_t) wc
== c
)
2233 if (wc
<= runp
[1] && !not_in
)
2235 if (wc
<= runp
[1] && not_in
)
2237 /* The current character is not in the
2247 if ((wint_t) *runp
== c
&& !not_in
)
2249 if ((wint_t) *runp
== c
&& not_in
)
2259 if (runp
== wp
&& !not_in
)
2265 if (!(flags
& SUPPRESS
))
2267 if ((flags
& MALLOC
)
2268 && str
+ MB_CUR_MAX
>= *strptr
+ strsize
)
2270 /* Enlarge the buffer. */
2271 size_t strleng
= str
- *strptr
;
2274 newstr
= (char *) realloc (*strptr
, 2 * strsize
);
2277 /* Can't allocate that much. Last-ditch
2279 newstr
= (char *) realloc (*strptr
,
2280 strleng
+ MB_CUR_MAX
);
2283 /* We lose. Oh well. Terminate the string
2284 and stop converting, so at least we don't
2286 ((char *) (*strptr
))[strleng
] = '\0';
2293 str
= newstr
+ strleng
;
2294 strsize
= strleng
+ MB_CUR_MAX
;
2300 str
= newstr
+ strleng
;
2306 n
= __wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
2307 if (n
== (size_t) -1)
2310 assert (n
<= MB_CUR_MAX
);
2313 while (--width
> 0 && inchar () != WEOF
);
2318 if (wp
[c
] == not_in
)
2320 ungetc_not_eof (c
, s
);
2325 if (!(flags
& SUPPRESS
))
2328 if ((flags
& MALLOC
)
2329 && (char *) str
== *strptr
+ strsize
)
2331 /* Enlarge the buffer. */
2332 size_t newsize
= 2 * strsize
;
2335 str
= (char *) realloc (*strptr
, newsize
);
2338 /* Can't allocate that much. Last-ditch
2340 if (newsize
> strsize
+ 1)
2342 newsize
= strsize
+ 1;
2345 /* We lose. Oh well. Terminate the
2346 string and stop converting,
2347 so at least we don't skip any input. */
2348 ((char *) (*strptr
))[strsize
- 1] = '\0';
2354 *strptr
= (char *) str
;
2361 while (--width
> 0 && inchar () != EOF
);
2365 /* We haven't succesfully read any character. */
2368 if (!(flags
& SUPPRESS
))
2370 #ifdef COMPILE_WSCANF
2371 /* We have to emit the code to get into the initial
2373 char buf
[MB_LEN_MAX
];
2374 size_t n
= __wcrtomb (buf
, L
'\0', &state
);
2375 if (n
> 0 && (flags
& MALLOC
)
2376 && str
+ n
>= *strptr
+ strsize
)
2378 /* Enlarge the buffer. */
2379 size_t strleng
= str
- *strptr
;
2382 newstr
= (char *) realloc (*strptr
, strleng
+ n
+ 1);
2385 /* We lose. Oh well. Terminate the string
2386 and stop converting, so at least we don't
2388 ((char *) (*strptr
))[strleng
] = '\0';
2395 str
= newstr
+ strleng
;
2396 strsize
= strleng
+ n
+ 1;
2400 str
= __mempcpy (str
, buf
, n
);
2404 if ((flags
& MALLOC
) && str
- *strptr
!= strsize
)
2406 char *cp
= (char *) realloc (*strptr
, str
- *strptr
);
2416 case L_('p'): /* Generic pointer. */
2418 /* A PTR must be the same size as a `long int'. */
2419 flags
&= ~(SHORT
|LONGDBL
);
2427 /* If this is an unknown format character punt. */
2432 /* The last thing we saw int the format string was a white space.
2433 Consume the last white spaces. */
2438 while (ISSPACE (c
));
2443 /* Unlock stream. */
2452 #ifdef COMPILE_WSCANF
2454 __vfwscanf (FILE *s
, const wchar_t *format
, va_list argptr
)
2456 return _IO_vfwscanf (s
, format
, argptr
, NULL
);
2458 ldbl_weak_alias (__vfwscanf
, vfwscanf
)
2461 ___vfscanf (FILE *s
, const char *format
, va_list argptr
)
2463 return _IO_vfscanf_internal (s
, format
, argptr
, NULL
);
2465 ldbl_strong_alias (_IO_vfscanf_internal
, _IO_vfscanf
)
2466 ldbl_strong_alias (___vfscanf
, __vfscanf
)
2467 ldbl_hidden_def (___vfscanf
, __vfscanf
)
2468 ldbl_weak_alias (___vfscanf
, vfscanf
)