(rfc3484_sort): Make sure that even if qsort doesn't support
[glibc.git] / stdio-common / vfscanf.c
blobe4728d00c951763d79ccb2b6c9af44896d65c74e
1 /* Copyright (C) 1991-2006, 2007 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, write to the Free
16 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA. */
19 #include <assert.h>
20 #include <errno.h>
21 #include <limits.h>
22 #include <ctype.h>
23 #include <stdarg.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 INTUSE(_IO_sputbackwc) (s, c))))
82 # define ungetc_not_eof(c, s) ((void) (--read_in, \
83 INTUSE(_IO_sputbackwc) (s, c)))
84 # define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
85 : ((c = _IO_getwc_unlocked (s)), \
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 (s, 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 INTUSE(_IO_sputbackc) (s, (unsigned char) c))))
114 # define ungetc_not_eof(c, s) ((void) (--read_in, \
115 INTUSE(_IO_sputbackc) (s, (unsigned char) c)))
116 # define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
117 : ((c = _IO_getc_unlocked (s)), \
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 (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 #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 /* Read formatted input from S according to the format string
196 FORMAT, using the argument list in ARG.
197 Return the number of assignments made, or -1 for an input error. */
198 #ifdef COMPILE_WSCANF
200 _IO_vfwscanf (_IO_FILE *s, const wchar_t *format, _IO_va_list argptr,
201 int *errp)
202 #else
204 _IO_vfscanf_internal (_IO_FILE *s, const char *format, _IO_va_list argptr,
205 int *errp)
206 #endif
208 va_list arg;
209 register const CHAR_T *f = format;
210 register UCHAR_T fc; /* Current character of the format. */
211 register WINT_T done = 0; /* Assignments done. */
212 register size_t read_in = 0; /* Chars read in. */
213 register WINT_T c = 0; /* Last char read. */
214 register int width; /* Maximum field width. */
215 register int flags; /* Modifiers for current format element. */
216 int errval = 0;
217 #ifndef COMPILE_WSCANF
218 __locale_t loc = _NL_CURRENT_LOCALE;
219 struct locale_data *const curctype = loc->__locales[LC_CTYPE];
220 #endif
222 /* Errno of last failed inchar call. */
223 int inchar_errno = 0;
224 /* Status for reading F-P nums. */
225 char got_dot, got_e, negative;
226 /* If a [...] is a [^...]. */
227 CHAR_T not_in;
228 #define exp_char not_in
229 /* Base for integral numbers. */
230 int base;
231 /* Decimal point character. */
232 #ifdef COMPILE_WSCANF
233 wint_t decimal;
234 #else
235 const char *decimal;
236 #endif
237 /* The thousands character of the current locale. */
238 #ifdef COMPILE_WSCANF
239 wint_t thousands;
240 #else
241 const char *thousands;
242 #endif
243 struct ptrs_to_free *ptrs_to_free = NULL;
244 /* State for the conversions. */
245 mbstate_t state;
246 /* Integral holding variables. */
247 union
249 long long int q;
250 unsigned long long int uq;
251 long int l;
252 unsigned long int ul;
253 } num;
254 /* Character-buffer pointer. */
255 char *str = NULL;
256 wchar_t *wstr = NULL;
257 char **strptr = NULL;
258 ssize_t strsize = 0;
259 /* We must not react on white spaces immediately because they can
260 possibly be matched even if in the input stream no character is
261 available anymore. */
262 int skip_space = 0;
263 /* Workspace. */
264 CHAR_T *tw; /* Temporary pointer. */
265 CHAR_T *wp = NULL; /* Workspace. */
266 size_t wpmax = 0; /* Maximal size of workspace. */
267 size_t wpsize; /* Currently used bytes in workspace. */
268 #define ADDW(Ch) \
269 do \
271 if (wpsize == wpmax) \
273 CHAR_T *old = wp; \
274 wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
275 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
276 if (old != NULL) \
277 MEMCPY (wp, old, wpsize); \
279 wp[wpsize++] = (Ch); \
281 while (0)
283 #ifdef __va_copy
284 __va_copy (arg, argptr);
285 #else
286 arg = (va_list) argptr;
287 #endif
289 #ifdef ORIENT
290 ORIENT;
291 #endif
293 ARGCHECK (s, format);
296 #ifndef COMPILE_WSCANF
297 struct locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
298 #endif
300 /* Figure out the decimal point character. */
301 #ifdef COMPILE_WSCANF
302 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
303 #else
304 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
305 #endif
306 /* Figure out the thousands separator character. */
307 #ifdef COMPILE_WSCANF
308 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
309 #else
310 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
311 if (*thousands == '\0')
312 thousands = NULL;
313 #endif
316 /* Lock the stream. */
317 LOCK_STREAM (s);
320 #ifndef COMPILE_WSCANF
321 /* From now on we use `state' to convert the format string. */
322 memset (&state, '\0', sizeof (state));
323 #endif
325 /* Run through the format string. */
326 while (*f != '\0')
328 unsigned int argpos;
329 /* Extract the next argument, which is of type TYPE.
330 For a %N$... spec, this is the Nth argument from the beginning;
331 otherwise it is the next argument after the state now in ARG. */
332 #ifdef __va_copy
333 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
334 ({ unsigned int pos = argpos; \
335 va_list arg; \
336 __va_copy (arg, argptr); \
337 while (--pos > 0) \
338 (void) va_arg (arg, void *); \
339 va_arg (arg, type); \
341 #else
342 # if 0
343 /* XXX Possible optimization. */
344 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
345 ({ va_list arg = (va_list) argptr; \
346 arg = (va_list) ((char *) arg \
347 + (argpos - 1) \
348 * __va_rounded_size (void *)); \
349 va_arg (arg, type); \
351 # else
352 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
353 ({ unsigned int pos = argpos; \
354 va_list arg = (va_list) argptr; \
355 while (--pos > 0) \
356 (void) va_arg (arg, void *); \
357 va_arg (arg, type); \
359 # endif
360 #endif
362 #ifndef COMPILE_WSCANF
363 if (!isascii ((unsigned char) *f))
365 /* Non-ASCII, may be a multibyte. */
366 int len = __mbrlen (f, strlen (f), &state);
367 if (len > 0)
371 c = inchar ();
372 if (__builtin_expect (c == EOF, 0))
373 input_error ();
374 else if (c != (unsigned char) *f++)
376 ungetc_not_eof (c, s);
377 conv_error ();
380 while (--len > 0);
381 continue;
384 #endif
386 fc = *f++;
387 if (fc != '%')
389 /* Remember to skip spaces. */
390 if (ISSPACE (fc))
392 skip_space = 1;
393 continue;
396 /* Read a character. */
397 c = inchar ();
399 /* Characters other than format specs must just match. */
400 if (__builtin_expect (c == EOF, 0))
401 input_error ();
403 /* We saw white space char as the last character in the format
404 string. Now it's time to skip all leading white space. */
405 if (skip_space)
407 while (ISSPACE (c))
408 if (__builtin_expect (inchar () == EOF, 0))
409 input_error ();
410 skip_space = 0;
413 if (__builtin_expect (c != fc, 0))
415 ungetc (c, s);
416 conv_error ();
419 continue;
422 /* This is the start of the conversion string. */
423 flags = 0;
425 /* Initialize state of modifiers. */
426 argpos = 0;
428 /* Prepare temporary buffer. */
429 wpsize = 0;
431 /* Check for a positional parameter specification. */
432 if (ISDIGIT ((UCHAR_T) *f))
434 argpos = (UCHAR_T) *f++ - L_('0');
435 while (ISDIGIT ((UCHAR_T) *f))
436 argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
437 if (*f == L_('$'))
438 ++f;
439 else
441 /* Oops; that was actually the field width. */
442 width = argpos;
443 argpos = 0;
444 goto got_width;
448 /* Check for the assignment-suppressing, the number grouping flag,
449 and the signal to use the locale's digit representation. */
450 while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
451 switch (*f++)
453 case L_('*'):
454 flags |= SUPPRESS;
455 break;
456 case L_('\''):
457 #ifdef COMPILE_WSCANF
458 if (thousands != L'\0')
459 #else
460 if (thousands != NULL)
461 #endif
462 flags |= GROUP;
463 break;
464 case L_('I'):
465 flags |= I18N;
466 break;
469 /* Find the maximum field width. */
470 width = 0;
471 while (ISDIGIT ((UCHAR_T) *f))
473 width *= 10;
474 width += (UCHAR_T) *f++ - L_('0');
476 got_width:
477 if (width == 0)
478 width = -1;
480 /* Check for type modifiers. */
481 switch (*f++)
483 case L_('h'):
484 /* ints are short ints or chars. */
485 if (*f == L_('h'))
487 ++f;
488 flags |= CHAR;
490 else
491 flags |= SHORT;
492 break;
493 case L_('l'):
494 if (*f == L_('l'))
496 /* A double `l' is equivalent to an `L'. */
497 ++f;
498 flags |= LONGDBL | LONG;
500 else
501 /* ints are long ints. */
502 flags |= LONG;
503 break;
504 case L_('q'):
505 case L_('L'):
506 /* doubles are long doubles, and ints are long long ints. */
507 flags |= LONGDBL | LONG;
508 break;
509 case L_('a'):
510 /* The `a' is used as a flag only if followed by `s', `S' or
511 `['. */
512 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
514 --f;
515 break;
517 /* In __isoc99_*scanf %as, %aS and %a[ extension is not
518 supported at all. */
519 if (s->_flags2 & _IO_FLAGS2_SCANF_STD)
521 --f;
522 break;
524 /* String conversions (%s, %[) take a `char **'
525 arg and fill it in with a malloc'd pointer. */
526 flags |= GNU_MALLOC;
527 break;
528 case L_('m'):
529 flags |= POSIX_MALLOC;
530 if (*f == L_('l'))
532 ++f;
533 flags |= LONG;
535 break;
536 case L_('z'):
537 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
538 flags |= LONGDBL;
539 else if (sizeof (size_t) > sizeof (unsigned int))
540 flags |= LONG;
541 break;
542 case L_('j'):
543 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
544 flags |= LONGDBL;
545 else if (sizeof (uintmax_t) > sizeof (unsigned int))
546 flags |= LONG;
547 break;
548 case L_('t'):
549 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
550 flags |= LONGDBL;
551 else if (sizeof (ptrdiff_t) > sizeof (int))
552 flags |= LONG;
553 break;
554 default:
555 /* Not a recognized modifier. Backup. */
556 --f;
557 break;
560 /* End of the format string? */
561 if (__builtin_expect (*f == L_('\0'), 0))
562 conv_error ();
564 /* Find the conversion specifier. */
565 fc = *f++;
566 if (skip_space || (fc != L_('[') && fc != L_('c')
567 && fc != L_('C') && fc != L_('n')))
569 /* Eat whitespace. */
570 int save_errno = errno;
571 __set_errno (0);
573 /* We add the additional test for EOF here since otherwise
574 inchar will restore the old errno value which might be
575 EINTR but does not indicate an interrupt since nothing
576 was read at this time. */
577 if (__builtin_expect ((c == EOF || inchar () == EOF)
578 && errno == EINTR, 0))
579 input_error ();
580 while (ISSPACE (c));
581 __set_errno (save_errno);
582 ungetc (c, s);
583 skip_space = 0;
586 switch (fc)
588 case L_('%'): /* Must match a literal '%'. */
589 c = inchar ();
590 if (__builtin_expect (c == EOF, 0))
591 input_error ();
592 if (__builtin_expect (c != fc, 0))
594 ungetc_not_eof (c, s);
595 conv_error ();
597 break;
599 case L_('n'): /* Answer number of assignments done. */
600 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
601 with the 'n' conversion specifier. */
602 if (!(flags & SUPPRESS))
604 /* Don't count the read-ahead. */
605 if (need_longlong && (flags & LONGDBL))
606 *ARG (long long int *) = read_in;
607 else if (need_long && (flags & LONG))
608 *ARG (long int *) = read_in;
609 else if (flags & SHORT)
610 *ARG (short int *) = read_in;
611 else if (!(flags & CHAR))
612 *ARG (int *) = read_in;
613 else
614 *ARG (char *) = read_in;
616 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
617 /* We have a severe problem here. The ISO C standard
618 contradicts itself in explaining the effect of the %n
619 format in `scanf'. While in ISO C:1990 and the ISO C
620 Amendement 1:1995 the result is described as
622 Execution of a %n directive does not effect the
623 assignment count returned at the completion of
624 execution of the f(w)scanf function.
626 in ISO C Corrigendum 1:1994 the following was added:
628 Subclause 7.9.6.2
629 Add the following fourth example:
631 #include <stdio.h>
632 int d1, d2, n1, n2, i;
633 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
634 the value 123 is assigned to d1 and the value3 to n1.
635 Because %n can never get an input failure the value
636 of 3 is also assigned to n2. The value of d2 is not
637 affected. The value 3 is assigned to i.
639 We go for now with the historically correct code from ISO C,
640 i.e., we don't count the %n assignments. When it ever
641 should proof to be wrong just remove the #ifdef above. */
642 ++done;
643 #endif
645 break;
647 case L_('c'): /* Match characters. */
648 if ((flags & LONG) == 0)
650 if (width == -1)
651 width = 1;
653 #define STRING_ARG(Str, Type, Width) \
654 do if (!(flags & SUPPRESS)) \
656 if (flags & MALLOC) \
658 /* The string is to be stored in a malloc'd buffer. */ \
659 /* For %mS using char ** is actually wrong, but \
660 shouldn't make a difference on any arch glibc \
661 supports and would unnecessarily complicate \
662 things. */ \
663 strptr = ARG (char **); \
664 if (strptr == NULL) \
665 conv_error (); \
666 /* Allocate an initial buffer. */ \
667 strsize = Width; \
668 *strptr = (char *) malloc (strsize * sizeof (Type)); \
669 Str = (Type *) *strptr; \
670 if (Str != NULL) \
671 add_ptr_to_free (strptr); \
672 else if (flags & POSIX_MALLOC) \
673 goto reteof; \
675 else \
676 Str = ARG (Type *); \
677 if (Str == NULL) \
678 conv_error (); \
679 } while (0)
680 #ifdef COMPILE_WSCANF
681 STRING_ARG (str, char, 100);
682 #else
683 STRING_ARG (str, char, (width > 1024 ? 1024 : width));
684 #endif
686 c = inchar ();
687 if (__builtin_expect (c == EOF, 0))
688 input_error ();
690 #ifdef COMPILE_WSCANF
691 /* We have to convert the wide character(s) into multibyte
692 characters and store the result. */
693 memset (&state, '\0', sizeof (state));
697 size_t n;
699 if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
700 && str + MB_CUR_MAX >= *strptr + strsize)
702 /* We have to enlarge the buffer if the `m' flag
703 was given. */
704 size_t strleng = str - *strptr;
705 char *newstr;
707 newstr = (char *) realloc (*strptr, strsize * 2);
708 if (newstr == NULL)
710 /* Can't allocate that much. Last-ditch effort. */
711 newstr = (char *) realloc (*strptr,
712 strleng + MB_CUR_MAX);
713 if (newstr == NULL)
714 /* c can't have `a' flag, only `m'. */
715 goto reteof;
716 else
718 *strptr = newstr;
719 str = newstr + strleng;
720 strsize = strleng + MB_CUR_MAX;
723 else
725 *strptr = newstr;
726 str = newstr + strleng;
727 strsize *= 2;
731 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
732 if (__builtin_expect (n == (size_t) -1, 0))
733 /* No valid wide character. */
734 input_error ();
736 /* Increment the output pointer. Even if we don't
737 write anything. */
738 str += n;
740 while (--width > 0 && inchar () != EOF);
741 #else
742 if (!(flags & SUPPRESS))
746 if ((flags & MALLOC)
747 && (char *) str == *strptr + strsize)
749 /* Enlarge the buffer. */
750 size_t newsize
751 = strsize
752 + (strsize >= width ? width - 1 : strsize);
754 str = (char *) realloc (*strptr, newsize);
755 if (str == NULL)
757 /* Can't allocate that much. Last-ditch
758 effort. */
759 str = (char *) realloc (*strptr, strsize + 1);
760 if (str == NULL)
761 /* c can't have `a' flag, only `m'. */
762 goto reteof;
763 else
765 *strptr = (char *) str;
766 str += strsize;
767 ++strsize;
770 else
772 *strptr = (char *) str;
773 str += strsize;
774 strsize = newsize;
777 *str++ = c;
779 while (--width > 0 && inchar () != EOF);
781 else
782 while (--width > 0 && inchar () != EOF);
783 #endif
785 if (!(flags & SUPPRESS))
787 if ((flags & MALLOC) && str - *strptr != strsize)
789 char *cp = (char *) realloc (*strptr, str - *strptr);
790 if (cp != NULL)
791 *strptr = cp;
793 strptr = NULL;
794 ++done;
797 break;
799 /* FALLTHROUGH */
800 case L_('C'):
801 if (width == -1)
802 width = 1;
804 STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width));
806 c = inchar ();
807 if (__builtin_expect (c == EOF, 0))
808 input_error ();
810 #ifdef COMPILE_WSCANF
811 /* Just store the incoming wide characters. */
812 if (!(flags & SUPPRESS))
816 if ((flags & MALLOC)
817 && wstr == (wchar_t *) *strptr + strsize)
819 size_t newsize
820 = strsize + (strsize > width ? width - 1 : strsize);
821 /* Enlarge the buffer. */
822 wstr = (wchar_t *) realloc (*strptr,
823 newsize * sizeof (wchar_t));
824 if (wstr == NULL)
826 /* Can't allocate that much. Last-ditch effort. */
827 wstr = (wchar_t *) realloc (*strptr,
828 (strsize + 1)
829 * sizeof (wchar_t));
830 if (wstr == NULL)
831 /* C or lc can't have `a' flag, only `m' flag. */
832 goto reteof;
833 else
835 *strptr = (char *) wstr;
836 wstr += strsize;
837 ++strsize;
840 else
842 *strptr = (char *) wstr;
843 wstr += strsize;
844 strsize = newsize;
847 *wstr++ = c;
849 while (--width > 0 && inchar () != EOF);
851 else
852 while (--width > 0 && inchar () != EOF);
853 #else
855 /* We have to convert the multibyte input sequence to wide
856 characters. */
857 char buf[1];
858 mbstate_t cstate;
860 memset (&cstate, '\0', sizeof (cstate));
864 /* This is what we present the mbrtowc function first. */
865 buf[0] = c;
867 if (!(flags & SUPPRESS) && (flags & MALLOC)
868 && wstr == (wchar_t *) *strptr + strsize)
870 size_t newsize
871 = strsize + (strsize > width ? width - 1 : strsize);
872 /* Enlarge the buffer. */
873 wstr = (wchar_t *) realloc (*strptr,
874 newsize * sizeof (wchar_t));
875 if (wstr == NULL)
877 /* Can't allocate that much. Last-ditch effort. */
878 wstr = (wchar_t *) realloc (*strptr,
879 ((strsize + 1)
880 * sizeof (wchar_t)));
881 if (wstr == NULL)
882 /* C or lc can't have `a' flag, only `m' flag. */
883 goto reteof;
884 else
886 *strptr = (char *) wstr;
887 wstr += strsize;
888 ++strsize;
891 else
893 *strptr = (char *) wstr;
894 wstr += strsize;
895 strsize = newsize;
899 while (1)
901 size_t n;
903 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
904 buf, 1, &cstate);
906 if (n == (size_t) -2)
908 /* Possibly correct character, just not enough
909 input. */
910 if (__builtin_expect (inchar () == EOF, 0))
911 encode_error ();
913 buf[0] = c;
914 continue;
917 if (__builtin_expect (n != 1, 0))
918 encode_error ();
920 /* We have a match. */
921 break;
924 /* Advance the result pointer. */
925 ++wstr;
927 while (--width > 0 && inchar () != EOF);
929 #endif
931 if (!(flags & SUPPRESS))
933 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
935 wchar_t *cp = (wchar_t *) realloc (*strptr,
936 ((wstr
937 - (wchar_t *) *strptr)
938 * sizeof (wchar_t)));
939 if (cp != NULL)
940 *strptr = (char *) cp;
942 strptr = NULL;
944 ++done;
947 break;
949 case L_('s'): /* Read a string. */
950 if (!(flags & LONG))
952 STRING_ARG (str, char, 100);
954 c = inchar ();
955 if (__builtin_expect (c == EOF, 0))
956 input_error ();
958 #ifdef COMPILE_WSCANF
959 memset (&state, '\0', sizeof (state));
960 #endif
964 if (ISSPACE (c))
966 ungetc_not_eof (c, s);
967 break;
970 #ifdef COMPILE_WSCANF
971 /* This is quite complicated. We have to convert the
972 wide characters into multibyte characters and then
973 store them. */
975 size_t n;
977 if (!(flags & SUPPRESS) && (flags & MALLOC)
978 && str + MB_CUR_MAX >= *strptr + strsize)
980 /* We have to enlarge the buffer if the `a' or `m'
981 flag was given. */
982 size_t strleng = str - *strptr;
983 char *newstr;
985 newstr = (char *) realloc (*strptr, strsize * 2);
986 if (newstr == NULL)
988 /* Can't allocate that much. Last-ditch
989 effort. */
990 newstr = (char *) realloc (*strptr,
991 strleng + MB_CUR_MAX);
992 if (newstr == NULL)
994 if (flags & POSIX_MALLOC)
995 goto reteof;
996 /* We lose. Oh well. Terminate the
997 string and stop converting,
998 so at least we don't skip any input. */
999 ((char *) (*strptr))[strleng] = '\0';
1000 strptr = NULL;
1001 ++done;
1002 conv_error ();
1004 else
1006 *strptr = newstr;
1007 str = newstr + strleng;
1008 strsize = strleng + MB_CUR_MAX;
1011 else
1013 *strptr = newstr;
1014 str = newstr + strleng;
1015 strsize *= 2;
1019 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
1020 &state);
1021 if (__builtin_expect (n == (size_t) -1, 0))
1022 encode_error ();
1024 assert (n <= MB_CUR_MAX);
1025 str += n;
1027 #else
1028 /* This is easy. */
1029 if (!(flags & SUPPRESS))
1031 *str++ = c;
1032 if ((flags & MALLOC)
1033 && (char *) str == *strptr + strsize)
1035 /* Enlarge the buffer. */
1036 str = (char *) realloc (*strptr, 2 * strsize);
1037 if (str == NULL)
1039 /* Can't allocate that much. Last-ditch
1040 effort. */
1041 str = (char *) realloc (*strptr, strsize + 1);
1042 if (str == NULL)
1044 if (flags & POSIX_MALLOC)
1045 goto reteof;
1046 /* We lose. Oh well. Terminate the
1047 string and stop converting,
1048 so at least we don't skip any input. */
1049 ((char *) (*strptr))[strsize - 1] = '\0';
1050 strptr = NULL;
1051 ++done;
1052 conv_error ();
1054 else
1056 *strptr = (char *) str;
1057 str += strsize;
1058 ++strsize;
1061 else
1063 *strptr = (char *) str;
1064 str += strsize;
1065 strsize *= 2;
1069 #endif
1071 while ((width <= 0 || --width > 0) && inchar () != EOF);
1073 if (!(flags & SUPPRESS))
1075 #ifdef COMPILE_WSCANF
1076 /* We have to emit the code to get into the initial
1077 state. */
1078 char buf[MB_LEN_MAX];
1079 size_t n = __wcrtomb (buf, L'\0', &state);
1080 if (n > 0 && (flags & MALLOC)
1081 && str + n >= *strptr + strsize)
1083 /* Enlarge the buffer. */
1084 size_t strleng = str - *strptr;
1085 char *newstr;
1087 newstr = (char *) realloc (*strptr, strleng + n + 1);
1088 if (newstr == NULL)
1090 if (flags & POSIX_MALLOC)
1091 goto reteof;
1092 /* We lose. Oh well. Terminate the string
1093 and stop converting, so at least we don't
1094 skip any input. */
1095 ((char *) (*strptr))[strleng] = '\0';
1096 strptr = NULL;
1097 ++done;
1098 conv_error ();
1100 else
1102 *strptr = newstr;
1103 str = newstr + strleng;
1104 strsize = strleng + n + 1;
1108 str = __mempcpy (str, buf, n);
1109 #endif
1110 *str++ = '\0';
1112 if ((flags & MALLOC) && str - *strptr != strsize)
1114 char *cp = (char *) realloc (*strptr, str - *strptr);
1115 if (cp != NULL)
1116 *strptr = cp;
1118 strptr = NULL;
1120 ++done;
1122 break;
1124 /* FALLTHROUGH */
1126 case L_('S'):
1128 #ifndef COMPILE_WSCANF
1129 mbstate_t cstate;
1130 #endif
1132 /* Wide character string. */
1133 STRING_ARG (wstr, wchar_t, 100);
1135 c = inchar ();
1136 if (__builtin_expect (c == EOF, 0))
1137 input_error ();
1139 #ifndef COMPILE_WSCANF
1140 memset (&cstate, '\0', sizeof (cstate));
1141 #endif
1145 if (ISSPACE (c))
1147 ungetc_not_eof (c, s);
1148 break;
1151 #ifdef COMPILE_WSCANF
1152 /* This is easy. */
1153 if (!(flags & SUPPRESS))
1155 *wstr++ = c;
1156 if ((flags & MALLOC)
1157 && wstr == (wchar_t *) *strptr + strsize)
1159 /* Enlarge the buffer. */
1160 wstr = (wchar_t *) realloc (*strptr,
1161 (2 * strsize)
1162 * sizeof (wchar_t));
1163 if (wstr == NULL)
1165 /* Can't allocate that much. Last-ditch
1166 effort. */
1167 wstr = (wchar_t *) realloc (*strptr,
1168 (strsize + 1)
1169 * sizeof (wchar_t));
1170 if (wstr == NULL)
1172 if (flags & POSIX_MALLOC)
1173 goto reteof;
1174 /* We lose. Oh well. Terminate the string
1175 and stop converting, so at least we don't
1176 skip any input. */
1177 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1178 strptr = NULL;
1179 ++done;
1180 conv_error ();
1182 else
1184 *strptr = (char *) wstr;
1185 wstr += strsize;
1186 ++strsize;
1189 else
1191 *strptr = (char *) wstr;
1192 wstr += strsize;
1193 strsize *= 2;
1197 #else
1199 char buf[1];
1201 buf[0] = c;
1203 while (1)
1205 size_t n;
1207 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1208 buf, 1, &cstate);
1210 if (n == (size_t) -2)
1212 /* Possibly correct character, just not enough
1213 input. */
1214 if (__builtin_expect (inchar () == EOF, 0))
1215 encode_error ();
1217 buf[0] = c;
1218 continue;
1221 if (__builtin_expect (n != 1, 0))
1222 encode_error ();
1224 /* We have a match. */
1225 ++wstr;
1226 break;
1229 if (!(flags & SUPPRESS) && (flags & MALLOC)
1230 && wstr == (wchar_t *) *strptr + strsize)
1232 /* Enlarge the buffer. */
1233 wstr = (wchar_t *) realloc (*strptr,
1234 (2 * strsize
1235 * sizeof (wchar_t)));
1236 if (wstr == NULL)
1238 /* Can't allocate that much. Last-ditch effort. */
1239 wstr = (wchar_t *) realloc (*strptr,
1240 ((strsize + 1)
1241 * sizeof (wchar_t)));
1242 if (wstr == NULL)
1244 if (flags & POSIX_MALLOC)
1245 goto reteof;
1246 /* We lose. Oh well. Terminate the
1247 string and stop converting, so at
1248 least we don't skip any input. */
1249 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1250 strptr = NULL;
1251 ++done;
1252 conv_error ();
1254 else
1256 *strptr = (char *) wstr;
1257 wstr += strsize;
1258 ++strsize;
1261 else
1263 *strptr = (char *) wstr;
1264 wstr += strsize;
1265 strsize *= 2;
1269 #endif
1271 while ((width <= 0 || --width > 0) && inchar () != EOF);
1273 if (!(flags & SUPPRESS))
1275 *wstr++ = L'\0';
1277 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1279 wchar_t *cp = (wchar_t *) realloc (*strptr,
1280 ((wstr
1281 - (wchar_t *) *strptr)
1282 * sizeof(wchar_t)));
1283 if (cp != NULL)
1284 *strptr = (char *) cp;
1286 strptr = NULL;
1288 ++done;
1291 break;
1293 case L_('x'): /* Hexadecimal integer. */
1294 case L_('X'): /* Ditto. */
1295 base = 16;
1296 goto number;
1298 case L_('o'): /* Octal integer. */
1299 base = 8;
1300 goto number;
1302 case L_('u'): /* Unsigned decimal integer. */
1303 base = 10;
1304 goto number;
1306 case L_('d'): /* Signed decimal integer. */
1307 base = 10;
1308 flags |= NUMBER_SIGNED;
1309 goto number;
1311 case L_('i'): /* Generic number. */
1312 base = 0;
1313 flags |= NUMBER_SIGNED;
1315 number:
1316 c = inchar ();
1317 if (__builtin_expect (c == EOF, 0))
1318 input_error ();
1320 /* Check for a sign. */
1321 if (c == L_('-') || c == L_('+'))
1323 ADDW (c);
1324 if (width > 0)
1325 --width;
1326 c = inchar ();
1329 /* Look for a leading indication of base. */
1330 if (width != 0 && c == L_('0'))
1332 if (width > 0)
1333 --width;
1335 ADDW (c);
1336 c = inchar ();
1338 if (width != 0 && TOLOWER (c) == L_('x'))
1340 if (base == 0)
1341 base = 16;
1342 if (base == 16)
1344 if (width > 0)
1345 --width;
1346 c = inchar ();
1349 else if (base == 0)
1350 base = 8;
1353 if (base == 0)
1354 base = 10;
1356 if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
1358 int from_level;
1359 int to_level;
1360 int level;
1361 #ifdef COMPILE_WSCANF
1362 const wchar_t *wcdigits[10];
1363 const wchar_t *wcdigits_extended[10];
1364 #else
1365 const char *mbdigits[10];
1366 const char *mbdigits_extended[10];
1367 #endif
1368 /* "to_inpunct" is a map from ASCII digits to their
1369 equivalent in locale. This is defined for locales
1370 which use an extra digits set. */
1371 wctrans_t map = __wctrans ("to_inpunct");
1372 int n;
1374 from_level = 0;
1375 #ifdef COMPILE_WSCANF
1376 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1377 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1378 #else
1379 to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
1380 #endif
1382 /* Get the alternative digit forms if there are any. */
1383 if (__builtin_expect (map != NULL, 0))
1385 /* Adding new level for extra digits set in locale file. */
1386 ++to_level;
1388 for (n = 0; n < 10; ++n)
1390 #ifdef COMPILE_WSCANF
1391 wcdigits[n] = (const wchar_t *)
1392 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1394 wchar_t *wc_extended = (wchar_t *)
1395 alloca ((to_level + 2) * sizeof (wchar_t));
1396 __wmemcpy (wc_extended, wcdigits[n], to_level);
1397 wc_extended[to_level] = __towctrans (L'0' + n, map);
1398 wc_extended[to_level + 1] = '\0';
1399 wcdigits_extended[n] = wc_extended;
1400 #else
1401 mbdigits[n]
1402 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1404 /* Get the equivalent wide char in map. */
1405 wint_t extra_wcdigit = __towctrans (L'0' + n, map);
1407 /* Convert it to multibyte representation. */
1408 mbstate_t state;
1409 memset (&state, '\0', sizeof (state));
1411 char extra_mbdigit[MB_LEN_MAX];
1412 size_t mblen
1413 = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
1415 if (mblen == (size_t) -1)
1417 /* Ignore this new level. */
1418 map = NULL;
1419 break;
1422 /* Calculate the length of mbdigits[n]. */
1423 const char *last_char = mbdigits[n];
1424 for (level = 0; level < to_level; ++level)
1425 last_char = strchr (last_char, '\0') + 1;
1427 size_t mbdigits_len = last_char - mbdigits[n];
1429 /* Allocate memory for extended multibyte digit. */
1430 char *mb_extended;
1431 mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
1433 /* And get the mbdigits + extra_digit string. */
1434 *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
1435 mbdigits_len),
1436 extra_mbdigit, mblen) = '\0';
1437 mbdigits_extended[n] = mb_extended;
1438 #endif
1442 /* Read the number into workspace. */
1443 while (c != EOF && width != 0)
1445 /* In this round we get the pointer to the digit strings
1446 and also perform the first round of comparisons. */
1447 for (n = 0; n < 10; ++n)
1449 /* Get the string for the digits with value N. */
1450 #ifdef COMPILE_WSCANF
1451 if (__builtin_expect (map != NULL, 0))
1452 wcdigits[n] = wcdigits_extended[n];
1453 else
1454 wcdigits[n] = (const wchar_t *)
1455 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1456 wcdigits[n] += from_level;
1458 if (c == (wint_t) *wcdigits[n])
1460 to_level = from_level;
1461 break;
1464 /* Advance the pointer to the next string. */
1465 ++wcdigits[n];
1466 #else
1467 const char *cmpp;
1468 int avail = width > 0 ? width : INT_MAX;
1470 if (__builtin_expect (map != NULL, 0))
1471 mbdigits[n] = mbdigits_extended[n];
1472 else
1473 mbdigits[n]
1474 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1476 for (level = 0; level < from_level; level++)
1477 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1479 cmpp = mbdigits[n];
1480 while ((unsigned char) *cmpp == c && avail >= 0)
1482 if (*++cmpp == '\0')
1483 break;
1484 else
1486 if (avail == 0 || inchar () == EOF)
1487 break;
1488 --avail;
1492 if (*cmpp == '\0')
1494 if (width > 0)
1495 width = avail;
1496 to_level = from_level;
1497 break;
1500 /* We are pushing all read characters back. */
1501 if (cmpp > mbdigits[n])
1503 ungetc (c, s);
1504 while (--cmpp > mbdigits[n])
1505 ungetc_not_eof ((unsigned char) *cmpp, s);
1506 c = (unsigned char) *cmpp;
1509 /* Advance the pointer to the next string. */
1510 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1511 #endif
1514 if (n == 10)
1516 /* Have not yet found the digit. */
1517 for (level = from_level + 1; level <= to_level; ++level)
1519 /* Search all ten digits of this level. */
1520 for (n = 0; n < 10; ++n)
1522 #ifdef COMPILE_WSCANF
1523 if (c == (wint_t) *wcdigits[n])
1524 break;
1526 /* Advance the pointer to the next string. */
1527 ++wcdigits[n];
1528 #else
1529 const char *cmpp;
1530 int avail = width > 0 ? width : INT_MAX;
1532 cmpp = mbdigits[n];
1533 while ((unsigned char) *cmpp == c && avail >= 0)
1535 if (*++cmpp == '\0')
1536 break;
1537 else
1539 if (avail == 0 || inchar () == EOF)
1540 break;
1541 --avail;
1545 if (*cmpp == '\0')
1547 if (width > 0)
1548 width = avail;
1549 break;
1552 /* We are pushing all read characters back. */
1553 if (cmpp > mbdigits[n])
1555 ungetc (c, s);
1556 while (--cmpp > mbdigits[n])
1557 ungetc_not_eof ((unsigned char) *cmpp, s);
1558 c = (unsigned char) *cmpp;
1561 /* Advance the pointer to the next string. */
1562 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1563 #endif
1566 if (n < 10)
1568 /* Found it. */
1569 from_level = level;
1570 to_level = level;
1571 break;
1576 if (n < 10)
1577 c = L_('0') + n;
1578 else if (flags & GROUP)
1580 /* Try matching against the thousands separator. */
1581 #ifdef COMPILE_WSCANF
1582 if (c != thousands)
1583 break;
1584 #else
1585 const char *cmpp = thousands;
1586 int avail = width > 0 ? width : INT_MAX;
1588 while ((unsigned char) *cmpp == c && avail >= 0)
1590 ADDW (c);
1591 if (*++cmpp == '\0')
1592 break;
1593 else
1595 if (avail == 0 || inchar () == EOF)
1596 break;
1597 --avail;
1601 if (*cmpp != '\0')
1603 /* We are pushing all read characters back. */
1604 if (cmpp > thousands)
1606 wpsize -= cmpp - thousands;
1607 ungetc (c, s);
1608 while (--cmpp > thousands)
1609 ungetc_not_eof ((unsigned char) *cmpp, s);
1610 c = (unsigned char) *cmpp;
1612 break;
1615 if (width > 0)
1616 width = avail;
1618 /* The last thousands character will be added back by
1619 the ADDW below. */
1620 --wpsize;
1621 #endif
1623 else
1624 break;
1626 ADDW (c);
1627 if (width > 0)
1628 --width;
1630 c = inchar ();
1633 else
1634 /* Read the number into workspace. */
1635 while (c != EOF && width != 0)
1637 if (base == 16)
1639 if (!ISXDIGIT (c))
1640 break;
1642 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
1644 if (base == 10 && (flags & GROUP))
1646 /* Try matching against the thousands separator. */
1647 #ifdef COMPILE_WSCANF
1648 if (c != thousands)
1649 break;
1650 #else
1651 const char *cmpp = thousands;
1652 int avail = width > 0 ? width : INT_MAX;
1654 while ((unsigned char) *cmpp == c && avail >= 0)
1656 ADDW (c);
1657 if (*++cmpp == '\0')
1658 break;
1659 else
1661 if (avail == 0 || inchar () == EOF)
1662 break;
1663 --avail;
1667 if (*cmpp != '\0')
1669 /* We are pushing all read characters back. */
1670 if (cmpp > thousands)
1672 wpsize -= cmpp - thousands;
1673 ungetc (c, s);
1674 while (--cmpp > thousands)
1675 ungetc_not_eof ((unsigned char) *cmpp, s);
1676 c = (unsigned char) *cmpp;
1678 break;
1681 if (width > 0)
1682 width = avail;
1684 /* The last thousands character will be added back by
1685 the ADDW below. */
1686 --wpsize;
1687 #endif
1689 else
1690 break;
1692 ADDW (c);
1693 if (width > 0)
1694 --width;
1696 c = inchar ();
1699 if (wpsize == 0
1700 || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1702 /* There was no number. If we are supposed to read a pointer
1703 we must recognize "(nil)" as well. */
1704 if (__builtin_expect (wpsize == 0
1705 && (flags & READ_POINTER)
1706 && (width < 0 || width >= 0)
1707 && c == '('
1708 && TOLOWER (inchar ()) == L_('n')
1709 && TOLOWER (inchar ()) == L_('i')
1710 && TOLOWER (inchar ()) == L_('l')
1711 && inchar () == L_(')'), 1))
1712 /* We must produce the value of a NULL pointer. A single
1713 '0' digit is enough. */
1714 ADDW (L_('0'));
1715 else
1717 /* The last read character is not part of the number
1718 anymore. */
1719 ungetc (c, s);
1721 conv_error ();
1724 else
1725 /* The just read character is not part of the number anymore. */
1726 ungetc (c, s);
1728 /* Convert the number. */
1729 ADDW (L_('\0'));
1730 if (need_longlong && (flags & LONGDBL))
1732 if (flags & NUMBER_SIGNED)
1733 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1734 else
1735 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1737 else
1739 if (flags & NUMBER_SIGNED)
1740 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1741 else
1742 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1744 if (__builtin_expect (wp == tw, 0))
1745 conv_error ();
1747 if (!(flags & SUPPRESS))
1749 if (flags & NUMBER_SIGNED)
1751 if (need_longlong && (flags & LONGDBL))
1752 *ARG (LONGLONG int *) = num.q;
1753 else if (need_long && (flags & LONG))
1754 *ARG (long int *) = num.l;
1755 else if (flags & SHORT)
1756 *ARG (short int *) = (short int) num.l;
1757 else if (!(flags & CHAR))
1758 *ARG (int *) = (int) num.l;
1759 else
1760 *ARG (signed char *) = (signed char) num.ul;
1762 else
1764 if (need_longlong && (flags & LONGDBL))
1765 *ARG (unsigned LONGLONG int *) = num.uq;
1766 else if (need_long && (flags & LONG))
1767 *ARG (unsigned long int *) = num.ul;
1768 else if (flags & SHORT)
1769 *ARG (unsigned short int *)
1770 = (unsigned short int) num.ul;
1771 else if (!(flags & CHAR))
1772 *ARG (unsigned int *) = (unsigned int) num.ul;
1773 else
1774 *ARG (unsigned char *) = (unsigned char) num.ul;
1776 ++done;
1778 break;
1780 case L_('e'): /* Floating-point numbers. */
1781 case L_('E'):
1782 case L_('f'):
1783 case L_('F'):
1784 case L_('g'):
1785 case L_('G'):
1786 case L_('a'):
1787 case L_('A'):
1788 c = inchar ();
1789 if (width > 0)
1790 --width;
1791 if (__builtin_expect (c == EOF, 0))
1792 input_error ();
1794 got_dot = got_e = 0;
1796 /* Check for a sign. */
1797 if (c == L_('-') || c == L_('+'))
1799 negative = c == L_('-');
1800 if (__builtin_expect (width == 0 || inchar () == EOF, 0))
1801 /* EOF is only an input error before we read any chars. */
1802 conv_error ();
1803 if (width > 0)
1804 --width;
1806 else
1807 negative = 0;
1809 /* Take care for the special arguments "nan" and "inf". */
1810 if (TOLOWER (c) == L_('n'))
1812 /* Maybe "nan". */
1813 ADDW (c);
1814 if (__builtin_expect (width == 0
1815 || inchar () == EOF
1816 || TOLOWER (c) != L_('a'), 0))
1817 conv_error ();
1818 if (width > 0)
1819 --width;
1820 ADDW (c);
1821 if (__builtin_expect (width == 0
1822 || inchar () == EOF
1823 || TOLOWER (c) != L_('n'), 0))
1824 conv_error ();
1825 if (width > 0)
1826 --width;
1827 ADDW (c);
1828 /* It is "nan". */
1829 goto scan_float;
1831 else if (TOLOWER (c) == L_('i'))
1833 /* Maybe "inf" or "infinity". */
1834 ADDW (c);
1835 if (__builtin_expect (width == 0
1836 || inchar () == EOF
1837 || TOLOWER (c) != L_('n'), 0))
1838 conv_error ();
1839 if (width > 0)
1840 --width;
1841 ADDW (c);
1842 if (__builtin_expect (width == 0
1843 || inchar () == EOF
1844 || TOLOWER (c) != L_('f'), 0))
1845 conv_error ();
1846 if (width > 0)
1847 --width;
1848 ADDW (c);
1849 /* It is as least "inf". */
1850 if (width != 0 && inchar () != EOF)
1852 if (TOLOWER (c) == L_('i'))
1854 if (width > 0)
1855 --width;
1856 /* Now we have to read the rest as well. */
1857 ADDW (c);
1858 if (__builtin_expect (width == 0
1859 || inchar () == EOF
1860 || TOLOWER (c) != L_('n'), 0))
1861 conv_error ();
1862 if (width > 0)
1863 --width;
1864 ADDW (c);
1865 if (__builtin_expect (width == 0
1866 || inchar () == EOF
1867 || TOLOWER (c) != L_('i'), 0))
1868 conv_error ();
1869 if (width > 0)
1870 --width;
1871 ADDW (c);
1872 if (__builtin_expect (width == 0
1873 || inchar () == EOF
1874 || TOLOWER (c) != L_('t'), 0))
1875 conv_error ();
1876 if (width > 0)
1877 --width;
1878 ADDW (c);
1879 if (__builtin_expect (width == 0
1880 || inchar () == EOF
1881 || TOLOWER (c) != L_('y'), 0))
1882 conv_error ();
1883 if (width > 0)
1884 --width;
1885 ADDW (c);
1887 else
1888 /* Never mind. */
1889 ungetc (c, s);
1891 goto scan_float;
1894 exp_char = L_('e');
1895 if (width != 0 && c == L_('0'))
1897 ADDW (c);
1898 c = inchar ();
1899 if (width > 0)
1900 --width;
1901 if (width != 0 && TOLOWER (c) == L_('x'))
1903 /* It is a number in hexadecimal format. */
1904 ADDW (c);
1906 flags |= HEXA_FLOAT;
1907 exp_char = L_('p');
1909 /* Grouping is not allowed. */
1910 flags &= ~GROUP;
1911 c = inchar ();
1912 if (width > 0)
1913 --width;
1917 while (1)
1919 if (ISDIGIT (c))
1920 ADDW (c);
1921 else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c))
1922 ADDW (c);
1923 else if (got_e && wp[wpsize - 1] == exp_char
1924 && (c == L_('-') || c == L_('+')))
1925 ADDW (c);
1926 else if (wpsize > 0 && !got_e
1927 && (CHAR_T) TOLOWER (c) == exp_char)
1929 ADDW (exp_char);
1930 got_e = got_dot = 1;
1932 else
1934 #ifdef COMPILE_WSCANF
1935 if (! got_dot && c == decimal)
1937 ADDW (c);
1938 got_dot = 1;
1940 else if ((flags & GROUP) != 0 && ! got_dot && c == thousands)
1941 ADDW (c);
1942 else
1944 /* The last read character is not part of the number
1945 anymore. */
1946 ungetc (c, s);
1947 break;
1949 #else
1950 const char *cmpp = decimal;
1951 int avail = width > 0 ? width : INT_MAX;
1953 if (! got_dot)
1955 while ((unsigned char) *cmpp == c && avail >= 0)
1956 if (*++cmpp == '\0')
1957 break;
1958 else
1960 if (avail == 0 || inchar () == EOF)
1961 break;
1962 --avail;
1966 if (*cmpp == '\0')
1968 /* Add all the characters. */
1969 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1970 ADDW ((unsigned char) *cmpp);
1971 if (width > 0)
1972 width = avail;
1973 got_dot = 1;
1975 else
1977 /* Figure out whether it is a thousands separator.
1978 There is one problem: we possibly read more than
1979 one character. We cannot push them back but since
1980 we know that parts of the `decimal' string matched,
1981 we can compare against it. */
1982 const char *cmp2p = thousands;
1984 if ((flags & GROUP) != 0 && ! got_dot)
1986 while (cmp2p - thousands < cmpp - decimal
1987 && *cmp2p == decimal[cmp2p - thousands])
1988 ++cmp2p;
1989 if (cmp2p - thousands == cmpp - decimal)
1991 while ((unsigned char) *cmp2p == c && avail >= 0)
1992 if (*++cmp2p == '\0')
1993 break;
1994 else
1996 if (avail == 0 || inchar () == EOF)
1997 break;
1998 --avail;
2003 if (cmp2p != NULL && *cmp2p == '\0')
2005 /* Add all the characters. */
2006 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
2007 ADDW ((unsigned char) *cmpp);
2008 if (width > 0)
2009 width = avail;
2011 else
2013 /* The last read character is not part of the number
2014 anymore. */
2015 ungetc (c, s);
2016 break;
2019 #endif
2022 if (width == 0 || inchar () == EOF)
2023 break;
2025 if (width > 0)
2026 --width;
2029 wctrans_t map;
2030 if (__builtin_expect ((flags & I18N) != 0, 0)
2031 /* Hexadecimal floats make no sense, fixing localized
2032 digits with ASCII letters. */
2033 && !(flags & HEXA_FLOAT)
2034 /* Minimum requirement. */
2035 && (wpsize == 0 || got_dot)
2036 && (map = __wctrans ("to_inpunct")) != NULL)
2038 /* Reget the first character. */
2039 inchar ();
2041 /* Localized digits, decimal points, and thousands
2042 separator. */
2043 wint_t wcdigits[12];
2045 /* First get decimal equivalent to check if we read it
2046 or not. */
2047 wcdigits[11] = __towctrans (L'.', map);
2049 /* If we have not read any character or have just read
2050 locale decimal point which matches the decimal point
2051 for localized FP numbers, then we may have localized
2052 digits. Note, we test GOT_DOT above. */
2053 #ifdef COMPILE_WSCANF
2054 if (wpsize == 0 || (wpsize == 1 && wcdigits[11] == decimal))
2055 #else
2056 char mbdigits[12][MB_LEN_MAX + 1];
2058 mbstate_t state;
2059 memset (&state, '\0', sizeof (state));
2061 bool match_so_far = wpsize == 0;
2062 size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state);
2063 if (mblen != (size_t) -1)
2065 mbdigits[11][mblen] = '\0';
2066 match_so_far |= (wpsize == strlen (decimal)
2067 && strcmp (decimal, mbdigits[11]) == 0);
2069 else
2071 size_t decimal_len = strlen (decimal);
2072 /* This should always be the case but the data comes
2073 from a file. */
2074 if (decimal_len <= MB_LEN_MAX)
2076 match_so_far |= wpsize == decimal_len;
2077 memcpy (mbdigits[11], decimal, decimal_len + 1);
2079 else
2080 match_so_far = false;
2083 if (match_so_far)
2084 #endif
2086 bool have_locthousands = (flags & GROUP) != 0;
2088 /* Now get the digits and the thousands-sep equivalents. */
2089 for (int n = 0; n < 11; ++n)
2091 if (n < 10)
2092 wcdigits[n] = __towctrans (L'0' + n, map);
2093 else if (n == 10)
2095 wcdigits[10] = __towctrans (L',', map);
2096 have_locthousands &= wcdigits[10] != L'\0';
2099 #ifndef COMPILE_WSCANF
2100 memset (&state, '\0', sizeof (state));
2102 size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n],
2103 &state);
2104 if (mblen == (size_t) -1)
2106 if (n == 10)
2108 if (have_locthousands)
2110 size_t thousands_len = strlen (thousands);
2111 if (thousands_len <= MB_LEN_MAX)
2112 memcpy (mbdigits[10], thousands,
2113 thousands_len + 1);
2114 else
2115 have_locthousands = false;
2118 else
2119 /* Ignore checking against localized digits. */
2120 goto no_i18nflt;
2122 else
2123 mbdigits[n][mblen] = '\0';
2124 #endif
2127 /* Start checking against localized digits, if
2128 convertion is done correctly. */
2129 while (1)
2131 if (got_e && wp[wpsize - 1] == exp_char
2132 && (c == L_('-') || c == L_('+')))
2133 ADDW (c);
2134 else if (wpsize > 0 && !got_e
2135 && (CHAR_T) TOLOWER (c) == exp_char)
2137 ADDW (exp_char);
2138 got_e = got_dot = 1;
2140 else
2142 /* Check against localized digits, decimal point,
2143 and thousands separator. */
2144 int n;
2145 for (n = 0; n < 12; ++n)
2147 #ifdef COMPILE_WSCANF
2148 if (c == wcdigits[n])
2150 if (n < 10)
2151 ADDW (L_('0') + n);
2152 else if (n == 11 && !got_dot)
2154 ADDW (decimal);
2155 got_dot = 1;
2157 else if (n == 10 && have_locthousands
2158 && ! got_dot)
2159 ADDW (thousands);
2160 else
2161 /* The last read character is not part
2162 of the number anymore. */
2163 n = 12;
2165 break;
2167 #else
2168 const char *cmpp = mbdigits[n];
2169 int avail = width > 0 ? width : INT_MAX;
2171 while ((unsigned char) *cmpp == c && avail >= 0)
2172 if (*++cmpp == '\0')
2173 break;
2174 else
2176 if (avail == 0 || inchar () == EOF)
2177 break;
2178 --avail;
2180 if (*cmpp == '\0')
2182 if (width > 0)
2183 width = avail;
2185 if (n < 10)
2186 ADDW (L_('0') + n);
2187 else if (n == 11 && !got_dot)
2189 /* Add all the characters. */
2190 for (cmpp = decimal; *cmpp != '\0';
2191 ++cmpp)
2192 ADDW ((unsigned char) *cmpp);
2194 got_dot = 1;
2196 else if (n == 10 && (flags & GROUP) != 0
2197 && ! got_dot)
2199 /* Add all the characters. */
2200 for (cmpp = thousands; *cmpp != '\0';
2201 ++cmpp)
2202 ADDW ((unsigned char) *cmpp);
2204 else
2205 /* The last read character is not part
2206 of the number anymore. */
2207 n = 12;
2209 break;
2212 /* We are pushing all read characters back. */
2213 if (cmpp > mbdigits[n])
2215 ungetc (c, s);
2216 while (--cmpp > mbdigits[n])
2217 ungetc_not_eof ((unsigned char) *cmpp, s);
2218 c = (unsigned char) *cmpp;
2220 #endif
2223 if (n >= 12)
2225 /* The last read character is not part
2226 of the number anymore. */
2227 ungetc (c, s);
2228 break;
2232 if (width == 0 || inchar () == EOF)
2233 break;
2235 if (width > 0)
2236 --width;
2240 #ifndef COMPILE_WSCANF
2241 no_i18nflt:
2243 #endif
2246 /* Have we read any character? If we try to read a number
2247 in hexadecimal notation and we have read only the `0x'
2248 prefix this is an error. */
2249 if (__builtin_expect (wpsize == 0
2250 || ((flags & HEXA_FLOAT) && wpsize == 2), 0))
2251 conv_error ();
2253 scan_float:
2254 /* Convert the number. */
2255 ADDW (L_('\0'));
2256 if ((flags & LONGDBL) && !__ldbl_is_dbl)
2258 long double d = __strtold_internal (wp, &tw, flags & GROUP);
2259 if (!(flags & SUPPRESS) && tw != wp)
2260 *ARG (long double *) = negative ? -d : d;
2262 else if (flags & (LONG | LONGDBL))
2264 double d = __strtod_internal (wp, &tw, flags & GROUP);
2265 if (!(flags & SUPPRESS) && tw != wp)
2266 *ARG (double *) = negative ? -d : d;
2268 else
2270 float d = __strtof_internal (wp, &tw, flags & GROUP);
2271 if (!(flags & SUPPRESS) && tw != wp)
2272 *ARG (float *) = negative ? -d : d;
2275 if (__builtin_expect (tw == wp, 0))
2276 conv_error ();
2278 if (!(flags & SUPPRESS))
2279 ++done;
2280 break;
2282 case L_('['): /* Character class. */
2283 if (flags & LONG)
2284 STRING_ARG (wstr, wchar_t, 100);
2285 else
2286 STRING_ARG (str, char, 100);
2288 if (*f == L_('^'))
2290 ++f;
2291 not_in = 1;
2293 else
2294 not_in = 0;
2296 if (width < 0)
2297 /* There is no width given so there is also no limit on the
2298 number of characters we read. Therefore we set width to
2299 a very high value to make the algorithm easier. */
2300 width = INT_MAX;
2302 #ifdef COMPILE_WSCANF
2303 /* Find the beginning and the end of the scanlist. We are not
2304 creating a lookup table since it would have to be too large.
2305 Instead we search each time through the string. This is not
2306 a constant lookup time but who uses this feature deserves to
2307 be punished. */
2308 tw = (wchar_t *) f; /* Marks the beginning. */
2310 if (*f == L']')
2311 ++f;
2313 while ((fc = *f++) != L'\0' && fc != L']');
2315 if (__builtin_expect (fc == L'\0', 0))
2316 conv_error ();
2317 wp = (wchar_t *) f - 1;
2318 #else
2319 /* Fill WP with byte flags indexed by character.
2320 We will use this flag map for matching input characters. */
2321 if (wpmax < UCHAR_MAX + 1)
2323 wpmax = UCHAR_MAX + 1;
2324 wp = (char *) alloca (wpmax);
2326 memset (wp, '\0', UCHAR_MAX + 1);
2328 fc = *f;
2329 if (fc == ']' || fc == '-')
2331 /* If ] or - appears before any char in the set, it is not
2332 the terminator or separator, but the first char in the
2333 set. */
2334 wp[fc] = 1;
2335 ++f;
2338 while ((fc = *f++) != '\0' && fc != ']')
2339 if (fc == '-' && *f != '\0' && *f != ']'
2340 && (unsigned char) f[-2] <= (unsigned char) *f)
2342 /* Add all characters from the one before the '-'
2343 up to (but not including) the next format char. */
2344 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
2345 wp[fc] = 1;
2347 else
2348 /* Add the character to the flag map. */
2349 wp[fc] = 1;
2351 if (__builtin_expect (fc == '\0', 0))
2352 conv_error();
2353 #endif
2355 if (flags & LONG)
2357 size_t now = read_in;
2358 #ifdef COMPILE_WSCANF
2359 if (__builtin_expect (inchar () == WEOF, 0))
2360 input_error ();
2364 wchar_t *runp;
2366 /* Test whether it's in the scanlist. */
2367 runp = tw;
2368 while (runp < wp)
2370 if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
2371 && runp != tw
2372 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2374 /* Match against all characters in between the
2375 first and last character of the sequence. */
2376 wchar_t wc;
2378 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2379 if ((wint_t) wc == c)
2380 break;
2382 if (wc <= runp[1] && !not_in)
2383 break;
2384 if (wc <= runp[1] && not_in)
2386 /* The current character is not in the
2387 scanset. */
2388 ungetc (c, s);
2389 goto out;
2392 runp += 2;
2394 else
2396 if ((wint_t) *runp == c && !not_in)
2397 break;
2398 if ((wint_t) *runp == c && not_in)
2400 ungetc (c, s);
2401 goto out;
2404 ++runp;
2408 if (runp == wp && !not_in)
2410 ungetc (c, s);
2411 goto out;
2414 if (!(flags & SUPPRESS))
2416 *wstr++ = c;
2418 if ((flags & MALLOC)
2419 && wstr == (wchar_t *) *strptr + strsize)
2421 /* Enlarge the buffer. */
2422 wstr = (wchar_t *) realloc (*strptr,
2423 (2 * strsize)
2424 * sizeof (wchar_t));
2425 if (wstr == NULL)
2427 /* Can't allocate that much. Last-ditch
2428 effort. */
2429 wstr = (wchar_t *)
2430 realloc (*strptr, (strsize + 1)
2431 * sizeof (wchar_t));
2432 if (wstr == NULL)
2434 if (flags & POSIX_MALLOC)
2435 goto reteof;
2436 /* We lose. Oh well. Terminate the string
2437 and stop converting, so at least we don't
2438 skip any input. */
2439 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2440 strptr = NULL;
2441 ++done;
2442 conv_error ();
2444 else
2446 *strptr = (char *) wstr;
2447 wstr += strsize;
2448 ++strsize;
2451 else
2453 *strptr = (char *) wstr;
2454 wstr += strsize;
2455 strsize *= 2;
2460 while (--width > 0 && inchar () != WEOF);
2461 out:
2462 #else
2463 char buf[MB_LEN_MAX];
2464 size_t cnt = 0;
2465 mbstate_t cstate;
2467 if (__builtin_expect (inchar () == EOF, 0))
2468 input_error ();
2470 memset (&cstate, '\0', sizeof (cstate));
2474 if (wp[c] == not_in)
2476 ungetc_not_eof (c, s);
2477 break;
2480 /* This is easy. */
2481 if (!(flags & SUPPRESS))
2483 size_t n;
2485 /* Convert it into a wide character. */
2486 buf[0] = c;
2487 n = __mbrtowc (wstr, buf, 1, &cstate);
2489 if (n == (size_t) -2)
2491 /* Possibly correct character, just not enough
2492 input. */
2493 ++cnt;
2494 assert (cnt < MB_CUR_MAX);
2495 continue;
2497 cnt = 0;
2499 ++wstr;
2500 if ((flags & MALLOC)
2501 && wstr == (wchar_t *) *strptr + strsize)
2503 /* Enlarge the buffer. */
2504 wstr = (wchar_t *) realloc (*strptr,
2505 (2 * strsize
2506 * sizeof (wchar_t)));
2507 if (wstr == NULL)
2509 /* Can't allocate that much. Last-ditch
2510 effort. */
2511 wstr = (wchar_t *)
2512 realloc (*strptr, ((strsize + 1)
2513 * sizeof (wchar_t)));
2514 if (wstr == NULL)
2516 if (flags & POSIX_MALLOC)
2517 goto reteof;
2518 /* We lose. Oh well. Terminate the
2519 string and stop converting,
2520 so at least we don't skip any input. */
2521 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2522 strptr = NULL;
2523 ++done;
2524 conv_error ();
2526 else
2528 *strptr = (char *) wstr;
2529 wstr += strsize;
2530 ++strsize;
2533 else
2535 *strptr = (char *) wstr;
2536 wstr += strsize;
2537 strsize *= 2;
2542 if (--width <= 0)
2543 break;
2545 while (inchar () != EOF);
2547 if (__builtin_expect (cnt != 0, 0))
2548 /* We stopped in the middle of recognizing another
2549 character. That's a problem. */
2550 encode_error ();
2551 #endif
2553 if (__builtin_expect (now == read_in, 0))
2554 /* We haven't succesfully read any character. */
2555 conv_error ();
2557 if (!(flags & SUPPRESS))
2559 *wstr++ = L'\0';
2561 if ((flags & MALLOC)
2562 && wstr - (wchar_t *) *strptr != strsize)
2564 wchar_t *cp = (wchar_t *)
2565 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2566 * sizeof(wchar_t)));
2567 if (cp != NULL)
2568 *strptr = (char *) cp;
2570 strptr = NULL;
2572 ++done;
2575 else
2577 size_t now = read_in;
2579 if (__builtin_expect (inchar () == EOF, 0))
2580 input_error ();
2582 #ifdef COMPILE_WSCANF
2584 memset (&state, '\0', sizeof (state));
2588 wchar_t *runp;
2589 size_t n;
2591 /* Test whether it's in the scanlist. */
2592 runp = tw;
2593 while (runp < wp)
2595 if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
2596 && runp != tw
2597 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2599 /* Match against all characters in between the
2600 first and last character of the sequence. */
2601 wchar_t wc;
2603 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2604 if ((wint_t) wc == c)
2605 break;
2607 if (wc <= runp[1] && !not_in)
2608 break;
2609 if (wc <= runp[1] && not_in)
2611 /* The current character is not in the
2612 scanset. */
2613 ungetc (c, s);
2614 goto out2;
2617 runp += 2;
2619 else
2621 if ((wint_t) *runp == c && !not_in)
2622 break;
2623 if ((wint_t) *runp == c && not_in)
2625 ungetc (c, s);
2626 goto out2;
2629 ++runp;
2633 if (runp == wp && !not_in)
2635 ungetc (c, s);
2636 goto out2;
2639 if (!(flags & SUPPRESS))
2641 if ((flags & MALLOC)
2642 && str + MB_CUR_MAX >= *strptr + strsize)
2644 /* Enlarge the buffer. */
2645 size_t strleng = str - *strptr;
2646 char *newstr;
2648 newstr = (char *) realloc (*strptr, 2 * strsize);
2649 if (newstr == NULL)
2651 /* Can't allocate that much. Last-ditch
2652 effort. */
2653 newstr = (char *) realloc (*strptr,
2654 strleng + MB_CUR_MAX);
2655 if (newstr == NULL)
2657 if (flags & POSIX_MALLOC)
2658 goto reteof;
2659 /* We lose. Oh well. Terminate the string
2660 and stop converting, so at least we don't
2661 skip any input. */
2662 ((char *) (*strptr))[strleng] = '\0';
2663 strptr = NULL;
2664 ++done;
2665 conv_error ();
2667 else
2669 *strptr = newstr;
2670 str = newstr + strleng;
2671 strsize = strleng + MB_CUR_MAX;
2674 else
2676 *strptr = newstr;
2677 str = newstr + strleng;
2678 strsize *= 2;
2683 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2684 if (__builtin_expect (n == (size_t) -1, 0))
2685 encode_error ();
2687 assert (n <= MB_CUR_MAX);
2688 str += n;
2690 while (--width > 0 && inchar () != WEOF);
2691 out2:
2692 #else
2695 if (wp[c] == not_in)
2697 ungetc_not_eof (c, s);
2698 break;
2701 /* This is easy. */
2702 if (!(flags & SUPPRESS))
2704 *str++ = c;
2705 if ((flags & MALLOC)
2706 && (char *) str == *strptr + strsize)
2708 /* Enlarge the buffer. */
2709 size_t newsize = 2 * strsize;
2711 allocagain:
2712 str = (char *) realloc (*strptr, newsize);
2713 if (str == NULL)
2715 /* Can't allocate that much. Last-ditch
2716 effort. */
2717 if (newsize > strsize + 1)
2719 newsize = strsize + 1;
2720 goto allocagain;
2722 if (flags & POSIX_MALLOC)
2723 goto reteof;
2724 /* We lose. Oh well. Terminate the
2725 string and stop converting,
2726 so at least we don't skip any input. */
2727 ((char *) (*strptr))[strsize - 1] = '\0';
2728 strptr = NULL;
2729 ++done;
2730 conv_error ();
2732 else
2734 *strptr = (char *) str;
2735 str += strsize;
2736 strsize = newsize;
2741 while (--width > 0 && inchar () != EOF);
2742 #endif
2744 if (__builtin_expect (now == read_in, 0))
2745 /* We haven't succesfully read any character. */
2746 conv_error ();
2748 if (!(flags & SUPPRESS))
2750 #ifdef COMPILE_WSCANF
2751 /* We have to emit the code to get into the initial
2752 state. */
2753 char buf[MB_LEN_MAX];
2754 size_t n = __wcrtomb (buf, L'\0', &state);
2755 if (n > 0 && (flags & MALLOC)
2756 && str + n >= *strptr + strsize)
2758 /* Enlarge the buffer. */
2759 size_t strleng = str - *strptr;
2760 char *newstr;
2762 newstr = (char *) realloc (*strptr, strleng + n + 1);
2763 if (newstr == NULL)
2765 if (flags & POSIX_MALLOC)
2766 goto reteof;
2767 /* We lose. Oh well. Terminate the string
2768 and stop converting, so at least we don't
2769 skip any input. */
2770 ((char *) (*strptr))[strleng] = '\0';
2771 strptr = NULL;
2772 ++done;
2773 conv_error ();
2775 else
2777 *strptr = newstr;
2778 str = newstr + strleng;
2779 strsize = strleng + n + 1;
2783 str = __mempcpy (str, buf, n);
2784 #endif
2785 *str++ = '\0';
2787 if ((flags & MALLOC) && str - *strptr != strsize)
2789 char *cp = (char *) realloc (*strptr, str - *strptr);
2790 if (cp != NULL)
2791 *strptr = cp;
2793 strptr = NULL;
2795 ++done;
2798 break;
2800 case L_('p'): /* Generic pointer. */
2801 base = 16;
2802 /* A PTR must be the same size as a `long int'. */
2803 flags &= ~(SHORT|LONGDBL);
2804 if (need_long)
2805 flags |= LONG;
2806 flags |= READ_POINTER;
2807 goto number;
2809 default:
2810 /* If this is an unknown format character punt. */
2811 conv_error ();
2815 /* The last thing we saw int the format string was a white space.
2816 Consume the last white spaces. */
2817 if (skip_space)
2820 c = inchar ();
2821 while (ISSPACE (c));
2822 ungetc (c, s);
2825 errout:
2826 /* Unlock stream. */
2827 UNLOCK_STREAM (s);
2829 if (errp != NULL)
2830 *errp |= errval;
2832 if (done == EOF)
2834 reteof:
2835 if (__builtin_expect (ptrs_to_free != NULL, 0))
2837 struct ptrs_to_free *p = ptrs_to_free;
2838 while (p != NULL)
2840 for (size_t cnt = 0; cnt < p->count; ++cnt)
2842 free (*p->ptrs[cnt]);
2843 *p->ptrs[cnt] = NULL;
2845 p = p->next;
2846 free (ptrs_to_free);
2847 ptrs_to_free = p;
2850 return EOF;
2852 else if (__builtin_expect (strptr != NULL, 0))
2854 free (*strptr);
2855 *strptr = NULL;
2857 return done;
2860 #ifdef COMPILE_WSCANF
2862 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2864 return _IO_vfwscanf (s, format, argptr, NULL);
2866 ldbl_weak_alias (__vfwscanf, vfwscanf)
2867 #else
2869 ___vfscanf (FILE *s, const char *format, va_list argptr)
2871 return _IO_vfscanf_internal (s, format, argptr, NULL);
2873 ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
2874 ldbl_strong_alias (___vfscanf, __vfscanf)
2875 ldbl_hidden_def (___vfscanf, __vfscanf)
2876 ldbl_weak_alias (___vfscanf, vfscanf)
2877 #endif