foo
[glibc.git] / stdio-common / vfscanf.c
blob20b9aa8ace5c8d07551d8e58359afc39c12ac587
1 /* Copyright (C) 1991-2014 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, see
16 <http://www.gnu.org/licenses/>. */
18 #include <assert.h>
19 #include <errno.h>
20 #include <limits.h>
21 #include <ctype.h>
22 #include <stdarg.h>
23 #include <stdbool.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <wchar.h>
29 #include <wctype.h>
30 #include <bits/libc-lock.h>
31 #include <locale/localeinfo.h>
33 #ifdef __GNUC__
34 # define HAVE_LONGLONG
35 # define LONGLONG long long
36 #else
37 # define LONGLONG long
38 #endif
40 /* Determine whether we have to handle `long long' at all. */
41 #if LONG_MAX == LONG_LONG_MAX
42 # define need_longlong 0
43 #else
44 # define need_longlong 1
45 #endif
47 /* Determine whether we have to handle `long'. */
48 #if INT_MAX == LONG_MAX
49 # define need_long 0
50 #else
51 # define need_long 1
52 #endif
54 /* Those are flags in the conversion format. */
55 #define LONG 0x0001 /* l: long or double */
56 #define LONGDBL 0x0002 /* L: long long or long double */
57 #define SHORT 0x0004 /* h: short */
58 #define SUPPRESS 0x0008 /* *: suppress assignment */
59 #define POINTER 0x0010 /* weird %p pointer (`fake hex') */
60 #define NOSKIP 0x0020 /* do not skip blanks */
61 #define NUMBER_SIGNED 0x0040 /* signed integer */
62 #define GROUP 0x0080 /* ': group numbers */
63 #define GNU_MALLOC 0x0100 /* a: malloc strings */
64 #define CHAR 0x0200 /* hh: char */
65 #define I18N 0x0400 /* I: use locale's digits */
66 #define HEXA_FLOAT 0x0800 /* hexadecimal float */
67 #define READ_POINTER 0x1000 /* this is a pointer value */
68 #define POSIX_MALLOC 0x2000 /* m: malloc strings */
69 #define MALLOC (GNU_MALLOC | POSIX_MALLOC)
71 #include <locale/localeinfo.h>
72 #include <libioP.h>
73 #include <libio.h>
75 #undef va_list
76 #define va_list _IO_va_list
78 #ifdef COMPILE_WSCANF
79 # define ungetc(c, s) ((void) (c == WEOF \
80 || (--read_in, \
81 _IO_sputbackwc (s, c))))
82 # define ungetc_not_eof(c, s) ((void) (--read_in, \
83 _IO_sputbackwc (s, c)))
84 # define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
85 : ((c = _IO_getwc_unlocked (stream)), \
86 (void) (c != WEOF \
87 ? ++read_in \
88 : (size_t) (inchar_errno = errno)), c))
90 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
91 # define ISSPACE(Ch) iswspace (Ch)
92 # define ISDIGIT(Ch) iswdigit (Ch)
93 # define ISXDIGIT(Ch) iswxdigit (Ch)
94 # define TOLOWER(Ch) towlower (Ch)
95 # define ORIENT if (_IO_fwide (stream, 1) != 1) return WEOF
96 # define __strtoll_internal __wcstoll_internal
97 # define __strtoull_internal __wcstoull_internal
98 # define __strtol_internal __wcstol_internal
99 # define __strtoul_internal __wcstoul_internal
100 # define __strtold_internal __wcstold_internal
101 # define __strtod_internal __wcstod_internal
102 # define __strtof_internal __wcstof_internal
104 # define L_(Str) L##Str
105 # define CHAR_T wchar_t
106 # define UCHAR_T unsigned int
107 # define WINT_T wint_t
108 # undef EOF
109 # define EOF WEOF
110 #else
111 # define ungetc(c, s) ((void) ((int) c == EOF \
112 || (--read_in, \
113 _IO_sputbackc (s, (unsigned char) c))))
114 # define ungetc_not_eof(c, s) ((void) (--read_in, \
115 _IO_sputbackc (s, (unsigned char) c)))
116 # define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
117 : ((c = _IO_getc_unlocked (stream)), \
118 (void) (c != EOF \
119 ? ++read_in \
120 : (size_t) (inchar_errno = errno)), c))
121 # define MEMCPY(d, s, n) memcpy (d, s, n)
122 # define ISSPACE(Ch) __isspace_l (Ch, loc)
123 # define ISDIGIT(Ch) __isdigit_l (Ch, loc)
124 # define ISXDIGIT(Ch) __isxdigit_l (Ch, loc)
125 # define TOLOWER(Ch) __tolower_l ((unsigned char) (Ch), loc)
126 # define ORIENT if (_IO_vtable_offset (stream) == 0 \
127 && _IO_fwide (stream, -1) != -1) \
128 return EOF
130 # define L_(Str) Str
131 # define CHAR_T char
132 # define UCHAR_T unsigned char
133 # define WINT_T int
134 #endif
136 #define encode_error() do { \
137 errval = 4; \
138 __set_errno (EILSEQ); \
139 goto errout; \
140 } while (0)
141 #define conv_error() do { \
142 errval = 2; \
143 goto errout; \
144 } while (0)
145 #define input_error() do { \
146 errval = 1; \
147 if (done == 0) done = EOF; \
148 goto errout; \
149 } while (0)
150 #define add_ptr_to_free(ptr) \
151 do \
153 if (ptrs_to_free == NULL \
154 || ptrs_to_free->count == (sizeof (ptrs_to_free->ptrs) \
155 / sizeof (ptrs_to_free->ptrs[0]))) \
157 struct ptrs_to_free *new_ptrs = alloca (sizeof (*ptrs_to_free)); \
158 new_ptrs->count = 0; \
159 new_ptrs->next = ptrs_to_free; \
160 ptrs_to_free = new_ptrs; \
162 ptrs_to_free->ptrs[ptrs_to_free->count++] = (ptr); \
164 while (0)
165 #define ARGCHECK(s, format) \
166 do \
168 /* Check file argument for consistence. */ \
169 CHECK_FILE (s, EOF); \
170 if (s->_flags & _IO_NO_READS) \
172 __set_errno (EBADF); \
173 return EOF; \
175 else if (format == NULL) \
177 MAYBE_SET_EINVAL; \
178 return EOF; \
180 } while (0)
181 #define LOCK_STREAM(S) \
182 __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
183 _IO_flockfile (S)
184 #define UNLOCK_STREAM(S) \
185 _IO_funlockfile (S); \
186 __libc_cleanup_region_end (0)
188 struct ptrs_to_free
190 size_t count;
191 struct ptrs_to_free *next;
192 char **ptrs[32];
195 #ifndef __va_copy
196 # define __va_copy(dst, src) (dst) = (va_list) (src)
197 #endif
199 /* Read formatted input from S according to the format string
200 FORMAT, using the argument list in ARG.
201 Return the number of assignments made, or -1 for an input error. */
202 #ifdef COMPILE_WSCANF
204 _IO_vfwscanf (_IO_FILE *stream, const wchar_t *format, _IO_va_list argptr,
205 int *errp)
206 #else
208 _IO_vfscanf_internal (_IO_FILE *stream, const char *format, _IO_va_list argptr,
209 int *errp)
210 #endif
212 va_list arg;
213 const CHAR_T *f = format;
214 UCHAR_T fc; /* Current character of the format. */
215 WINT_T done = 0; /* Assignments done. */
216 size_t read_in = 0; /* Chars read in. */
217 WINT_T c = 0; /* Last char read. */
218 int width; /* Maximum field width. */
219 int flags; /* Modifiers for current format element. */
220 int errval = 0;
221 #ifndef COMPILE_WSCANF
222 __locale_t loc = _NL_CURRENT_LOCALE;
223 struct __locale_data *const curctype = loc->__locales[LC_CTYPE];
224 #endif
226 /* Errno of last failed inchar call. */
227 int inchar_errno = 0;
228 /* Status for reading F-P nums. */
229 char got_digit, got_dot, got_e, negative;
230 /* If a [...] is a [^...]. */
231 CHAR_T not_in;
232 #define exp_char not_in
233 /* Base for integral numbers. */
234 int base;
235 /* Decimal point character. */
236 #ifdef COMPILE_WSCANF
237 wint_t decimal;
238 #else
239 const char *decimal;
240 #endif
241 /* The thousands character of the current locale. */
242 #ifdef COMPILE_WSCANF
243 wint_t thousands;
244 #else
245 const char *thousands;
246 #endif
247 struct ptrs_to_free *ptrs_to_free = NULL;
248 /* State for the conversions. */
249 mbstate_t state;
250 /* Integral holding variables. */
251 union
253 long long int q;
254 unsigned long long int uq;
255 long int l;
256 unsigned long int ul;
257 } num;
258 /* Character-buffer pointer. */
259 char *str = NULL;
260 wchar_t *wstr = NULL;
261 char **strptr = NULL;
262 ssize_t strsize = 0;
263 /* We must not react on white spaces immediately because they can
264 possibly be matched even if in the input stream no character is
265 available anymore. */
266 int skip_space = 0;
267 /* Workspace. */
268 CHAR_T *tw; /* Temporary pointer. */
269 CHAR_T *wp = NULL; /* Workspace. */
270 size_t wpmax = 0; /* Maximal size of workspace. */
271 size_t wpsize; /* Currently used bytes in workspace. */
272 bool use_malloc = false;
273 #define ADDW(Ch) \
274 do \
276 if (__glibc_unlikely (wpsize == wpmax)) \
278 CHAR_T *old = wp; \
279 size_t newsize = (UCHAR_MAX + 1 > 2 * wpmax \
280 ? UCHAR_MAX + 1 : 2 * wpmax); \
281 if (use_malloc || !__libc_use_alloca (newsize)) \
283 wp = realloc (use_malloc ? wp : NULL, newsize); \
284 if (wp == NULL) \
286 if (use_malloc) \
287 free (old); \
288 done = EOF; \
289 goto errout; \
291 if (! use_malloc) \
292 MEMCPY (wp, old, wpsize); \
293 wpmax = newsize; \
294 use_malloc = true; \
296 else \
298 size_t s = wpmax * sizeof (CHAR_T); \
299 wp = (CHAR_T *) extend_alloca (wp, s, \
300 newsize * sizeof (CHAR_T)); \
301 wpmax = s / sizeof (CHAR_T); \
302 if (old != NULL) \
303 MEMCPY (wp, old, wpsize); \
306 wp[wpsize++] = (Ch); \
308 while (0)
310 __va_copy (arg, argptr);
312 #ifdef ORIENT
313 ORIENT;
314 #endif
316 ARGCHECK (stream, format);
319 #ifndef COMPILE_WSCANF
320 struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
321 #endif
323 /* Figure out the decimal point character. */
324 #ifdef COMPILE_WSCANF
325 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
326 #else
327 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
328 #endif
329 /* Figure out the thousands separator character. */
330 #ifdef COMPILE_WSCANF
331 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
332 #else
333 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
334 if (*thousands == '\0')
335 thousands = NULL;
336 #endif
339 /* Lock the stream. */
340 LOCK_STREAM (stream);
343 #ifndef COMPILE_WSCANF
344 /* From now on we use `state' to convert the format string. */
345 memset (&state, '\0', sizeof (state));
346 #endif
348 /* Run through the format string. */
349 while (*f != '\0')
351 unsigned int argpos;
352 /* Extract the next argument, which is of type TYPE.
353 For a %N$... spec, this is the Nth argument from the beginning;
354 otherwise it is the next argument after the state now in ARG. */
355 #define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
356 ({ unsigned int pos = argpos; \
357 va_list argcopy; \
358 __va_copy (argcopy, argptr); \
359 while (--pos > 0) \
360 (void) va_arg (argcopy, void *); \
361 va_arg (argcopy, type); \
364 #ifndef COMPILE_WSCANF
365 if (!isascii ((unsigned char) *f))
367 /* Non-ASCII, may be a multibyte. */
368 int len = __mbrlen (f, strlen (f), &state);
369 if (len > 0)
373 c = inchar ();
374 if (__glibc_unlikely (c == EOF))
375 input_error ();
376 else if (c != (unsigned char) *f++)
378 ungetc_not_eof (c, stream);
379 conv_error ();
382 while (--len > 0);
383 continue;
386 #endif
388 fc = *f++;
389 if (fc != '%')
391 /* Remember to skip spaces. */
392 if (ISSPACE (fc))
394 skip_space = 1;
395 continue;
398 /* Read a character. */
399 c = inchar ();
401 /* Characters other than format specs must just match. */
402 if (__glibc_unlikely (c == EOF))
403 input_error ();
405 /* We saw white space char as the last character in the format
406 string. Now it's time to skip all leading white space. */
407 if (skip_space)
409 while (ISSPACE (c))
410 if (__glibc_unlikely (inchar () == EOF))
411 input_error ();
412 skip_space = 0;
415 if (__glibc_unlikely (c != fc))
417 ungetc (c, stream);
418 conv_error ();
421 continue;
424 /* This is the start of the conversion string. */
425 flags = 0;
427 /* Initialize state of modifiers. */
428 argpos = 0;
430 /* Prepare temporary buffer. */
431 wpsize = 0;
433 /* Check for a positional parameter specification. */
434 if (ISDIGIT ((UCHAR_T) *f))
436 argpos = (UCHAR_T) *f++ - L_('0');
437 while (ISDIGIT ((UCHAR_T) *f))
438 argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
439 if (*f == L_('$'))
440 ++f;
441 else
443 /* Oops; that was actually the field width. */
444 width = argpos;
445 argpos = 0;
446 goto got_width;
450 /* Check for the assignment-suppressing, the number grouping flag,
451 and the signal to use the locale's digit representation. */
452 while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
453 switch (*f++)
455 case L_('*'):
456 flags |= SUPPRESS;
457 break;
458 case L_('\''):
459 #ifdef COMPILE_WSCANF
460 if (thousands != L'\0')
461 #else
462 if (thousands != NULL)
463 #endif
464 flags |= GROUP;
465 break;
466 case L_('I'):
467 flags |= I18N;
468 break;
471 /* Find the maximum field width. */
472 width = 0;
473 while (ISDIGIT ((UCHAR_T) *f))
475 width *= 10;
476 width += (UCHAR_T) *f++ - L_('0');
478 got_width:
479 if (width == 0)
480 width = -1;
482 /* Check for type modifiers. */
483 switch (*f++)
485 case L_('h'):
486 /* ints are short ints or chars. */
487 if (*f == L_('h'))
489 ++f;
490 flags |= CHAR;
492 else
493 flags |= SHORT;
494 break;
495 case L_('l'):
496 if (*f == L_('l'))
498 /* A double `l' is equivalent to an `L'. */
499 ++f;
500 flags |= LONGDBL | LONG;
502 else
503 /* ints are long ints. */
504 flags |= LONG;
505 break;
506 case L_('q'):
507 case L_('L'):
508 /* doubles are long doubles, and ints are long long ints. */
509 flags |= LONGDBL | LONG;
510 break;
511 case L_('a'):
512 /* The `a' is used as a flag only if followed by `s', `S' or
513 `['. */
514 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
516 --f;
517 break;
519 /* In __isoc99_*scanf %as, %aS and %a[ extension is not
520 supported at all. */
521 if (stream->_flags2 & _IO_FLAGS2_SCANF_STD)
523 --f;
524 break;
526 /* String conversions (%s, %[) take a `char **'
527 arg and fill it in with a malloc'd pointer. */
528 flags |= GNU_MALLOC;
529 break;
530 case L_('m'):
531 flags |= POSIX_MALLOC;
532 if (*f == L_('l'))
534 ++f;
535 flags |= LONG;
537 break;
538 case L_('z'):
539 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
540 flags |= LONGDBL;
541 else if (sizeof (size_t) > sizeof (unsigned int))
542 flags |= LONG;
543 break;
544 case L_('j'):
545 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
546 flags |= LONGDBL;
547 else if (sizeof (uintmax_t) > sizeof (unsigned int))
548 flags |= LONG;
549 break;
550 case L_('t'):
551 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
552 flags |= LONGDBL;
553 else if (sizeof (ptrdiff_t) > sizeof (int))
554 flags |= LONG;
555 break;
556 default:
557 /* Not a recognized modifier. Backup. */
558 --f;
559 break;
562 /* End of the format string? */
563 if (__glibc_unlikely (*f == L_('\0')))
564 conv_error ();
566 /* Find the conversion specifier. */
567 fc = *f++;
568 if (skip_space || (fc != L_('[') && fc != L_('c')
569 && fc != L_('C') && fc != L_('n')))
571 /* Eat whitespace. */
572 int save_errno = errno;
573 __set_errno (0);
575 /* We add the additional test for EOF here since otherwise
576 inchar will restore the old errno value which might be
577 EINTR but does not indicate an interrupt since nothing
578 was read at this time. */
579 if (__builtin_expect ((c == EOF || inchar () == EOF)
580 && errno == EINTR, 0))
581 input_error ();
582 while (ISSPACE (c));
583 __set_errno (save_errno);
584 ungetc (c, stream);
585 skip_space = 0;
588 switch (fc)
590 case L_('%'): /* Must match a literal '%'. */
591 c = inchar ();
592 if (__glibc_unlikely (c == EOF))
593 input_error ();
594 if (__glibc_unlikely (c != fc))
596 ungetc_not_eof (c, stream);
597 conv_error ();
599 break;
601 case L_('n'): /* Answer number of assignments done. */
602 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
603 with the 'n' conversion specifier. */
604 if (!(flags & SUPPRESS))
606 /* Don't count the read-ahead. */
607 if (need_longlong && (flags & LONGDBL))
608 *ARG (long long int *) = read_in;
609 else if (need_long && (flags & LONG))
610 *ARG (long int *) = read_in;
611 else if (flags & SHORT)
612 *ARG (short int *) = read_in;
613 else if (!(flags & CHAR))
614 *ARG (int *) = read_in;
615 else
616 *ARG (char *) = read_in;
618 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
619 /* We have a severe problem here. The ISO C standard
620 contradicts itself in explaining the effect of the %n
621 format in `scanf'. While in ISO C:1990 and the ISO C
622 Amendement 1:1995 the result is described as
624 Execution of a %n directive does not effect the
625 assignment count returned at the completion of
626 execution of the f(w)scanf function.
628 in ISO C Corrigendum 1:1994 the following was added:
630 Subclause 7.9.6.2
631 Add the following fourth example:
633 #include <stdio.h>
634 int d1, d2, n1, n2, i;
635 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
636 the value 123 is assigned to d1 and the value3 to n1.
637 Because %n can never get an input failure the value
638 of 3 is also assigned to n2. The value of d2 is not
639 affected. The value 3 is assigned to i.
641 We go for now with the historically correct code from ISO C,
642 i.e., we don't count the %n assignments. When it ever
643 should proof to be wrong just remove the #ifdef above. */
644 ++done;
645 #endif
647 break;
649 case L_('c'): /* Match characters. */
650 if ((flags & LONG) == 0)
652 if (width == -1)
653 width = 1;
655 #define STRING_ARG(Str, Type, Width) \
656 do if (!(flags & SUPPRESS)) \
658 if (flags & MALLOC) \
660 /* The string is to be stored in a malloc'd buffer. */ \
661 /* For %mS using char ** is actually wrong, but \
662 shouldn't make a difference on any arch glibc \
663 supports and would unnecessarily complicate \
664 things. */ \
665 strptr = ARG (char **); \
666 if (strptr == NULL) \
667 conv_error (); \
668 /* Allocate an initial buffer. */ \
669 strsize = Width; \
670 *strptr = (char *) malloc (strsize * sizeof (Type)); \
671 Str = (Type *) *strptr; \
672 if (Str != NULL) \
673 add_ptr_to_free (strptr); \
674 else if (flags & POSIX_MALLOC) \
676 done = EOF; \
677 goto errout; \
680 else \
681 Str = ARG (Type *); \
682 if (Str == NULL) \
683 conv_error (); \
684 } while (0)
685 #ifdef COMPILE_WSCANF
686 STRING_ARG (str, char, 100);
687 #else
688 STRING_ARG (str, char, (width > 1024 ? 1024 : width));
689 #endif
691 c = inchar ();
692 if (__glibc_unlikely (c == EOF))
693 input_error ();
695 #ifdef COMPILE_WSCANF
696 /* We have to convert the wide character(s) into multibyte
697 characters and store the result. */
698 memset (&state, '\0', sizeof (state));
702 size_t n;
704 if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
705 && str + MB_CUR_MAX >= *strptr + strsize)
707 /* We have to enlarge the buffer if the `m' flag
708 was given. */
709 size_t strleng = str - *strptr;
710 char *newstr;
712 newstr = (char *) realloc (*strptr, strsize * 2);
713 if (newstr == NULL)
715 /* Can't allocate that much. Last-ditch effort. */
716 newstr = (char *) realloc (*strptr,
717 strleng + MB_CUR_MAX);
718 if (newstr == NULL)
720 /* c can't have `a' flag, only `m'. */
721 done = EOF;
722 goto errout;
724 else
726 *strptr = newstr;
727 str = newstr + strleng;
728 strsize = strleng + MB_CUR_MAX;
731 else
733 *strptr = newstr;
734 str = newstr + strleng;
735 strsize *= 2;
739 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
740 if (__glibc_unlikely (n == (size_t) -1))
741 /* No valid wide character. */
742 input_error ();
744 /* Increment the output pointer. Even if we don't
745 write anything. */
746 str += n;
748 while (--width > 0 && inchar () != EOF);
749 #else
750 if (!(flags & SUPPRESS))
754 if ((flags & MALLOC)
755 && (char *) str == *strptr + strsize)
757 /* Enlarge the buffer. */
758 size_t newsize
759 = strsize
760 + (strsize >= width ? width - 1 : strsize);
762 str = (char *) realloc (*strptr, newsize);
763 if (str == NULL)
765 /* Can't allocate that much. Last-ditch
766 effort. */
767 str = (char *) realloc (*strptr, strsize + 1);
768 if (str == NULL)
770 /* c can't have `a' flag, only `m'. */
771 done = EOF;
772 goto errout;
774 else
776 *strptr = (char *) str;
777 str += strsize;
778 ++strsize;
781 else
783 *strptr = (char *) str;
784 str += strsize;
785 strsize = newsize;
788 *str++ = c;
790 while (--width > 0 && inchar () != EOF);
792 else
793 while (--width > 0 && inchar () != EOF);
794 #endif
796 if (!(flags & SUPPRESS))
798 if ((flags & MALLOC) && str - *strptr != strsize)
800 char *cp = (char *) realloc (*strptr, str - *strptr);
801 if (cp != NULL)
802 *strptr = cp;
804 strptr = NULL;
805 ++done;
808 break;
810 /* FALLTHROUGH */
811 case L_('C'):
812 if (width == -1)
813 width = 1;
815 STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width));
817 c = inchar ();
818 if (__glibc_unlikely (c == EOF))
819 input_error ();
821 #ifdef COMPILE_WSCANF
822 /* Just store the incoming wide characters. */
823 if (!(flags & SUPPRESS))
827 if ((flags & MALLOC)
828 && wstr == (wchar_t *) *strptr + strsize)
830 size_t newsize
831 = strsize + (strsize > width ? width - 1 : strsize);
832 /* Enlarge the buffer. */
833 wstr = (wchar_t *) realloc (*strptr,
834 newsize * sizeof (wchar_t));
835 if (wstr == NULL)
837 /* Can't allocate that much. Last-ditch effort. */
838 wstr = (wchar_t *) realloc (*strptr,
839 (strsize + 1)
840 * sizeof (wchar_t));
841 if (wstr == NULL)
843 /* C or lc can't have `a' flag, only `m'
844 flag. */
845 done = EOF;
846 goto errout;
848 else
850 *strptr = (char *) wstr;
851 wstr += strsize;
852 ++strsize;
855 else
857 *strptr = (char *) wstr;
858 wstr += strsize;
859 strsize = newsize;
862 *wstr++ = c;
864 while (--width > 0 && inchar () != EOF);
866 else
867 while (--width > 0 && inchar () != EOF);
868 #else
870 /* We have to convert the multibyte input sequence to wide
871 characters. */
872 char buf[1];
873 mbstate_t cstate;
875 memset (&cstate, '\0', sizeof (cstate));
879 /* This is what we present the mbrtowc function first. */
880 buf[0] = c;
882 if (!(flags & SUPPRESS) && (flags & MALLOC)
883 && wstr == (wchar_t *) *strptr + strsize)
885 size_t newsize
886 = strsize + (strsize > width ? width - 1 : strsize);
887 /* Enlarge the buffer. */
888 wstr = (wchar_t *) realloc (*strptr,
889 newsize * sizeof (wchar_t));
890 if (wstr == NULL)
892 /* Can't allocate that much. Last-ditch effort. */
893 wstr = (wchar_t *) realloc (*strptr,
894 ((strsize + 1)
895 * sizeof (wchar_t)));
896 if (wstr == NULL)
898 /* C or lc can't have `a' flag, only `m' flag. */
899 done = EOF;
900 goto errout;
902 else
904 *strptr = (char *) wstr;
905 wstr += strsize;
906 ++strsize;
909 else
911 *strptr = (char *) wstr;
912 wstr += strsize;
913 strsize = newsize;
917 while (1)
919 size_t n;
921 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
922 buf, 1, &cstate);
924 if (n == (size_t) -2)
926 /* Possibly correct character, just not enough
927 input. */
928 if (__glibc_unlikely (inchar () == EOF))
929 encode_error ();
931 buf[0] = c;
932 continue;
935 if (__glibc_unlikely (n != 1))
936 encode_error ();
938 /* We have a match. */
939 break;
942 /* Advance the result pointer. */
943 ++wstr;
945 while (--width > 0 && inchar () != EOF);
947 #endif
949 if (!(flags & SUPPRESS))
951 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
953 wchar_t *cp = (wchar_t *) realloc (*strptr,
954 ((wstr
955 - (wchar_t *) *strptr)
956 * sizeof (wchar_t)));
957 if (cp != NULL)
958 *strptr = (char *) cp;
960 strptr = NULL;
962 ++done;
965 break;
967 case L_('s'): /* Read a string. */
968 if (!(flags & LONG))
970 STRING_ARG (str, char, 100);
972 c = inchar ();
973 if (__glibc_unlikely (c == EOF))
974 input_error ();
976 #ifdef COMPILE_WSCANF
977 memset (&state, '\0', sizeof (state));
978 #endif
982 if (ISSPACE (c))
984 ungetc_not_eof (c, stream);
985 break;
988 #ifdef COMPILE_WSCANF
989 /* This is quite complicated. We have to convert the
990 wide characters into multibyte characters and then
991 store them. */
993 size_t n;
995 if (!(flags & SUPPRESS) && (flags & MALLOC)
996 && str + MB_CUR_MAX >= *strptr + strsize)
998 /* We have to enlarge the buffer if the `a' or `m'
999 flag was given. */
1000 size_t strleng = str - *strptr;
1001 char *newstr;
1003 newstr = (char *) realloc (*strptr, strsize * 2);
1004 if (newstr == NULL)
1006 /* Can't allocate that much. Last-ditch
1007 effort. */
1008 newstr = (char *) realloc (*strptr,
1009 strleng + MB_CUR_MAX);
1010 if (newstr == NULL)
1012 if (flags & POSIX_MALLOC)
1014 done = EOF;
1015 goto errout;
1017 /* We lose. Oh well. Terminate the
1018 string and stop converting,
1019 so at least we don't skip any input. */
1020 ((char *) (*strptr))[strleng] = '\0';
1021 strptr = NULL;
1022 ++done;
1023 conv_error ();
1025 else
1027 *strptr = newstr;
1028 str = newstr + strleng;
1029 strsize = strleng + MB_CUR_MAX;
1032 else
1034 *strptr = newstr;
1035 str = newstr + strleng;
1036 strsize *= 2;
1040 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
1041 &state);
1042 if (__glibc_unlikely (n == (size_t) -1))
1043 encode_error ();
1045 assert (n <= MB_CUR_MAX);
1046 str += n;
1048 #else
1049 /* This is easy. */
1050 if (!(flags & SUPPRESS))
1052 *str++ = c;
1053 if ((flags & MALLOC)
1054 && (char *) str == *strptr + strsize)
1056 /* Enlarge the buffer. */
1057 str = (char *) realloc (*strptr, 2 * strsize);
1058 if (str == NULL)
1060 /* Can't allocate that much. Last-ditch
1061 effort. */
1062 str = (char *) realloc (*strptr, strsize + 1);
1063 if (str == NULL)
1065 if (flags & POSIX_MALLOC)
1067 done = EOF;
1068 goto errout;
1070 /* We lose. Oh well. Terminate the
1071 string and stop converting,
1072 so at least we don't skip any input. */
1073 ((char *) (*strptr))[strsize - 1] = '\0';
1074 strptr = NULL;
1075 ++done;
1076 conv_error ();
1078 else
1080 *strptr = (char *) str;
1081 str += strsize;
1082 ++strsize;
1085 else
1087 *strptr = (char *) str;
1088 str += strsize;
1089 strsize *= 2;
1093 #endif
1095 while ((width <= 0 || --width > 0) && inchar () != EOF);
1097 if (!(flags & SUPPRESS))
1099 #ifdef COMPILE_WSCANF
1100 /* We have to emit the code to get into the initial
1101 state. */
1102 char buf[MB_LEN_MAX];
1103 size_t n = __wcrtomb (buf, L'\0', &state);
1104 if (n > 0 && (flags & MALLOC)
1105 && str + n >= *strptr + strsize)
1107 /* Enlarge the buffer. */
1108 size_t strleng = str - *strptr;
1109 char *newstr;
1111 newstr = (char *) realloc (*strptr, strleng + n + 1);
1112 if (newstr == NULL)
1114 if (flags & POSIX_MALLOC)
1116 done = EOF;
1117 goto errout;
1119 /* We lose. Oh well. Terminate the string
1120 and stop converting, so at least we don't
1121 skip any input. */
1122 ((char *) (*strptr))[strleng] = '\0';
1123 strptr = NULL;
1124 ++done;
1125 conv_error ();
1127 else
1129 *strptr = newstr;
1130 str = newstr + strleng;
1131 strsize = strleng + n + 1;
1135 str = __mempcpy (str, buf, n);
1136 #endif
1137 *str++ = '\0';
1139 if ((flags & MALLOC) && str - *strptr != strsize)
1141 char *cp = (char *) realloc (*strptr, str - *strptr);
1142 if (cp != NULL)
1143 *strptr = cp;
1145 strptr = NULL;
1147 ++done;
1149 break;
1151 /* FALLTHROUGH */
1153 case L_('S'):
1155 #ifndef COMPILE_WSCANF
1156 mbstate_t cstate;
1157 #endif
1159 /* Wide character string. */
1160 STRING_ARG (wstr, wchar_t, 100);
1162 c = inchar ();
1163 if (__builtin_expect (c == EOF, 0))
1164 input_error ();
1166 #ifndef COMPILE_WSCANF
1167 memset (&cstate, '\0', sizeof (cstate));
1168 #endif
1172 if (ISSPACE (c))
1174 ungetc_not_eof (c, stream);
1175 break;
1178 #ifdef COMPILE_WSCANF
1179 /* This is easy. */
1180 if (!(flags & SUPPRESS))
1182 *wstr++ = c;
1183 if ((flags & MALLOC)
1184 && wstr == (wchar_t *) *strptr + strsize)
1186 /* Enlarge the buffer. */
1187 wstr = (wchar_t *) realloc (*strptr,
1188 (2 * strsize)
1189 * sizeof (wchar_t));
1190 if (wstr == NULL)
1192 /* Can't allocate that much. Last-ditch
1193 effort. */
1194 wstr = (wchar_t *) realloc (*strptr,
1195 (strsize + 1)
1196 * sizeof (wchar_t));
1197 if (wstr == NULL)
1199 if (flags & POSIX_MALLOC)
1201 done = EOF;
1202 goto errout;
1204 /* We lose. Oh well. Terminate the string
1205 and stop converting, so at least we don't
1206 skip any input. */
1207 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1208 strptr = NULL;
1209 ++done;
1210 conv_error ();
1212 else
1214 *strptr = (char *) wstr;
1215 wstr += strsize;
1216 ++strsize;
1219 else
1221 *strptr = (char *) wstr;
1222 wstr += strsize;
1223 strsize *= 2;
1227 #else
1229 char buf[1];
1231 buf[0] = c;
1233 while (1)
1235 size_t n;
1237 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1238 buf, 1, &cstate);
1240 if (n == (size_t) -2)
1242 /* Possibly correct character, just not enough
1243 input. */
1244 if (__glibc_unlikely (inchar () == EOF))
1245 encode_error ();
1247 buf[0] = c;
1248 continue;
1251 if (__glibc_unlikely (n != 1))
1252 encode_error ();
1254 /* We have a match. */
1255 ++wstr;
1256 break;
1259 if (!(flags & SUPPRESS) && (flags & MALLOC)
1260 && wstr == (wchar_t *) *strptr + strsize)
1262 /* Enlarge the buffer. */
1263 wstr = (wchar_t *) realloc (*strptr,
1264 (2 * strsize
1265 * sizeof (wchar_t)));
1266 if (wstr == NULL)
1268 /* Can't allocate that much. Last-ditch effort. */
1269 wstr = (wchar_t *) realloc (*strptr,
1270 ((strsize + 1)
1271 * sizeof (wchar_t)));
1272 if (wstr == NULL)
1274 if (flags & POSIX_MALLOC)
1276 done = EOF;
1277 goto errout;
1279 /* We lose. Oh well. Terminate the
1280 string and stop converting, so at
1281 least we don't skip any input. */
1282 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1283 strptr = NULL;
1284 ++done;
1285 conv_error ();
1287 else
1289 *strptr = (char *) wstr;
1290 wstr += strsize;
1291 ++strsize;
1294 else
1296 *strptr = (char *) wstr;
1297 wstr += strsize;
1298 strsize *= 2;
1302 #endif
1304 while ((width <= 0 || --width > 0) && inchar () != EOF);
1306 if (!(flags & SUPPRESS))
1308 *wstr++ = L'\0';
1310 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1312 wchar_t *cp = (wchar_t *) realloc (*strptr,
1313 ((wstr
1314 - (wchar_t *) *strptr)
1315 * sizeof(wchar_t)));
1316 if (cp != NULL)
1317 *strptr = (char *) cp;
1319 strptr = NULL;
1321 ++done;
1324 break;
1326 case L_('x'): /* Hexadecimal integer. */
1327 case L_('X'): /* Ditto. */
1328 base = 16;
1329 goto number;
1331 case L_('o'): /* Octal integer. */
1332 base = 8;
1333 goto number;
1335 case L_('u'): /* Unsigned decimal integer. */
1336 base = 10;
1337 goto number;
1339 case L_('d'): /* Signed decimal integer. */
1340 base = 10;
1341 flags |= NUMBER_SIGNED;
1342 goto number;
1344 case L_('i'): /* Generic number. */
1345 base = 0;
1346 flags |= NUMBER_SIGNED;
1348 number:
1349 c = inchar ();
1350 if (__glibc_unlikely (c == EOF))
1351 input_error ();
1353 /* Check for a sign. */
1354 if (c == L_('-') || c == L_('+'))
1356 ADDW (c);
1357 if (width > 0)
1358 --width;
1359 c = inchar ();
1362 /* Look for a leading indication of base. */
1363 if (width != 0 && c == L_('0'))
1365 if (width > 0)
1366 --width;
1368 ADDW (c);
1369 c = inchar ();
1371 if (width != 0 && TOLOWER (c) == L_('x'))
1373 if (base == 0)
1374 base = 16;
1375 if (base == 16)
1377 if (width > 0)
1378 --width;
1379 c = inchar ();
1382 else if (base == 0)
1383 base = 8;
1386 if (base == 0)
1387 base = 10;
1389 if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
1391 int from_level;
1392 int to_level;
1393 int level;
1394 #ifdef COMPILE_WSCANF
1395 const wchar_t *wcdigits[10];
1396 const wchar_t *wcdigits_extended[10];
1397 #else
1398 const char *mbdigits[10];
1399 const char *mbdigits_extended[10];
1400 #endif
1401 /* "to_inpunct" is a map from ASCII digits to their
1402 equivalent in locale. This is defined for locales
1403 which use an extra digits set. */
1404 wctrans_t map = __wctrans ("to_inpunct");
1405 int n;
1407 from_level = 0;
1408 #ifdef COMPILE_WSCANF
1409 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1410 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1411 #else
1412 to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
1413 #endif
1415 /* Get the alternative digit forms if there are any. */
1416 if (__glibc_unlikely (map != NULL))
1418 /* Adding new level for extra digits set in locale file. */
1419 ++to_level;
1421 for (n = 0; n < 10; ++n)
1423 #ifdef COMPILE_WSCANF
1424 wcdigits[n] = (const wchar_t *)
1425 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1427 wchar_t *wc_extended = (wchar_t *)
1428 alloca ((to_level + 2) * sizeof (wchar_t));
1429 __wmemcpy (wc_extended, wcdigits[n], to_level);
1430 wc_extended[to_level] = __towctrans (L'0' + n, map);
1431 wc_extended[to_level + 1] = '\0';
1432 wcdigits_extended[n] = wc_extended;
1433 #else
1434 mbdigits[n]
1435 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1437 /* Get the equivalent wide char in map. */
1438 wint_t extra_wcdigit = __towctrans (L'0' + n, map);
1440 /* Convert it to multibyte representation. */
1441 mbstate_t dstate;
1442 memset (&dstate, '\0', sizeof (dstate));
1444 char extra_mbdigit[MB_LEN_MAX];
1445 size_t mblen
1446 = __wcrtomb (extra_mbdigit, extra_wcdigit, &dstate);
1448 if (mblen == (size_t) -1)
1450 /* Ignore this new level. */
1451 map = NULL;
1452 break;
1455 /* Calculate the length of mbdigits[n]. */
1456 const char *last_char = mbdigits[n];
1457 for (level = 0; level < to_level; ++level)
1458 last_char = strchr (last_char, '\0') + 1;
1460 size_t mbdigits_len = last_char - mbdigits[n];
1462 /* Allocate memory for extended multibyte digit. */
1463 char *mb_extended;
1464 mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
1466 /* And get the mbdigits + extra_digit string. */
1467 *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
1468 mbdigits_len),
1469 extra_mbdigit, mblen) = '\0';
1470 mbdigits_extended[n] = mb_extended;
1471 #endif
1475 /* Read the number into workspace. */
1476 while (c != EOF && width != 0)
1478 /* In this round we get the pointer to the digit strings
1479 and also perform the first round of comparisons. */
1480 for (n = 0; n < 10; ++n)
1482 /* Get the string for the digits with value N. */
1483 #ifdef COMPILE_WSCANF
1484 if (__glibc_unlikely (map != NULL))
1485 wcdigits[n] = wcdigits_extended[n];
1486 else
1487 wcdigits[n] = (const wchar_t *)
1488 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1489 wcdigits[n] += from_level;
1491 if (c == (wint_t) *wcdigits[n])
1493 to_level = from_level;
1494 break;
1497 /* Advance the pointer to the next string. */
1498 ++wcdigits[n];
1499 #else
1500 const char *cmpp;
1501 int avail = width > 0 ? width : INT_MAX;
1503 if (__glibc_unlikely (map != NULL))
1504 mbdigits[n] = mbdigits_extended[n];
1505 else
1506 mbdigits[n]
1507 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1509 for (level = 0; level < from_level; level++)
1510 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1512 cmpp = mbdigits[n];
1513 while ((unsigned char) *cmpp == c && avail >= 0)
1515 if (*++cmpp == '\0')
1516 break;
1517 else
1519 if (avail == 0 || inchar () == EOF)
1520 break;
1521 --avail;
1525 if (*cmpp == '\0')
1527 if (width > 0)
1528 width = avail;
1529 to_level = from_level;
1530 break;
1533 /* We are pushing all read characters back. */
1534 if (cmpp > mbdigits[n])
1536 ungetc (c, stream);
1537 while (--cmpp > mbdigits[n])
1538 ungetc_not_eof ((unsigned char) *cmpp, stream);
1539 c = (unsigned char) *cmpp;
1542 /* Advance the pointer to the next string. */
1543 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1544 #endif
1547 if (n == 10)
1549 /* Have not yet found the digit. */
1550 for (level = from_level + 1; level <= to_level; ++level)
1552 /* Search all ten digits of this level. */
1553 for (n = 0; n < 10; ++n)
1555 #ifdef COMPILE_WSCANF
1556 if (c == (wint_t) *wcdigits[n])
1557 break;
1559 /* Advance the pointer to the next string. */
1560 ++wcdigits[n];
1561 #else
1562 const char *cmpp;
1563 int avail = width > 0 ? width : INT_MAX;
1565 cmpp = mbdigits[n];
1566 while ((unsigned char) *cmpp == c && avail >= 0)
1568 if (*++cmpp == '\0')
1569 break;
1570 else
1572 if (avail == 0 || inchar () == EOF)
1573 break;
1574 --avail;
1578 if (*cmpp == '\0')
1580 if (width > 0)
1581 width = avail;
1582 break;
1585 /* We are pushing all read characters back. */
1586 if (cmpp > mbdigits[n])
1588 ungetc (c, stream);
1589 while (--cmpp > mbdigits[n])
1590 ungetc_not_eof ((unsigned char) *cmpp,
1591 stream);
1592 c = (unsigned char) *cmpp;
1595 /* Advance the pointer to the next string. */
1596 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1597 #endif
1600 if (n < 10)
1602 /* Found it. */
1603 from_level = level;
1604 to_level = level;
1605 break;
1610 if (n < 10)
1611 c = L_('0') + n;
1612 else if (flags & GROUP)
1614 /* Try matching against the thousands separator. */
1615 #ifdef COMPILE_WSCANF
1616 if (c != thousands)
1617 break;
1618 #else
1619 const char *cmpp = thousands;
1620 int avail = width > 0 ? width : INT_MAX;
1622 while ((unsigned char) *cmpp == c && avail >= 0)
1624 ADDW (c);
1625 if (*++cmpp == '\0')
1626 break;
1627 else
1629 if (avail == 0 || inchar () == EOF)
1630 break;
1631 --avail;
1635 if (*cmpp != '\0')
1637 /* We are pushing all read characters back. */
1638 if (cmpp > thousands)
1640 wpsize -= cmpp - thousands;
1641 ungetc (c, stream);
1642 while (--cmpp > thousands)
1643 ungetc_not_eof ((unsigned char) *cmpp, stream);
1644 c = (unsigned char) *cmpp;
1646 break;
1649 if (width > 0)
1650 width = avail;
1652 /* The last thousands character will be added back by
1653 the ADDW below. */
1654 --wpsize;
1655 #endif
1657 else
1658 break;
1660 ADDW (c);
1661 if (width > 0)
1662 --width;
1664 c = inchar ();
1667 else
1668 /* Read the number into workspace. */
1669 while (c != EOF && width != 0)
1671 if (base == 16)
1673 if (!ISXDIGIT (c))
1674 break;
1676 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
1678 if (base == 10 && (flags & GROUP))
1680 /* Try matching against the thousands separator. */
1681 #ifdef COMPILE_WSCANF
1682 if (c != thousands)
1683 break;
1684 #else
1685 const char *cmpp = thousands;
1686 int avail = width > 0 ? width : INT_MAX;
1688 while ((unsigned char) *cmpp == c && avail >= 0)
1690 ADDW (c);
1691 if (*++cmpp == '\0')
1692 break;
1693 else
1695 if (avail == 0 || inchar () == EOF)
1696 break;
1697 --avail;
1701 if (*cmpp != '\0')
1703 /* We are pushing all read characters back. */
1704 if (cmpp > thousands)
1706 wpsize -= cmpp - thousands;
1707 ungetc (c, stream);
1708 while (--cmpp > thousands)
1709 ungetc_not_eof ((unsigned char) *cmpp,
1710 stream);
1711 c = (unsigned char) *cmpp;
1713 break;
1716 if (width > 0)
1717 width = avail;
1719 /* The last thousands character will be added back by
1720 the ADDW below. */
1721 --wpsize;
1722 #endif
1724 else
1725 break;
1727 ADDW (c);
1728 if (width > 0)
1729 --width;
1731 c = inchar ();
1734 if (wpsize == 0
1735 || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1737 /* There was no number. If we are supposed to read a pointer
1738 we must recognize "(nil)" as well. */
1739 if (__builtin_expect (wpsize == 0
1740 && (flags & READ_POINTER)
1741 && (width < 0 || width >= 5)
1742 && c == '('
1743 && TOLOWER (inchar ()) == L_('n')
1744 && TOLOWER (inchar ()) == L_('i')
1745 && TOLOWER (inchar ()) == L_('l')
1746 && inchar () == L_(')'), 1))
1747 /* We must produce the value of a NULL pointer. A single
1748 '0' digit is enough. */
1749 ADDW (L_('0'));
1750 else
1752 /* The last read character is not part of the number
1753 anymore. */
1754 ungetc (c, stream);
1756 conv_error ();
1759 else
1760 /* The just read character is not part of the number anymore. */
1761 ungetc (c, stream);
1763 /* Convert the number. */
1764 ADDW (L_('\0'));
1765 if (need_longlong && (flags & LONGDBL))
1767 if (flags & NUMBER_SIGNED)
1768 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1769 else
1770 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1772 else
1774 if (flags & NUMBER_SIGNED)
1775 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1776 else
1777 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1779 if (__glibc_unlikely (wp == tw))
1780 conv_error ();
1782 if (!(flags & SUPPRESS))
1784 if (flags & NUMBER_SIGNED)
1786 if (need_longlong && (flags & LONGDBL))
1787 *ARG (LONGLONG int *) = num.q;
1788 else if (need_long && (flags & LONG))
1789 *ARG (long int *) = num.l;
1790 else if (flags & SHORT)
1791 *ARG (short int *) = (short int) num.l;
1792 else if (!(flags & CHAR))
1793 *ARG (int *) = (int) num.l;
1794 else
1795 *ARG (signed char *) = (signed char) num.ul;
1797 else
1799 if (need_longlong && (flags & LONGDBL))
1800 *ARG (unsigned LONGLONG int *) = num.uq;
1801 else if (need_long && (flags & LONG))
1802 *ARG (unsigned long int *) = num.ul;
1803 else if (flags & SHORT)
1804 *ARG (unsigned short int *)
1805 = (unsigned short int) num.ul;
1806 else if (!(flags & CHAR))
1807 *ARG (unsigned int *) = (unsigned int) num.ul;
1808 else
1809 *ARG (unsigned char *) = (unsigned char) num.ul;
1811 ++done;
1813 break;
1815 case L_('e'): /* Floating-point numbers. */
1816 case L_('E'):
1817 case L_('f'):
1818 case L_('F'):
1819 case L_('g'):
1820 case L_('G'):
1821 case L_('a'):
1822 case L_('A'):
1823 c = inchar ();
1824 if (width > 0)
1825 --width;
1826 if (__glibc_unlikely (c == EOF))
1827 input_error ();
1829 got_digit = got_dot = got_e = 0;
1831 /* Check for a sign. */
1832 if (c == L_('-') || c == L_('+'))
1834 negative = c == L_('-');
1835 if (__glibc_unlikely (width == 0 || inchar () == EOF))
1836 /* EOF is only an input error before we read any chars. */
1837 conv_error ();
1838 if (width > 0)
1839 --width;
1841 else
1842 negative = 0;
1844 /* Take care for the special arguments "nan" and "inf". */
1845 if (TOLOWER (c) == L_('n'))
1847 /* Maybe "nan". */
1848 ADDW (c);
1849 if (__builtin_expect (width == 0
1850 || inchar () == EOF
1851 || TOLOWER (c) != L_('a'), 0))
1852 conv_error ();
1853 if (width > 0)
1854 --width;
1855 ADDW (c);
1856 if (__builtin_expect (width == 0
1857 || inchar () == EOF
1858 || TOLOWER (c) != L_('n'), 0))
1859 conv_error ();
1860 if (width > 0)
1861 --width;
1862 ADDW (c);
1863 /* It is "nan". */
1864 goto scan_float;
1866 else if (TOLOWER (c) == L_('i'))
1868 /* Maybe "inf" or "infinity". */
1869 ADDW (c);
1870 if (__builtin_expect (width == 0
1871 || inchar () == EOF
1872 || TOLOWER (c) != L_('n'), 0))
1873 conv_error ();
1874 if (width > 0)
1875 --width;
1876 ADDW (c);
1877 if (__builtin_expect (width == 0
1878 || inchar () == EOF
1879 || TOLOWER (c) != L_('f'), 0))
1880 conv_error ();
1881 if (width > 0)
1882 --width;
1883 ADDW (c);
1884 /* It is as least "inf". */
1885 if (width != 0 && inchar () != EOF)
1887 if (TOLOWER (c) == L_('i'))
1889 if (width > 0)
1890 --width;
1891 /* Now we have to read the rest as well. */
1892 ADDW (c);
1893 if (__builtin_expect (width == 0
1894 || inchar () == EOF
1895 || TOLOWER (c) != L_('n'), 0))
1896 conv_error ();
1897 if (width > 0)
1898 --width;
1899 ADDW (c);
1900 if (__builtin_expect (width == 0
1901 || inchar () == EOF
1902 || TOLOWER (c) != L_('i'), 0))
1903 conv_error ();
1904 if (width > 0)
1905 --width;
1906 ADDW (c);
1907 if (__builtin_expect (width == 0
1908 || inchar () == EOF
1909 || TOLOWER (c) != L_('t'), 0))
1910 conv_error ();
1911 if (width > 0)
1912 --width;
1913 ADDW (c);
1914 if (__builtin_expect (width == 0
1915 || inchar () == EOF
1916 || TOLOWER (c) != L_('y'), 0))
1917 conv_error ();
1918 if (width > 0)
1919 --width;
1920 ADDW (c);
1922 else
1923 /* Never mind. */
1924 ungetc (c, stream);
1926 goto scan_float;
1929 exp_char = L_('e');
1930 if (width != 0 && c == L_('0'))
1932 ADDW (c);
1933 c = inchar ();
1934 if (width > 0)
1935 --width;
1936 if (width != 0 && TOLOWER (c) == L_('x'))
1938 /* It is a number in hexadecimal format. */
1939 ADDW (c);
1941 flags |= HEXA_FLOAT;
1942 exp_char = L_('p');
1944 /* Grouping is not allowed. */
1945 flags &= ~GROUP;
1946 c = inchar ();
1947 if (width > 0)
1948 --width;
1950 else
1951 got_digit = 1;
1954 while (1)
1956 if (ISDIGIT (c))
1958 ADDW (c);
1959 got_digit = 1;
1961 else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c))
1963 ADDW (c);
1964 got_digit = 1;
1966 else if (got_e && wp[wpsize - 1] == exp_char
1967 && (c == L_('-') || c == L_('+')))
1968 ADDW (c);
1969 else if (got_digit && !got_e
1970 && (CHAR_T) TOLOWER (c) == exp_char)
1972 ADDW (exp_char);
1973 got_e = got_dot = 1;
1975 else
1977 #ifdef COMPILE_WSCANF
1978 if (! got_dot && c == decimal)
1980 ADDW (c);
1981 got_dot = 1;
1983 else if ((flags & GROUP) != 0 && ! got_dot && c == thousands)
1984 ADDW (c);
1985 else
1987 /* The last read character is not part of the number
1988 anymore. */
1989 ungetc (c, stream);
1990 break;
1992 #else
1993 const char *cmpp = decimal;
1994 int avail = width > 0 ? width : INT_MAX;
1996 if (! got_dot)
1998 while ((unsigned char) *cmpp == c && avail >= 0)
1999 if (*++cmpp == '\0')
2000 break;
2001 else
2003 if (avail == 0 || inchar () == EOF)
2004 break;
2005 --avail;
2009 if (*cmpp == '\0')
2011 /* Add all the characters. */
2012 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
2013 ADDW ((unsigned char) *cmpp);
2014 if (width > 0)
2015 width = avail;
2016 got_dot = 1;
2018 else
2020 /* Figure out whether it is a thousands separator.
2021 There is one problem: we possibly read more than
2022 one character. We cannot push them back but since
2023 we know that parts of the `decimal' string matched,
2024 we can compare against it. */
2025 const char *cmp2p = thousands;
2027 if ((flags & GROUP) != 0 && ! got_dot)
2029 while (cmp2p - thousands < cmpp - decimal
2030 && *cmp2p == decimal[cmp2p - thousands])
2031 ++cmp2p;
2032 if (cmp2p - thousands == cmpp - decimal)
2034 while ((unsigned char) *cmp2p == c && avail >= 0)
2035 if (*++cmp2p == '\0')
2036 break;
2037 else
2039 if (avail == 0 || inchar () == EOF)
2040 break;
2041 --avail;
2046 if (cmp2p != NULL && *cmp2p == '\0')
2048 /* Add all the characters. */
2049 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
2050 ADDW ((unsigned char) *cmpp);
2051 if (width > 0)
2052 width = avail;
2054 else
2056 /* The last read character is not part of the number
2057 anymore. */
2058 ungetc (c, stream);
2059 break;
2062 #endif
2065 if (width == 0 || inchar () == EOF)
2066 break;
2068 if (width > 0)
2069 --width;
2072 wctrans_t map;
2073 if (__builtin_expect ((flags & I18N) != 0, 0)
2074 /* Hexadecimal floats make no sense, fixing localized
2075 digits with ASCII letters. */
2076 && !(flags & HEXA_FLOAT)
2077 /* Minimum requirement. */
2078 && (wpsize == 0 || got_dot)
2079 && (map = __wctrans ("to_inpunct")) != NULL)
2081 /* Reget the first character. */
2082 inchar ();
2084 /* Localized digits, decimal points, and thousands
2085 separator. */
2086 wint_t wcdigits[12];
2088 /* First get decimal equivalent to check if we read it
2089 or not. */
2090 wcdigits[11] = __towctrans (L'.', map);
2092 /* If we have not read any character or have just read
2093 locale decimal point which matches the decimal point
2094 for localized FP numbers, then we may have localized
2095 digits. Note, we test GOT_DOT above. */
2096 #ifdef COMPILE_WSCANF
2097 if (wpsize == 0 || (wpsize == 1 && wcdigits[11] == decimal))
2098 #else
2099 char mbdigits[12][MB_LEN_MAX + 1];
2101 mbstate_t dstate;
2102 memset (&dstate, '\0', sizeof (dstate));
2104 bool match_so_far = wpsize == 0;
2105 size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &dstate);
2106 if (mblen != (size_t) -1)
2108 mbdigits[11][mblen] = '\0';
2109 match_so_far |= (wpsize == strlen (decimal)
2110 && strcmp (decimal, mbdigits[11]) == 0);
2112 else
2114 size_t decimal_len = strlen (decimal);
2115 /* This should always be the case but the data comes
2116 from a file. */
2117 if (decimal_len <= MB_LEN_MAX)
2119 match_so_far |= wpsize == decimal_len;
2120 memcpy (mbdigits[11], decimal, decimal_len + 1);
2122 else
2123 match_so_far = false;
2126 if (match_so_far)
2127 #endif
2129 bool have_locthousands = (flags & GROUP) != 0;
2131 /* Now get the digits and the thousands-sep equivalents. */
2132 for (int n = 0; n < 11; ++n)
2134 if (n < 10)
2135 wcdigits[n] = __towctrans (L'0' + n, map);
2136 else if (n == 10)
2138 wcdigits[10] = __towctrans (L',', map);
2139 have_locthousands &= wcdigits[10] != L'\0';
2142 #ifndef COMPILE_WSCANF
2143 memset (&state, '\0', sizeof (state));
2145 mblen = __wcrtomb (mbdigits[n], wcdigits[n], &state);
2146 if (mblen == (size_t) -1)
2148 if (n == 10)
2150 if (have_locthousands)
2152 size_t thousands_len = strlen (thousands);
2153 if (thousands_len <= MB_LEN_MAX)
2154 memcpy (mbdigits[10], thousands,
2155 thousands_len + 1);
2156 else
2157 have_locthousands = false;
2160 else
2161 /* Ignore checking against localized digits. */
2162 goto no_i18nflt;
2164 else
2165 mbdigits[n][mblen] = '\0';
2166 #endif
2169 /* Start checking against localized digits, if
2170 conversion is done correctly. */
2171 while (1)
2173 if (got_e && wp[wpsize - 1] == exp_char
2174 && (c == L_('-') || c == L_('+')))
2175 ADDW (c);
2176 else if (wpsize > 0 && !got_e
2177 && (CHAR_T) TOLOWER (c) == exp_char)
2179 ADDW (exp_char);
2180 got_e = got_dot = 1;
2182 else
2184 /* Check against localized digits, decimal point,
2185 and thousands separator. */
2186 int n;
2187 for (n = 0; n < 12; ++n)
2189 #ifdef COMPILE_WSCANF
2190 if (c == wcdigits[n])
2192 if (n < 10)
2193 ADDW (L_('0') + n);
2194 else if (n == 11 && !got_dot)
2196 ADDW (decimal);
2197 got_dot = 1;
2199 else if (n == 10 && have_locthousands
2200 && ! got_dot)
2201 ADDW (thousands);
2202 else
2203 /* The last read character is not part
2204 of the number anymore. */
2205 n = 12;
2207 break;
2209 #else
2210 const char *cmpp = mbdigits[n];
2211 int avail = width > 0 ? width : INT_MAX;
2213 while ((unsigned char) *cmpp == c && avail >= 0)
2214 if (*++cmpp == '\0')
2215 break;
2216 else
2218 if (avail == 0 || inchar () == EOF)
2219 break;
2220 --avail;
2222 if (*cmpp == '\0')
2224 if (width > 0)
2225 width = avail;
2227 if (n < 10)
2228 ADDW (L_('0') + n);
2229 else if (n == 11 && !got_dot)
2231 /* Add all the characters. */
2232 for (cmpp = decimal; *cmpp != '\0';
2233 ++cmpp)
2234 ADDW ((unsigned char) *cmpp);
2236 got_dot = 1;
2238 else if (n == 10 && (flags & GROUP) != 0
2239 && ! got_dot)
2241 /* Add all the characters. */
2242 for (cmpp = thousands; *cmpp != '\0';
2243 ++cmpp)
2244 ADDW ((unsigned char) *cmpp);
2246 else
2247 /* The last read character is not part
2248 of the number anymore. */
2249 n = 12;
2251 break;
2254 /* We are pushing all read characters back. */
2255 if (cmpp > mbdigits[n])
2257 ungetc (c, stream);
2258 while (--cmpp > mbdigits[n])
2259 ungetc_not_eof ((unsigned char) *cmpp,
2260 stream);
2261 c = (unsigned char) *cmpp;
2263 #endif
2266 if (n >= 12)
2268 /* The last read character is not part
2269 of the number anymore. */
2270 ungetc (c, stream);
2271 break;
2275 if (width == 0 || inchar () == EOF)
2276 break;
2278 if (width > 0)
2279 --width;
2283 #ifndef COMPILE_WSCANF
2284 no_i18nflt:
2286 #endif
2289 /* Have we read any character? If we try to read a number
2290 in hexadecimal notation and we have read only the `0x'
2291 prefix this is an error. */
2292 if (__builtin_expect (wpsize == 0
2293 || ((flags & HEXA_FLOAT) && wpsize == 2), 0))
2294 conv_error ();
2296 scan_float:
2297 /* Convert the number. */
2298 ADDW (L_('\0'));
2299 if ((flags & LONGDBL) && !__ldbl_is_dbl)
2301 long double d = __strtold_internal (wp, &tw, flags & GROUP);
2302 if (!(flags & SUPPRESS) && tw != wp)
2303 *ARG (long double *) = negative ? -d : d;
2305 else if (flags & (LONG | LONGDBL))
2307 double d = __strtod_internal (wp, &tw, flags & GROUP);
2308 if (!(flags & SUPPRESS) && tw != wp)
2309 *ARG (double *) = negative ? -d : d;
2311 else
2313 float d = __strtof_internal (wp, &tw, flags & GROUP);
2314 if (!(flags & SUPPRESS) && tw != wp)
2315 *ARG (float *) = negative ? -d : d;
2318 if (__glibc_unlikely (tw == wp))
2319 conv_error ();
2321 if (!(flags & SUPPRESS))
2322 ++done;
2323 break;
2325 case L_('['): /* Character class. */
2326 if (flags & LONG)
2327 STRING_ARG (wstr, wchar_t, 100);
2328 else
2329 STRING_ARG (str, char, 100);
2331 if (*f == L_('^'))
2333 ++f;
2334 not_in = 1;
2336 else
2337 not_in = 0;
2339 if (width < 0)
2340 /* There is no width given so there is also no limit on the
2341 number of characters we read. Therefore we set width to
2342 a very high value to make the algorithm easier. */
2343 width = INT_MAX;
2345 #ifdef COMPILE_WSCANF
2346 /* Find the beginning and the end of the scanlist. We are not
2347 creating a lookup table since it would have to be too large.
2348 Instead we search each time through the string. This is not
2349 a constant lookup time but who uses this feature deserves to
2350 be punished. */
2351 tw = (wchar_t *) f; /* Marks the beginning. */
2353 if (*f == L']')
2354 ++f;
2356 while ((fc = *f++) != L'\0' && fc != L']');
2358 if (__glibc_unlikely (fc == L'\0'))
2359 conv_error ();
2360 wchar_t *twend = (wchar_t *) f - 1;
2361 #else
2362 /* Fill WP with byte flags indexed by character.
2363 We will use this flag map for matching input characters. */
2364 if (wpmax < UCHAR_MAX + 1)
2366 wpmax = UCHAR_MAX + 1;
2367 wp = (char *) alloca (wpmax);
2369 memset (wp, '\0', UCHAR_MAX + 1);
2371 fc = *f;
2372 if (fc == ']' || fc == '-')
2374 /* If ] or - appears before any char in the set, it is not
2375 the terminator or separator, but the first char in the
2376 set. */
2377 wp[fc] = 1;
2378 ++f;
2381 while ((fc = *f++) != '\0' && fc != ']')
2382 if (fc == '-' && *f != '\0' && *f != ']'
2383 && (unsigned char) f[-2] <= (unsigned char) *f)
2385 /* Add all characters from the one before the '-'
2386 up to (but not including) the next format char. */
2387 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
2388 wp[fc] = 1;
2390 else
2391 /* Add the character to the flag map. */
2392 wp[fc] = 1;
2394 if (__glibc_unlikely (fc == '\0'))
2395 conv_error();
2396 #endif
2398 if (flags & LONG)
2400 size_t now = read_in;
2401 #ifdef COMPILE_WSCANF
2402 if (__glibc_unlikely (inchar () == WEOF))
2403 input_error ();
2407 wchar_t *runp;
2409 /* Test whether it's in the scanlist. */
2410 runp = tw;
2411 while (runp < twend)
2413 if (runp[0] == L'-' && runp[1] != '\0'
2414 && runp + 1 != twend
2415 && runp != tw
2416 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2418 /* Match against all characters in between the
2419 first and last character of the sequence. */
2420 wchar_t wc;
2422 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2423 if ((wint_t) wc == c)
2424 break;
2426 if (wc <= runp[1] && !not_in)
2427 break;
2428 if (wc <= runp[1] && not_in)
2430 /* The current character is not in the
2431 scanset. */
2432 ungetc (c, stream);
2433 goto out;
2436 runp += 2;
2438 else
2440 if ((wint_t) *runp == c && !not_in)
2441 break;
2442 if ((wint_t) *runp == c && not_in)
2444 ungetc (c, stream);
2445 goto out;
2448 ++runp;
2452 if (runp == twend && !not_in)
2454 ungetc (c, stream);
2455 goto out;
2458 if (!(flags & SUPPRESS))
2460 *wstr++ = c;
2462 if ((flags & MALLOC)
2463 && wstr == (wchar_t *) *strptr + strsize)
2465 /* Enlarge the buffer. */
2466 wstr = (wchar_t *) realloc (*strptr,
2467 (2 * strsize)
2468 * sizeof (wchar_t));
2469 if (wstr == NULL)
2471 /* Can't allocate that much. Last-ditch
2472 effort. */
2473 wstr = (wchar_t *)
2474 realloc (*strptr, (strsize + 1)
2475 * sizeof (wchar_t));
2476 if (wstr == NULL)
2478 if (flags & POSIX_MALLOC)
2480 done = EOF;
2481 goto errout;
2483 /* We lose. Oh well. Terminate the string
2484 and stop converting, so at least we don't
2485 skip any input. */
2486 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2487 strptr = NULL;
2488 ++done;
2489 conv_error ();
2491 else
2493 *strptr = (char *) wstr;
2494 wstr += strsize;
2495 ++strsize;
2498 else
2500 *strptr = (char *) wstr;
2501 wstr += strsize;
2502 strsize *= 2;
2507 while (--width > 0 && inchar () != WEOF);
2508 out:
2509 #else
2510 char buf[MB_LEN_MAX];
2511 size_t cnt = 0;
2512 mbstate_t cstate;
2514 if (__glibc_unlikely (inchar () == EOF))
2515 input_error ();
2517 memset (&cstate, '\0', sizeof (cstate));
2521 if (wp[c] == not_in)
2523 ungetc_not_eof (c, stream);
2524 break;
2527 /* This is easy. */
2528 if (!(flags & SUPPRESS))
2530 size_t n;
2532 /* Convert it into a wide character. */
2533 buf[0] = c;
2534 n = __mbrtowc (wstr, buf, 1, &cstate);
2536 if (n == (size_t) -2)
2538 /* Possibly correct character, just not enough
2539 input. */
2540 ++cnt;
2541 assert (cnt < MB_CUR_MAX);
2542 continue;
2544 cnt = 0;
2546 ++wstr;
2547 if ((flags & MALLOC)
2548 && wstr == (wchar_t *) *strptr + strsize)
2550 /* Enlarge the buffer. */
2551 wstr = (wchar_t *) realloc (*strptr,
2552 (2 * strsize
2553 * sizeof (wchar_t)));
2554 if (wstr == NULL)
2556 /* Can't allocate that much. Last-ditch
2557 effort. */
2558 wstr = (wchar_t *)
2559 realloc (*strptr, ((strsize + 1)
2560 * sizeof (wchar_t)));
2561 if (wstr == NULL)
2563 if (flags & POSIX_MALLOC)
2565 done = EOF;
2566 goto errout;
2568 /* We lose. Oh well. Terminate the
2569 string and stop converting,
2570 so at least we don't skip any input. */
2571 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2572 strptr = NULL;
2573 ++done;
2574 conv_error ();
2576 else
2578 *strptr = (char *) wstr;
2579 wstr += strsize;
2580 ++strsize;
2583 else
2585 *strptr = (char *) wstr;
2586 wstr += strsize;
2587 strsize *= 2;
2592 if (--width <= 0)
2593 break;
2595 while (inchar () != EOF);
2597 if (__glibc_unlikely (cnt != 0))
2598 /* We stopped in the middle of recognizing another
2599 character. That's a problem. */
2600 encode_error ();
2601 #endif
2603 if (__glibc_unlikely (now == read_in))
2604 /* We haven't succesfully read any character. */
2605 conv_error ();
2607 if (!(flags & SUPPRESS))
2609 *wstr++ = L'\0';
2611 if ((flags & MALLOC)
2612 && wstr - (wchar_t *) *strptr != strsize)
2614 wchar_t *cp = (wchar_t *)
2615 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2616 * sizeof(wchar_t)));
2617 if (cp != NULL)
2618 *strptr = (char *) cp;
2620 strptr = NULL;
2622 ++done;
2625 else
2627 size_t now = read_in;
2629 if (__glibc_unlikely (inchar () == EOF))
2630 input_error ();
2632 #ifdef COMPILE_WSCANF
2634 memset (&state, '\0', sizeof (state));
2638 wchar_t *runp;
2639 size_t n;
2641 /* Test whether it's in the scanlist. */
2642 runp = tw;
2643 while (runp < twend)
2645 if (runp[0] == L'-' && runp[1] != '\0'
2646 && runp + 1 != twend
2647 && runp != tw
2648 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2650 /* Match against all characters in between the
2651 first and last character of the sequence. */
2652 wchar_t wc;
2654 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2655 if ((wint_t) wc == c)
2656 break;
2658 if (wc <= runp[1] && !not_in)
2659 break;
2660 if (wc <= runp[1] && not_in)
2662 /* The current character is not in the
2663 scanset. */
2664 ungetc (c, stream);
2665 goto out2;
2668 runp += 2;
2670 else
2672 if ((wint_t) *runp == c && !not_in)
2673 break;
2674 if ((wint_t) *runp == c && not_in)
2676 ungetc (c, stream);
2677 goto out2;
2680 ++runp;
2684 if (runp == twend && !not_in)
2686 ungetc (c, stream);
2687 goto out2;
2690 if (!(flags & SUPPRESS))
2692 if ((flags & MALLOC)
2693 && str + MB_CUR_MAX >= *strptr + strsize)
2695 /* Enlarge the buffer. */
2696 size_t strleng = str - *strptr;
2697 char *newstr;
2699 newstr = (char *) realloc (*strptr, 2 * strsize);
2700 if (newstr == NULL)
2702 /* Can't allocate that much. Last-ditch
2703 effort. */
2704 newstr = (char *) realloc (*strptr,
2705 strleng + MB_CUR_MAX);
2706 if (newstr == NULL)
2708 if (flags & POSIX_MALLOC)
2710 done = EOF;
2711 goto errout;
2713 /* We lose. Oh well. Terminate the string
2714 and stop converting, so at least we don't
2715 skip any input. */
2716 ((char *) (*strptr))[strleng] = '\0';
2717 strptr = NULL;
2718 ++done;
2719 conv_error ();
2721 else
2723 *strptr = newstr;
2724 str = newstr + strleng;
2725 strsize = strleng + MB_CUR_MAX;
2728 else
2730 *strptr = newstr;
2731 str = newstr + strleng;
2732 strsize *= 2;
2737 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2738 if (__glibc_unlikely (n == (size_t) -1))
2739 encode_error ();
2741 assert (n <= MB_CUR_MAX);
2742 str += n;
2744 while (--width > 0 && inchar () != WEOF);
2745 out2:
2746 #else
2749 if (wp[c] == not_in)
2751 ungetc_not_eof (c, stream);
2752 break;
2755 /* This is easy. */
2756 if (!(flags & SUPPRESS))
2758 *str++ = c;
2759 if ((flags & MALLOC)
2760 && (char *) str == *strptr + strsize)
2762 /* Enlarge the buffer. */
2763 size_t newsize = 2 * strsize;
2765 allocagain:
2766 str = (char *) realloc (*strptr, newsize);
2767 if (str == NULL)
2769 /* Can't allocate that much. Last-ditch
2770 effort. */
2771 if (newsize > strsize + 1)
2773 newsize = strsize + 1;
2774 goto allocagain;
2776 if (flags & POSIX_MALLOC)
2778 done = EOF;
2779 goto errout;
2781 /* We lose. Oh well. Terminate the
2782 string and stop converting,
2783 so at least we don't skip any input. */
2784 ((char *) (*strptr))[strsize - 1] = '\0';
2785 strptr = NULL;
2786 ++done;
2787 conv_error ();
2789 else
2791 *strptr = (char *) str;
2792 str += strsize;
2793 strsize = newsize;
2798 while (--width > 0 && inchar () != EOF);
2799 #endif
2801 if (__glibc_unlikely (now == read_in))
2802 /* We haven't succesfully read any character. */
2803 conv_error ();
2805 if (!(flags & SUPPRESS))
2807 #ifdef COMPILE_WSCANF
2808 /* We have to emit the code to get into the initial
2809 state. */
2810 char buf[MB_LEN_MAX];
2811 size_t n = __wcrtomb (buf, L'\0', &state);
2812 if (n > 0 && (flags & MALLOC)
2813 && str + n >= *strptr + strsize)
2815 /* Enlarge the buffer. */
2816 size_t strleng = str - *strptr;
2817 char *newstr;
2819 newstr = (char *) realloc (*strptr, strleng + n + 1);
2820 if (newstr == NULL)
2822 if (flags & POSIX_MALLOC)
2824 done = EOF;
2825 goto errout;
2827 /* We lose. Oh well. Terminate the string
2828 and stop converting, so at least we don't
2829 skip any input. */
2830 ((char *) (*strptr))[strleng] = '\0';
2831 strptr = NULL;
2832 ++done;
2833 conv_error ();
2835 else
2837 *strptr = newstr;
2838 str = newstr + strleng;
2839 strsize = strleng + n + 1;
2843 str = __mempcpy (str, buf, n);
2844 #endif
2845 *str++ = '\0';
2847 if ((flags & MALLOC) && str - *strptr != strsize)
2849 char *cp = (char *) realloc (*strptr, str - *strptr);
2850 if (cp != NULL)
2851 *strptr = cp;
2853 strptr = NULL;
2855 ++done;
2858 break;
2860 case L_('p'): /* Generic pointer. */
2861 base = 16;
2862 /* A PTR must be the same size as a `long int'. */
2863 flags &= ~(SHORT|LONGDBL);
2864 if (need_long)
2865 flags |= LONG;
2866 flags |= READ_POINTER;
2867 goto number;
2869 default:
2870 /* If this is an unknown format character punt. */
2871 conv_error ();
2875 /* The last thing we saw int the format string was a white space.
2876 Consume the last white spaces. */
2877 if (skip_space)
2880 c = inchar ();
2881 while (ISSPACE (c));
2882 ungetc (c, stream);
2885 errout:
2886 /* Unlock stream. */
2887 UNLOCK_STREAM (stream);
2889 if (use_malloc)
2890 free (wp);
2892 if (errp != NULL)
2893 *errp |= errval;
2895 if (__glibc_unlikely (done == EOF))
2897 if (__glibc_unlikely (ptrs_to_free != NULL))
2899 struct ptrs_to_free *p = ptrs_to_free;
2900 while (p != NULL)
2902 for (size_t cnt = 0; cnt < p->count; ++cnt)
2904 free (*p->ptrs[cnt]);
2905 *p->ptrs[cnt] = NULL;
2907 p = p->next;
2908 ptrs_to_free = p;
2912 else if (__glibc_unlikely (strptr != NULL))
2914 free (*strptr);
2915 *strptr = NULL;
2917 return done;
2920 #ifdef COMPILE_WSCANF
2922 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2924 return _IO_vfwscanf (s, format, argptr, NULL);
2926 ldbl_weak_alias (__vfwscanf, vfwscanf)
2927 #else
2929 ___vfscanf (FILE *s, const char *format, va_list argptr)
2931 return _IO_vfscanf_internal (s, format, argptr, NULL);
2933 ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
2934 ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf)
2935 ldbl_strong_alias (___vfscanf, __vfscanf)
2936 ldbl_hidden_def (___vfscanf, __vfscanf)
2937 ldbl_weak_alias (___vfscanf, vfscanf)
2938 #endif