1 /* Copyright (C) 1991-1999, 2000 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
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_WPRINTF
76 # define ungetc(c, s) ((void) (c == WEOF \
78 _IO_sputbackwc (s, c))))
79 # define inchar() (c == WEOF ? WEOF \
80 : ((c = _IO_getwc_unlocked (s)), \
81 (void) (c != WEOF && ++read_in), c))
83 # define MEMCPY(d, s, n) wmemcpy (d, s, n)
84 # define ISSPACE(Ch) iswspace (Ch)
85 # define ISDIGIT(Ch) iswdigit (Ch)
86 # define ISXDIGIT(Ch) iswxdigit (Ch)
87 # define TOLOWER(Ch) towlower (Ch)
88 # define ORIENT if (s->_vtable_offset == 0 && _IO_fwide (s, 1) != 1)\
90 # define __strtoll_internal __wcstoll_internal
91 # define __strtoull_internal __wcstoull_internal
92 # define __strtol_internal __wcstol_internal
93 # define __strtoul_internal __wcstoul_internal
94 # define __strtold_internal __wcstold_internal
95 # define __strtod_internal __wcstod_internal
96 # define __strtof_internal __wcstof_internal
98 # define L_(Str) L##Str
99 # define CHAR_T wchar_t
100 # define UCHAR_T unsigned int
101 # define WINT_T wint_t
103 # define ungetc(c, s) ((void) ((int) c == EOF \
105 _IO_sputbackc (s, (unsigned char) c))))
106 # define inchar() (c == EOF ? EOF \
107 : ((c = _IO_getc_unlocked (s)), \
108 (void) (c != EOF && ++read_in), c))
109 # define MEMCPY(d, s, n) memcpy (d, s, n)
110 # define ISSPACE(Ch) isspace (Ch)
111 # define ISDIGIT(Ch) isdigit (Ch)
112 # define ISXDIGIT(Ch) isxdigit (Ch)
113 # define TOLOWER(Ch) tolower (Ch)
114 # define ORIENT if (_IO_fwide (s, -1) != -1) return EOF
118 # define UCHAR_T unsigned char
122 # define encode_error() do { \
123 if (errp != NULL) *errp |= 4; \
124 _IO_funlockfile (s); \
125 __libc_cleanup_end (0); \
126 __set_errno (EILSEQ); \
129 # define conv_error() do { \
130 if (errp != NULL) *errp |= 2; \
131 _IO_funlockfile (s); \
132 __libc_cleanup_end (0); \
135 # define input_error() do { \
136 _IO_funlockfile (s); \
137 if (errp != NULL) *errp |= 1; \
138 __libc_cleanup_end (0); \
139 return done ?: EOF; \
141 # define memory_error() do { \
142 _IO_funlockfile (s); \
143 __set_errno (ENOMEM); \
144 __libc_cleanup_end (0); \
147 # define ARGCHECK(s, format) \
150 /* Check file argument for consistence. */ \
151 CHECK_FILE (s, EOF); \
152 if (s->_flags & _IO_NO_READS) \
154 __set_errno (EBADF); \
157 else if (format == NULL) \
163 # define LOCK_STREAM(S) \
164 __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S)); \
166 # define UNLOCK_STREAM(S) \
167 _IO_funlockfile (S); \
168 __libc_cleanup_region_end (0)
170 # define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
171 # define inchar() (c == EOF ? EOF \
172 : ((c = getc (s)), (void) (c != EOF && ++read_in), c))
173 # define MEMCPY(d, s, n) memcpy (d, s, n)
174 # define ISSPACE(Ch) isspace (Ch)
175 # define ISDIGIT(Ch) isdigit (Ch)
176 # define ISXDIGIT(Ch) isxdigit (Ch)
177 # define TOLOWER(Ch) tolower (Ch)
181 # define UCHAR_T unsigned char
184 # define encode_error() do { \
186 __set_errno (EILSEQ); \
189 # define conv_error() do { \
193 # define input_error() do { \
195 return done ?: EOF; \
197 # define memory_error() do { \
199 __set_errno (ENOMEM); \
202 # define ARGCHECK(s, format) \
205 /* Check file argument for consistence. */ \
206 if (!__validfp (s) || !s->__mode.__read) \
208 __set_errno (EBADF); \
211 else if (format == NULL) \
213 __set_errno (EINVAL); \
218 /* XXX For now !!! */
219 # define flockfile(S) /* nothing */
220 # define funlockfile(S) /* nothing */
221 # define LOCK_STREAM(S)
222 # define UNLOCK_STREAM(S)
224 # define LOCK_STREAM(S) \
225 __libc_cleanup_region_start (&__funlockfile, (S)); \
227 # define UNLOCK_STREAM(S) \
229 __libc_cleanup_region_end (0)
234 /* Read formatted input from S according to the format string
235 FORMAT, using the argument list in ARG.
236 Return the number of assignments made, or -1 for an input error. */
238 # ifdef COMPILE_WPRINTF
240 _IO_vfwscanf (s
, format
, argptr
, errp
)
242 const wchar_t *format
;
247 _IO_vfscanf (s
, format
, argptr
, errp
)
255 __vfscanf (FILE *s
, const char *format
, va_list argptr
)
259 register const CHAR_T
*f
= format
;
260 register UCHAR_T fc
; /* Current character of the format. */
261 register size_t done
= 0; /* Assignments done. */
262 register size_t read_in
= 0; /* Chars read in. */
263 register WINT_T c
= 0; /* Last char read. */
264 register int width
; /* Maximum field width. */
265 register int flags
; /* Modifiers for current format element. */
267 /* Status for reading F-P nums. */
268 char got_dot
, got_e
, negative
;
269 /* If a [...] is a [^...]. */
271 #define exp_char not_in
272 /* Base for integral numbers. */
274 /* Signedness for integral numbers. */
276 #define is_hexa number_signed
277 /* Decimal point character. */
279 /* The thousands character of the current locale. */
281 /* State for the conversions. */
283 /* Integral holding variables. */
287 unsigned long long int uq
;
289 unsigned long int ul
;
291 /* Character-buffer pointer. */
293 wchar_t *wstr
= NULL
;
294 char **strptr
= NULL
;
296 /* We must not react on white spaces immediately because they can
297 possibly be matched even if in the input stream no character is
298 available anymore. */
300 /* Nonzero if we are reading a pointer. */
303 CHAR_T
*tw
; /* Temporary pointer. */
304 CHAR_T
*wp
= NULL
; /* Workspace. */
305 size_t wpmax
= 0; /* Maximal size of workspace. */
306 size_t wpsize
; /* Currently used bytes in workspace. */
310 if (wpsize == wpmax) \
313 wpmax = UCHAR_MAX > 2 * wpmax ? UCHAR_MAX : 2 * wpmax; \
314 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
316 MEMCPY (wp, old, wpsize); \
318 wp[wpsize++] = (Ch); \
323 __va_copy (arg
, argptr
);
325 arg
= (va_list) argptr
;
332 ARGCHECK (s
, format
);
334 /* Figure out the decimal point character. */
335 memset (&state
, '\0', sizeof (state
));
336 if (__mbrtowc (&decimal
, _NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
),
337 strlen (_NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
)), &state
)
339 decimal
= (wchar_t) *_NL_CURRENT (LC_NUMERIC
, DECIMAL_POINT
);
340 /* Figure out the thousands separator character. */
341 memset (&state
, '\0', sizeof (state
));
342 if (__mbrtowc (&thousands
, _NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
),
343 strlen (_NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
)),
345 thousands
= (wchar_t) *_NL_CURRENT (LC_NUMERIC
, THOUSANDS_SEP
);
347 /* Lock the stream. */
351 #ifndef COMPILE_WPRINTF
352 /* From now on we use `state' to convert the format string. */
353 memset (&state
, '\0', sizeof (state
));
356 /* Run through the format string. */
360 /* Extract the next argument, which is of type TYPE.
361 For a %N$... spec, this is the Nth argument from the beginning;
362 otherwise it is the next argument after the state now in ARG. */
364 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
365 ({ unsigned int pos = argpos; \
367 __va_copy (arg, argptr); \
369 (void) va_arg (arg, void *); \
370 va_arg (arg, type); \
374 /* XXX Possible optimization. */
375 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
376 ({ va_list arg = (va_list) argptr; \
377 arg = (va_list) ((char *) arg \
379 * __va_rounded_size (void *)); \
380 va_arg (arg, type); \
383 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
384 ({ unsigned int pos = argpos; \
385 va_list arg = (va_list) argptr; \
387 (void) va_arg (arg, void *); \
388 va_arg (arg, type); \
393 #ifndef COMPILE_WPRINTF
396 /* Non-ASCII, may be a multibyte. */
397 int len
= __mbrlen (f
, strlen (f
), &state
);
420 /* Remember to skip spaces. */
427 /* Read a character. */
430 /* Characters other than format specs must just match. */
434 /* We saw white space char as the last character in the format
435 string. Now it's time to skip all leading white space. */
439 if (inchar () == EOF
&& errno
== EINTR
)
453 /* This is the start of the conversion string. */
456 /* Not yet decided whether we read a pointer or not. */
459 /* Initialize state of modifiers. */
462 /* Prepare temporary buffer. */
465 /* Check for a positional parameter specification. */
468 argpos
= *f
++ - L_('0');
470 argpos
= argpos
* 10 + (*f
++ - L_('0'));
475 /* Oops; that was actually the field width. */
483 /* Check for the assignment-suppressing, the number grouping flag,
484 and the signal to use the locale's digit representation. */
485 while (*f
== L_('*') || *f
== L_('\'') || *f
== L_('I'))
499 /* We have seen width. */
503 /* Find the maximum field width. */
508 width
+= *f
++ - L_('0');
514 /* Check for type modifiers. */
518 /* ints are short ints or chars. */
530 /* A double `l' is equivalent to an `L'. */
532 flags
|= LONGDBL
| LONG
;
535 /* ints are long ints. */
540 /* doubles are long doubles, and ints are long long ints. */
541 flags
|= LONGDBL
| LONG
;
544 /* The `a' is used as a flag only if followed by `s', `S' or
546 if (*f
!= L_('s') && *f
!= L_('S') && *f
!= L_('['))
551 /* String conversions (%s, %[) take a `char **'
552 arg and fill it in with a malloc'd pointer. */
556 if (need_longlong
&& sizeof (size_t) > sizeof (unsigned long int))
558 else if (sizeof (size_t) > sizeof (unsigned int))
562 if (need_longlong
&& sizeof (uintmax_t) > sizeof (unsigned long int))
564 else if (sizeof (uintmax_t) > sizeof (unsigned int))
568 if (need_longlong
&& sizeof (ptrdiff_t) > sizeof (long int))
570 else if (sizeof (ptrdiff_t) > sizeof (int))
574 /* Not a recognized modifier. Backup. */
579 /* End of the format string? */
583 /* Find the conversion specifier. */
585 if (skip_space
|| (fc
!= L_('[') && fc
!= L_('c')
586 && fc
!= L_('C') && fc
!= L_('n')))
588 /* Eat whitespace. */
589 int save_errno
= errno
;
592 if (inchar () == EOF
&& errno
== EINTR
)
602 case L_('%'): /* Must match a literal '%'. */
613 case L_('n'): /* Answer number of assignments done. */
614 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
615 with the 'n' conversion specifier. */
616 if (!(flags
& SUPPRESS
))
618 /* Don't count the read-ahead. */
619 if (need_longlong
&& (flags
& LONGDBL
))
620 *ARG (long long int *) = read_in
;
621 else if (need_long
&& (flags
& LONG
))
622 *ARG (long int *) = read_in
;
623 else if (flags
& SHORT
)
624 *ARG (short int *) = read_in
;
625 else if (!(flags
& CHAR
))
626 *ARG (int *) = read_in
;
628 *ARG (char *) = read_in
;
630 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
631 /* We have a severe problem here. The ISO C standard
632 contradicts itself in explaining the effect of the %n
633 format in `scanf'. While in ISO C:1990 and the ISO C
634 Amendement 1:1995 the result is described as
636 Execution of a %n directive does not effect the
637 assignment count returned at the completion of
638 execution of the f(w)scanf function.
640 in ISO C Corrigendum 1:1994 the following was added:
643 Add the following fourth example:
646 int d1, d2, n1, n2, i;
647 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
648 the value 123 is assigned to d1 and the value3 to n1.
649 Because %n can never get an input failure the value
650 of 3 is also assigned to n2. The value of d2 is not
651 affected. The value 3 is assigned to i.
653 We go for now with the historically correct code from ISO C,
654 i.e., we don't count the %n assignments. When it ever
655 should proof to be wrong just remove the #ifdef above. */
661 case L_('c'): /* Match characters. */
662 if ((flags
& LONG
) == 0)
664 if (!(flags
& SUPPRESS
))
678 #ifdef COMPILE_WPRINTF
679 /* We have to convert the wide character(s) into multibyte
680 characters and store the result. */
681 memset (&state
, '\0', sizeof (state
));
687 n
= wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
688 if (n
== (size_t) -1)
689 /* No valid wide character. */
692 /* Increment the output pointer. Even if we don't
696 while (--width
> 0 && inchar () != EOF
);
698 if (!(flags
& SUPPRESS
))
702 while (--width
> 0 && inchar () != EOF
);
705 while (--width
> 0 && inchar () != EOF
);
708 if (!(flags
& SUPPRESS
))
715 if (!(flags
& SUPPRESS
))
717 wstr
= ARG (wchar_t *);
726 #ifdef COMPILE_WPRINTF
727 /* Just store the incoming wide characters. */
728 if (!(flags
& SUPPRESS
))
732 while (--width
> 0 && inchar () != EOF
);
735 while (--width
> 0 && inchar () != EOF
);
738 /* We have to convert the multibyte input sequence to wide
740 char buf
[MB_LEN_MAX
];
743 memset (&cstate
, '\0', sizeof (cstate
));
749 /* This is what we present the mbrtowc function first. */
757 n
= __mbrtowc (!(flags
& SUPPRESS
) ? wstr
: NULL
,
760 if (n
== (size_t) -2)
762 /* Possibly correct character, just not enough
764 assert (cnt
< MB_CUR_MAX
);
766 if (inchar () == EOF
)
776 /* We have a match. */
780 /* Advance the result pointer. */
783 while (--width
> 0 && inchar () != EOF
);
787 if (!(flags
& SUPPRESS
))
792 case L_('s'): /* Read a string. */
795 #define STRING_ARG(Str, Type) \
796 do if (!(flags & SUPPRESS)) \
798 if (flags & MALLOC) \
800 /* The string is to be stored in a malloc'd buffer. */ \
801 strptr = ARG (char **); \
802 if (strptr == NULL) \
804 /* Allocate an initial buffer. */ \
806 *strptr = (char *) malloc (strsize * sizeof (Type)); \
807 Str = (Type *) *strptr; \
810 Str = ARG (Type *); \
814 STRING_ARG (str
, char);
820 #ifdef COMPILE_WPRINTF
821 memset (&state
, '\0', sizeof (state
));
832 #ifdef COMPILE_WPRINTF
833 /* This is quite complicated. We have to convert the
834 wide characters into multibyte characters and then
839 if (!(flags
& SUPPRESS
) && (flags
& MALLOC
)
840 && str
+ MB_CUR_MAX
>= *strptr
+ strsize
)
842 /* We have to enlarge the buffer if the `a' flag
844 str
= (char *) realloc (*strptr
, strsize
* 2);
847 /* Can't allocate that much. Last-ditch
849 str
= (char *) realloc (*strptr
, strsize
+ 1);
852 /* We lose. Oh well. Terminate the
853 string and stop converting,
854 so at least we don't skip any input. */
855 ((char *) (*strptr
))[strsize
- 1] = '\0';
861 *strptr
= (char *) str
;
868 *strptr
= (char *) str
;
874 n
= wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
875 if (n
== (size_t) -1)
878 assert (n
<= MB_CUR_MAX
);
883 if (!(flags
& SUPPRESS
))
887 && (char *) str
== *strptr
+ strsize
)
889 /* Enlarge the buffer. */
890 str
= (char *) realloc (*strptr
, 2 * strsize
);
893 /* Can't allocate that much. Last-ditch
895 str
= (char *) realloc (*strptr
, strsize
+ 1);
898 /* We lose. Oh well. Terminate the
899 string and stop converting,
900 so at least we don't skip any input. */
901 ((char *) (*strptr
))[strsize
- 1] = '\0';
907 *strptr
= (char *) str
;
914 *strptr
= (char *) str
;
922 while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
924 if (!(flags
& SUPPRESS
))
926 #ifdef COMPILE_WPRINTF
927 /* We have to emit the code to get into the intial
929 char buf
[MB_LEN_MAX
];
930 size_t n
= wcrtomb (buf
, L
'\0', &state
);
931 if (n
> 0 && (flags
& MALLOC
)
932 && str
+ n
>= *strptr
+ strsize
)
934 /* Enlarge the buffer. */
935 str
= (char *) realloc (*strptr
,
936 (str
+ n
+ 1) - *strptr
);
939 /* We lose. Oh well. Terminate the string
940 and stop converting, so at least we don't
942 ((char *) (*strptr
))[strsize
- 1] = '\0';
948 *strptr
= (char *) str
;
949 str
= ((char *) *strptr
) + strsize
;
950 strsize
= (str
+ n
+ 1) - *strptr
;
954 str
= __mempcpy (str
, buf
, n
);
958 if ((flags
& MALLOC
) && str
- *strptr
!= strsize
)
960 char *cp
= (char *) realloc (*strptr
, str
- *strptr
);
973 #ifndef COMPILE_WPRINTF
977 /* Wide character string. */
978 STRING_ARG (wstr
, wchar_t);
984 #ifndef COMPILE_WPRINTF
985 memset (&cstate
, '\0', sizeof (cstate
));
996 #ifdef COMPILE_WPRINTF
998 if (!(flags
& SUPPRESS
))
1001 if ((flags
& MALLOC
)
1002 && wstr
== (wchar_t *) *strptr
+ strsize
)
1004 /* Enlarge the buffer. */
1005 wstr
= (wchar_t *) realloc (*strptr
,
1007 * sizeof (wchar_t));
1010 /* Can't allocate that much. Last-ditch
1012 wstr
= (wchar_t *) realloc (*strptr
,
1014 + sizeof (wchar_t)));
1017 /* We lose. Oh well. Terminate the string
1018 and stop converting, so at least we don't
1020 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1026 *strptr
= (char *) wstr
;
1033 *strptr
= (char *) wstr
;
1041 char buf
[MB_LEN_MAX
];
1051 n
= __mbrtowc (!(flags
& SUPPRESS
) ? wstr
: NULL
,
1054 if (n
== (size_t) -2)
1056 /* Possibly correct character, just not enough
1058 assert (cnt
< MB_CUR_MAX
);
1060 if (inchar () == EOF
)
1070 /* We have a match. */
1074 if (!(flags
& SUPPRESS
) && (flags
& MALLOC
)
1075 && wstr
== (wchar_t *) *strptr
+ strsize
)
1077 /* Enlarge the buffer. */
1078 wstr
= (wchar_t *) realloc (*strptr
,
1080 * sizeof (wchar_t)));
1083 /* Can't allocate that much. Last-ditch effort. */
1084 wstr
= (wchar_t *) realloc (*strptr
,
1086 * sizeof (wchar_t)));
1089 /* We lose. Oh well. Terminate the
1090 string and stop converting, so at
1091 least we don't skip any input. */
1092 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1098 *strptr
= (char *) wstr
;
1105 *strptr
= (char *) wstr
;
1113 while ((width
<= 0 || --width
> 0) && inchar () != EOF
);
1115 if (!(flags
& SUPPRESS
))
1119 if ((flags
& MALLOC
) && wstr
- (wchar_t *) *strptr
!= strsize
)
1121 wchar_t *cp
= (wchar_t *) realloc (*strptr
,
1123 - (wchar_t *) *strptr
)
1124 * sizeof(wchar_t)));
1126 *strptr
= (char *) cp
;
1134 case L_('x'): /* Hexadecimal integer. */
1135 case L_('X'): /* Ditto. */
1140 case L_('o'): /* Octal integer. */
1145 case L_('u'): /* Unsigned decimal integer. */
1150 case L_('d'): /* Signed decimal integer. */
1155 case L_('i'): /* Generic number. */
1164 /* Check for a sign. */
1165 if (c
== L_('-') || c
== L_('+'))
1173 /* Look for a leading indication of base. */
1174 if (width
!= 0 && c
== L_('0'))
1182 if (width
!= 0 && TOLOWER (c
) == L_('x'))
1200 if (base
== 10 && (flags
& I18N
) != 0)
1204 #ifdef COMPILE_WPRINTF
1205 const wchar_t *wcdigits
[10];
1207 const char *mbdigits
[10];
1212 #ifdef COMPILE_WPRINTF
1213 to_level
= _NL_CURRENT_WORD (LC_CTYPE
,
1214 _NL_CTYPE_INDIGITS_WC_LEN
) - 1;
1216 to_level
= _NL_CURRENT_WORD (LC_CTYPE
,
1217 _NL_CTYPE_INDIGITS_MB_LEN
) - 1;
1220 /* In this round we get the pointer to the digit strings
1221 and also perform the first round of comparisons. */
1222 for (n
= 0; n
< 10; ++n
)
1224 /* Get the string for the digits with value N. */
1225 #ifdef COMPILE_WPRINTF
1226 wcdigits
[n
] = (const wchar_t *)
1227 _NL_CURRENT (LC_CTYPE
, _NL_CTYPE_INDIGITS0_WC
+ n
);
1228 if (c
== *wcdigits
[n
])
1231 /* Advance the pointer to the next string. */
1237 mbdigits
[n
] = _NL_CURRENT (LC_CTYPE
,
1238 _NL_CTYPE_INDIGITS0_MB
+ n
);
1239 dlen
= strlen (mbdigits
[n
]);
1244 if (c
!= mbdigits
[n
][dcnt
])
1254 /* Advance the pointer to the next string. */
1255 mbdigits
[n
] += dlen
+ 1;
1261 /*Have not yet found the digit. */
1262 while (++from_level
<= to_level
)
1264 /* Search all ten digits of this level. */
1265 for (n
= 0; n
< 10; ++n
)
1267 #ifdef COMPILE_WPRINTF
1268 if (c
== *wcdigits
[n
])
1271 /* Advance the pointer to the next string. */
1274 size_t dlen
= strlen (mbdigits
[n
]);
1280 if (c
!= mbdigits
[n
][dcnt
])
1290 /* Advance the pointer to the next string. */
1291 mbdigits
[n
] += dlen
+ 1;
1306 /* Haven't found anything. Push the last character back
1307 and return an error. */
1315 /* Read the number into workspace. */
1316 while (c
!= EOF
&& width
!= 0)
1318 if (base
== 16 ? !ISXDIGIT (c
) :
1319 ((!ISDIGIT (c
) || c
- L_('0') >= base
) &&
1320 !((flags
& GROUP
) && base
== 10 && c
== thousands
)))
1330 || (wpsize
== 1 && (wp
[0] == L_('+') || wp
[0] == L_('-'))))
1332 /* There was no number. If we are supposed to read a pointer
1333 we must recognize "(nil)" as well. */
1334 if (wpsize
== 0 && read_pointer
&& (width
< 0 || width
>= 0)
1336 && TOLOWER (inchar ()) == L_('n')
1337 && TOLOWER (inchar ()) == L_('i')
1338 && TOLOWER (inchar ()) == L_('l')
1339 && inchar () == L_(')'))
1340 /* We must produce the value of a NULL pointer. A single
1341 '0' digit is enough. */
1345 /* The last read character is not part of the number
1353 /* The just read character is not part of the number anymore. */
1356 /* Convert the number. */
1358 if (need_longlong
&& (flags
& LONGDBL
))
1361 num
.q
= __strtoll_internal (wp
, &tw
, base
, flags
& GROUP
);
1363 num
.uq
= __strtoull_internal (wp
, &tw
, base
, flags
& GROUP
);
1368 num
.l
= __strtol_internal (wp
, &tw
, base
, flags
& GROUP
);
1370 num
.ul
= __strtoul_internal (wp
, &tw
, base
, flags
& GROUP
);
1375 if (!(flags
& SUPPRESS
))
1377 if (! number_signed
)
1379 if (need_longlong
&& (flags
& LONGDBL
))
1380 *ARG (unsigned LONGLONG
int *) = num
.uq
;
1381 else if (need_long
&& (flags
& LONG
))
1382 *ARG (unsigned long int *) = num
.ul
;
1383 else if (flags
& SHORT
)
1384 *ARG (unsigned short int *)
1385 = (unsigned short int) num
.ul
;
1386 else if (!(flags
& CHAR
))
1387 *ARG (unsigned int *) = (unsigned int) num
.ul
;
1389 *ARG (unsigned char *) = (unsigned char) num
.ul
;
1393 if (need_longlong
&& (flags
& LONGDBL
))
1394 *ARG (LONGLONG
int *) = num
.q
;
1395 else if (need_long
&& (flags
& LONG
))
1396 *ARG (long int *) = num
.l
;
1397 else if (flags
& SHORT
)
1398 *ARG (short int *) = (short int) num
.l
;
1399 else if (!(flags
& CHAR
))
1400 *ARG (int *) = (int) num
.l
;
1402 *ARG (signed char *) = (signed char) num
.ul
;
1408 case L_('e'): /* Floating-point numbers. */
1419 /* Check for a sign. */
1420 if (c
== L_('-') || c
== L_('+'))
1422 negative
= c
== L_('-');
1423 if (width
== 0 || inchar () == EOF
)
1424 /* EOF is only an input error before we read any chars. */
1426 if (! ISDIGIT (c
) && c
!= decimal
)
1428 /* This is no valid number. */
1438 /* Take care for the special arguments "nan" and "inf". */
1439 if (TOLOWER (c
) == L_('n'))
1443 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('a'))
1448 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('n'))
1456 else if (TOLOWER (c
) == L_('i'))
1458 /* Maybe "inf" or "infinity". */
1460 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('n'))
1465 if (width
== 0 || inchar () == EOF
|| TOLOWER (c
) != L_('f'))
1470 /* It is as least "inf". */
1471 if (width
!= 0 && inchar () != EOF
)
1473 if (TOLOWER (c
) == L_('i'))
1477 /* Now we have to read the rest as well. */
1479 if (width
== 0 || inchar () == EOF
1480 || TOLOWER (c
) != L_('n'))
1485 if (width
== 0 || inchar () == EOF
1486 || TOLOWER (c
) != L_('i'))
1491 if (width
== 0 || inchar () == EOF
1492 || TOLOWER (c
) != L_('t'))
1497 if (width
== 0 || inchar () == EOF
1498 || TOLOWER (c
) != L_('y'))
1513 if (width
!= 0 && c
== L_('0'))
1519 if (width
!= 0 && TOLOWER (c
) == L_('x'))
1521 /* It is a number in hexadecimal format. */
1527 /* Grouping is not allowed. */
1535 got_dot
= got_e
= 0;
1540 else if (!got_e
&& is_hexa
&& ISXDIGIT (c
))
1542 else if (got_e
&& wp
[wpsize
- 1] == exp_char
1543 && (c
== L_('-') || c
== L_('+')))
1545 else if (wpsize
> 0 && !got_e
&& TOLOWER (c
) == exp_char
)
1548 got_e
= got_dot
= 1;
1550 else if (c
== decimal
&& !got_dot
)
1555 else if ((flags
& GROUP
) && c
== thousands
&& !got_dot
)
1559 /* The last read character is not part of the number
1567 while (width
!= 0 && inchar () != EOF
);
1569 /* Have we read any character? If we try to read a number
1570 in hexadecimal notation and we have read only the `0x'
1571 prefix or no exponent this is an error. */
1572 if (wpsize
== 0 || (is_hexa
&& (wpsize
== 2 || ! got_e
)))
1576 /* Convert the number. */
1578 if (flags
& LONGDBL
)
1580 long double d
= __strtold_internal (wp
, &tw
, flags
& GROUP
);
1581 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1582 *ARG (long double *) = negative
? -d
: d
;
1584 else if (flags
& LONG
)
1586 double d
= __strtod_internal (wp
, &tw
, flags
& GROUP
);
1587 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1588 *ARG (double *) = negative
? -d
: d
;
1592 float d
= __strtof_internal (wp
, &tw
, flags
& GROUP
);
1593 if (!(flags
& SUPPRESS
) && tw
!= wp
)
1594 *ARG (float *) = negative
? -d
: d
;
1600 if (!(flags
& SUPPRESS
))
1604 case L_('['): /* Character class. */
1606 STRING_ARG (wstr
, wchar_t);
1608 STRING_ARG (str
, char);
1619 /* There is no width given so there is also no limit on the
1620 number of characters we read. Therefore we set width to
1621 a very high value to make the algorithm easier. */
1624 #ifdef COMPILE_WPRINTF
1625 /* Find the beginning and the end of the scanlist. We are not
1626 creating a lookup table since it would have to be too large.
1627 Instead we search each time through the string. This is not
1628 a constant lookup time but who uses this feature deserves to
1630 tw
= (wchar_t *) f
; /* Marks the beginning. */
1632 if (*f
== ']' || *f
== '-')
1635 while ((fc
= *f
++) != L
'\0' && fc
!= L
']');
1639 wp
= (wchar_t *) f
- 1;
1641 /* Fill WP with byte flags indexed by character.
1642 We will use this flag map for matching input characters. */
1643 if (wpmax
< UCHAR_MAX
)
1646 wp
= (char *) alloca (wpmax
);
1648 memset (wp
, '\0', UCHAR_MAX
);
1651 if (fc
== ']' || fc
== '-')
1653 /* If ] or - appears before any char in the set, it is not
1654 the terminator or separator, but the first char in the
1660 while ((fc
= *f
++) != '\0' && fc
!= ']')
1661 if (fc
== '-' && *f
!= '\0' && *f
!= ']'
1662 && (unsigned char) f
[-2] <= (unsigned char) *f
)
1664 /* Add all characters from the one before the '-'
1665 up to (but not including) the next format char. */
1666 for (fc
= f
[-2]; fc
< *f
; ++fc
)
1670 /* Add the character to the flag map. */
1679 size_t now
= read_in
;
1680 #ifdef COMPILE_WPRINTF
1685 if (inchar () == WEOF
)
1688 /* Test whether it's in the scanlist. */
1692 if (runp
[0] == L
'-' && runp
[1] != '\0' && runp
[1] != ']'
1694 && (unsigned int) runp
[-1] <= (unsigned int) runp
[1])
1696 /* Match against all characters in between the
1697 first and last character of the sequence. */
1700 for (wc
= runp
[-1] + 1; wc
< runp
[1]; ++wc
)
1704 if (wc
== runp
[1] && !not_in
)
1706 if (wc
== runp
[1] && not_in
)
1708 /* The current character is not in the
1716 if (*runp
== runp
[1] && !not_in
)
1718 if (*runp
!= runp
[1] && not_in
)
1728 if (!(flags
& SUPPRESS
))
1732 if ((flags
& MALLOC
)
1733 && wstr
== (wchar_t *) *strptr
+ strsize
)
1735 /* Enlarge the buffer. */
1736 wstr
= (wchar_t *) realloc (*strptr
,
1738 * sizeof (wchar_t));
1741 /* Can't allocate that much. Last-ditch
1744 realloc (*strptr
, (strsize
1745 + sizeof (wchar_t)));
1748 /* We lose. Oh well. Terminate the string
1749 and stop converting, so at least we don't
1751 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1757 *strptr
= (char *) wstr
;
1764 *strptr
= (char *) wstr
;
1771 while (--width
> 0);
1774 char buf
[MB_LEN_MAX
];
1778 memset (&cstate
, '\0', sizeof (cstate
));
1783 if (inchar () == EOF
)
1786 if (wp
[c
] == not_in
)
1793 if (!(flags
& SUPPRESS
))
1797 /* Convert it into a wide character. */
1798 n
= __mbrtowc (wstr
, buf
, cnt
, &cstate
);
1800 if (n
== (size_t) -2)
1802 /* Possibly correct character, just not enough
1804 assert (cnt
< MB_CUR_MAX
);
1812 if ((flags
& MALLOC
)
1813 && wstr
== (wchar_t *) *strptr
+ strsize
)
1815 /* Enlarge the buffer. */
1816 wstr
= (wchar_t *) realloc (*strptr
,
1818 * sizeof (wchar_t)));
1821 /* Can't allocate that much. Last-ditch
1824 realloc (*strptr
, ((strsize
+ 1)
1825 * sizeof (wchar_t)));
1828 /* We lose. Oh well. Terminate the
1829 string and stop converting,
1830 so at least we don't skip any input. */
1831 ((wchar_t *) (*strptr
))[strsize
- 1] = L
'\0';
1837 *strptr
= (char *) wstr
;
1844 *strptr
= (char *) wstr
;
1851 while (--width
> 0);
1854 /* We stopped in the middle of recognizing another
1855 character. That's a problem. */
1860 /* We haven't succesfully read any character. */
1863 if (!(flags
& SUPPRESS
))
1867 if ((flags
& MALLOC
)
1868 && wstr
- (wchar_t *) *strptr
!= strsize
)
1870 wchar_t *cp
= (wchar_t *)
1871 realloc (*strptr
, ((wstr
- (wchar_t *) *strptr
)
1872 * sizeof(wchar_t)));
1874 *strptr
= (char *) cp
;
1882 size_t now
= read_in
;
1883 #ifdef COMPILE_WPRINTF
1885 memset (&state
, '\0', sizeof (state
));
1892 if (inchar () == WEOF
)
1895 /* Test whether it's in the scanlist. */
1899 if (runp
[0] == L
'-' && runp
[1] != '\0' && runp
[1] != ']'
1901 && (unsigned int) runp
[-1] <= (unsigned int) runp
[1])
1903 /* Match against all characters in between the
1904 first and last character of the sequence. */
1907 for (wc
= runp
[-1] + 1; wc
< runp
[1]; ++wc
)
1911 if (wc
== runp
[1] && !not_in
)
1913 if (wc
== runp
[1] && not_in
)
1915 /* The current character is not in the
1923 if (*runp
== runp
[1] && !not_in
)
1925 if (*runp
!= runp
[1] && not_in
)
1935 if (!(flags
& SUPPRESS
))
1937 if ((flags
& MALLOC
)
1938 && str
+ MB_CUR_MAX
>= *strptr
+ strsize
)
1940 /* Enlarge the buffer. */
1941 str
= (char *) realloc (*strptr
, 2 * strsize
);
1944 /* Can't allocate that much. Last-ditch
1946 str
= (char *) realloc (*strptr
, strsize
+ 1);
1949 /* We lose. Oh well. Terminate the string
1950 and stop converting, so at least we don't
1952 (*strptr
)[strsize
- 1] = '\0';
1972 n
= wcrtomb (!(flags
& SUPPRESS
) ? str
: NULL
, c
, &state
);
1973 if (n
== (size_t) -1)
1976 assert (n
<= MB_CUR_MAX
);
1979 while (--width
> 0);
1984 if (inchar () == EOF
)
1987 if (wp
[c
] == not_in
)
1994 if (!(flags
& SUPPRESS
))
1997 if ((flags
& MALLOC
)
1998 && (char *) str
== *strptr
+ strsize
)
2000 /* Enlarge the buffer. */
2001 str
= (char *) realloc (*strptr
, 2 * strsize
);
2004 /* Can't allocate that much. Last-ditch
2006 str
= (char *) realloc (*strptr
, strsize
+ 1);
2009 /* We lose. Oh well. Terminate the
2010 string and stop converting,
2011 so at least we don't skip any input. */
2012 ((char *) (*strptr
))[strsize
- 1] = '\0';
2018 *strptr
= (char *) str
;
2025 *strptr
= (char *) str
;
2032 while (--width
> 0);
2036 /* We haven't succesfully read any character. */
2039 if (!(flags
& SUPPRESS
))
2041 #ifdef COMPILE_WPRINTF
2042 /* We have to emit the code to get into the intial
2044 char buf
[MB_LEN_MAX
];
2045 size_t n
= wcrtomb (buf
, L
'\0', &state
);
2046 if (n
> 0 && (flags
& MALLOC
)
2047 && str
+ n
>= *strptr
+ strsize
)
2049 /* Enlarge the buffer. */
2050 str
= (char *) realloc (*strptr
,
2051 (str
+ n
+ 1) - *strptr
);
2054 /* We lose. Oh well. Terminate the string
2055 and stop converting, so at least we don't
2057 ((char *) (*strptr
))[strsize
- 1] = '\0';
2063 *strptr
= (char *) str
;
2064 str
= ((char *) *strptr
) + strsize
;
2065 strsize
= (str
+ n
+ 1) - *strptr
;
2069 str
= __mempcpy (str
, buf
, n
);
2073 if ((flags
& MALLOC
) && str
- *strptr
!= strsize
)
2075 char *cp
= (char *) realloc (*strptr
, str
- *strptr
);
2085 case L_('p'): /* Generic pointer. */
2087 /* A PTR must be the same size as a `long int'. */
2088 flags
&= ~(SHORT
|LONGDBL
);
2096 /* If this is an unknown format character punt. */
2101 /* The last thing we saw int the format string was a white space.
2102 Consume the last white spaces. */
2107 while (ISSPACE (c
));
2111 /* Unlock stream. */
2118 # ifdef COMPILE_WPRINTF
2120 __vfwscanf (FILE *s
, const wchar_t *format
, va_list argptr
)
2122 return _IO_vfwscanf (s
, format
, argptr
, NULL
);
2126 __vfscanf (FILE *s
, const char *format
, va_list argptr
)
2128 return _IO_vfscanf (s
, format
, argptr
, NULL
);
2133 #ifdef COMPILE_WPRINTF
2134 weak_alias (__vfwscanf
, vfwscanf
)
2136 weak_alias (__vfscanf
, vfscanf
)