1 /* Copyright (C) 1991-2002, 2003 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
30 #include <bits/libc-lock.h>
31 #include <locale/localeinfo.h>
34 # define HAVE_LONGLONG
35 # define LONGLONG long long
37 # define LONGLONG long
40 /* Determine whether we have to handle `long long' at all. */
41 #if LONG_MAX == LONG_LONG_MAX
42 # define need_longlong 0
44 # define need_longlong 1
47 /* Determine whether we have to handle `long'. */
48 #if INT_MAX == LONG_MAX
54 /* Those are flags in the conversion format. */
55 #define LONG 0x001 /* l: long or double */
56 #define LONGDBL 0x002 /* L: long long or long double */
57 #define SHORT 0x004 /* h: short */
58 #define SUPPRESS 0x008 /* *: suppress assignment */
59 #define POINTER 0x010 /* weird %p pointer (`fake hex') */
60 #define NOSKIP 0x020 /* do not skip blanks */
61 #define WIDTH 0x040 /* width was given */
62 #define GROUP 0x080 /* ': group numbers */
63 #define MALLOC 0x100 /* a: malloc strings */
64 #define CHAR 0x200 /* hh: char */
65 #define I18N 0x400 /* I: use locale's digits */
73 # define va_list _IO_va_list
75 # ifdef COMPILE_WSCANF
76 # define ungetc(c, s) ((void) (c == WEOF \
78 INTUSE(_IO_sputbackwc) (s, c))))
79 # define ungetc_not_eof(c, s) ((void) (--read_in, \
80 INTUSE(_IO_sputbackwc) (s, c)))
81 # define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
82 : ((c = _IO_getwc_unlocked (s)), \
85 : (size_t) (inchar_errno = errno)), c))
87 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
88 # define ISSPACE(Ch) iswspace (Ch)
89 # define ISDIGIT(Ch) iswdigit (Ch)
90 # define ISXDIGIT(Ch) iswxdigit (Ch)
91 # define TOLOWER(Ch) towlower (Ch)
92 # define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
93 # define __strtoll_internal __wcstoll_internal
94 # define __strtoull_internal __wcstoull_internal
95 # define __strtol_internal __wcstol_internal
96 # define __strtoul_internal __wcstoul_internal
97 # define __strtold_internal __wcstold_internal
98 # define __strtod_internal __wcstod_internal
99 # define __strtof_internal __wcstof_internal
101 # define L_(Str) L##Str
102 # define CHAR_T wchar_t
103 # define UCHAR_T unsigned int
104 # define WINT_T wint_t
108 # define ungetc(c, s) ((void) ((int) c == EOF \
110 INTUSE(_IO_sputbackc) (s, (unsigned char) c))))
111 # define ungetc_not_eof(c, s) ((void) (--read_in, \
112 INTUSE(_IO_sputbackc) (s, (unsigned char) c)))
113 # define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
114 : ((c = _IO_getc_unlocked (s)), \
117 : (size_t) (inchar_errno = errno)), c))
118 # define MEMCPY(d, s, n) memcpy (d, s, n)
119 # define ISSPACE(Ch) isspace (Ch)
120 # define ISDIGIT(Ch) isdigit (Ch)
121 # define ISXDIGIT(Ch) isxdigit (Ch)
122 # define TOLOWER(Ch) tolower (Ch)
123 # define ORIENT if (s->_vtable_offset == 0 \
124 && _IO_fwide (s, -1) != -1) \
129 # define UCHAR_T unsigned char
133 # define encode_error() do { \
134 if (errp != NULL) *errp |= 4; \
135 _IO_funlockfile (s); \
136 __libc_cleanup_end (0); \
137 __set_errno (EILSEQ); \
140 # define conv_error() do { \
141 if (errp != NULL) *errp |= 2; \
142 _IO_funlockfile (s); \
143 __libc_cleanup_end (0); \
146 # define input_error() do { \
147 _IO_funlockfile (s); \
148 if (errp != NULL) *errp |= 1; \
149 __libc_cleanup_end (0); \
150 return done ?: EOF; \
152 # define memory_error() do { \
153 _IO_funlockfile (s); \
154 __set_errno (ENOMEM); \
155 __libc_cleanup_end (0); \
158 # define ARGCHECK(s, format) \
161 /* Check file argument for consistence. */ \
162 CHECK_FILE (s, EOF); \
163 if (s->_flags & _IO_NO_READS) \
165 __set_errno (EBADF); \
168 else if (format == NULL) \
174 # define LOCK_STREAM(S) \
175 __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
177 # define UNLOCK_STREAM(S) \
178 _IO_funlockfile (S); \
179 __libc_cleanup_region_end (0)
181 # define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
182 # define ungetc_not_eof(c, s) (--read_in, (ungetc) (c, s))
183 # define inchar() (c == EOF ? EOF \
184 : ((c = getc (s)), (void) (c != EOF && ++read_in), c))
185 # define MEMCPY(d, s, n) memcpy (d, s, n)
186 # define ISSPACE(Ch) isspace (Ch)
187 # define ISDIGIT(Ch) isdigit (Ch)
188 # define ISXDIGIT(Ch) isxdigit (Ch)
189 # define TOLOWER(Ch) tolower (Ch)
193 # define UCHAR_T unsigned char
196 # define encode_error() do { \
198 __set_errno (EILSEQ); \
201 # define conv_error() do { \
205 # define input_error() do { \
207 return done ?: EOF; \
209 # define memory_error() do { \
211 __set_errno (ENOMEM); \
214 # define ARGCHECK(s, format) \
217 /* Check file argument for consistence. */ \
218 if (!__validfp (s) || !s->__mode.__read) \
220 __set_errno (EBADF); \
223 else if (format == NULL) \
225 __set_errno (EINVAL); \
230 /* XXX For now !!! */
231 # define flockfile(S) /* nothing */
232 # define funlockfile(S) /* nothing */
233 # define LOCK_STREAM(S)
234 # define UNLOCK_STREAM(S)
236 # define LOCK_STREAM(S) \
237 __libc_cleanup_region_start (&__funlockfile, (S)); \
239 # define UNLOCK_STREAM(S) \
241 __libc_cleanup_region_end (0)
246 /* Read formatted input from S according to the format string
247 FORMAT, using the argument list in ARG.
248 Return the number of assignments made, or -1 for an input error. */
250 # ifdef COMPILE_WSCANF
252 _IO_vfwscanf (s
, format
, argptr
, errp
)
254 const wchar_t *format
;
259 _IO_vfscanf (s
, format
, argptr
, errp
)
267 __vfscanf (FILE *s
, const char *format
, va_list argptr
)
271 register const CHAR_T
*f
= format
;
272 register UCHAR_T fc
; /* Current character of the format. */
273 register WINT_T done
= 0; /* Assignments done. */
274 register size_t read_in
= 0; /* Chars read in. */
275 register WINT_T c
= 0; /* Last char read. */
276 register int width
; /* Maximum field width. */
277 register int flags
; /* Modifiers for current format element. */
279 /* Errno of last failed inchar call. */
280 int inchar_errno
= 0;
281 /* Status for reading F-P nums. */
282 char got_dot
, got_e
, negative
;
283 /* If a [...] is a [^...]. */
285 #define exp_char not_in
286 /* Base for integral numbers. */
288 /* Signedness for integral numbers. */
290 #define is_hexa number_signed
291 /* Decimal point character. */
292 #ifdef COMPILE_WSCANF
297 /* The thousands character of the current locale. */
298 #ifdef COMPILE_WSCANF
301 const char *thousands
;
303 /* State for the conversions. */
305 /* Integral holding variables. */
309 unsigned long long int uq
;
311 unsigned long int ul
;
313 /* Character-buffer pointer. */
315 wchar_t *wstr
= NULL
;
316 char **strptr
= NULL
;
318 /* We must not react on white spaces immediately because they can
319 possibly be matched even if in the input stream no character is
320 available anymore. */
322 /* Nonzero if we are reading a pointer. */
325 CHAR_T
*tw
; /* Temporary pointer. */
326 CHAR_T
*wp
= NULL
; /* Workspace. */
327 size_t wpmax
= 0; /* Maximal size of workspace. */
328 size_t wpsize
; /* Currently used bytes in workspace. */
332 if (wpsize == wpmax) \
335 wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
336 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
338 MEMCPY (wp, old, wpsize); \
340 wp[wpsize++] = (Ch); \
345 __va_copy (arg
, argptr
);
347 arg
= (va_list) argptr
;
354 ARGCHECK (s
, format
);
356 /* Figure out the decimal point character. */
357 #ifdef COMPILE_WSCANF
358 decimal
= _NL_CURRENT_WORD (LC_NUMERIC
, _NL_NUMERIC_DECIMAL_POINT_WC
);
360 decimal
= _NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
);
362 /* Figure out the thousands separator character. */
363 #ifdef COMPILE_WSCANF
364 thousands
= _NL_CURRENT_WORD (LC_NUMERIC
, _NL_NUMERIC_THOUSANDS_SEP_WC
);
366 thousands
= _NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
);
367 if (*thousands
== '\0')
371 /* Lock the stream. */
375 #ifndef COMPILE_WSCANF
376 /* From now on we use `state' to convert the format string. */
377 memset (&state
, '\0', sizeof (state
));
380 /* Run through the format string. */
384 /* Extract the next argument, which is of type TYPE.
385 For a %N$... spec, this is the Nth argument from the beginning;
386 otherwise it is the next argument after the state now in ARG. */
388 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
389 ({ unsigned int pos = argpos; \
391 __va_copy (arg, argptr); \
393 (void) va_arg (arg, void *); \
394 va_arg (arg, type); \
398 /* XXX Possible optimization. */
399 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
400 ({ va_list arg = (va_list) argptr; \
401 arg = (va_list) ((char *) arg \
403 * __va_rounded_size (void *)); \
404 va_arg (arg, type); \
407 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
408 ({ unsigned int pos = argpos; \
409 va_list arg = (va_list) argptr; \
411 (void) va_arg (arg, void *); \
412 va_arg (arg, type); \
417 #ifndef COMPILE_WSCANF
418 if (!isascii ((unsigned char) *f
))
420 /* Non-ASCII, may be a multibyte. */
421 int len
= __mbrlen (f
, strlen (f
), &state
);
429 else if (c
!= (unsigned char) *f
++)
431 ungetc_not_eof (c
, s
);
444 /* Remember to skip spaces. */
451 /* Read a character. */
454 /* Characters other than format specs must just match. */
458 /* We saw white space char as the last character in the format
459 string. Now it's time to skip all leading white space. */
463 if (inchar () == EOF
&& errno
== EINTR
)
477 /* This is the start of the conversion string. */
480 /* Not yet decided whether we read a pointer or not. */
483 /* Initialize state of modifiers. */
486 /* Prepare temporary buffer. */
489 /* Check for a positional parameter specification. */
490 if (ISDIGIT ((UCHAR_T
) *f
))
492 argpos
= (UCHAR_T
) *f
++ - L_('0');
493 while (ISDIGIT ((UCHAR_T
) *f
))
494 argpos
= argpos
* 10 + ((UCHAR_T
) *f
++ - L_('0'));
499 /* Oops; that was actually the field width. */
507 /* Check for the assignment-suppressing, the number grouping flag,
508 and the signal to use the locale's digit representation. */
509 while (*f
== L_('*') || *f
== L_('\'') || *f
== L_('I'))
523 /* We have seen width. */
524 if (ISDIGIT ((UCHAR_T
) *f
))
527 /* Find the maximum field width. */
529 while (ISDIGIT ((UCHAR_T
) *f
))
532 width
+= (UCHAR_T
) *f
++ - L_('0');
538 /* Check for type modifiers. */
542 /* ints are short ints or chars. */
554 /* A double `l' is equivalent to an `L'. */
556 flags
|= LONGDBL
| LONG
;
559 /* ints are long ints. */
564 /* doubles are long doubles, and ints are long long ints. */
565 flags
|= LONGDBL
| LONG
;
568 /* The `a' is used as a flag only if followed by `s', `S' or
570 if (*f
!= L_('s') && *f
!= L_('S') && *f
!= L_('['))
575 /* String conversions (%s, %[) take a `char **'
576 arg and fill it in with a malloc'd pointer. */
580 if (need_longlong
&& sizeof (size_t) > sizeof (unsigned long int))
582 else if (sizeof (size_t) > sizeof (unsigned int))
586 if (need_longlong
&& sizeof (uintmax_t) > sizeof (unsigned long int))
588 else if (sizeof (uintmax_t) > sizeof (unsigned int))
592 if (need_longlong
&& sizeof (ptrdiff_t) > sizeof (long int))
594 else if (sizeof (ptrdiff_t) > sizeof (int))
598 /* Not a recognized modifier. Backup. */
603 /* End of the format string? */
607 /* Find the conversion specifier. */
609 if (skip_space
|| (fc
!= L_('[') && fc
!= L_('c')
610 && fc
!= L_('C') && fc
!= L_('n')))
612 /* Eat whitespace. */
613 int save_errno
= errno
;
616 if (inchar () == EOF
&& errno
== EINTR
)
626 case L_('%'): /* Must match a literal '%'. */
632 ungetc_not_eof (c
, s
);
637 case L_('n'): /* Answer number of assignments done. */
638 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
639 with the 'n' conversion specifier. */
640 if (!(flags
& SUPPRESS
))
642 /* Don't count the read-ahead. */
643 if (need_longlong
&& (flags
& LONGDBL
))
644 *ARG (long long int *) = read_in
;
645 else if (need_long
&& (flags
& LONG
))
646 *ARG (long int *) = read_in
;
647 else if (flags
& SHORT
)
648 *ARG (short int *) = read_in
;
649 else if (!(flags
& CHAR
))
650 *ARG (int *) = read_in
;
652 *ARG (char *) = read_in
;
654 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
655 /* We have a severe problem here. The ISO C standard
656 contradicts itself in explaining the effect of the %n
657 format in `scanf'. While in ISO C:1990 and the ISO C
658 Amendement 1:1995 the result is described as
660 Execution of a %n directive does not effect the
661 assignment count returned at the completion of
662 execution of the f(w)scanf function.
664 in ISO C Corrigendum 1:1994 the following was added:
667 Add the following fourth example:
670 int d1, d2, n1, n2, i;
671 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
672 the value 123 is assigned to d1 and the value3 to n1.
673 Because %n can never get an input failure the value
674 of 3 is also assigned to n2. The value of d2 is not
675 affected. The value 3 is assigned to i.
677 We go for now with the historically correct code from ISO C,
678 i.e., we don't count the %n assignments. When it ever
679 should proof to be wrong just remove the #ifdef above. */
685 case L_('c'): /* Match characters. */
686 if ((flags
& LONG
) == 0)
688 if (!(flags
& SUPPRESS
))
702 #ifdef COMPILE_WSCANF
703 /* We have to convert the wide character(s) into multibyte
704 characters and store the result. */
705 memset (&state
, '\0', sizeof (state
));
711 n
= __wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
712 if (n
== (size_t) -1)
713 /* No valid wide character. */
716 /* Increment the output pointer. Even if we don't
720 while (--width
> 0 && inchar () != EOF
);
722 if (!(flags
& SUPPRESS
))
726 while (--width
> 0 && inchar () != EOF
);
729 while (--width
> 0 && inchar () != EOF
);
732 if (!(flags
& SUPPRESS
))
739 if (!(flags
& SUPPRESS
))
741 wstr
= ARG (wchar_t *);
750 #ifdef COMPILE_WSCANF
751 /* Just store the incoming wide characters. */
752 if (!(flags
& SUPPRESS
))
756 while (--width
> 0 && inchar () != EOF
);
759 while (--width
> 0 && inchar () != EOF
);
762 /* We have to convert the multibyte input sequence to wide
767 memset (&cstate
, '\0', sizeof (cstate
));
771 /* This is what we present the mbrtowc function first. */
778 n
= __mbrtowc (!(flags
& SUPPRESS
) ? wstr
: NULL
,
781 if (n
== (size_t) -2)
783 /* Possibly correct character, just not enough
785 if (inchar () == EOF
)
795 /* We have a match. */
799 /* Advance the result pointer. */
802 while (--width
> 0 && inchar () != EOF
);
806 if (!(flags
& SUPPRESS
))
811 case L_('s'): /* Read a string. */
814 #define STRING_ARG(Str, Type) \
815 do if (!(flags & SUPPRESS)) \
817 if (flags & MALLOC) \
819 /* The string is to be stored in a malloc'd buffer. */ \
820 strptr = ARG (char **); \
821 if (strptr == NULL) \
823 /* Allocate an initial buffer. */ \
825 *strptr = (char *) malloc (strsize * sizeof (Type)); \
826 Str = (Type *) *strptr; \
829 Str = ARG (Type *); \
833 STRING_ARG (str
, char);
839 #ifdef COMPILE_WSCANF
840 memset (&state
, '\0', sizeof (state
));
847 ungetc_not_eof (c
, s
);
851 #ifdef COMPILE_WSCANF
852 /* This is quite complicated. We have to convert the
853 wide characters into multibyte characters and then
858 if (!(flags
& SUPPRESS
) && (flags
& MALLOC
)
859 && str
+ MB_CUR_MAX
>= *strptr
+ strsize
)
861 /* We have to enlarge the buffer if the `a' flag
863 size_t strleng
= str
- *strptr
;
866 newstr
= (char *) realloc (*strptr
, strsize
* 2);
869 /* Can't allocate that much. Last-ditch
871 newstr
= (char *) realloc (*strptr
,
872 strleng
+ MB_CUR_MAX
);
875 /* We lose. Oh well. Terminate the
876 string and stop converting,
877 so at least we don't skip any input. */
878 ((char *) (*strptr
))[strleng
] = '\0';
885 str
= newstr
+ strleng
;
886 strsize
= strleng
+ MB_CUR_MAX
;
892 str
= newstr
+ strleng
;
897 n
= __wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
,
899 if (n
== (size_t) -1)
902 assert (n
<= MB_CUR_MAX
);
907 if (!(flags
& SUPPRESS
))
911 && (char *) str
== *strptr
+ strsize
)
913 /* Enlarge the buffer. */
914 str
= (char *) realloc (*strptr
, 2 * strsize
);
917 /* Can't allocate that much. Last-ditch
919 str
= (char *) realloc (*strptr
, strsize
+ 1);
922 /* We lose. Oh well. Terminate the
923 string and stop converting,
924 so at least we don't skip any input. */
925 ((char *) (*strptr
))[strsize
- 1] = '\0';
931 *strptr
= (char *) str
;
938 *strptr
= (char *) str
;
946 while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
948 if (!(flags
& SUPPRESS
))
950 #ifdef COMPILE_WSCANF
951 /* We have to emit the code to get into the initial
953 char buf
[MB_LEN_MAX
];
954 size_t n
= __wcrtomb (buf
, L
'\0', &state
);
955 if (n
> 0 && (flags
& MALLOC
)
956 && str
+ n
>= *strptr
+ strsize
)
958 /* Enlarge the buffer. */
959 size_t strleng
= str
- *strptr
;
962 newstr
= (char *) realloc (*strptr
, strleng
+ n
+ 1);
965 /* We lose. Oh well. Terminate the string
966 and stop converting, so at least we don't
968 ((char *) (*strptr
))[strleng
] = '\0';
975 str
= newstr
+ strleng
;
976 strsize
= strleng
+ n
+ 1;
980 str
= __mempcpy (str
, buf
, n
);
984 if ((flags
& MALLOC
) && str
- *strptr
!= strsize
)
986 char *cp
= (char *) realloc (*strptr
, str
- *strptr
);
999 #ifndef COMPILE_WSCANF
1003 /* Wide character string. */
1004 STRING_ARG (wstr
, wchar_t);
1010 #ifndef COMPILE_WSCANF
1011 memset (&cstate
, '\0', sizeof (cstate
));
1018 ungetc_not_eof (c
, s
);
1022 #ifdef COMPILE_WSCANF
1024 if (!(flags
& SUPPRESS
))
1027 if ((flags
& MALLOC
)
1028 && wstr
== (wchar_t *) *strptr
+ strsize
)
1030 /* Enlarge the buffer. */
1031 wstr
= (wchar_t *) realloc (*strptr
,
1033 * sizeof (wchar_t));
1036 /* Can't allocate that much. Last-ditch
1038 wstr
= (wchar_t *) realloc (*strptr
,
1040 * sizeof (wchar_t));
1043 /* We lose. Oh well. Terminate the string
1044 and stop converting, so at least we don't
1046 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1052 *strptr
= (char *) wstr
;
1059 *strptr
= (char *) wstr
;
1075 n
= __mbrtowc (!(flags
& SUPPRESS
) ? wstr
: NULL
,
1078 if (n
== (size_t) -2)
1080 /* Possibly correct character, just not enough
1082 if (inchar () == EOF
)
1092 /* We have a match. */
1097 if (!(flags
& SUPPRESS
) && (flags
& MALLOC
)
1098 && wstr
== (wchar_t *) *strptr
+ strsize
)
1100 /* Enlarge the buffer. */
1101 wstr
= (wchar_t *) realloc (*strptr
,
1103 * sizeof (wchar_t)));
1106 /* Can't allocate that much. Last-ditch effort. */
1107 wstr
= (wchar_t *) realloc (*strptr
,
1109 * sizeof (wchar_t)));
1112 /* We lose. Oh well. Terminate the
1113 string and stop converting, so at
1114 least we don't skip any input. */
1115 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1121 *strptr
= (char *) wstr
;
1128 *strptr
= (char *) wstr
;
1136 while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
1138 if (!(flags
& SUPPRESS
))
1142 if ((flags
& MALLOC
) && wstr
- (wchar_t *) *strptr
!= strsize
)
1144 wchar_t *cp
= (wchar_t *) realloc (*strptr
,
1146 - (wchar_t *) *strptr
)
1147 * sizeof(wchar_t)));
1149 *strptr
= (char *) cp
;
1157 case L_('x'): /* Hexadecimal integer. */
1158 case L_('X'): /* Ditto. */
1163 case L_('o'): /* Octal integer. */
1168 case L_('u'): /* Unsigned decimal integer. */
1173 case L_('d'): /* Signed decimal integer. */
1178 case L_('i'): /* Generic number. */
1187 /* Check for a sign. */
1188 if (c
== L_('-') || c
== L_('+'))
1196 /* Look for a leading indication of base. */
1197 if (width
!= 0 && c
== L_('0'))
1205 if (width
!= 0 && TOLOWER (c
) == L_('x'))
1223 if (base
== 10 && (flags
& I18N
) != 0)
1228 #ifdef COMPILE_WSCANF
1229 const wchar_t *wcdigits
[10];
1231 const char *mbdigits
[10];
1236 #ifdef COMPILE_WSCANF
1237 to_level
= _NL_CURRENT_WORD (LC_CTYPE
,
1238 _NL_CTYPE_INDIGITS_WC_LEN
) - 1;
1240 to_level
= _NL_CURRENT_WORD (LC_CTYPE
,
1241 _NL_CTYPE_INDIGITS_MB_LEN
) - 1;
1244 /* Read the number into workspace. */
1245 while (c
!= EOF
&& width
!= 0)
1247 /* In this round we get the pointer to the digit strings
1248 and also perform the first round of comparisons. */
1249 for (n
= 0; n
< 10; ++n
)
1251 /* Get the string for the digits with value N. */
1252 #ifdef COMPILE_WSCANF
1253 wcdigits
[n
] = (const wchar_t *)
1254 _NL_CURRENT (LC_CTYPE
, _NL_CTYPE_INDIGITS0_WC
+ n
);
1255 wcdigits
[n
] += from_level
;
1257 if (c
== (wint_t) *wcdigits
[n
])
1259 to_level
= from_level
;
1263 /* Advance the pointer to the next string. */
1267 int avail
= width
> 0 ? width
: INT_MAX
;
1269 mbdigits
[n
] = _NL_CURRENT (LC_CTYPE
,
1270 _NL_CTYPE_INDIGITS0_MB
+ n
);
1272 for (level
= 0; level
< from_level
; level
++)
1273 mbdigits
[n
] = strchr (mbdigits
[n
], '\0') + 1;
1276 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1278 if (*++cmpp
== '\0')
1282 if ((c
= inchar ()) == EOF
)
1292 to_level
= from_level
;
1296 /* We are pushing all read characters back. */
1297 if (cmpp
> mbdigits
[n
])
1300 while (--cmpp
> mbdigits
[n
])
1301 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1302 c
= (unsigned char) *cmpp
;
1305 /* Advance the pointer to the next string. */
1306 mbdigits
[n
] = strchr (mbdigits
[n
], '\0') + 1;
1312 /* Have not yet found the digit. */
1313 for (level
= from_level
+ 1; level
<= to_level
; ++level
)
1315 /* Search all ten digits of this level. */
1316 for (n
= 0; n
< 10; ++n
)
1318 #ifdef COMPILE_WSCANF
1319 if (c
== (wint_t) *wcdigits
[n
])
1322 /* Advance the pointer to the next string. */
1326 int avail
= width
> 0 ? width
: INT_MAX
;
1329 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1331 if (*++cmpp
== '\0')
1335 if ((c
= inchar ()) == EOF
)
1348 /* We are pushing all read characters back. */
1349 if (cmpp
> mbdigits
[n
])
1352 while (--cmpp
> mbdigits
[n
])
1353 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1354 c
= (unsigned char) *cmpp
;
1357 /* Advance the pointer to the next string. */
1358 mbdigits
[n
] = strchr (mbdigits
[n
], '\0') + 1;
1374 else if ((flags
& GROUP
)
1375 #ifdef COMPILE_WSCANF
1376 && thousands
!= L
'\0'
1378 && thousands
!= NULL
1382 /* Try matching against the thousands separator. */
1383 #ifdef COMPILE_WSCANF
1387 const char *cmpp
= thousands
;
1388 int avail
= width
> 0 ? width
: INT_MAX
;
1390 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1393 if (*++cmpp
== '\0')
1397 if ((c
= inchar ()) == EOF
)
1405 /* We are pushing all read characters back. */
1406 if (cmpp
> thousands
)
1408 wpsize
-= cmpp
- thousands
;
1410 while (--cmpp
> thousands
)
1411 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1412 c
= (unsigned char) *cmpp
;
1420 /* The last thousands character will be added back by
1436 /* Read the number into workspace. */
1437 while (c
!= EOF
&& width
!= 0)
1444 else if (!ISDIGIT (c
) || (int) (c
- L_('0')) >= base
)
1446 if (base
== 10 && (flags
& GROUP
)
1447 #ifdef COMPILE_WSCANF
1448 && thousands
!= L
'\0'
1450 && thousands
!= NULL
1454 /* Try matching against the thousands separator. */
1455 #ifdef COMPILE_WSCANF
1459 const char *cmpp
= thousands
;
1460 int avail
= width
> 0 ? width
: INT_MAX
;
1462 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1465 if (*++cmpp
== '\0')
1469 if ((c
= inchar ()) == EOF
)
1477 /* We are pushing all read characters back. */
1478 if (cmpp
> thousands
)
1480 wpsize
-= cmpp
- thousands
;
1482 while (--cmpp
> thousands
)
1483 ungetc_not_eof ((unsigned char) *cmpp
, s
);
1484 c
= (unsigned char) *cmpp
;
1492 /* The last thousands character will be added back by
1508 || (wpsize
== 1 && (wp
[0] == L_('+') || wp
[0] == L_('-'))))
1510 /* There was no number. If we are supposed to read a pointer
1511 we must recognize "(nil)" as well. */
1512 if (wpsize
== 0 && read_pointer
&& (width
< 0 || width
>= 0)
1514 && TOLOWER (inchar ()) == L_('n')
1515 && TOLOWER (inchar ()) == L_('i')
1516 && TOLOWER (inchar ()) == L_('l')
1517 && inchar () == L_(')'))
1518 /* We must produce the value of a NULL pointer. A single
1519 '0' digit is enough. */
1523 /* The last read character is not part of the number
1531 /* The just read character is not part of the number anymore. */
1534 /* Convert the number. */
1536 if (need_longlong
&& (flags
& LONGDBL
))
1539 num
.q
= __strtoll_internal (wp
, &tw
, base
, flags
& GROUP
);
1541 num
.uq
= __strtoull_internal (wp
, &tw
, base
, flags
& GROUP
);
1546 num
.l
= __strtol_internal (wp
, &tw
, base
, flags
& GROUP
);
1548 num
.ul
= __strtoul_internal (wp
, &tw
, base
, flags
& GROUP
);
1553 if (!(flags
& SUPPRESS
))
1555 if (! number_signed
)
1557 if (need_longlong
&& (flags
& LONGDBL
))
1558 *ARG (unsigned LONGLONG
int *) = num
.uq
;
1559 else if (need_long
&& (flags
& LONG
))
1560 *ARG (unsigned long int *) = num
.ul
;
1561 else if (flags
& SHORT
)
1562 *ARG (unsigned short int *)
1563 = (unsigned short int) num
.ul
;
1564 else if (!(flags
& CHAR
))
1565 *ARG (unsigned int *) = (unsigned int) num
.ul
;
1567 *ARG (unsigned char *) = (unsigned char) num
.ul
;
1571 if (need_longlong
&& (flags
& LONGDBL
))
1572 *ARG (LONGLONG
int *) = num
.q
;
1573 else if (need_long
&& (flags
& LONG
))
1574 *ARG (long int *) = num
.l
;
1575 else if (flags
& SHORT
)
1576 *ARG (short int *) = (short int) num
.l
;
1577 else if (!(flags
& CHAR
))
1578 *ARG (int *) = (int) num
.l
;
1580 *ARG (signed char *) = (signed char) num
.ul
;
1586 case L_('e'): /* Floating-point numbers. */
1598 /* Check for a sign. */
1599 if (c
== L_('-') || c
== L_('+'))
1601 negative
= c
== L_('-');
1602 if (width
== 0 || inchar () == EOF
)
1603 /* EOF is only an input error before we read any chars. */
1605 if (! ISDIGIT (c
) && TOLOWER (c
) != L_('i')
1606 && TOLOWER (c
) != L_('n'))
1608 #ifdef COMPILE_WSCANF
1611 /* This is no valid number. */
1616 /* Match against the decimal point. At this point
1617 we are taking advantage of the fact that we can
1618 push more than one character back. This is
1619 (almost) never necessary since the decimal point
1620 string hopefully never contains more than one
1622 const char *cmpp
= decimal
;
1623 int avail
= width
> 0 ? width
: INT_MAX
;
1625 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1626 if (*++cmpp
== '\0')
1630 if (inchar () == EOF
)
1637 /* This is no valid number. */
1641 if (cmpp
== decimal
)
1643 c
= (unsigned char) *--cmpp
;
1658 /* Take care for the special arguments "nan" and "inf". */
1659 if (TOLOWER (c
) == L_('n'))
1663 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('a'))
1668 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('n'))
1676 else if (TOLOWER (c
) == L_('i'))
1678 /* Maybe "inf" or "infinity". */
1680 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('n'))
1685 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('f'))
1690 /* It is as least "inf". */
1691 if (width
!= 0 && inchar () != EOF
)
1693 if (TOLOWER (c
) == L_('i'))
1697 /* Now we have to read the rest as well. */
1699 if (width
== 0 || inchar () == EOF
1700 || TOLOWER (c
) != L_('n'))
1705 if (width
== 0 || inchar () == EOF
1706 || TOLOWER (c
) != L_('i'))
1711 if (width
== 0 || inchar () == EOF
1712 || TOLOWER (c
) != L_('t'))
1717 if (width
== 0 || inchar () == EOF
1718 || TOLOWER (c
) != L_('y'))
1733 if (width
!= 0 && c
== L_('0'))
1739 if (width
!= 0 && TOLOWER (c
) == L_('x'))
1741 /* It is a number in hexadecimal format. */
1747 /* Grouping is not allowed. */
1755 got_dot
= got_e
= 0;
1760 else if (!got_e
&& is_hexa
&& ISXDIGIT (c
))
1762 else if (got_e
&& wp
[wpsize
- 1] == exp_char
1763 && (c
== L_('-') || c
== L_('+')))
1765 else if (wpsize
> 0 && !got_e
1766 && (CHAR_T
) TOLOWER (c
) == exp_char
)
1769 got_e
= got_dot
= 1;
1773 #ifdef COMPILE_WSCANF
1774 if (! got_dot
&& c
== decimal
)
1779 else if (thousands
!= L
'\0' && ! got_dot
&& c
== thousands
)
1783 /* The last read character is not part of the number
1789 const char *cmpp
= decimal
;
1790 int avail
= width
> 0 ? width
: INT_MAX
;
1794 while ((unsigned char) *cmpp
== c
&& avail
> 0)
1795 if (*++cmpp
== '\0')
1799 if (inchar () == EOF
)
1807 /* Add all the characters. */
1808 for (cmpp
= decimal
; *cmpp
!= '\0'; ++cmpp
)
1809 ADDW ((unsigned char) *cmpp
);
1816 /* Figure out whether it is a thousands separator.
1817 There is one problem: we possibly read more than
1818 one character. We cannot push them back but since
1819 we know that parts of the `decimal' string matched,
1820 we can compare against it. */
1821 const char *cmp2p
= thousands
;
1823 if (thousands
!= NULL
&& ! got_dot
)
1826 && *cmp2p
== decimal
[cmp2p
- thousands
])
1830 while ((unsigned char) *cmp2p
== c
&& avail
> 0)
1831 if (*++cmp2p
== '\0')
1835 if (inchar () == EOF
)
1842 if (cmp2p
!= NULL
&& *cmp2p
== '\0')
1844 /* Add all the characters. */
1845 for (cmpp
= thousands
; *cmpp
!= '\0'; ++cmpp
)
1846 ADDW ((unsigned char) *cmpp
);
1852 /* The last read character is not part of the number
1863 while (width
!= 0 && inchar () != EOF
);
1865 /* Have we read any character? If we try to read a number
1866 in hexadecimal notation and we have read only the `0x'
1867 prefix or no exponent this is an error. */
1868 if (wpsize
== 0 || (is_hexa
&& (wpsize
== 2 || ! got_e
)))
1872 /* Convert the number. */
1874 if (flags
& LONGDBL
)
1876 long double d
= __strtold_internal (wp
, &tw
, flags
& GROUP
);
1877 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1878 *ARG (long double *) = negative
? -d
: d
;
1880 else if (flags
& LONG
)
1882 double d
= __strtod_internal (wp
, &tw
, flags
& GROUP
);
1883 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1884 *ARG (double *) = negative
? -d
: d
;
1888 float d
= __strtof_internal (wp
, &tw
, flags
& GROUP
);
1889 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1890 *ARG (float *) = negative
? -d
: d
;
1896 if (!(flags
& SUPPRESS
))
1900 case L_('['): /* Character class. */
1902 STRING_ARG (wstr
, wchar_t);
1904 STRING_ARG (str
, char);
1915 /* There is no width given so there is also no limit on the
1916 number of characters we read. Therefore we set width to
1917 a very high value to make the algorithm easier. */
1920 #ifdef COMPILE_WSCANF
1921 /* Find the beginning and the end of the scanlist. We are not
1922 creating a lookup table since it would have to be too large.
1923 Instead we search each time through the string. This is not
1924 a constant lookup time but who uses this feature deserves to
1926 tw
= (wchar_t *) f
; /* Marks the beginning. */
1931 while ((fc
= *f
++) != L
'\0' && fc
!= L
']');
1935 wp
= (wchar_t *) f
- 1;
1937 /* Fill WP with byte flags indexed by character.
1938 We will use this flag map for matching input characters. */
1939 if (wpmax
< UCHAR_MAX
+ 1)
1941 wpmax
= UCHAR_MAX
+ 1;
1942 wp
= (char *) alloca (wpmax
);
1944 memset (wp
, '\0', UCHAR_MAX
+ 1);
1947 if (fc
== ']' || fc
== '-')
1949 /* If ] or - appears before any char in the set, it is not
1950 the terminator or separator, but the first char in the
1956 while ((fc
= *f
++) != '\0' && fc
!= ']')
1957 if (fc
== '-' && *f
!= '\0' && *f
!= ']'
1958 && (unsigned char) f
[-2] <= (unsigned char) *f
)
1960 /* Add all characters from the one before the '-'
1961 up to (but not including) the next format char. */
1962 for (fc
= (unsigned char) f
[-2]; fc
< (unsigned char) *f
; ++fc
)
1966 /* Add the character to the flag map. */
1975 size_t now
= read_in
;
1976 #ifdef COMPILE_WSCANF
1977 if (inchar () == WEOF
)
1984 /* Test whether it's in the scanlist. */
1988 if (runp
[0] == L
'-' && runp
[1] != '\0' && runp
+ 1 != wp
1990 && (unsigned int) runp
[-1] <= (unsigned int) runp
[1])
1992 /* Match against all characters in between the
1993 first and last character of the sequence. */
1996 for (wc
= runp
[-1] + 1; wc
<= runp
[1]; ++wc
)
1997 if ((wint_t) wc
== c
)
2000 if (wc
<= runp
[1] && !not_in
)
2002 if (wc
<= runp
[1] && not_in
)
2004 /* The current character is not in the
2014 if ((wint_t) *runp
== c
&& !not_in
)
2016 if ((wint_t) *runp
== c
&& not_in
)
2026 if (runp
== wp
&& !not_in
)
2032 if (!(flags
& SUPPRESS
))
2036 if ((flags
& MALLOC
)
2037 && wstr
== (wchar_t *) *strptr
+ strsize
)
2039 /* Enlarge the buffer. */
2040 wstr
= (wchar_t *) realloc (*strptr
,
2042 * sizeof (wchar_t));
2045 /* Can't allocate that much. Last-ditch
2048 realloc (*strptr
, (strsize
+ 1)
2049 * sizeof (wchar_t));
2052 /* We lose. Oh well. Terminate the string
2053 and stop converting, so at least we don't
2055 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
2061 *strptr
= (char *) wstr
;
2068 *strptr
= (char *) wstr
;
2075 while (--width
> 0 && inchar () != WEOF
);
2078 char buf
[MB_LEN_MAX
];
2082 if (inchar () == EOF
)
2085 memset (&cstate
, '\0', sizeof (cstate
));
2089 if (wp
[c
] == not_in
)
2091 ungetc_not_eof (c
, s
);
2096 if (!(flags
& SUPPRESS
))
2100 /* Convert it into a wide character. */
2102 n
= __mbrtowc (wstr
, buf
, 1, &cstate
);
2104 if (n
== (size_t) -2)
2106 /* Possibly correct character, just not enough
2109 assert (cnt
< MB_CUR_MAX
);
2115 if ((flags
& MALLOC
)
2116 && wstr
== (wchar_t *) *strptr
+ strsize
)
2118 /* Enlarge the buffer. */
2119 wstr
= (wchar_t *) realloc (*strptr
,
2121 * sizeof (wchar_t)));
2124 /* Can't allocate that much. Last-ditch
2127 realloc (*strptr
, ((strsize
+ 1)
2128 * sizeof (wchar_t)));
2131 /* We lose. Oh well. Terminate the
2132 string and stop converting,
2133 so at least we don't skip any input. */
2134 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
2140 *strptr
= (char *) wstr
;
2147 *strptr
= (char *) wstr
;
2157 while (inchar () != EOF
);
2160 /* We stopped in the middle of recognizing another
2161 character. That's a problem. */
2166 /* We haven't succesfully read any character. */
2169 if (!(flags
& SUPPRESS
))
2173 if ((flags
& MALLOC
)
2174 && wstr
- (wchar_t *) *strptr
!= strsize
)
2176 wchar_t *cp
= (wchar_t *)
2177 realloc (*strptr
, ((wstr
- (wchar_t *) *strptr
)
2178 * sizeof(wchar_t)));
2180 *strptr
= (char *) cp
;
2188 size_t now
= read_in
;
2190 if (inchar () == EOF
)
2193 #ifdef COMPILE_WSCANF
2195 memset (&state
, '\0', sizeof (state
));
2202 /* Test whether it's in the scanlist. */
2206 if (runp
[0] == L
'-' && runp
[1] != '\0' && runp
+ 1 != wp
2208 && (unsigned int) runp
[-1] <= (unsigned int) runp
[1])
2210 /* Match against all characters in between the
2211 first and last character of the sequence. */
2214 for (wc
= runp
[-1] + 1; wc
<= runp
[1]; ++wc
)
2215 if ((wint_t) wc
== c
)
2218 if (wc
<= runp
[1] && !not_in
)
2220 if (wc
<= runp
[1] && not_in
)
2222 /* The current character is not in the
2232 if ((wint_t) *runp
== c
&& !not_in
)
2234 if ((wint_t) *runp
== c
&& not_in
)
2244 if (runp
== wp
&& !not_in
)
2250 if (!(flags
& SUPPRESS
))
2252 if ((flags
& MALLOC
)
2253 && str
+ MB_CUR_MAX
>= *strptr
+ strsize
)
2255 /* Enlarge the buffer. */
2256 size_t strleng
= str
- *strptr
;
2259 newstr
= (char *) realloc (*strptr
, 2 * strsize
);
2262 /* Can't allocate that much. Last-ditch
2264 newstr
= (char *) realloc (*strptr
,
2265 strleng
+ MB_CUR_MAX
);
2268 /* We lose. Oh well. Terminate the string
2269 and stop converting, so at least we don't
2271 ((char *) (*strptr
))[strleng
] = '\0';
2278 str
= newstr
+ strleng
;
2279 strsize
= strleng
+ MB_CUR_MAX
;
2285 str
= newstr
+ strleng
;
2291 n
= __wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
2292 if (n
== (size_t) -1)
2295 assert (n
<= MB_CUR_MAX
);
2298 while (--width
> 0 && inchar () != WEOF
);
2303 if (wp
[c
] == not_in
)
2305 ungetc_not_eof (c
, s
);
2310 if (!(flags
& SUPPRESS
))
2313 if ((flags
& MALLOC
)
2314 && (char *) str
== *strptr
+ strsize
)
2316 /* Enlarge the buffer. */
2317 str
= (char *) realloc (*strptr
, 2 * strsize
);
2320 /* Can't allocate that much. Last-ditch
2322 str
= (char *) realloc (*strptr
, strsize
+ 1);
2325 /* We lose. Oh well. Terminate the
2326 string and stop converting,
2327 so at least we don't skip any input. */
2328 ((char *) (*strptr
))[strsize
- 1] = '\0';
2334 *strptr
= (char *) str
;
2341 *strptr
= (char *) str
;
2348 while (--width
> 0 && inchar () != EOF
);
2352 /* We haven't succesfully read any character. */
2355 if (!(flags
& SUPPRESS
))
2357 #ifdef COMPILE_WSCANF
2358 /* We have to emit the code to get into the initial
2360 char buf
[MB_LEN_MAX
];
2361 size_t n
= __wcrtomb (buf
, L
'\0', &state
);
2362 if (n
> 0 && (flags
& MALLOC
)
2363 && str
+ n
>= *strptr
+ strsize
)
2365 /* Enlarge the buffer. */
2366 size_t strleng
= str
- *strptr
;
2369 newstr
= (char *) realloc (*strptr
, strleng
+ n
+ 1);
2372 /* We lose. Oh well. Terminate the string
2373 and stop converting, so at least we don't
2375 ((char *) (*strptr
))[strleng
] = '\0';
2382 str
= newstr
+ strleng
;
2383 strsize
= strleng
+ n
+ 1;
2387 str
= __mempcpy (str
, buf
, n
);
2391 if ((flags
& MALLOC
) && str
- *strptr
!= strsize
)
2393 char *cp
= (char *) realloc (*strptr
, str
- *strptr
);
2403 case L_('p'): /* Generic pointer. */
2405 /* A PTR must be the same size as a `long int'. */
2406 flags
&= ~(SHORT
|LONGDBL
);
2414 /* If this is an unknown format character punt. */
2419 /* The last thing we saw int the format string was a white space.
2420 Consume the last white spaces. */
2425 while (ISSPACE (c
));
2429 /* Unlock stream. */
2436 # ifdef COMPILE_WSCANF
2438 __vfwscanf (FILE *s
, const wchar_t *format
, va_list argptr
)
2440 return _IO_vfwscanf (s
, format
, argptr
, NULL
);
2444 __vfscanf (FILE *s
, const char *format
, va_list argptr
)
2446 return INTUSE(_IO_vfscanf
) (s
, format
, argptr
, NULL
);
2448 libc_hidden_def (__vfscanf
)
2452 #ifdef COMPILE_WSCANF
2453 weak_alias (__vfwscanf
, vfwscanf
)
2455 weak_alias (__vfscanf
, vfscanf
)