arm: Implement memchr ifunc selection in C
[glibc.git] / stdio-common / vfscanf.c
blob7d9d17bd84f105fa160eaa2377ae0bd24dba0963
1 /* Copyright (C) 1991-2017 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 <libc-diag.h>
31 #include <libc-lock.h>
32 #include <locale/localeinfo.h>
33 #include <scratch_buffer.h>
35 #ifdef __GNUC__
36 # define HAVE_LONGLONG
37 # define LONGLONG long long
38 #else
39 # define LONGLONG long
40 #endif
42 /* Determine whether we have to handle `long long' at all. */
43 #if LONG_MAX == LONG_LONG_MAX
44 # define need_longlong 0
45 #else
46 # define need_longlong 1
47 #endif
49 /* Determine whether we have to handle `long'. */
50 #if INT_MAX == LONG_MAX
51 # define need_long 0
52 #else
53 # define need_long 1
54 #endif
56 /* Those are flags in the conversion format. */
57 #define LONG 0x0001 /* l: long or double */
58 #define LONGDBL 0x0002 /* L: long long or long double */
59 #define SHORT 0x0004 /* h: short */
60 #define SUPPRESS 0x0008 /* *: suppress assignment */
61 #define POINTER 0x0010 /* weird %p pointer (`fake hex') */
62 #define NOSKIP 0x0020 /* do not skip blanks */
63 #define NUMBER_SIGNED 0x0040 /* signed integer */
64 #define GROUP 0x0080 /* ': group numbers */
65 #define GNU_MALLOC 0x0100 /* a: malloc strings */
66 #define CHAR 0x0200 /* hh: char */
67 #define I18N 0x0400 /* I: use locale's digits */
68 #define HEXA_FLOAT 0x0800 /* hexadecimal float */
69 #define READ_POINTER 0x1000 /* this is a pointer value */
70 #define POSIX_MALLOC 0x2000 /* m: malloc strings */
71 #define MALLOC (GNU_MALLOC | POSIX_MALLOC)
73 #include <locale/localeinfo.h>
74 #include <libioP.h>
75 #include <libio.h>
77 #undef va_list
78 #define va_list _IO_va_list
80 #ifdef COMPILE_WSCANF
81 # define ungetc(c, s) ((void) (c == WEOF \
82 || (--read_in, \
83 _IO_sputbackwc (s, c))))
84 # define ungetc_not_eof(c, s) ((void) (--read_in, \
85 _IO_sputbackwc (s, c)))
86 # define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
87 : ((c = _IO_getwc_unlocked (s)), \
88 (void) (c != WEOF \
89 ? ++read_in \
90 : (size_t) (inchar_errno = errno)), c))
92 # define ISSPACE(Ch) iswspace (Ch)
93 # define ISDIGIT(Ch) iswdigit (Ch)
94 # define ISXDIGIT(Ch) iswxdigit (Ch)
95 # define TOLOWER(Ch) towlower (Ch)
96 # define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
97 # define __strtoll_internal __wcstoll_internal
98 # define __strtoull_internal __wcstoull_internal
99 # define __strtol_internal __wcstol_internal
100 # define __strtoul_internal __wcstoul_internal
101 # define __strtold_internal __wcstold_internal
102 # define __strtod_internal __wcstod_internal
103 # define __strtof_internal __wcstof_internal
105 # define L_(Str) L##Str
106 # define CHAR_T wchar_t
107 # define UCHAR_T unsigned int
108 # define WINT_T wint_t
109 # undef EOF
110 # define EOF WEOF
111 #else
112 # define ungetc(c, s) ((void) ((int) c == EOF \
113 || (--read_in, \
114 _IO_sputbackc (s, (unsigned char) c))))
115 # define ungetc_not_eof(c, s) ((void) (--read_in, \
116 _IO_sputbackc (s, (unsigned char) c)))
117 # define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
118 : ((c = _IO_getc_unlocked (s)), \
119 (void) (c != EOF \
120 ? ++read_in \
121 : (size_t) (inchar_errno = errno)), c))
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 (s) == 0 \
127 && _IO_fwide (s, -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 #include "printf-parse.h" /* Use read_int. */
138 #define encode_error() do { \
139 errval = 4; \
140 __set_errno (EILSEQ); \
141 goto errout; \
142 } while (0)
143 #define conv_error() do { \
144 errval = 2; \
145 goto errout; \
146 } while (0)
147 #define input_error() do { \
148 errval = 1; \
149 if (done == 0) done = EOF; \
150 goto errout; \
151 } while (0)
152 #define add_ptr_to_free(ptr) \
153 do \
155 if (ptrs_to_free == NULL \
156 || ptrs_to_free->count == (sizeof (ptrs_to_free->ptrs) \
157 / sizeof (ptrs_to_free->ptrs[0]))) \
159 struct ptrs_to_free *new_ptrs = alloca (sizeof (*ptrs_to_free)); \
160 new_ptrs->count = 0; \
161 new_ptrs->next = ptrs_to_free; \
162 ptrs_to_free = new_ptrs; \
164 ptrs_to_free->ptrs[ptrs_to_free->count++] = (ptr); \
166 while (0)
167 #define ARGCHECK(s, format) \
168 do \
170 /* Check file argument for consistence. */ \
171 CHECK_FILE (s, EOF); \
172 if (s->_flags & _IO_NO_READS) \
174 __set_errno (EBADF); \
175 return EOF; \
177 else if (format == NULL) \
179 MAYBE_SET_EINVAL; \
180 return EOF; \
182 } while (0)
183 #define LOCK_STREAM(S) \
184 __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
185 _IO_flockfile (S)
186 #define UNLOCK_STREAM(S) \
187 _IO_funlockfile (S); \
188 __libc_cleanup_region_end (0)
190 struct ptrs_to_free
192 size_t count;
193 struct ptrs_to_free *next;
194 char **ptrs[32];
197 struct char_buffer {
198 CHAR_T *current;
199 CHAR_T *end;
200 struct scratch_buffer scratch;
203 /* Returns a pointer to the first CHAR_T object in the buffer. Only
204 valid if char_buffer_add (BUFFER, CH) has been called and
205 char_buffer_error (BUFFER) is false. */
206 static inline CHAR_T *
207 char_buffer_start (const struct char_buffer *buffer)
209 return (CHAR_T *) buffer->scratch.data;
212 /* Returns the number of CHAR_T objects in the buffer. Only valid if
213 char_buffer_error (BUFFER) is false. */
214 static inline size_t
215 char_buffer_size (const struct char_buffer *buffer)
217 return buffer->current - char_buffer_start (buffer);
220 /* Reinitializes BUFFER->current and BUFFER->end to cover the entire
221 scratch buffer. */
222 static inline void
223 char_buffer_rewind (struct char_buffer *buffer)
225 buffer->current = char_buffer_start (buffer);
226 buffer->end = buffer->current + buffer->scratch.length / sizeof (CHAR_T);
229 /* Returns true if a previous call to char_buffer_add (BUFFER, CH)
230 failed. */
231 static inline bool
232 char_buffer_error (const struct char_buffer *buffer)
234 return __glibc_unlikely (buffer->current == NULL);
237 /* Slow path for char_buffer_add. */
238 static void
239 char_buffer_add_slow (struct char_buffer *buffer, CHAR_T ch)
241 if (char_buffer_error (buffer))
242 return;
243 size_t offset = buffer->end - (CHAR_T *) buffer->scratch.data;
244 if (!scratch_buffer_grow_preserve (&buffer->scratch))
246 buffer->current = NULL;
247 buffer->end = NULL;
248 return;
250 char_buffer_rewind (buffer);
251 buffer->current += offset;
252 *buffer->current++ = ch;
255 /* Adds CH to BUFFER. This function does not report any errors, check
256 for them with char_buffer_error. */
257 static inline void
258 char_buffer_add (struct char_buffer *buffer, CHAR_T ch)
259 __attribute__ ((always_inline));
260 static inline void
261 char_buffer_add (struct char_buffer *buffer, CHAR_T ch)
263 if (__glibc_unlikely (buffer->current == buffer->end))
264 char_buffer_add_slow (buffer, ch);
265 else
266 *buffer->current++ = ch;
269 /* Read formatted input from S according to the format string
270 FORMAT, using the argument list in ARG.
271 Return the number of assignments made, or -1 for an input error. */
272 #ifdef COMPILE_WSCANF
274 _IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr,
275 int *errp)
276 #else
278 _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
279 int *errp)
280 #endif
282 va_list arg;
283 const CHAR_T *f = format;
284 UCHAR_T fc; /* Current character of the format. */
285 WINT_T done = 0; /* Assignments done. */
286 size_t read_in = 0; /* Chars read in. */
287 WINT_T c = 0; /* Last char read. */
288 int width; /* Maximum field width. */
289 int flags; /* Modifiers for current format element. */
290 int errval = 0;
291 #ifndef COMPILE_WSCANF
292 locale_t loc = _NL_CURRENT_LOCALE;
293 struct __locale_data *const curctype = loc->__locales[LC_CTYPE];
294 #endif
296 /* Errno of last failed inchar call. */
297 int inchar_errno = 0;
298 /* Status for reading F-P nums. */
299 char got_digit, got_dot, got_e, negative;
300 /* If a [...] is a [^...]. */
301 CHAR_T not_in;
302 #define exp_char not_in
303 /* Base for integral numbers. */
304 int base;
305 /* Decimal point character. */
306 #ifdef COMPILE_WSCANF
307 wint_t decimal;
308 #else
309 const char *decimal;
310 #endif
311 /* The thousands character of the current locale. */
312 #ifdef COMPILE_WSCANF
313 wint_t thousands;
314 #else
315 const char *thousands;
316 #endif
317 struct ptrs_to_free *ptrs_to_free = NULL;
318 /* State for the conversions. */
319 mbstate_t state;
320 /* Integral holding variables. */
321 union
323 long long int q;
324 unsigned long long int uq;
325 long int l;
326 unsigned long int ul;
327 } num;
328 /* Character-buffer pointer. */
329 char *str = NULL;
330 wchar_t *wstr = NULL;
331 char **strptr = NULL;
332 ssize_t strsize = 0;
333 /* We must not react on white spaces immediately because they can
334 possibly be matched even if in the input stream no character is
335 available anymore. */
336 int skip_space = 0;
337 /* Workspace. */
338 CHAR_T *tw; /* Temporary pointer. */
339 struct char_buffer charbuf;
340 scratch_buffer_init (&charbuf.scratch);
342 #ifdef __va_copy
343 __va_copy (arg, argptr);
344 #else
345 arg = (va_list) argptr;
346 #endif
348 #ifdef ORIENT
349 ORIENT;
350 #endif
352 ARGCHECK (s, format);
355 #ifndef COMPILE_WSCANF
356 struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
357 #endif
359 /* Figure out the decimal point character. */
360 #ifdef COMPILE_WSCANF
361 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
362 #else
363 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
364 #endif
365 /* Figure out the thousands separator character. */
366 #ifdef COMPILE_WSCANF
367 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
368 #else
369 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
370 if (*thousands == '\0')
371 thousands = NULL;
372 #endif
375 /* Lock the stream. */
376 LOCK_STREAM (s);
379 #ifndef COMPILE_WSCANF
380 /* From now on we use `state' to convert the format string. */
381 memset (&state, '\0', sizeof (state));
382 #endif
384 /* Run through the format string. */
385 while (*f != '\0')
387 unsigned int argpos;
388 /* Extract the next argument, which is of type TYPE.
389 For a %N$... spec, this is the Nth argument from the beginning;
390 otherwise it is the next argument after the state now in ARG. */
391 #ifdef __va_copy
392 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
393 ({ unsigned int pos = argpos; \
394 va_list arg; \
395 __va_copy (arg, argptr); \
396 while (--pos > 0) \
397 (void) va_arg (arg, void *); \
398 va_arg (arg, type); \
400 #else
401 # if 0
402 /* XXX Possible optimization. */
403 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
404 ({ va_list arg = (va_list) argptr; \
405 arg = (va_list) ((char *) arg \
406 + (argpos - 1) \
407 * __va_rounded_size (void *)); \
408 va_arg (arg, type); \
410 # else
411 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
412 ({ unsigned int pos = argpos; \
413 va_list arg = (va_list) argptr; \
414 while (--pos > 0) \
415 (void) va_arg (arg, void *); \
416 va_arg (arg, type); \
418 # endif
419 #endif
421 #ifndef COMPILE_WSCANF
422 if (!isascii ((unsigned char) *f))
424 /* Non-ASCII, may be a multibyte. */
425 int len = __mbrlen (f, strlen (f), &state);
426 if (len > 0)
430 c = inchar ();
431 if (__glibc_unlikely (c == EOF))
432 input_error ();
433 else if (c != (unsigned char) *f++)
435 ungetc_not_eof (c, s);
436 conv_error ();
439 while (--len > 0);
440 continue;
443 #endif
445 fc = *f++;
446 if (fc != '%')
448 /* Remember to skip spaces. */
449 if (ISSPACE (fc))
451 skip_space = 1;
452 continue;
455 /* Read a character. */
456 c = inchar ();
458 /* Characters other than format specs must just match. */
459 if (__glibc_unlikely (c == EOF))
460 input_error ();
462 /* We saw white space char as the last character in the format
463 string. Now it's time to skip all leading white space. */
464 if (skip_space)
466 while (ISSPACE (c))
467 if (__glibc_unlikely (inchar () == EOF))
468 input_error ();
469 skip_space = 0;
472 if (__glibc_unlikely (c != fc))
474 ungetc (c, s);
475 conv_error ();
478 continue;
481 /* This is the start of the conversion string. */
482 flags = 0;
484 /* Initialize state of modifiers. */
485 argpos = 0;
487 /* Prepare temporary buffer. */
488 char_buffer_rewind (&charbuf);
490 /* Check for a positional parameter specification. */
491 if (ISDIGIT ((UCHAR_T) *f))
493 argpos = read_int ((const UCHAR_T **) &f);
494 if (*f == L_('$'))
495 ++f;
496 else
498 /* Oops; that was actually the field width. */
499 width = argpos;
500 argpos = 0;
501 goto got_width;
505 /* Check for the assignment-suppressing, the number grouping flag,
506 and the signal to use the locale's digit representation. */
507 while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
508 switch (*f++)
510 case L_('*'):
511 flags |= SUPPRESS;
512 break;
513 case L_('\''):
514 #ifdef COMPILE_WSCANF
515 if (thousands != L'\0')
516 #else
517 if (thousands != NULL)
518 #endif
519 flags |= GROUP;
520 break;
521 case L_('I'):
522 flags |= I18N;
523 break;
526 /* Find the maximum field width. */
527 width = 0;
528 if (ISDIGIT ((UCHAR_T) *f))
529 width = read_int ((const UCHAR_T **) &f);
530 got_width:
531 if (width == 0)
532 width = -1;
534 /* Check for type modifiers. */
535 switch (*f++)
537 case L_('h'):
538 /* ints are short ints or chars. */
539 if (*f == L_('h'))
541 ++f;
542 flags |= CHAR;
544 else
545 flags |= SHORT;
546 break;
547 case L_('l'):
548 if (*f == L_('l'))
550 /* A double `l' is equivalent to an `L'. */
551 ++f;
552 flags |= LONGDBL | LONG;
554 else
555 /* ints are long ints. */
556 flags |= LONG;
557 break;
558 case L_('q'):
559 case L_('L'):
560 /* doubles are long doubles, and ints are long long ints. */
561 flags |= LONGDBL | LONG;
562 break;
563 case L_('a'):
564 /* The `a' is used as a flag only if followed by `s', `S' or
565 `['. */
566 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
568 --f;
569 break;
571 /* In __isoc99_*scanf %as, %aS and %a[ extension is not
572 supported at all. */
573 if (s->_flags2 & _IO_FLAGS2_SCANF_STD)
575 --f;
576 break;
578 /* String conversions (%s, %[) take a `char **'
579 arg and fill it in with a malloc'd pointer. */
580 flags |= GNU_MALLOC;
581 break;
582 case L_('m'):
583 flags |= POSIX_MALLOC;
584 if (*f == L_('l'))
586 ++f;
587 flags |= LONG;
589 break;
590 case L_('z'):
591 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
592 flags |= LONGDBL;
593 else if (sizeof (size_t) > sizeof (unsigned int))
594 flags |= LONG;
595 break;
596 case L_('j'):
597 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
598 flags |= LONGDBL;
599 else if (sizeof (uintmax_t) > sizeof (unsigned int))
600 flags |= LONG;
601 break;
602 case L_('t'):
603 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
604 flags |= LONGDBL;
605 else if (sizeof (ptrdiff_t) > sizeof (int))
606 flags |= LONG;
607 break;
608 default:
609 /* Not a recognized modifier. Backup. */
610 --f;
611 break;
614 /* End of the format string? */
615 if (__glibc_unlikely (*f == L_('\0')))
616 conv_error ();
618 /* Find the conversion specifier. */
619 fc = *f++;
620 if (skip_space || (fc != L_('[') && fc != L_('c')
621 && fc != L_('C') && fc != L_('n')))
623 /* Eat whitespace. */
624 int save_errno = errno;
625 __set_errno (0);
627 /* We add the additional test for EOF here since otherwise
628 inchar will restore the old errno value which might be
629 EINTR but does not indicate an interrupt since nothing
630 was read at this time. */
631 if (__builtin_expect ((c == EOF || inchar () == EOF)
632 && errno == EINTR, 0))
633 input_error ();
634 while (ISSPACE (c));
635 __set_errno (save_errno);
636 ungetc (c, s);
637 skip_space = 0;
640 switch (fc)
642 case L_('%'): /* Must match a literal '%'. */
643 c = inchar ();
644 if (__glibc_unlikely (c == EOF))
645 input_error ();
646 if (__glibc_unlikely (c != fc))
648 ungetc_not_eof (c, s);
649 conv_error ();
651 break;
653 case L_('n'): /* Answer number of assignments done. */
654 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
655 with the 'n' conversion specifier. */
656 if (!(flags & SUPPRESS))
658 /* Don't count the read-ahead. */
659 if (need_longlong && (flags & LONGDBL))
660 *ARG (long long int *) = read_in;
661 else if (need_long && (flags & LONG))
662 *ARG (long int *) = read_in;
663 else if (flags & SHORT)
664 *ARG (short int *) = read_in;
665 else if (!(flags & CHAR))
666 *ARG (int *) = read_in;
667 else
668 *ARG (char *) = read_in;
670 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
671 /* We have a severe problem here. The ISO C standard
672 contradicts itself in explaining the effect of the %n
673 format in `scanf'. While in ISO C:1990 and the ISO C
674 Amendement 1:1995 the result is described as
676 Execution of a %n directive does not effect the
677 assignment count returned at the completion of
678 execution of the f(w)scanf function.
680 in ISO C Corrigendum 1:1994 the following was added:
682 Subclause 7.9.6.2
683 Add the following fourth example:
685 #include <stdio.h>
686 int d1, d2, n1, n2, i;
687 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
688 the value 123 is assigned to d1 and the value3 to n1.
689 Because %n can never get an input failure the value
690 of 3 is also assigned to n2. The value of d2 is not
691 affected. The value 3 is assigned to i.
693 We go for now with the historically correct code from ISO C,
694 i.e., we don't count the %n assignments. When it ever
695 should proof to be wrong just remove the #ifdef above. */
696 ++done;
697 #endif
699 break;
701 case L_('c'): /* Match characters. */
702 if ((flags & LONG) == 0)
704 if (width == -1)
705 width = 1;
707 #define STRING_ARG(Str, Type, Width) \
708 do if (!(flags & SUPPRESS)) \
710 if (flags & MALLOC) \
712 /* The string is to be stored in a malloc'd buffer. */ \
713 /* For %mS using char ** is actually wrong, but \
714 shouldn't make a difference on any arch glibc \
715 supports and would unnecessarily complicate \
716 things. */ \
717 strptr = ARG (char **); \
718 if (strptr == NULL) \
719 conv_error (); \
720 /* Allocate an initial buffer. */ \
721 strsize = Width; \
722 *strptr = (char *) malloc (strsize * sizeof (Type)); \
723 Str = (Type *) *strptr; \
724 if (Str != NULL) \
725 add_ptr_to_free (strptr); \
726 else if (flags & POSIX_MALLOC) \
728 done = EOF; \
729 goto errout; \
732 else \
733 Str = ARG (Type *); \
734 if (Str == NULL) \
735 conv_error (); \
736 } while (0)
737 #ifdef COMPILE_WSCANF
738 STRING_ARG (str, char, 100);
739 #else
740 STRING_ARG (str, char, (width > 1024 ? 1024 : width));
741 #endif
743 c = inchar ();
744 if (__glibc_unlikely (c == EOF))
745 input_error ();
747 #ifdef COMPILE_WSCANF
748 /* We have to convert the wide character(s) into multibyte
749 characters and store the result. */
750 memset (&state, '\0', sizeof (state));
754 size_t n;
756 if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
757 && *strptr + strsize - str <= MB_LEN_MAX)
759 /* We have to enlarge the buffer if the `m' flag
760 was given. */
761 size_t strleng = str - *strptr;
762 char *newstr;
764 newstr = (char *) realloc (*strptr, strsize * 2);
765 if (newstr == NULL)
767 /* Can't allocate that much. Last-ditch effort. */
768 newstr = (char *) realloc (*strptr,
769 strleng + MB_LEN_MAX);
770 if (newstr == NULL)
772 /* c can't have `a' flag, only `m'. */
773 done = EOF;
774 goto errout;
776 else
778 *strptr = newstr;
779 str = newstr + strleng;
780 strsize = strleng + MB_LEN_MAX;
783 else
785 *strptr = newstr;
786 str = newstr + strleng;
787 strsize *= 2;
791 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
792 if (__glibc_unlikely (n == (size_t) -1))
793 /* No valid wide character. */
794 input_error ();
796 /* Increment the output pointer. Even if we don't
797 write anything. */
798 str += n;
800 while (--width > 0 && inchar () != EOF);
801 #else
802 if (!(flags & SUPPRESS))
806 if ((flags & MALLOC)
807 && (char *) str == *strptr + strsize)
809 /* Enlarge the buffer. */
810 size_t newsize
811 = strsize
812 + (strsize >= width ? width - 1 : strsize);
814 str = (char *) realloc (*strptr, newsize);
815 if (str == NULL)
817 /* Can't allocate that much. Last-ditch
818 effort. */
819 str = (char *) realloc (*strptr, strsize + 1);
820 if (str == NULL)
822 /* c can't have `a' flag, only `m'. */
823 done = EOF;
824 goto errout;
826 else
828 *strptr = (char *) str;
829 str += strsize;
830 ++strsize;
833 else
835 *strptr = (char *) str;
836 str += strsize;
837 strsize = newsize;
840 *str++ = c;
842 while (--width > 0 && inchar () != EOF);
844 else
845 while (--width > 0 && inchar () != EOF);
846 #endif
848 if (!(flags & SUPPRESS))
850 if ((flags & MALLOC) && str - *strptr != strsize)
852 char *cp = (char *) realloc (*strptr, str - *strptr);
853 if (cp != NULL)
854 *strptr = cp;
856 strptr = NULL;
857 ++done;
860 break;
862 /* FALLTHROUGH */
863 case L_('C'):
864 if (width == -1)
865 width = 1;
867 STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width));
869 c = inchar ();
870 if (__glibc_unlikely (c == EOF))
871 input_error ();
873 #ifdef COMPILE_WSCANF
874 /* Just store the incoming wide characters. */
875 if (!(flags & SUPPRESS))
879 if ((flags & MALLOC)
880 && wstr == (wchar_t *) *strptr + strsize)
882 size_t newsize
883 = strsize + (strsize > width ? width - 1 : strsize);
884 /* Enlarge the buffer. */
885 wstr = (wchar_t *) realloc (*strptr,
886 newsize * sizeof (wchar_t));
887 if (wstr == NULL)
889 /* Can't allocate that much. Last-ditch effort. */
890 wstr = (wchar_t *) realloc (*strptr,
891 (strsize + 1)
892 * sizeof (wchar_t));
893 if (wstr == NULL)
895 /* C or lc can't have `a' flag, only `m'
896 flag. */
897 done = EOF;
898 goto errout;
900 else
902 *strptr = (char *) wstr;
903 wstr += strsize;
904 ++strsize;
907 else
909 *strptr = (char *) wstr;
910 wstr += strsize;
911 strsize = newsize;
914 *wstr++ = c;
916 while (--width > 0 && inchar () != EOF);
918 else
919 while (--width > 0 && inchar () != EOF);
920 #else
922 /* We have to convert the multibyte input sequence to wide
923 characters. */
924 char buf[1];
925 mbstate_t cstate;
927 memset (&cstate, '\0', sizeof (cstate));
931 /* This is what we present the mbrtowc function first. */
932 buf[0] = c;
934 if (!(flags & SUPPRESS) && (flags & MALLOC)
935 && wstr == (wchar_t *) *strptr + strsize)
937 size_t newsize
938 = strsize + (strsize > width ? width - 1 : strsize);
939 /* Enlarge the buffer. */
940 wstr = (wchar_t *) realloc (*strptr,
941 newsize * sizeof (wchar_t));
942 if (wstr == NULL)
944 /* Can't allocate that much. Last-ditch effort. */
945 wstr = (wchar_t *) realloc (*strptr,
946 ((strsize + 1)
947 * sizeof (wchar_t)));
948 if (wstr == NULL)
950 /* C or lc can't have `a' flag, only `m' flag. */
951 done = EOF;
952 goto errout;
954 else
956 *strptr = (char *) wstr;
957 wstr += strsize;
958 ++strsize;
961 else
963 *strptr = (char *) wstr;
964 wstr += strsize;
965 strsize = newsize;
969 while (1)
971 size_t n;
973 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
974 buf, 1, &cstate);
976 if (n == (size_t) -2)
978 /* Possibly correct character, just not enough
979 input. */
980 if (__glibc_unlikely (inchar () == EOF))
981 encode_error ();
983 buf[0] = c;
984 continue;
987 if (__glibc_unlikely (n != 1))
988 encode_error ();
990 /* We have a match. */
991 break;
994 /* Advance the result pointer. */
995 ++wstr;
997 while (--width > 0 && inchar () != EOF);
999 #endif
1001 if (!(flags & SUPPRESS))
1003 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1005 wchar_t *cp = (wchar_t *) realloc (*strptr,
1006 ((wstr
1007 - (wchar_t *) *strptr)
1008 * sizeof (wchar_t)));
1009 if (cp != NULL)
1010 *strptr = (char *) cp;
1012 strptr = NULL;
1014 ++done;
1017 break;
1019 case L_('s'): /* Read a string. */
1020 if (!(flags & LONG))
1022 STRING_ARG (str, char, 100);
1024 c = inchar ();
1025 if (__glibc_unlikely (c == EOF))
1026 input_error ();
1028 #ifdef COMPILE_WSCANF
1029 memset (&state, '\0', sizeof (state));
1030 #endif
1034 if (ISSPACE (c))
1036 ungetc_not_eof (c, s);
1037 break;
1040 #ifdef COMPILE_WSCANF
1041 /* This is quite complicated. We have to convert the
1042 wide characters into multibyte characters and then
1043 store them. */
1045 size_t n;
1047 if (!(flags & SUPPRESS) && (flags & MALLOC)
1048 && *strptr + strsize - str <= MB_LEN_MAX)
1050 /* We have to enlarge the buffer if the `a' or `m'
1051 flag was given. */
1052 size_t strleng = str - *strptr;
1053 char *newstr;
1055 newstr = (char *) realloc (*strptr, strsize * 2);
1056 if (newstr == NULL)
1058 /* Can't allocate that much. Last-ditch
1059 effort. */
1060 newstr = (char *) realloc (*strptr,
1061 strleng + MB_LEN_MAX);
1062 if (newstr == NULL)
1064 if (flags & POSIX_MALLOC)
1066 done = EOF;
1067 goto errout;
1069 /* We lose. Oh well. Terminate the
1070 string and stop converting,
1071 so at least we don't skip any input. */
1072 ((char *) (*strptr))[strleng] = '\0';
1073 strptr = NULL;
1074 ++done;
1075 conv_error ();
1077 else
1079 *strptr = newstr;
1080 str = newstr + strleng;
1081 strsize = strleng + MB_LEN_MAX;
1084 else
1086 *strptr = newstr;
1087 str = newstr + strleng;
1088 strsize *= 2;
1092 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
1093 &state);
1094 if (__glibc_unlikely (n == (size_t) -1))
1095 encode_error ();
1097 assert (n <= MB_LEN_MAX);
1098 str += n;
1100 #else
1101 /* This is easy. */
1102 if (!(flags & SUPPRESS))
1104 *str++ = c;
1105 if ((flags & MALLOC)
1106 && (char *) str == *strptr + strsize)
1108 /* Enlarge the buffer. */
1109 str = (char *) realloc (*strptr, 2 * strsize);
1110 if (str == NULL)
1112 /* Can't allocate that much. Last-ditch
1113 effort. */
1114 str = (char *) realloc (*strptr, strsize + 1);
1115 if (str == NULL)
1117 if (flags & POSIX_MALLOC)
1119 done = EOF;
1120 goto errout;
1122 /* We lose. Oh well. Terminate the
1123 string and stop converting,
1124 so at least we don't skip any input. */
1125 ((char *) (*strptr))[strsize - 1] = '\0';
1126 strptr = NULL;
1127 ++done;
1128 conv_error ();
1130 else
1132 *strptr = (char *) str;
1133 str += strsize;
1134 ++strsize;
1137 else
1139 *strptr = (char *) str;
1140 str += strsize;
1141 strsize *= 2;
1145 #endif
1147 while ((width <= 0 || --width > 0) && inchar () != EOF);
1149 if (!(flags & SUPPRESS))
1151 #ifdef COMPILE_WSCANF
1152 /* We have to emit the code to get into the initial
1153 state. */
1154 char buf[MB_LEN_MAX];
1155 size_t n = __wcrtomb (buf, L'\0', &state);
1156 if (n > 0 && (flags & MALLOC)
1157 && str + n >= *strptr + strsize)
1159 /* Enlarge the buffer. */
1160 size_t strleng = str - *strptr;
1161 char *newstr;
1163 newstr = (char *) realloc (*strptr, strleng + n + 1);
1164 if (newstr == NULL)
1166 if (flags & POSIX_MALLOC)
1168 done = EOF;
1169 goto errout;
1171 /* We lose. Oh well. Terminate the string
1172 and stop converting, so at least we don't
1173 skip any input. */
1174 ((char *) (*strptr))[strleng] = '\0';
1175 strptr = NULL;
1176 ++done;
1177 conv_error ();
1179 else
1181 *strptr = newstr;
1182 str = newstr + strleng;
1183 strsize = strleng + n + 1;
1187 str = __mempcpy (str, buf, n);
1188 #endif
1189 *str++ = '\0';
1191 if ((flags & MALLOC) && str - *strptr != strsize)
1193 char *cp = (char *) realloc (*strptr, str - *strptr);
1194 if (cp != NULL)
1195 *strptr = cp;
1197 strptr = NULL;
1199 ++done;
1201 break;
1203 /* FALLTHROUGH */
1205 case L_('S'):
1207 #ifndef COMPILE_WSCANF
1208 mbstate_t cstate;
1209 #endif
1211 /* Wide character string. */
1212 STRING_ARG (wstr, wchar_t, 100);
1214 c = inchar ();
1215 if (__builtin_expect (c == EOF, 0))
1216 input_error ();
1218 #ifndef COMPILE_WSCANF
1219 memset (&cstate, '\0', sizeof (cstate));
1220 #endif
1224 if (ISSPACE (c))
1226 ungetc_not_eof (c, s);
1227 break;
1230 #ifdef COMPILE_WSCANF
1231 /* This is easy. */
1232 if (!(flags & SUPPRESS))
1234 *wstr++ = c;
1235 if ((flags & MALLOC)
1236 && wstr == (wchar_t *) *strptr + strsize)
1238 /* Enlarge the buffer. */
1239 wstr = (wchar_t *) realloc (*strptr,
1240 (2 * strsize)
1241 * sizeof (wchar_t));
1242 if (wstr == NULL)
1244 /* Can't allocate that much. Last-ditch
1245 effort. */
1246 wstr = (wchar_t *) realloc (*strptr,
1247 (strsize + 1)
1248 * sizeof (wchar_t));
1249 if (wstr == NULL)
1251 if (flags & POSIX_MALLOC)
1253 done = EOF;
1254 goto errout;
1256 /* We lose. Oh well. Terminate the string
1257 and stop converting, so at least we don't
1258 skip any input. */
1259 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1260 strptr = NULL;
1261 ++done;
1262 conv_error ();
1264 else
1266 *strptr = (char *) wstr;
1267 wstr += strsize;
1268 ++strsize;
1271 else
1273 *strptr = (char *) wstr;
1274 wstr += strsize;
1275 strsize *= 2;
1279 #else
1281 char buf[1];
1283 buf[0] = c;
1285 while (1)
1287 size_t n;
1289 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1290 buf, 1, &cstate);
1292 if (n == (size_t) -2)
1294 /* Possibly correct character, just not enough
1295 input. */
1296 if (__glibc_unlikely (inchar () == EOF))
1297 encode_error ();
1299 buf[0] = c;
1300 continue;
1303 if (__glibc_unlikely (n != 1))
1304 encode_error ();
1306 /* We have a match. */
1307 ++wstr;
1308 break;
1311 if (!(flags & SUPPRESS) && (flags & MALLOC)
1312 && wstr == (wchar_t *) *strptr + strsize)
1314 /* Enlarge the buffer. */
1315 wstr = (wchar_t *) realloc (*strptr,
1316 (2 * strsize
1317 * sizeof (wchar_t)));
1318 if (wstr == NULL)
1320 /* Can't allocate that much. Last-ditch effort. */
1321 wstr = (wchar_t *) realloc (*strptr,
1322 ((strsize + 1)
1323 * sizeof (wchar_t)));
1324 if (wstr == NULL)
1326 if (flags & POSIX_MALLOC)
1328 done = EOF;
1329 goto errout;
1331 /* We lose. Oh well. Terminate the
1332 string and stop converting, so at
1333 least we don't skip any input. */
1334 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1335 strptr = NULL;
1336 ++done;
1337 conv_error ();
1339 else
1341 *strptr = (char *) wstr;
1342 wstr += strsize;
1343 ++strsize;
1346 else
1348 *strptr = (char *) wstr;
1349 wstr += strsize;
1350 strsize *= 2;
1354 #endif
1356 while ((width <= 0 || --width > 0) && inchar () != EOF);
1358 if (!(flags & SUPPRESS))
1360 *wstr++ = L'\0';
1362 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1364 wchar_t *cp = (wchar_t *) realloc (*strptr,
1365 ((wstr
1366 - (wchar_t *) *strptr)
1367 * sizeof(wchar_t)));
1368 if (cp != NULL)
1369 *strptr = (char *) cp;
1371 strptr = NULL;
1373 ++done;
1376 break;
1378 case L_('x'): /* Hexadecimal integer. */
1379 case L_('X'): /* Ditto. */
1380 base = 16;
1381 goto number;
1383 case L_('o'): /* Octal integer. */
1384 base = 8;
1385 goto number;
1387 case L_('u'): /* Unsigned decimal integer. */
1388 base = 10;
1389 goto number;
1391 case L_('d'): /* Signed decimal integer. */
1392 base = 10;
1393 flags |= NUMBER_SIGNED;
1394 goto number;
1396 case L_('i'): /* Generic number. */
1397 base = 0;
1398 flags |= NUMBER_SIGNED;
1400 number:
1401 c = inchar ();
1402 if (__glibc_unlikely (c == EOF))
1403 input_error ();
1405 /* Check for a sign. */
1406 if (c == L_('-') || c == L_('+'))
1408 char_buffer_add (&charbuf, c);
1409 if (width > 0)
1410 --width;
1411 c = inchar ();
1414 /* Look for a leading indication of base. */
1415 if (width != 0 && c == L_('0'))
1417 if (width > 0)
1418 --width;
1420 char_buffer_add (&charbuf, c);
1421 c = inchar ();
1423 if (width != 0 && TOLOWER (c) == L_('x'))
1425 if (base == 0)
1426 base = 16;
1427 if (base == 16)
1429 if (width > 0)
1430 --width;
1431 c = inchar ();
1434 else if (base == 0)
1435 base = 8;
1438 if (base == 0)
1439 base = 10;
1441 if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
1443 int from_level;
1444 int to_level;
1445 int level;
1446 #ifdef COMPILE_WSCANF
1447 const wchar_t *wcdigits[10];
1448 const wchar_t *wcdigits_extended[10];
1449 #else
1450 const char *mbdigits[10];
1451 const char *mbdigits_extended[10];
1452 #endif
1453 /* "to_inpunct" is a map from ASCII digits to their
1454 equivalent in locale. This is defined for locales
1455 which use an extra digits set. */
1456 wctrans_t map = __wctrans ("to_inpunct");
1457 int n;
1459 from_level = 0;
1460 #ifdef COMPILE_WSCANF
1461 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1462 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1463 #else
1464 to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
1465 #endif
1467 /* Get the alternative digit forms if there are any. */
1468 if (__glibc_unlikely (map != NULL))
1470 /* Adding new level for extra digits set in locale file. */
1471 ++to_level;
1473 for (n = 0; n < 10; ++n)
1475 #ifdef COMPILE_WSCANF
1476 wcdigits[n] = (const wchar_t *)
1477 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1479 wchar_t *wc_extended = (wchar_t *)
1480 alloca ((to_level + 2) * sizeof (wchar_t));
1481 __wmemcpy (wc_extended, wcdigits[n], to_level);
1482 wc_extended[to_level] = __towctrans (L'0' + n, map);
1483 wc_extended[to_level + 1] = '\0';
1484 wcdigits_extended[n] = wc_extended;
1485 #else
1486 mbdigits[n]
1487 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1489 /* Get the equivalent wide char in map. */
1490 wint_t extra_wcdigit = __towctrans (L'0' + n, map);
1492 /* Convert it to multibyte representation. */
1493 mbstate_t state;
1494 memset (&state, '\0', sizeof (state));
1496 char extra_mbdigit[MB_LEN_MAX];
1497 size_t mblen
1498 = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
1500 if (mblen == (size_t) -1)
1502 /* Ignore this new level. */
1503 map = NULL;
1504 break;
1507 /* Calculate the length of mbdigits[n]. */
1508 const char *last_char = mbdigits[n];
1509 for (level = 0; level < to_level; ++level)
1510 last_char = strchr (last_char, '\0') + 1;
1512 size_t mbdigits_len = last_char - mbdigits[n];
1514 /* Allocate memory for extended multibyte digit. */
1515 char *mb_extended;
1516 mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
1518 /* And get the mbdigits + extra_digit string. */
1519 *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
1520 mbdigits_len),
1521 extra_mbdigit, mblen) = '\0';
1522 mbdigits_extended[n] = mb_extended;
1523 #endif
1527 /* Read the number into workspace. */
1528 while (c != EOF && width != 0)
1530 /* In this round we get the pointer to the digit strings
1531 and also perform the first round of comparisons. */
1532 for (n = 0; n < 10; ++n)
1534 /* Get the string for the digits with value N. */
1535 #ifdef COMPILE_WSCANF
1537 /* wcdigits_extended[] is fully set in the loop
1538 above, but the test for "map != NULL" is done
1539 inside the loop here and outside the loop there. */
1540 DIAG_PUSH_NEEDS_COMMENT;
1541 DIAG_IGNORE_NEEDS_COMMENT (4.7, "-Wmaybe-uninitialized");
1543 if (__glibc_unlikely (map != NULL))
1544 wcdigits[n] = wcdigits_extended[n];
1545 else
1546 wcdigits[n] = (const wchar_t *)
1547 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1548 wcdigits[n] += from_level;
1550 DIAG_POP_NEEDS_COMMENT;
1552 if (c == (wint_t) *wcdigits[n])
1554 to_level = from_level;
1555 break;
1558 /* Advance the pointer to the next string. */
1559 ++wcdigits[n];
1560 #else
1561 const char *cmpp;
1562 int avail = width > 0 ? width : INT_MAX;
1564 if (__glibc_unlikely (map != NULL))
1565 mbdigits[n] = mbdigits_extended[n];
1566 else
1567 mbdigits[n]
1568 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1570 for (level = 0; level < from_level; level++)
1571 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1573 cmpp = mbdigits[n];
1574 while ((unsigned char) *cmpp == c && avail >= 0)
1576 if (*++cmpp == '\0')
1577 break;
1578 else
1580 if (avail == 0 || inchar () == EOF)
1581 break;
1582 --avail;
1586 if (*cmpp == '\0')
1588 if (width > 0)
1589 width = avail;
1590 to_level = from_level;
1591 break;
1594 /* We are pushing all read characters back. */
1595 if (cmpp > mbdigits[n])
1597 ungetc (c, s);
1598 while (--cmpp > mbdigits[n])
1599 ungetc_not_eof ((unsigned char) *cmpp, s);
1600 c = (unsigned char) *cmpp;
1603 /* Advance the pointer to the next string. */
1604 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1605 #endif
1608 if (n == 10)
1610 /* Have not yet found the digit. */
1611 for (level = from_level + 1; level <= to_level; ++level)
1613 /* Search all ten digits of this level. */
1614 for (n = 0; n < 10; ++n)
1616 #ifdef COMPILE_WSCANF
1617 if (c == (wint_t) *wcdigits[n])
1618 break;
1620 /* Advance the pointer to the next string. */
1621 ++wcdigits[n];
1622 #else
1623 const char *cmpp;
1624 int avail = width > 0 ? width : INT_MAX;
1626 cmpp = mbdigits[n];
1627 while ((unsigned char) *cmpp == c && avail >= 0)
1629 if (*++cmpp == '\0')
1630 break;
1631 else
1633 if (avail == 0 || inchar () == EOF)
1634 break;
1635 --avail;
1639 if (*cmpp == '\0')
1641 if (width > 0)
1642 width = avail;
1643 break;
1646 /* We are pushing all read characters back. */
1647 if (cmpp > mbdigits[n])
1649 ungetc (c, s);
1650 while (--cmpp > mbdigits[n])
1651 ungetc_not_eof ((unsigned char) *cmpp, s);
1652 c = (unsigned char) *cmpp;
1655 /* Advance the pointer to the next string. */
1656 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1657 #endif
1660 if (n < 10)
1662 /* Found it. */
1663 from_level = level;
1664 to_level = level;
1665 break;
1670 if (n < 10)
1671 c = L_('0') + n;
1672 else if (flags & GROUP)
1674 /* Try matching against the thousands separator. */
1675 #ifdef COMPILE_WSCANF
1676 if (c != thousands)
1677 break;
1678 #else
1679 const char *cmpp = thousands;
1680 int avail = width > 0 ? width : INT_MAX;
1682 while ((unsigned char) *cmpp == c && avail >= 0)
1684 char_buffer_add (&charbuf, c);
1685 if (*++cmpp == '\0')
1686 break;
1687 else
1689 if (avail == 0 || inchar () == EOF)
1690 break;
1691 --avail;
1695 if (char_buffer_error (&charbuf))
1697 __set_errno (ENOMEM);
1698 done = EOF;
1699 goto errout;
1702 if (*cmpp != '\0')
1704 /* We are pushing all read characters back. */
1705 if (cmpp > thousands)
1707 charbuf.current -= cmpp - thousands;
1708 ungetc (c, s);
1709 while (--cmpp > thousands)
1710 ungetc_not_eof ((unsigned char) *cmpp, s);
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 char_buffer_add below. */
1721 --charbuf.current;
1722 #endif
1724 else
1725 break;
1727 char_buffer_add (&charbuf, c);
1728 if (width > 0)
1729 --width;
1731 c = inchar ();
1734 else
1735 /* Read the number into workspace. */
1736 while (c != EOF && width != 0)
1738 if (base == 16)
1740 if (!ISXDIGIT (c))
1741 break;
1743 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
1745 if (base == 10 && (flags & GROUP))
1747 /* Try matching against the thousands separator. */
1748 #ifdef COMPILE_WSCANF
1749 if (c != thousands)
1750 break;
1751 #else
1752 const char *cmpp = thousands;
1753 int avail = width > 0 ? width : INT_MAX;
1755 while ((unsigned char) *cmpp == c && avail >= 0)
1757 char_buffer_add (&charbuf, c);
1758 if (*++cmpp == '\0')
1759 break;
1760 else
1762 if (avail == 0 || inchar () == EOF)
1763 break;
1764 --avail;
1768 if (char_buffer_error (&charbuf))
1770 __set_errno (ENOMEM);
1771 done = EOF;
1772 goto errout;
1775 if (*cmpp != '\0')
1777 /* We are pushing all read characters back. */
1778 if (cmpp > thousands)
1780 charbuf.current -= cmpp - thousands;
1781 ungetc (c, s);
1782 while (--cmpp > thousands)
1783 ungetc_not_eof ((unsigned char) *cmpp, s);
1784 c = (unsigned char) *cmpp;
1786 break;
1789 if (width > 0)
1790 width = avail;
1792 /* The last thousands character will be added back by
1793 the char_buffer_add below. */
1794 --charbuf.current;
1795 #endif
1797 else
1798 break;
1800 char_buffer_add (&charbuf, c);
1801 if (width > 0)
1802 --width;
1804 c = inchar ();
1807 if (char_buffer_error (&charbuf))
1809 __set_errno (ENOMEM);
1810 done = EOF;
1811 goto errout;
1814 if (char_buffer_size (&charbuf) == 0
1815 || (char_buffer_size (&charbuf) == 1
1816 && (char_buffer_start (&charbuf)[0] == L_('+')
1817 || char_buffer_start (&charbuf)[0] == L_('-'))))
1819 /* There was no number. If we are supposed to read a pointer
1820 we must recognize "(nil)" as well. */
1821 if (__builtin_expect (char_buffer_size (&charbuf) == 0
1822 && (flags & READ_POINTER)
1823 && (width < 0 || width >= 5)
1824 && c == '('
1825 && TOLOWER (inchar ()) == L_('n')
1826 && TOLOWER (inchar ()) == L_('i')
1827 && TOLOWER (inchar ()) == L_('l')
1828 && inchar () == L_(')'), 1))
1829 /* We must produce the value of a NULL pointer. A single
1830 '0' digit is enough. */
1831 char_buffer_add (&charbuf, L_('0'));
1832 else
1834 /* The last read character is not part of the number
1835 anymore. */
1836 ungetc (c, s);
1838 conv_error ();
1841 else
1842 /* The just read character is not part of the number anymore. */
1843 ungetc (c, s);
1845 /* Convert the number. */
1846 char_buffer_add (&charbuf, L_('\0'));
1847 if (char_buffer_error (&charbuf))
1849 __set_errno (ENOMEM);
1850 done = EOF;
1851 goto errout;
1853 if (need_longlong && (flags & LONGDBL))
1855 if (flags & NUMBER_SIGNED)
1856 num.q = __strtoll_internal
1857 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
1858 else
1859 num.uq = __strtoull_internal
1860 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
1862 else
1864 if (flags & NUMBER_SIGNED)
1865 num.l = __strtol_internal
1866 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
1867 else
1868 num.ul = __strtoul_internal
1869 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
1871 if (__glibc_unlikely (char_buffer_start (&charbuf) == tw))
1872 conv_error ();
1874 if (!(flags & SUPPRESS))
1876 if (flags & NUMBER_SIGNED)
1878 if (need_longlong && (flags & LONGDBL))
1879 *ARG (LONGLONG int *) = num.q;
1880 else if (need_long && (flags & LONG))
1881 *ARG (long int *) = num.l;
1882 else if (flags & SHORT)
1883 *ARG (short int *) = (short int) num.l;
1884 else if (!(flags & CHAR))
1885 *ARG (int *) = (int) num.l;
1886 else
1887 *ARG (signed char *) = (signed char) num.ul;
1889 else
1891 if (need_longlong && (flags & LONGDBL))
1892 *ARG (unsigned LONGLONG int *) = num.uq;
1893 else if (need_long && (flags & LONG))
1894 *ARG (unsigned long int *) = num.ul;
1895 else if (flags & SHORT)
1896 *ARG (unsigned short int *)
1897 = (unsigned short int) num.ul;
1898 else if (!(flags & CHAR))
1899 *ARG (unsigned int *) = (unsigned int) num.ul;
1900 else
1901 *ARG (unsigned char *) = (unsigned char) num.ul;
1903 ++done;
1905 break;
1907 case L_('e'): /* Floating-point numbers. */
1908 case L_('E'):
1909 case L_('f'):
1910 case L_('F'):
1911 case L_('g'):
1912 case L_('G'):
1913 case L_('a'):
1914 case L_('A'):
1915 c = inchar ();
1916 if (width > 0)
1917 --width;
1918 if (__glibc_unlikely (c == EOF))
1919 input_error ();
1921 got_digit = got_dot = got_e = 0;
1923 /* Check for a sign. */
1924 if (c == L_('-') || c == L_('+'))
1926 negative = c == L_('-');
1927 if (__glibc_unlikely (width == 0 || inchar () == EOF))
1928 /* EOF is only an input error before we read any chars. */
1929 conv_error ();
1930 if (width > 0)
1931 --width;
1933 else
1934 negative = 0;
1936 /* Take care for the special arguments "nan" and "inf". */
1937 if (TOLOWER (c) == L_('n'))
1939 /* Maybe "nan". */
1940 char_buffer_add (&charbuf, c);
1941 if (__builtin_expect (width == 0
1942 || inchar () == EOF
1943 || TOLOWER (c) != L_('a'), 0))
1944 conv_error ();
1945 if (width > 0)
1946 --width;
1947 char_buffer_add (&charbuf, c);
1948 if (__builtin_expect (width == 0
1949 || inchar () == EOF
1950 || TOLOWER (c) != L_('n'), 0))
1951 conv_error ();
1952 if (width > 0)
1953 --width;
1954 char_buffer_add (&charbuf, c);
1955 /* It is "nan". */
1956 goto scan_float;
1958 else if (TOLOWER (c) == L_('i'))
1960 /* Maybe "inf" or "infinity". */
1961 char_buffer_add (&charbuf, c);
1962 if (__builtin_expect (width == 0
1963 || inchar () == EOF
1964 || TOLOWER (c) != L_('n'), 0))
1965 conv_error ();
1966 if (width > 0)
1967 --width;
1968 char_buffer_add (&charbuf, c);
1969 if (__builtin_expect (width == 0
1970 || inchar () == EOF
1971 || TOLOWER (c) != L_('f'), 0))
1972 conv_error ();
1973 if (width > 0)
1974 --width;
1975 char_buffer_add (&charbuf, c);
1976 /* It is as least "inf". */
1977 if (width != 0 && inchar () != EOF)
1979 if (TOLOWER (c) == L_('i'))
1981 if (width > 0)
1982 --width;
1983 /* Now we have to read the rest as well. */
1984 char_buffer_add (&charbuf, c);
1985 if (__builtin_expect (width == 0
1986 || inchar () == EOF
1987 || TOLOWER (c) != L_('n'), 0))
1988 conv_error ();
1989 if (width > 0)
1990 --width;
1991 char_buffer_add (&charbuf, c);
1992 if (__builtin_expect (width == 0
1993 || inchar () == EOF
1994 || TOLOWER (c) != L_('i'), 0))
1995 conv_error ();
1996 if (width > 0)
1997 --width;
1998 char_buffer_add (&charbuf, c);
1999 if (__builtin_expect (width == 0
2000 || inchar () == EOF
2001 || TOLOWER (c) != L_('t'), 0))
2002 conv_error ();
2003 if (width > 0)
2004 --width;
2005 char_buffer_add (&charbuf, c);
2006 if (__builtin_expect (width == 0
2007 || inchar () == EOF
2008 || TOLOWER (c) != L_('y'), 0))
2009 conv_error ();
2010 if (width > 0)
2011 --width;
2012 char_buffer_add (&charbuf, c);
2014 else
2015 /* Never mind. */
2016 ungetc (c, s);
2018 goto scan_float;
2021 exp_char = L_('e');
2022 if (width != 0 && c == L_('0'))
2024 char_buffer_add (&charbuf, c);
2025 c = inchar ();
2026 if (width > 0)
2027 --width;
2028 if (width != 0 && TOLOWER (c) == L_('x'))
2030 /* It is a number in hexadecimal format. */
2031 char_buffer_add (&charbuf, c);
2033 flags |= HEXA_FLOAT;
2034 exp_char = L_('p');
2036 /* Grouping is not allowed. */
2037 flags &= ~GROUP;
2038 c = inchar ();
2039 if (width > 0)
2040 --width;
2042 else
2043 got_digit = 1;
2046 while (1)
2048 if (char_buffer_error (&charbuf))
2050 __set_errno (ENOMEM);
2051 done = EOF;
2052 goto errout;
2054 if (ISDIGIT (c))
2056 char_buffer_add (&charbuf, c);
2057 got_digit = 1;
2059 else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c))
2061 char_buffer_add (&charbuf, c);
2062 got_digit = 1;
2064 else if (got_e && charbuf.current[-1] == exp_char
2065 && (c == L_('-') || c == L_('+')))
2066 char_buffer_add (&charbuf, c);
2067 else if (got_digit && !got_e
2068 && (CHAR_T) TOLOWER (c) == exp_char)
2070 char_buffer_add (&charbuf, exp_char);
2071 got_e = got_dot = 1;
2073 else
2075 #ifdef COMPILE_WSCANF
2076 if (! got_dot && c == decimal)
2078 char_buffer_add (&charbuf, c);
2079 got_dot = 1;
2081 else if ((flags & GROUP) != 0 && ! got_dot && c == thousands)
2082 char_buffer_add (&charbuf, c);
2083 else
2085 /* The last read character is not part of the number
2086 anymore. */
2087 ungetc (c, s);
2088 break;
2090 #else
2091 const char *cmpp = decimal;
2092 int avail = width > 0 ? width : INT_MAX;
2094 if (! got_dot)
2096 while ((unsigned char) *cmpp == c && avail >= 0)
2097 if (*++cmpp == '\0')
2098 break;
2099 else
2101 if (avail == 0 || inchar () == EOF)
2102 break;
2103 --avail;
2107 if (*cmpp == '\0')
2109 /* Add all the characters. */
2110 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
2111 char_buffer_add (&charbuf, (unsigned char) *cmpp);
2112 if (width > 0)
2113 width = avail;
2114 got_dot = 1;
2116 else
2118 /* Figure out whether it is a thousands separator.
2119 There is one problem: we possibly read more than
2120 one character. We cannot push them back but since
2121 we know that parts of the `decimal' string matched,
2122 we can compare against it. */
2123 const char *cmp2p = thousands;
2125 if ((flags & GROUP) != 0 && ! got_dot)
2127 while (cmp2p - thousands < cmpp - decimal
2128 && *cmp2p == decimal[cmp2p - thousands])
2129 ++cmp2p;
2130 if (cmp2p - thousands == cmpp - decimal)
2132 while ((unsigned char) *cmp2p == c && avail >= 0)
2133 if (*++cmp2p == '\0')
2134 break;
2135 else
2137 if (avail == 0 || inchar () == EOF)
2138 break;
2139 --avail;
2144 if (cmp2p != NULL && *cmp2p == '\0')
2146 /* Add all the characters. */
2147 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
2148 char_buffer_add (&charbuf, (unsigned char) *cmpp);
2149 if (width > 0)
2150 width = avail;
2152 else
2154 /* The last read character is not part of the number
2155 anymore. */
2156 ungetc (c, s);
2157 break;
2160 #endif
2163 if (width == 0 || inchar () == EOF)
2164 break;
2166 if (width > 0)
2167 --width;
2170 if (char_buffer_error (&charbuf))
2172 __set_errno (ENOMEM);
2173 done = EOF;
2174 goto errout;
2177 wctrans_t map;
2178 if (__builtin_expect ((flags & I18N) != 0, 0)
2179 /* Hexadecimal floats make no sense, fixing localized
2180 digits with ASCII letters. */
2181 && !(flags & HEXA_FLOAT)
2182 /* Minimum requirement. */
2183 && (char_buffer_size (&charbuf) == 0 || got_dot)
2184 && (map = __wctrans ("to_inpunct")) != NULL)
2186 /* Reget the first character. */
2187 inchar ();
2189 /* Localized digits, decimal points, and thousands
2190 separator. */
2191 wint_t wcdigits[12];
2193 /* First get decimal equivalent to check if we read it
2194 or not. */
2195 wcdigits[11] = __towctrans (L'.', map);
2197 /* If we have not read any character or have just read
2198 locale decimal point which matches the decimal point
2199 for localized FP numbers, then we may have localized
2200 digits. Note, we test GOT_DOT above. */
2201 #ifdef COMPILE_WSCANF
2202 if (char_buffer_size (&charbuf) == 0
2203 || (char_buffer_size (&charbuf) == 1
2204 && wcdigits[11] == decimal))
2205 #else
2206 char mbdigits[12][MB_LEN_MAX + 1];
2208 mbstate_t state;
2209 memset (&state, '\0', sizeof (state));
2211 bool match_so_far = char_buffer_size (&charbuf) == 0;
2212 size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state);
2213 if (mblen != (size_t) -1)
2215 mbdigits[11][mblen] = '\0';
2216 match_so_far |=
2217 (char_buffer_size (&charbuf) == strlen (decimal)
2218 && strcmp (decimal, mbdigits[11]) == 0);
2220 else
2222 size_t decimal_len = strlen (decimal);
2223 /* This should always be the case but the data comes
2224 from a file. */
2225 if (decimal_len <= MB_LEN_MAX)
2227 match_so_far |= char_buffer_size (&charbuf) == decimal_len;
2228 memcpy (mbdigits[11], decimal, decimal_len + 1);
2230 else
2231 match_so_far = false;
2234 if (match_so_far)
2235 #endif
2237 bool have_locthousands = (flags & GROUP) != 0;
2239 /* Now get the digits and the thousands-sep equivalents. */
2240 for (int n = 0; n < 11; ++n)
2242 if (n < 10)
2243 wcdigits[n] = __towctrans (L'0' + n, map);
2244 else if (n == 10)
2246 wcdigits[10] = __towctrans (L',', map);
2247 have_locthousands &= wcdigits[10] != L'\0';
2250 #ifndef COMPILE_WSCANF
2251 memset (&state, '\0', sizeof (state));
2253 size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n],
2254 &state);
2255 if (mblen == (size_t) -1)
2257 if (n == 10)
2259 if (have_locthousands)
2261 size_t thousands_len = strlen (thousands);
2262 if (thousands_len <= MB_LEN_MAX)
2263 memcpy (mbdigits[10], thousands,
2264 thousands_len + 1);
2265 else
2266 have_locthousands = false;
2269 else
2270 /* Ignore checking against localized digits. */
2271 goto no_i18nflt;
2273 else
2274 mbdigits[n][mblen] = '\0';
2275 #endif
2278 /* Start checking against localized digits, if
2279 conversion is done correctly. */
2280 while (1)
2282 if (char_buffer_error (&charbuf))
2284 __set_errno (ENOMEM);
2285 done = EOF;
2286 goto errout;
2288 if (got_e && charbuf.current[-1] == exp_char
2289 && (c == L_('-') || c == L_('+')))
2290 char_buffer_add (&charbuf, c);
2291 else if (char_buffer_size (&charbuf) > 0 && !got_e
2292 && (CHAR_T) TOLOWER (c) == exp_char)
2294 char_buffer_add (&charbuf, exp_char);
2295 got_e = got_dot = 1;
2297 else
2299 /* Check against localized digits, decimal point,
2300 and thousands separator. */
2301 int n;
2302 for (n = 0; n < 12; ++n)
2304 #ifdef COMPILE_WSCANF
2305 if (c == wcdigits[n])
2307 if (n < 10)
2308 char_buffer_add (&charbuf, L_('0') + n);
2309 else if (n == 11 && !got_dot)
2311 char_buffer_add (&charbuf, decimal);
2312 got_dot = 1;
2314 else if (n == 10 && have_locthousands
2315 && ! got_dot)
2316 char_buffer_add (&charbuf, thousands);
2317 else
2318 /* The last read character is not part
2319 of the number anymore. */
2320 n = 12;
2322 break;
2324 #else
2325 const char *cmpp = mbdigits[n];
2326 int avail = width > 0 ? width : INT_MAX;
2328 while ((unsigned char) *cmpp == c && avail >= 0)
2329 if (*++cmpp == '\0')
2330 break;
2331 else
2333 if (avail == 0 || inchar () == EOF)
2334 break;
2335 --avail;
2337 if (*cmpp == '\0')
2339 if (width > 0)
2340 width = avail;
2342 if (n < 10)
2343 char_buffer_add (&charbuf, L_('0') + n);
2344 else if (n == 11 && !got_dot)
2346 /* Add all the characters. */
2347 for (cmpp = decimal; *cmpp != '\0';
2348 ++cmpp)
2349 char_buffer_add (&charbuf,
2350 (unsigned char) *cmpp);
2352 got_dot = 1;
2354 else if (n == 10 && (flags & GROUP) != 0
2355 && ! got_dot)
2357 /* Add all the characters. */
2358 for (cmpp = thousands; *cmpp != '\0';
2359 ++cmpp)
2360 char_buffer_add (&charbuf,
2361 (unsigned char) *cmpp);
2363 else
2364 /* The last read character is not part
2365 of the number anymore. */
2366 n = 12;
2368 break;
2371 /* We are pushing all read characters back. */
2372 if (cmpp > mbdigits[n])
2374 ungetc (c, s);
2375 while (--cmpp > mbdigits[n])
2376 ungetc_not_eof ((unsigned char) *cmpp, s);
2377 c = (unsigned char) *cmpp;
2379 #endif
2382 if (n >= 12)
2384 /* The last read character is not part
2385 of the number anymore. */
2386 ungetc (c, s);
2387 break;
2391 if (width == 0 || inchar () == EOF)
2392 break;
2394 if (width > 0)
2395 --width;
2399 #ifndef COMPILE_WSCANF
2400 no_i18nflt:
2402 #endif
2405 if (char_buffer_error (&charbuf))
2407 __set_errno (ENOMEM);
2408 done = EOF;
2409 goto errout;
2412 /* Have we read any character? If we try to read a number
2413 in hexadecimal notation and we have read only the `0x'
2414 prefix this is an error. */
2415 if (__glibc_unlikely (char_buffer_size (&charbuf) == 0
2416 || ((flags & HEXA_FLOAT)
2417 && char_buffer_size (&charbuf) == 2)))
2418 conv_error ();
2420 scan_float:
2421 /* Convert the number. */
2422 char_buffer_add (&charbuf, L_('\0'));
2423 if (char_buffer_error (&charbuf))
2425 __set_errno (ENOMEM);
2426 done = EOF;
2427 goto errout;
2429 if ((flags & LONGDBL) && !__ldbl_is_dbl)
2431 long double d = __strtold_internal
2432 (char_buffer_start (&charbuf), &tw, flags & GROUP);
2433 if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
2434 *ARG (long double *) = negative ? -d : d;
2436 else if (flags & (LONG | LONGDBL))
2438 double d = __strtod_internal
2439 (char_buffer_start (&charbuf), &tw, flags & GROUP);
2440 if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
2441 *ARG (double *) = negative ? -d : d;
2443 else
2445 float d = __strtof_internal
2446 (char_buffer_start (&charbuf), &tw, flags & GROUP);
2447 if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
2448 *ARG (float *) = negative ? -d : d;
2451 if (__glibc_unlikely (tw == char_buffer_start (&charbuf)))
2452 conv_error ();
2454 if (!(flags & SUPPRESS))
2455 ++done;
2456 break;
2458 case L_('['): /* Character class. */
2459 if (flags & LONG)
2460 STRING_ARG (wstr, wchar_t, 100);
2461 else
2462 STRING_ARG (str, char, 100);
2464 if (*f == L_('^'))
2466 ++f;
2467 not_in = 1;
2469 else
2470 not_in = 0;
2472 if (width < 0)
2473 /* There is no width given so there is also no limit on the
2474 number of characters we read. Therefore we set width to
2475 a very high value to make the algorithm easier. */
2476 width = INT_MAX;
2478 #ifdef COMPILE_WSCANF
2479 /* Find the beginning and the end of the scanlist. We are not
2480 creating a lookup table since it would have to be too large.
2481 Instead we search each time through the string. This is not
2482 a constant lookup time but who uses this feature deserves to
2483 be punished. */
2484 tw = (wchar_t *) f; /* Marks the beginning. */
2486 if (*f == L']')
2487 ++f;
2489 while ((fc = *f++) != L'\0' && fc != L']');
2491 if (__glibc_unlikely (fc == L'\0'))
2492 conv_error ();
2493 wchar_t *twend = (wchar_t *) f - 1;
2494 #else
2495 /* Fill WP with byte flags indexed by character.
2496 We will use this flag map for matching input characters. */
2497 if (!scratch_buffer_set_array_size
2498 (&charbuf.scratch, UCHAR_MAX + 1, 1))
2500 done = EOF;
2501 goto errout;
2503 memset (charbuf.scratch.data, '\0', UCHAR_MAX + 1);
2505 fc = *f;
2506 if (fc == ']' || fc == '-')
2508 /* If ] or - appears before any char in the set, it is not
2509 the terminator or separator, but the first char in the
2510 set. */
2511 ((char *)charbuf.scratch.data)[fc] = 1;
2512 ++f;
2515 while ((fc = *f++) != '\0' && fc != ']')
2516 if (fc == '-' && *f != '\0' && *f != ']'
2517 && (unsigned char) f[-2] <= (unsigned char) *f)
2519 /* Add all characters from the one before the '-'
2520 up to (but not including) the next format char. */
2521 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
2522 ((char *)charbuf.scratch.data)[fc] = 1;
2524 else
2525 /* Add the character to the flag map. */
2526 ((char *)charbuf.scratch.data)[fc] = 1;
2528 if (__glibc_unlikely (fc == '\0'))
2529 conv_error();
2530 #endif
2532 if (flags & LONG)
2534 size_t now = read_in;
2535 #ifdef COMPILE_WSCANF
2536 if (__glibc_unlikely (inchar () == WEOF))
2537 input_error ();
2541 wchar_t *runp;
2543 /* Test whether it's in the scanlist. */
2544 runp = tw;
2545 while (runp < twend)
2547 if (runp[0] == L'-' && runp[1] != '\0'
2548 && runp + 1 != twend
2549 && runp != tw
2550 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2552 /* Match against all characters in between the
2553 first and last character of the sequence. */
2554 wchar_t wc;
2556 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2557 if ((wint_t) wc == c)
2558 break;
2560 if (wc <= runp[1] && !not_in)
2561 break;
2562 if (wc <= runp[1] && not_in)
2564 /* The current character is not in the
2565 scanset. */
2566 ungetc (c, s);
2567 goto out;
2570 runp += 2;
2572 else
2574 if ((wint_t) *runp == c && !not_in)
2575 break;
2576 if ((wint_t) *runp == c && not_in)
2578 ungetc (c, s);
2579 goto out;
2582 ++runp;
2586 if (runp == twend && !not_in)
2588 ungetc (c, s);
2589 goto out;
2592 if (!(flags & SUPPRESS))
2594 *wstr++ = c;
2596 if ((flags & MALLOC)
2597 && wstr == (wchar_t *) *strptr + strsize)
2599 /* Enlarge the buffer. */
2600 wstr = (wchar_t *) realloc (*strptr,
2601 (2 * strsize)
2602 * sizeof (wchar_t));
2603 if (wstr == NULL)
2605 /* Can't allocate that much. Last-ditch
2606 effort. */
2607 wstr = (wchar_t *)
2608 realloc (*strptr, (strsize + 1)
2609 * sizeof (wchar_t));
2610 if (wstr == NULL)
2612 if (flags & POSIX_MALLOC)
2614 done = EOF;
2615 goto errout;
2617 /* We lose. Oh well. Terminate the string
2618 and stop converting, so at least we don't
2619 skip any input. */
2620 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2621 strptr = NULL;
2622 ++done;
2623 conv_error ();
2625 else
2627 *strptr = (char *) wstr;
2628 wstr += strsize;
2629 ++strsize;
2632 else
2634 *strptr = (char *) wstr;
2635 wstr += strsize;
2636 strsize *= 2;
2641 while (--width > 0 && inchar () != WEOF);
2642 out:
2643 #else
2644 char buf[MB_LEN_MAX];
2645 size_t cnt = 0;
2646 mbstate_t cstate;
2648 if (__glibc_unlikely (inchar () == EOF))
2649 input_error ();
2651 memset (&cstate, '\0', sizeof (cstate));
2655 if (((char *) charbuf.scratch.data)[c] == not_in)
2657 ungetc_not_eof (c, s);
2658 break;
2661 /* This is easy. */
2662 if (!(flags & SUPPRESS))
2664 size_t n;
2666 /* Convert it into a wide character. */
2667 buf[0] = c;
2668 n = __mbrtowc (wstr, buf, 1, &cstate);
2670 if (n == (size_t) -2)
2672 /* Possibly correct character, just not enough
2673 input. */
2674 ++cnt;
2675 assert (cnt < MB_LEN_MAX);
2676 continue;
2678 cnt = 0;
2680 ++wstr;
2681 if ((flags & MALLOC)
2682 && wstr == (wchar_t *) *strptr + strsize)
2684 /* Enlarge the buffer. */
2685 wstr = (wchar_t *) realloc (*strptr,
2686 (2 * strsize
2687 * sizeof (wchar_t)));
2688 if (wstr == NULL)
2690 /* Can't allocate that much. Last-ditch
2691 effort. */
2692 wstr = (wchar_t *)
2693 realloc (*strptr, ((strsize + 1)
2694 * sizeof (wchar_t)));
2695 if (wstr == NULL)
2697 if (flags & POSIX_MALLOC)
2699 done = EOF;
2700 goto errout;
2702 /* We lose. Oh well. Terminate the
2703 string and stop converting,
2704 so at least we don't skip any input. */
2705 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2706 strptr = NULL;
2707 ++done;
2708 conv_error ();
2710 else
2712 *strptr = (char *) wstr;
2713 wstr += strsize;
2714 ++strsize;
2717 else
2719 *strptr = (char *) wstr;
2720 wstr += strsize;
2721 strsize *= 2;
2726 if (--width <= 0)
2727 break;
2729 while (inchar () != EOF);
2731 if (__glibc_unlikely (cnt != 0))
2732 /* We stopped in the middle of recognizing another
2733 character. That's a problem. */
2734 encode_error ();
2735 #endif
2737 if (__glibc_unlikely (now == read_in))
2738 /* We haven't succesfully read any character. */
2739 conv_error ();
2741 if (!(flags & SUPPRESS))
2743 *wstr++ = L'\0';
2745 if ((flags & MALLOC)
2746 && wstr - (wchar_t *) *strptr != strsize)
2748 wchar_t *cp = (wchar_t *)
2749 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2750 * sizeof(wchar_t)));
2751 if (cp != NULL)
2752 *strptr = (char *) cp;
2754 strptr = NULL;
2756 ++done;
2759 else
2761 size_t now = read_in;
2763 if (__glibc_unlikely (inchar () == EOF))
2764 input_error ();
2766 #ifdef COMPILE_WSCANF
2768 memset (&state, '\0', sizeof (state));
2772 wchar_t *runp;
2773 size_t n;
2775 /* Test whether it's in the scanlist. */
2776 runp = tw;
2777 while (runp < twend)
2779 if (runp[0] == L'-' && runp[1] != '\0'
2780 && runp + 1 != twend
2781 && runp != tw
2782 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2784 /* Match against all characters in between the
2785 first and last character of the sequence. */
2786 wchar_t wc;
2788 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2789 if ((wint_t) wc == c)
2790 break;
2792 if (wc <= runp[1] && !not_in)
2793 break;
2794 if (wc <= runp[1] && not_in)
2796 /* The current character is not in the
2797 scanset. */
2798 ungetc (c, s);
2799 goto out2;
2802 runp += 2;
2804 else
2806 if ((wint_t) *runp == c && !not_in)
2807 break;
2808 if ((wint_t) *runp == c && not_in)
2810 ungetc (c, s);
2811 goto out2;
2814 ++runp;
2818 if (runp == twend && !not_in)
2820 ungetc (c, s);
2821 goto out2;
2824 if (!(flags & SUPPRESS))
2826 if ((flags & MALLOC)
2827 && *strptr + strsize - str <= MB_LEN_MAX)
2829 /* Enlarge the buffer. */
2830 size_t strleng = str - *strptr;
2831 char *newstr;
2833 newstr = (char *) realloc (*strptr, 2 * strsize);
2834 if (newstr == NULL)
2836 /* Can't allocate that much. Last-ditch
2837 effort. */
2838 newstr = (char *) realloc (*strptr,
2839 strleng + MB_LEN_MAX);
2840 if (newstr == NULL)
2842 if (flags & POSIX_MALLOC)
2844 done = EOF;
2845 goto errout;
2847 /* We lose. Oh well. Terminate the string
2848 and stop converting, so at least we don't
2849 skip any input. */
2850 ((char *) (*strptr))[strleng] = '\0';
2851 strptr = NULL;
2852 ++done;
2853 conv_error ();
2855 else
2857 *strptr = newstr;
2858 str = newstr + strleng;
2859 strsize = strleng + MB_LEN_MAX;
2862 else
2864 *strptr = newstr;
2865 str = newstr + strleng;
2866 strsize *= 2;
2871 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2872 if (__glibc_unlikely (n == (size_t) -1))
2873 encode_error ();
2875 assert (n <= MB_LEN_MAX);
2876 str += n;
2878 while (--width > 0 && inchar () != WEOF);
2879 out2:
2880 #else
2883 if (((char *) charbuf.scratch.data)[c] == not_in)
2885 ungetc_not_eof (c, s);
2886 break;
2889 /* This is easy. */
2890 if (!(flags & SUPPRESS))
2892 *str++ = c;
2893 if ((flags & MALLOC)
2894 && (char *) str == *strptr + strsize)
2896 /* Enlarge the buffer. */
2897 size_t newsize = 2 * strsize;
2899 allocagain:
2900 str = (char *) realloc (*strptr, newsize);
2901 if (str == NULL)
2903 /* Can't allocate that much. Last-ditch
2904 effort. */
2905 if (newsize > strsize + 1)
2907 newsize = strsize + 1;
2908 goto allocagain;
2910 if (flags & POSIX_MALLOC)
2912 done = EOF;
2913 goto errout;
2915 /* We lose. Oh well. Terminate the
2916 string and stop converting,
2917 so at least we don't skip any input. */
2918 ((char *) (*strptr))[strsize - 1] = '\0';
2919 strptr = NULL;
2920 ++done;
2921 conv_error ();
2923 else
2925 *strptr = (char *) str;
2926 str += strsize;
2927 strsize = newsize;
2932 while (--width > 0 && inchar () != EOF);
2933 #endif
2935 if (__glibc_unlikely (now == read_in))
2936 /* We haven't succesfully read any character. */
2937 conv_error ();
2939 if (!(flags & SUPPRESS))
2941 #ifdef COMPILE_WSCANF
2942 /* We have to emit the code to get into the initial
2943 state. */
2944 char buf[MB_LEN_MAX];
2945 size_t n = __wcrtomb (buf, L'\0', &state);
2946 if (n > 0 && (flags & MALLOC)
2947 && str + n >= *strptr + strsize)
2949 /* Enlarge the buffer. */
2950 size_t strleng = str - *strptr;
2951 char *newstr;
2953 newstr = (char *) realloc (*strptr, strleng + n + 1);
2954 if (newstr == NULL)
2956 if (flags & POSIX_MALLOC)
2958 done = EOF;
2959 goto errout;
2961 /* We lose. Oh well. Terminate the string
2962 and stop converting, so at least we don't
2963 skip any input. */
2964 ((char *) (*strptr))[strleng] = '\0';
2965 strptr = NULL;
2966 ++done;
2967 conv_error ();
2969 else
2971 *strptr = newstr;
2972 str = newstr + strleng;
2973 strsize = strleng + n + 1;
2977 str = __mempcpy (str, buf, n);
2978 #endif
2979 *str++ = '\0';
2981 if ((flags & MALLOC) && str - *strptr != strsize)
2983 char *cp = (char *) realloc (*strptr, str - *strptr);
2984 if (cp != NULL)
2985 *strptr = cp;
2987 strptr = NULL;
2989 ++done;
2992 break;
2994 case L_('p'): /* Generic pointer. */
2995 base = 16;
2996 /* A PTR must be the same size as a `long int'. */
2997 flags &= ~(SHORT|LONGDBL);
2998 if (need_long)
2999 flags |= LONG;
3000 flags |= READ_POINTER;
3001 goto number;
3003 default:
3004 /* If this is an unknown format character punt. */
3005 conv_error ();
3009 /* The last thing we saw int the format string was a white space.
3010 Consume the last white spaces. */
3011 if (skip_space)
3014 c = inchar ();
3015 while (ISSPACE (c));
3016 ungetc (c, s);
3019 errout:
3020 /* Unlock stream. */
3021 UNLOCK_STREAM (s);
3023 scratch_buffer_free (&charbuf.scratch);
3024 if (errp != NULL)
3025 *errp |= errval;
3027 if (__glibc_unlikely (done == EOF))
3029 if (__glibc_unlikely (ptrs_to_free != NULL))
3031 struct ptrs_to_free *p = ptrs_to_free;
3032 while (p != NULL)
3034 for (size_t cnt = 0; cnt < p->count; ++cnt)
3036 free (*p->ptrs[cnt]);
3037 *p->ptrs[cnt] = NULL;
3039 p = p->next;
3040 ptrs_to_free = p;
3044 else if (__glibc_unlikely (strptr != NULL))
3046 free (*strptr);
3047 *strptr = NULL;
3049 return done;
3052 #ifdef COMPILE_WSCANF
3054 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
3056 return _IO_vfwscanf (s, format, argptr, NULL);
3058 ldbl_weak_alias (__vfwscanf, vfwscanf)
3059 #else
3061 ___vfscanf (FILE *s, const char *format, va_list argptr)
3063 return _IO_vfscanf_internal (s, format, argptr, NULL);
3065 ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
3066 ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf)
3067 ldbl_strong_alias (___vfscanf, __vfscanf)
3068 ldbl_hidden_def (___vfscanf, __vfscanf)
3069 ldbl_weak_alias (___vfscanf, vfscanf)
3070 #endif