Update.
[glibc.git] / stdio-common / vfscanf.c
blob603940da4c58f87e3f4058b8f6116565baf78a94
1 /* Copyright (C) 1991-2002, 2003, 2004 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 0x001 /* l: long or double */
56 #define LONGDBL 0x002 /* L: long long or long double */
57 #define SHORT 0x004 /* h: short */
58 #define SUPPRESS 0x008 /* *: suppress assignment */
59 #define POINTER 0x010 /* weird %p pointer (`fake hex') */
60 #define NOSKIP 0x020 /* do not skip blanks */
61 #define WIDTH 0x040 /* width was given */
62 #define GROUP 0x080 /* ': group numbers */
63 #define MALLOC 0x100 /* a: malloc strings */
64 #define CHAR 0x200 /* hh: char */
65 #define I18N 0x400 /* I: use locale's digits */
68 #include <locale/localeinfo.h>
69 #include <libioP.h>
70 #include <libio.h>
72 #undef va_list
73 #define va_list _IO_va_list
75 #ifdef COMPILE_WSCANF
76 # define ungetc(c, s) ((void) (c == WEOF \
77 || (--read_in, \
78 INTUSE(_IO_sputbackwc) (s, c))))
79 # define ungetc_not_eof(c, s) ((void) (--read_in, \
80 INTUSE(_IO_sputbackwc) (s, c)))
81 # define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
82 : ((c = _IO_getwc_unlocked (s)), \
83 (void) (c != WEOF \
84 ? ++read_in \
85 : (size_t) (inchar_errno = errno)), c))
87 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
88 # define ISSPACE(Ch) iswspace (Ch)
89 # define ISDIGIT(Ch) iswdigit (Ch)
90 # define ISXDIGIT(Ch) iswxdigit (Ch)
91 # define TOLOWER(Ch) towlower (Ch)
92 # define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
93 # define __strtoll_internal __wcstoll_internal
94 # define __strtoull_internal __wcstoull_internal
95 # define __strtol_internal __wcstol_internal
96 # define __strtoul_internal __wcstoul_internal
97 # define __strtold_internal __wcstold_internal
98 # define __strtod_internal __wcstod_internal
99 # define __strtof_internal __wcstof_internal
101 # define L_(Str) L##Str
102 # define CHAR_T wchar_t
103 # define UCHAR_T unsigned int
104 # define WINT_T wint_t
105 # undef EOF
106 # define EOF WEOF
107 #else
108 # define ungetc(c, s) ((void) ((int) c == EOF \
109 || (--read_in, \
110 INTUSE(_IO_sputbackc) (s, (unsigned char) c))))
111 # define ungetc_not_eof(c, s) ((void) (--read_in, \
112 INTUSE(_IO_sputbackc) (s, (unsigned char) c)))
113 # define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
114 : ((c = _IO_getc_unlocked (s)), \
115 (void) (c != EOF \
116 ? ++read_in \
117 : (size_t) (inchar_errno = errno)), c))
118 # define MEMCPY(d, s, n) memcpy (d, s, n)
119 # define ISSPACE(Ch) __isspace_l (Ch, loc)
120 # define ISDIGIT(Ch) __isdigit_l (Ch, loc)
121 # define ISXDIGIT(Ch) __isxdigit_l (Ch, loc)
122 # define TOLOWER(Ch) __tolower_l (Ch, loc)
123 # define ORIENT if (_IO_vtable_offset (s) == 0 \
124 && _IO_fwide (s, -1) != -1) \
125 return EOF
127 # define L_(Str) Str
128 # define CHAR_T char
129 # define UCHAR_T unsigned char
130 # define WINT_T int
131 #endif
133 #define encode_error() do { \
134 errval = 4; \
135 __set_errno (EILSEQ); \
136 goto errout; \
137 } while (0)
138 #define conv_error() do { \
139 errval = 2; \
140 goto errout; \
141 } while (0)
142 #define input_error() do { \
143 errval = 1; \
144 if (done == 0) done = EOF; \
145 goto errout; \
146 } while (0)
147 #define memory_error() do { \
148 __set_errno (ENOMEM); \
149 done = EOF; \
150 goto errout; \
151 } while (0)
152 #define ARGCHECK(s, format) \
153 do \
155 /* Check file argument for consistence. */ \
156 CHECK_FILE (s, EOF); \
157 if (s->_flags & _IO_NO_READS) \
159 __set_errno (EBADF); \
160 return EOF; \
162 else if (format == NULL) \
164 MAYBE_SET_EINVAL; \
165 return EOF; \
167 } while (0)
168 #define LOCK_STREAM(S) \
169 __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
170 _IO_flockfile (S)
171 #define UNLOCK_STREAM(S) \
172 _IO_funlockfile (S); \
173 __libc_cleanup_region_end (0)
176 /* Read formatted input from S according to the format string
177 FORMAT, using the argument list in ARG.
178 Return the number of assignments made, or -1 for an input error. */
179 #ifdef COMPILE_WSCANF
181 _IO_vfwscanf (s, format, argptr, errp)
182 _IO_FILE *s;
183 const wchar_t *format;
184 _IO_va_list argptr;
185 int *errp;
186 #else
188 _IO_vfscanf (s, format, argptr, errp)
189 _IO_FILE *s;
190 const char *format;
191 _IO_va_list argptr;
192 int *errp;
193 #endif
195 va_list arg;
196 register const CHAR_T *f = format;
197 register UCHAR_T fc; /* Current character of the format. */
198 register WINT_T done = 0; /* Assignments done. */
199 register size_t read_in = 0; /* Chars read in. */
200 register WINT_T c = 0; /* Last char read. */
201 register int width; /* Maximum field width. */
202 register int flags; /* Modifiers for current format element. */
203 int errval = 0;
204 #ifndef COMPILE_WSCANF
205 __locale_t loc = _NL_CURRENT_LOCALE;
206 struct locale_data *const curctype = loc->__locales[LC_CTYPE];
207 #endif
209 /* Errno of last failed inchar call. */
210 int inchar_errno = 0;
211 /* Status for reading F-P nums. */
212 char got_dot, got_e, negative;
213 /* If a [...] is a [^...]. */
214 CHAR_T not_in;
215 #define exp_char not_in
216 /* Base for integral numbers. */
217 int base;
218 /* Signedness for integral numbers. */
219 int number_signed;
220 #define is_hexa number_signed
221 /* Decimal point character. */
222 #ifdef COMPILE_WSCANF
223 wint_t decimal;
224 #else
225 const char *decimal;
226 #endif
227 /* The thousands character of the current locale. */
228 #ifdef COMPILE_WSCANF
229 wint_t thousands;
230 #else
231 const char *thousands;
232 #endif
233 /* State for the conversions. */
234 mbstate_t state;
235 /* Integral holding variables. */
236 union
238 long long int q;
239 unsigned long long int uq;
240 long int l;
241 unsigned long int ul;
242 } num;
243 /* Character-buffer pointer. */
244 char *str = NULL;
245 wchar_t *wstr = NULL;
246 char **strptr = NULL;
247 ssize_t strsize = 0;
248 /* We must not react on white spaces immediately because they can
249 possibly be matched even if in the input stream no character is
250 available anymore. */
251 int skip_space = 0;
252 /* Nonzero if we are reading a pointer. */
253 int read_pointer;
254 /* Workspace. */
255 CHAR_T *tw; /* Temporary pointer. */
256 CHAR_T *wp = NULL; /* Workspace. */
257 size_t wpmax = 0; /* Maximal size of workspace. */
258 size_t wpsize; /* Currently used bytes in workspace. */
259 #define ADDW(Ch) \
260 do \
262 if (wpsize == wpmax) \
264 CHAR_T *old = wp; \
265 wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
266 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
267 if (old != NULL) \
268 MEMCPY (wp, old, wpsize); \
270 wp[wpsize++] = (Ch); \
272 while (0)
274 #ifdef __va_copy
275 __va_copy (arg, argptr);
276 #else
277 arg = (va_list) argptr;
278 #endif
280 #ifdef ORIENT
281 ORIENT;
282 #endif
284 ARGCHECK (s, format);
287 #ifndef COMPILE_WSCANF
288 struct locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
289 #endif
291 /* Figure out the decimal point character. */
292 #ifdef COMPILE_WSCANF
293 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
294 #else
295 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
296 #endif
297 /* Figure out the thousands separator character. */
298 #ifdef COMPILE_WSCANF
299 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
300 #else
301 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
302 if (*thousands == '\0')
303 thousands = NULL;
304 #endif
307 /* Lock the stream. */
308 LOCK_STREAM (s);
311 #ifndef COMPILE_WSCANF
312 /* From now on we use `state' to convert the format string. */
313 memset (&state, '\0', sizeof (state));
314 #endif
316 /* Run through the format string. */
317 while (*f != '\0')
319 unsigned int argpos;
320 /* Extract the next argument, which is of type TYPE.
321 For a %N$... spec, this is the Nth argument from the beginning;
322 otherwise it is the next argument after the state now in ARG. */
323 #ifdef __va_copy
324 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
325 ({ unsigned int pos = argpos; \
326 va_list arg; \
327 __va_copy (arg, argptr); \
328 while (--pos > 0) \
329 (void) va_arg (arg, void *); \
330 va_arg (arg, type); \
332 #else
333 # if 0
334 /* XXX Possible optimization. */
335 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
336 ({ va_list arg = (va_list) argptr; \
337 arg = (va_list) ((char *) arg \
338 + (argpos - 1) \
339 * __va_rounded_size (void *)); \
340 va_arg (arg, type); \
342 # else
343 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
344 ({ unsigned int pos = argpos; \
345 va_list arg = (va_list) argptr; \
346 while (--pos > 0) \
347 (void) va_arg (arg, void *); \
348 va_arg (arg, type); \
350 # endif
351 #endif
353 #ifndef COMPILE_WSCANF
354 if (!isascii ((unsigned char) *f))
356 /* Non-ASCII, may be a multibyte. */
357 int len = __mbrlen (f, strlen (f), &state);
358 if (len > 0)
362 c = inchar ();
363 if (c == EOF)
364 input_error ();
365 else if (c != (unsigned char) *f++)
367 ungetc_not_eof (c, s);
368 conv_error ();
371 while (--len > 0);
372 continue;
375 #endif
377 fc = *f++;
378 if (fc != '%')
380 /* Remember to skip spaces. */
381 if (ISSPACE (fc))
383 skip_space = 1;
384 continue;
387 /* Read a character. */
388 c = inchar ();
390 /* Characters other than format specs must just match. */
391 if (c == EOF)
392 input_error ();
394 /* We saw white space char as the last character in the format
395 string. Now it's time to skip all leading white space. */
396 if (skip_space)
398 while (ISSPACE (c))
399 if (inchar () == EOF && errno == EINTR)
400 conv_error ();
401 skip_space = 0;
404 if (c != fc)
406 ungetc (c, s);
407 conv_error ();
410 continue;
413 /* This is the start of the conversion string. */
414 flags = 0;
416 /* Not yet decided whether we read a pointer or not. */
417 read_pointer = 0;
419 /* Initialize state of modifiers. */
420 argpos = 0;
422 /* Prepare temporary buffer. */
423 wpsize = 0;
425 /* Check for a positional parameter specification. */
426 if (ISDIGIT ((UCHAR_T) *f))
428 argpos = (UCHAR_T) *f++ - L_('0');
429 while (ISDIGIT ((UCHAR_T) *f))
430 argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
431 if (*f == L_('$'))
432 ++f;
433 else
435 /* Oops; that was actually the field width. */
436 width = argpos;
437 flags |= WIDTH;
438 argpos = 0;
439 goto got_width;
443 /* Check for the assignment-suppressing, the number grouping flag,
444 and the signal to use the locale's digit representation. */
445 while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
446 switch (*f++)
448 case L_('*'):
449 flags |= SUPPRESS;
450 break;
451 case L_('\''):
452 flags |= GROUP;
453 break;
454 case L_('I'):
455 flags |= I18N;
456 break;
459 /* We have seen width. */
460 if (ISDIGIT ((UCHAR_T) *f))
461 flags |= WIDTH;
463 /* Find the maximum field width. */
464 width = 0;
465 while (ISDIGIT ((UCHAR_T) *f))
467 width *= 10;
468 width += (UCHAR_T) *f++ - L_('0');
470 got_width:
471 if (width == 0)
472 width = -1;
474 /* Check for type modifiers. */
475 switch (*f++)
477 case L_('h'):
478 /* ints are short ints or chars. */
479 if (*f == L_('h'))
481 ++f;
482 flags |= CHAR;
484 else
485 flags |= SHORT;
486 break;
487 case L_('l'):
488 if (*f == L_('l'))
490 /* A double `l' is equivalent to an `L'. */
491 ++f;
492 flags |= LONGDBL | LONG;
494 else
495 /* ints are long ints. */
496 flags |= LONG;
497 break;
498 case L_('q'):
499 case L_('L'):
500 /* doubles are long doubles, and ints are long long ints. */
501 flags |= LONGDBL | LONG;
502 break;
503 case L_('a'):
504 /* The `a' is used as a flag only if followed by `s', `S' or
505 `['. */
506 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
508 --f;
509 break;
511 /* String conversions (%s, %[) take a `char **'
512 arg and fill it in with a malloc'd pointer. */
513 flags |= MALLOC;
514 break;
515 case L_('z'):
516 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
517 flags |= LONGDBL;
518 else if (sizeof (size_t) > sizeof (unsigned int))
519 flags |= LONG;
520 break;
521 case L_('j'):
522 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
523 flags |= LONGDBL;
524 else if (sizeof (uintmax_t) > sizeof (unsigned int))
525 flags |= LONG;
526 break;
527 case L_('t'):
528 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
529 flags |= LONGDBL;
530 else if (sizeof (ptrdiff_t) > sizeof (int))
531 flags |= LONG;
532 break;
533 default:
534 /* Not a recognized modifier. Backup. */
535 --f;
536 break;
539 /* End of the format string? */
540 if (*f == L_('\0'))
541 conv_error ();
543 /* Find the conversion specifier. */
544 fc = *f++;
545 if (skip_space || (fc != L_('[') && fc != L_('c')
546 && fc != L_('C') && fc != L_('n')))
548 /* Eat whitespace. */
549 int save_errno = errno;
550 errno = 0;
552 if (inchar () == EOF && errno == EINTR)
553 input_error ();
554 while (ISSPACE (c));
555 errno = save_errno;
556 ungetc (c, s);
557 skip_space = 0;
560 switch (fc)
562 case L_('%'): /* Must match a literal '%'. */
563 c = inchar ();
564 if (c == EOF)
565 input_error ();
566 if (c != fc)
568 ungetc_not_eof (c, s);
569 conv_error ();
571 break;
573 case L_('n'): /* Answer number of assignments done. */
574 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
575 with the 'n' conversion specifier. */
576 if (!(flags & SUPPRESS))
578 /* Don't count the read-ahead. */
579 if (need_longlong && (flags & LONGDBL))
580 *ARG (long long int *) = read_in;
581 else if (need_long && (flags & LONG))
582 *ARG (long int *) = read_in;
583 else if (flags & SHORT)
584 *ARG (short int *) = read_in;
585 else if (!(flags & CHAR))
586 *ARG (int *) = read_in;
587 else
588 *ARG (char *) = read_in;
590 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
591 /* We have a severe problem here. The ISO C standard
592 contradicts itself in explaining the effect of the %n
593 format in `scanf'. While in ISO C:1990 and the ISO C
594 Amendement 1:1995 the result is described as
596 Execution of a %n directive does not effect the
597 assignment count returned at the completion of
598 execution of the f(w)scanf function.
600 in ISO C Corrigendum 1:1994 the following was added:
602 Subclause 7.9.6.2
603 Add the following fourth example:
605 #include <stdio.h>
606 int d1, d2, n1, n2, i;
607 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
608 the value 123 is assigned to d1 and the value3 to n1.
609 Because %n can never get an input failure the value
610 of 3 is also assigned to n2. The value of d2 is not
611 affected. The value 3 is assigned to i.
613 We go for now with the historically correct code from ISO C,
614 i.e., we don't count the %n assignments. When it ever
615 should proof to be wrong just remove the #ifdef above. */
616 ++done;
617 #endif
619 break;
621 case L_('c'): /* Match characters. */
622 if ((flags & LONG) == 0)
624 if (!(flags & SUPPRESS))
626 str = ARG (char *);
627 if (str == NULL)
628 conv_error ();
631 c = inchar ();
632 if (c == EOF)
633 input_error ();
635 if (width == -1)
636 width = 1;
638 #ifdef COMPILE_WSCANF
639 /* We have to convert the wide character(s) into multibyte
640 characters and store the result. */
641 memset (&state, '\0', sizeof (state));
645 size_t n;
647 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
648 if (n == (size_t) -1)
649 /* No valid wide character. */
650 input_error ();
652 /* Increment the output pointer. Even if we don't
653 write anything. */
654 str += n;
656 while (--width > 0 && inchar () != EOF);
657 #else
658 if (!(flags & SUPPRESS))
661 *str++ = c;
662 while (--width > 0 && inchar () != EOF);
664 else
665 while (--width > 0 && inchar () != EOF);
666 #endif
668 if (!(flags & SUPPRESS))
669 ++done;
671 break;
673 /* FALLTHROUGH */
674 case L_('C'):
675 if (!(flags & SUPPRESS))
677 wstr = ARG (wchar_t *);
678 if (wstr == NULL)
679 conv_error ();
682 c = inchar ();
683 if (c == EOF)
684 input_error ();
686 #ifdef COMPILE_WSCANF
687 /* Just store the incoming wide characters. */
688 if (!(flags & SUPPRESS))
691 *wstr++ = c;
692 while (--width > 0 && inchar () != EOF);
694 else
695 while (--width > 0 && inchar () != EOF);
696 #else
698 /* We have to convert the multibyte input sequence to wide
699 characters. */
700 char buf[1];
701 mbstate_t cstate;
703 memset (&cstate, '\0', sizeof (cstate));
707 /* This is what we present the mbrtowc function first. */
708 buf[0] = c;
710 while (1)
712 size_t n;
714 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
715 buf, 1, &cstate);
717 if (n == (size_t) -2)
719 /* Possibly correct character, just not enough
720 input. */
721 if (inchar () == EOF)
722 encode_error ();
724 buf[0] = c;
725 continue;
728 if (n != 1)
729 encode_error ();
731 /* We have a match. */
732 break;
735 /* Advance the result pointer. */
736 ++wstr;
738 while (--width > 0 && inchar () != EOF);
740 #endif
742 if (!(flags & SUPPRESS))
743 ++done;
745 break;
747 case L_('s'): /* Read a string. */
748 if (!(flags & LONG))
750 #define STRING_ARG(Str, Type) \
751 do if (!(flags & SUPPRESS)) \
753 if (flags & MALLOC) \
755 /* The string is to be stored in a malloc'd buffer. */ \
756 strptr = ARG (char **); \
757 if (strptr == NULL) \
758 conv_error (); \
759 /* Allocate an initial buffer. */ \
760 strsize = 100; \
761 *strptr = (char *) malloc (strsize * sizeof (Type)); \
762 Str = (Type *) *strptr; \
764 else \
765 Str = ARG (Type *); \
766 if (Str == NULL) \
767 conv_error (); \
768 } while (0)
769 STRING_ARG (str, char);
771 c = inchar ();
772 if (c == EOF)
773 input_error ();
775 #ifdef COMPILE_WSCANF
776 memset (&state, '\0', sizeof (state));
777 #endif
781 if (ISSPACE (c))
783 ungetc_not_eof (c, s);
784 break;
787 #ifdef COMPILE_WSCANF
788 /* This is quite complicated. We have to convert the
789 wide characters into multibyte characters and then
790 store them. */
792 size_t n;
794 if (!(flags & SUPPRESS) && (flags & MALLOC)
795 && str + MB_CUR_MAX >= *strptr + strsize)
797 /* We have to enlarge the buffer if the `a' flag
798 was given. */
799 size_t strleng = str - *strptr;
800 char *newstr;
802 newstr = (char *) realloc (*strptr, strsize * 2);
803 if (newstr == NULL)
805 /* Can't allocate that much. Last-ditch
806 effort. */
807 newstr = (char *) realloc (*strptr,
808 strleng + MB_CUR_MAX);
809 if (newstr == NULL)
811 /* We lose. Oh well. Terminate the
812 string and stop converting,
813 so at least we don't skip any input. */
814 ((char *) (*strptr))[strleng] = '\0';
815 ++done;
816 conv_error ();
818 else
820 *strptr = newstr;
821 str = newstr + strleng;
822 strsize = strleng + MB_CUR_MAX;
825 else
827 *strptr = newstr;
828 str = newstr + strleng;
829 strsize *= 2;
833 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
834 &state);
835 if (n == (size_t) -1)
836 encode_error ();
838 assert (n <= MB_CUR_MAX);
839 str += n;
841 #else
842 /* This is easy. */
843 if (!(flags & SUPPRESS))
845 *str++ = c;
846 if ((flags & MALLOC)
847 && (char *) str == *strptr + strsize)
849 /* Enlarge the buffer. */
850 str = (char *) realloc (*strptr, 2 * strsize);
851 if (str == NULL)
853 /* Can't allocate that much. Last-ditch
854 effort. */
855 str = (char *) realloc (*strptr, strsize + 1);
856 if (str == NULL)
858 /* We lose. Oh well. Terminate the
859 string and stop converting,
860 so at least we don't skip any input. */
861 ((char *) (*strptr))[strsize - 1] = '\0';
862 ++done;
863 conv_error ();
865 else
867 *strptr = (char *) str;
868 str += strsize;
869 ++strsize;
872 else
874 *strptr = (char *) str;
875 str += strsize;
876 strsize *= 2;
880 #endif
882 while ((width <= 0 || --width > 0) && inchar () != EOF);
884 if (!(flags & SUPPRESS))
886 #ifdef COMPILE_WSCANF
887 /* We have to emit the code to get into the initial
888 state. */
889 char buf[MB_LEN_MAX];
890 size_t n = __wcrtomb (buf, L'\0', &state);
891 if (n > 0 && (flags & MALLOC)
892 && str + n >= *strptr + strsize)
894 /* Enlarge the buffer. */
895 size_t strleng = str - *strptr;
896 char *newstr;
898 newstr = (char *) realloc (*strptr, strleng + n + 1);
899 if (newstr == NULL)
901 /* We lose. Oh well. Terminate the string
902 and stop converting, so at least we don't
903 skip any input. */
904 ((char *) (*strptr))[strleng] = '\0';
905 ++done;
906 conv_error ();
908 else
910 *strptr = newstr;
911 str = newstr + strleng;
912 strsize = strleng + n + 1;
916 str = __mempcpy (str, buf, n);
917 #endif
918 *str++ = '\0';
920 if ((flags & MALLOC) && str - *strptr != strsize)
922 char *cp = (char *) realloc (*strptr, str - *strptr);
923 if (cp != NULL)
924 *strptr = cp;
927 ++done;
929 break;
931 /* FALLTHROUGH */
933 case L_('S'):
935 #ifndef COMPILE_WSCANF
936 mbstate_t cstate;
937 #endif
939 /* Wide character string. */
940 STRING_ARG (wstr, wchar_t);
942 c = inchar ();
943 if (c == EOF)
944 input_error ();
946 #ifndef COMPILE_WSCANF
947 memset (&cstate, '\0', sizeof (cstate));
948 #endif
952 if (ISSPACE (c))
954 ungetc_not_eof (c, s);
955 break;
958 #ifdef COMPILE_WSCANF
959 /* This is easy. */
960 if (!(flags & SUPPRESS))
962 *wstr++ = c;
963 if ((flags & MALLOC)
964 && wstr == (wchar_t *) *strptr + strsize)
966 /* Enlarge the buffer. */
967 wstr = (wchar_t *) realloc (*strptr,
968 (2 * strsize)
969 * sizeof (wchar_t));
970 if (wstr == NULL)
972 /* Can't allocate that much. Last-ditch
973 effort. */
974 wstr = (wchar_t *) realloc (*strptr,
975 (strsize + 1)
976 * sizeof (wchar_t));
977 if (wstr == NULL)
979 /* We lose. Oh well. Terminate the string
980 and stop converting, so at least we don't
981 skip any input. */
982 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
983 ++done;
984 conv_error ();
986 else
988 *strptr = (char *) wstr;
989 wstr += strsize;
990 ++strsize;
993 else
995 *strptr = (char *) wstr;
996 wstr += strsize;
997 strsize *= 2;
1001 #else
1003 char buf[1];
1005 buf[0] = c;
1007 while (1)
1009 size_t n;
1011 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1012 buf, 1, &cstate);
1014 if (n == (size_t) -2)
1016 /* Possibly correct character, just not enough
1017 input. */
1018 if (inchar () == EOF)
1019 encode_error ();
1021 buf[0] = c;
1022 continue;
1025 if (n != 1)
1026 encode_error ();
1028 /* We have a match. */
1029 ++wstr;
1030 break;
1033 if (!(flags & SUPPRESS) && (flags & MALLOC)
1034 && wstr == (wchar_t *) *strptr + strsize)
1036 /* Enlarge the buffer. */
1037 wstr = (wchar_t *) realloc (*strptr,
1038 (2 * strsize
1039 * sizeof (wchar_t)));
1040 if (wstr == NULL)
1042 /* Can't allocate that much. Last-ditch effort. */
1043 wstr = (wchar_t *) realloc (*strptr,
1044 ((strsize + 1)
1045 * sizeof (wchar_t)));
1046 if (wstr == NULL)
1048 /* We lose. Oh well. Terminate the
1049 string and stop converting, so at
1050 least we don't skip any input. */
1051 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1052 ++done;
1053 conv_error ();
1055 else
1057 *strptr = (char *) wstr;
1058 wstr += strsize;
1059 ++strsize;
1062 else
1064 *strptr = (char *) wstr;
1065 wstr += strsize;
1066 strsize *= 2;
1070 #endif
1072 while ((width <= 0 || --width > 0) && inchar () != EOF);
1074 if (!(flags & SUPPRESS))
1076 *wstr++ = L'\0';
1078 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1080 wchar_t *cp = (wchar_t *) realloc (*strptr,
1081 ((wstr
1082 - (wchar_t *) *strptr)
1083 * sizeof(wchar_t)));
1084 if (cp != NULL)
1085 *strptr = (char *) cp;
1088 ++done;
1091 break;
1093 case L_('x'): /* Hexadecimal integer. */
1094 case L_('X'): /* Ditto. */
1095 base = 16;
1096 number_signed = 0;
1097 goto number;
1099 case L_('o'): /* Octal integer. */
1100 base = 8;
1101 number_signed = 0;
1102 goto number;
1104 case L_('u'): /* Unsigned decimal integer. */
1105 base = 10;
1106 number_signed = 0;
1107 goto number;
1109 case L_('d'): /* Signed decimal integer. */
1110 base = 10;
1111 number_signed = 1;
1112 goto number;
1114 case L_('i'): /* Generic number. */
1115 base = 0;
1116 number_signed = 1;
1118 number:
1119 c = inchar ();
1120 if (c == EOF)
1121 input_error ();
1123 /* Check for a sign. */
1124 if (c == L_('-') || c == L_('+'))
1126 ADDW (c);
1127 if (width > 0)
1128 --width;
1129 c = inchar ();
1132 /* Look for a leading indication of base. */
1133 if (width != 0 && c == L_('0'))
1135 if (width > 0)
1136 --width;
1138 ADDW (c);
1139 c = inchar ();
1141 if (width != 0 && TOLOWER (c) == L_('x'))
1143 if (base == 0)
1144 base = 16;
1145 if (base == 16)
1147 if (width > 0)
1148 --width;
1149 c = inchar ();
1152 else if (base == 0)
1153 base = 8;
1156 if (base == 0)
1157 base = 10;
1159 if (base == 10 && (flags & I18N) != 0)
1161 int from_level;
1162 int to_level;
1163 int level;
1164 #ifdef COMPILE_WSCANF
1165 const wchar_t *wcdigits[10];
1166 #else
1167 const char *mbdigits[10];
1168 #endif
1169 int n;
1171 from_level = 0;
1172 #ifdef COMPILE_WSCANF
1173 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1174 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1175 #else
1176 to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
1177 #endif
1179 /* Read the number into workspace. */
1180 while (c != EOF && width != 0)
1182 /* In this round we get the pointer to the digit strings
1183 and also perform the first round of comparisons. */
1184 for (n = 0; n < 10; ++n)
1186 /* Get the string for the digits with value N. */
1187 #ifdef COMPILE_WSCANF
1188 wcdigits[n] = (const wchar_t *)
1189 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1190 wcdigits[n] += from_level;
1192 if (c == (wint_t) *wcdigits[n])
1194 to_level = from_level;
1195 break;
1198 /* Advance the pointer to the next string. */
1199 ++wcdigits[n];
1200 #else
1201 const char *cmpp;
1202 int avail = width > 0 ? width : INT_MAX;
1204 mbdigits[n]
1205 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1207 for (level = 0; level < from_level; level++)
1208 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1210 cmpp = mbdigits[n];
1211 while ((unsigned char) *cmpp == c && avail > 0)
1213 if (*++cmpp == '\0')
1214 break;
1215 else
1217 if ((c = inchar ()) == EOF)
1218 break;
1219 --avail;
1223 if (*cmpp == '\0')
1225 if (width > 0)
1226 width = avail;
1227 to_level = from_level;
1228 break;
1231 /* We are pushing all read characters back. */
1232 if (cmpp > mbdigits[n])
1234 ungetc (c, s);
1235 while (--cmpp > mbdigits[n])
1236 ungetc_not_eof ((unsigned char) *cmpp, s);
1237 c = (unsigned char) *cmpp;
1240 /* Advance the pointer to the next string. */
1241 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1242 #endif
1245 if (n == 10)
1247 /* Have not yet found the digit. */
1248 for (level = from_level + 1; level <= to_level; ++level)
1250 /* Search all ten digits of this level. */
1251 for (n = 0; n < 10; ++n)
1253 #ifdef COMPILE_WSCANF
1254 if (c == (wint_t) *wcdigits[n])
1255 break;
1257 /* Advance the pointer to the next string. */
1258 ++wcdigits[n];
1259 #else
1260 const char *cmpp;
1261 int avail = width > 0 ? width : INT_MAX;
1263 cmpp = mbdigits[n];
1264 while ((unsigned char) *cmpp == c && avail > 0)
1266 if (*++cmpp == '\0')
1267 break;
1268 else
1270 if ((c = inchar ()) == EOF)
1271 break;
1272 --avail;
1276 if (*cmpp == '\0')
1278 if (width > 0)
1279 width = avail;
1280 break;
1283 /* We are pushing all read characters back. */
1284 if (cmpp > mbdigits[n])
1286 ungetc (c, s);
1287 while (--cmpp > mbdigits[n])
1288 ungetc_not_eof ((unsigned char) *cmpp, s);
1289 c = (unsigned char) *cmpp;
1292 /* Advance the pointer to the next string. */
1293 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1294 #endif
1297 if (n < 10)
1299 /* Found it. */
1300 from_level = level;
1301 to_level = level;
1302 break;
1307 if (n < 10)
1308 c = L_('0') + n;
1309 else if ((flags & GROUP)
1310 #ifdef COMPILE_WSCANF
1311 && thousands != L'\0'
1312 #else
1313 && thousands != NULL
1314 #endif
1317 /* Try matching against the thousands separator. */
1318 #ifdef COMPILE_WSCANF
1319 if (c != thousands)
1320 break;
1321 #else
1322 const char *cmpp = thousands;
1323 int avail = width > 0 ? width : INT_MAX;
1325 while ((unsigned char) *cmpp == c && avail > 0)
1327 ADDW (c);
1328 if (*++cmpp == '\0')
1329 break;
1330 else
1332 if ((c = inchar ()) == EOF)
1333 break;
1334 --avail;
1338 if (*cmpp != '\0')
1340 /* We are pushing all read characters back. */
1341 if (cmpp > thousands)
1343 wpsize -= cmpp - thousands;
1344 ungetc (c, s);
1345 while (--cmpp > thousands)
1346 ungetc_not_eof ((unsigned char) *cmpp, s);
1347 c = (unsigned char) *cmpp;
1349 break;
1352 if (width > 0)
1353 width = avail;
1355 /* The last thousands character will be added back by
1356 the ADDW below. */
1357 --wpsize;
1358 #endif
1360 else
1361 break;
1363 ADDW (c);
1364 if (width > 0)
1365 --width;
1367 c = inchar ();
1370 else
1371 /* Read the number into workspace. */
1372 while (c != EOF && width != 0)
1374 if (base == 16)
1376 if (!ISXDIGIT (c))
1377 break;
1379 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
1381 if (base == 10 && (flags & GROUP)
1382 #ifdef COMPILE_WSCANF
1383 && thousands != L'\0'
1384 #else
1385 && thousands != NULL
1386 #endif
1389 /* Try matching against the thousands separator. */
1390 #ifdef COMPILE_WSCANF
1391 if (c != thousands)
1392 break;
1393 #else
1394 const char *cmpp = thousands;
1395 int avail = width > 0 ? width : INT_MAX;
1397 while ((unsigned char) *cmpp == c && avail > 0)
1399 ADDW (c);
1400 if (*++cmpp == '\0')
1401 break;
1402 else
1404 if ((c = inchar ()) == EOF)
1405 break;
1406 --avail;
1410 if (*cmpp != '\0')
1412 /* We are pushing all read characters back. */
1413 if (cmpp > thousands)
1415 wpsize -= cmpp - thousands;
1416 ungetc (c, s);
1417 while (--cmpp > thousands)
1418 ungetc_not_eof ((unsigned char) *cmpp, s);
1419 c = (unsigned char) *cmpp;
1421 break;
1424 if (width > 0)
1425 width = avail;
1427 /* The last thousands character will be added back by
1428 the ADDW below. */
1429 --wpsize;
1430 #endif
1432 else
1433 break;
1435 ADDW (c);
1436 if (width > 0)
1437 --width;
1439 c = inchar ();
1442 if (wpsize == 0
1443 || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1445 /* There was no number. If we are supposed to read a pointer
1446 we must recognize "(nil)" as well. */
1447 if (wpsize == 0 && read_pointer && (width < 0 || width >= 0)
1448 && c == '('
1449 && TOLOWER (inchar ()) == L_('n')
1450 && TOLOWER (inchar ()) == L_('i')
1451 && TOLOWER (inchar ()) == L_('l')
1452 && inchar () == L_(')'))
1453 /* We must produce the value of a NULL pointer. A single
1454 '0' digit is enough. */
1455 ADDW (L_('0'));
1456 else
1458 /* The last read character is not part of the number
1459 anymore. */
1460 ungetc (c, s);
1462 conv_error ();
1465 else
1466 /* The just read character is not part of the number anymore. */
1467 ungetc (c, s);
1469 /* Convert the number. */
1470 ADDW (L_('\0'));
1471 if (need_longlong && (flags & LONGDBL))
1473 if (number_signed)
1474 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1475 else
1476 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1478 else
1480 if (number_signed)
1481 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1482 else
1483 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1485 if (wp == tw)
1486 conv_error ();
1488 if (!(flags & SUPPRESS))
1490 if (! number_signed)
1492 if (need_longlong && (flags & LONGDBL))
1493 *ARG (unsigned LONGLONG int *) = num.uq;
1494 else if (need_long && (flags & LONG))
1495 *ARG (unsigned long int *) = num.ul;
1496 else if (flags & SHORT)
1497 *ARG (unsigned short int *)
1498 = (unsigned short int) num.ul;
1499 else if (!(flags & CHAR))
1500 *ARG (unsigned int *) = (unsigned int) num.ul;
1501 else
1502 *ARG (unsigned char *) = (unsigned char) num.ul;
1504 else
1506 if (need_longlong && (flags & LONGDBL))
1507 *ARG (LONGLONG int *) = num.q;
1508 else if (need_long && (flags & LONG))
1509 *ARG (long int *) = num.l;
1510 else if (flags & SHORT)
1511 *ARG (short int *) = (short int) num.l;
1512 else if (!(flags & CHAR))
1513 *ARG (int *) = (int) num.l;
1514 else
1515 *ARG (signed char *) = (signed char) num.ul;
1517 ++done;
1519 break;
1521 case L_('e'): /* Floating-point numbers. */
1522 case L_('E'):
1523 case L_('f'):
1524 case L_('F'):
1525 case L_('g'):
1526 case L_('G'):
1527 case L_('a'):
1528 case L_('A'):
1529 c = inchar ();
1530 if (c == EOF)
1531 input_error ();
1533 /* Check for a sign. */
1534 if (c == L_('-') || c == L_('+'))
1536 negative = c == L_('-');
1537 if (width == 0 || inchar () == EOF)
1538 /* EOF is only an input error before we read any chars. */
1539 conv_error ();
1540 if (! ISDIGIT (c) && TOLOWER (c) != L_('i')
1541 && TOLOWER (c) != L_('n'))
1543 #ifdef COMPILE_WSCANF
1544 if (c != decimal)
1546 /* This is no valid number. */
1547 ungetc (c, s);
1548 conv_error ();
1550 #else
1551 /* Match against the decimal point. At this point
1552 we are taking advantage of the fact that we can
1553 push more than one character back. This is
1554 (almost) never necessary since the decimal point
1555 string hopefully never contains more than one
1556 byte. */
1557 const char *cmpp = decimal;
1558 int avail = width > 0 ? width : INT_MAX;
1560 while ((unsigned char) *cmpp == c && avail > 0)
1561 if (*++cmpp == '\0')
1562 break;
1563 else
1565 if (inchar () == EOF)
1566 break;
1567 --avail;
1570 if (*cmpp != '\0')
1572 /* This is no valid number. */
1573 while (1)
1575 ungetc (c, s);
1576 if (cmpp == decimal)
1577 break;
1578 c = (unsigned char) *--cmpp;
1581 conv_error ();
1583 if (width > 0)
1584 width = avail;
1585 #endif
1587 if (width > 0)
1588 --width;
1590 else
1591 negative = 0;
1593 /* Take care for the special arguments "nan" and "inf". */
1594 if (TOLOWER (c) == L_('n'))
1596 /* Maybe "nan". */
1597 ADDW (c);
1598 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('a'))
1599 conv_error ();
1600 if (width > 0)
1601 --width;
1602 ADDW (c);
1603 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1604 conv_error ();
1605 if (width > 0)
1606 --width;
1607 ADDW (c);
1608 /* It is "nan". */
1609 goto scan_float;
1611 else if (TOLOWER (c) == L_('i'))
1613 /* Maybe "inf" or "infinity". */
1614 ADDW (c);
1615 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1616 conv_error ();
1617 if (width > 0)
1618 --width;
1619 ADDW (c);
1620 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('f'))
1621 conv_error ();
1622 if (width > 0)
1623 --width;
1624 ADDW (c);
1625 /* It is as least "inf". */
1626 if (width != 0 && inchar () != EOF)
1628 if (TOLOWER (c) == L_('i'))
1630 if (width > 0)
1631 --width;
1632 /* Now we have to read the rest as well. */
1633 ADDW (c);
1634 if (width == 0 || inchar () == EOF
1635 || TOLOWER (c) != L_('n'))
1636 conv_error ();
1637 if (width > 0)
1638 --width;
1639 ADDW (c);
1640 if (width == 0 || inchar () == EOF
1641 || TOLOWER (c) != L_('i'))
1642 conv_error ();
1643 if (width > 0)
1644 --width;
1645 ADDW (c);
1646 if (width == 0 || inchar () == EOF
1647 || TOLOWER (c) != L_('t'))
1648 conv_error ();
1649 if (width > 0)
1650 --width;
1651 ADDW (c);
1652 if (width == 0 || inchar () == EOF
1653 || TOLOWER (c) != L_('y'))
1654 conv_error ();
1655 if (width > 0)
1656 --width;
1657 ADDW (c);
1659 else
1660 /* Never mind. */
1661 ungetc (c, s);
1663 goto scan_float;
1666 is_hexa = 0;
1667 exp_char = L_('e');
1668 if (width != 0 && c == L_('0'))
1670 ADDW (c);
1671 c = inchar ();
1672 if (width > 0)
1673 --width;
1674 if (width != 0 && TOLOWER (c) == L_('x'))
1676 /* It is a number in hexadecimal format. */
1677 ADDW (c);
1679 is_hexa = 1;
1680 exp_char = L_('p');
1682 /* Grouping is not allowed. */
1683 flags &= ~GROUP;
1684 c = inchar ();
1685 if (width > 0)
1686 --width;
1690 got_dot = got_e = 0;
1693 if (ISDIGIT (c))
1694 ADDW (c);
1695 else if (!got_e && is_hexa && ISXDIGIT (c))
1696 ADDW (c);
1697 else if (got_e && wp[wpsize - 1] == exp_char
1698 && (c == L_('-') || c == L_('+')))
1699 ADDW (c);
1700 else if (wpsize > 0 && !got_e
1701 && (CHAR_T) TOLOWER (c) == exp_char)
1703 ADDW (exp_char);
1704 got_e = got_dot = 1;
1706 else
1708 #ifdef COMPILE_WSCANF
1709 if (! got_dot && c == decimal)
1711 ADDW (c);
1712 got_dot = 1;
1714 else if ((flags & GROUP) != 0 && thousands != L'\0'
1715 && ! got_dot && c == thousands)
1716 ADDW (c);
1717 else
1719 /* The last read character is not part of the number
1720 anymore. */
1721 ungetc (c, s);
1722 break;
1724 #else
1725 const char *cmpp = decimal;
1726 int avail = width > 0 ? width : INT_MAX;
1728 if (! got_dot)
1730 while ((unsigned char) *cmpp == c && avail > 0)
1731 if (*++cmpp == '\0')
1732 break;
1733 else
1735 if (inchar () == EOF)
1736 break;
1737 --avail;
1741 if (*cmpp == '\0')
1743 /* Add all the characters. */
1744 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1745 ADDW ((unsigned char) *cmpp);
1746 if (width > 0)
1747 width = avail;
1748 got_dot = 1;
1750 else
1752 /* Figure out whether it is a thousands separator.
1753 There is one problem: we possibly read more than
1754 one character. We cannot push them back but since
1755 we know that parts of the `decimal' string matched,
1756 we can compare against it. */
1757 const char *cmp2p = thousands;
1759 if ((flags & GROUP) != 0 && thousands != NULL
1760 && ! got_dot)
1762 while (cmp2p - thousands < cmpp - decimal
1763 && *cmp2p == decimal[cmp2p - thousands])
1764 ++cmp2p;
1765 if (cmp2p - thousands == cmpp - decimal)
1767 while ((unsigned char) *cmp2p == c && avail > 0)
1768 if (*++cmp2p == '\0')
1769 break;
1770 else
1772 if (inchar () == EOF)
1773 break;
1774 --avail;
1779 if (cmp2p != NULL && *cmp2p == '\0')
1781 /* Add all the characters. */
1782 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
1783 ADDW ((unsigned char) *cmpp);
1784 if (width > 0)
1785 width = avail;
1787 else
1789 /* The last read character is not part of the number
1790 anymore. */
1791 ungetc (c, s);
1792 break;
1795 #endif
1797 if (width > 0)
1798 --width;
1800 while (width != 0 && inchar () != EOF);
1802 /* Have we read any character? If we try to read a number
1803 in hexadecimal notation and we have read only the `0x'
1804 prefix or no exponent this is an error. */
1805 if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
1806 conv_error ();
1808 scan_float:
1809 /* Convert the number. */
1810 ADDW (L_('\0'));
1811 if (flags & LONGDBL)
1813 long double d = __strtold_internal (wp, &tw, flags & GROUP);
1814 if (!(flags & SUPPRESS) && tw != wp)
1815 *ARG (long double *) = negative ? -d : d;
1817 else if (flags & LONG)
1819 double d = __strtod_internal (wp, &tw, flags & GROUP);
1820 if (!(flags & SUPPRESS) && tw != wp)
1821 *ARG (double *) = negative ? -d : d;
1823 else
1825 float d = __strtof_internal (wp, &tw, flags & GROUP);
1826 if (!(flags & SUPPRESS) && tw != wp)
1827 *ARG (float *) = negative ? -d : d;
1830 if (tw == wp)
1831 conv_error ();
1833 if (!(flags & SUPPRESS))
1834 ++done;
1835 break;
1837 case L_('['): /* Character class. */
1838 if (flags & LONG)
1839 STRING_ARG (wstr, wchar_t);
1840 else
1841 STRING_ARG (str, char);
1843 if (*f == L_('^'))
1845 ++f;
1846 not_in = 1;
1848 else
1849 not_in = 0;
1851 if (width < 0)
1852 /* There is no width given so there is also no limit on the
1853 number of characters we read. Therefore we set width to
1854 a very high value to make the algorithm easier. */
1855 width = INT_MAX;
1857 #ifdef COMPILE_WSCANF
1858 /* Find the beginning and the end of the scanlist. We are not
1859 creating a lookup table since it would have to be too large.
1860 Instead we search each time through the string. This is not
1861 a constant lookup time but who uses this feature deserves to
1862 be punished. */
1863 tw = (wchar_t *) f; /* Marks the beginning. */
1865 if (*f == L']')
1866 ++f;
1868 while ((fc = *f++) != L'\0' && fc != L']');
1870 if (fc == L'\0')
1871 conv_error ();
1872 wp = (wchar_t *) f - 1;
1873 #else
1874 /* Fill WP with byte flags indexed by character.
1875 We will use this flag map for matching input characters. */
1876 if (wpmax < UCHAR_MAX + 1)
1878 wpmax = UCHAR_MAX + 1;
1879 wp = (char *) alloca (wpmax);
1881 memset (wp, '\0', UCHAR_MAX + 1);
1883 fc = *f;
1884 if (fc == ']' || fc == '-')
1886 /* If ] or - appears before any char in the set, it is not
1887 the terminator or separator, but the first char in the
1888 set. */
1889 wp[fc] = 1;
1890 ++f;
1893 while ((fc = *f++) != '\0' && fc != ']')
1894 if (fc == '-' && *f != '\0' && *f != ']'
1895 && (unsigned char) f[-2] <= (unsigned char) *f)
1897 /* Add all characters from the one before the '-'
1898 up to (but not including) the next format char. */
1899 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
1900 wp[fc] = 1;
1902 else
1903 /* Add the character to the flag map. */
1904 wp[fc] = 1;
1906 if (fc == '\0')
1907 conv_error();
1908 #endif
1910 if (flags & LONG)
1912 size_t now = read_in;
1913 #ifdef COMPILE_WSCANF
1914 if (inchar () == WEOF)
1915 input_error ();
1919 wchar_t *runp;
1921 /* Test whether it's in the scanlist. */
1922 runp = tw;
1923 while (runp < wp)
1925 if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
1926 && runp != tw
1927 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
1929 /* Match against all characters in between the
1930 first and last character of the sequence. */
1931 wchar_t wc;
1933 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
1934 if ((wint_t) wc == c)
1935 break;
1937 if (wc <= runp[1] && !not_in)
1938 break;
1939 if (wc <= runp[1] && not_in)
1941 /* The current character is not in the
1942 scanset. */
1943 ungetc (c, s);
1944 goto out;
1947 runp += 2;
1949 else
1951 if ((wint_t) *runp == c && !not_in)
1952 break;
1953 if ((wint_t) *runp == c && not_in)
1955 ungetc (c, s);
1956 goto out;
1959 ++runp;
1963 if (runp == wp && !not_in)
1965 ungetc (c, s);
1966 goto out;
1969 if (!(flags & SUPPRESS))
1971 *wstr++ = c;
1973 if ((flags & MALLOC)
1974 && wstr == (wchar_t *) *strptr + strsize)
1976 /* Enlarge the buffer. */
1977 wstr = (wchar_t *) realloc (*strptr,
1978 (2 * strsize)
1979 * sizeof (wchar_t));
1980 if (wstr == NULL)
1982 /* Can't allocate that much. Last-ditch
1983 effort. */
1984 wstr = (wchar_t *)
1985 realloc (*strptr, (strsize + 1)
1986 * sizeof (wchar_t));
1987 if (wstr == NULL)
1989 /* We lose. Oh well. Terminate the string
1990 and stop converting, so at least we don't
1991 skip any input. */
1992 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1993 ++done;
1994 conv_error ();
1996 else
1998 *strptr = (char *) wstr;
1999 wstr += strsize;
2000 ++strsize;
2003 else
2005 *strptr = (char *) wstr;
2006 wstr += strsize;
2007 strsize *= 2;
2012 while (--width > 0 && inchar () != WEOF);
2013 out:
2014 #else
2015 char buf[MB_LEN_MAX];
2016 size_t cnt = 0;
2017 mbstate_t cstate;
2019 if (inchar () == EOF)
2020 input_error ();
2022 memset (&cstate, '\0', sizeof (cstate));
2026 if (wp[c] == not_in)
2028 ungetc_not_eof (c, s);
2029 break;
2032 /* This is easy. */
2033 if (!(flags & SUPPRESS))
2035 size_t n;
2037 /* Convert it into a wide character. */
2038 buf[0] = c;
2039 n = __mbrtowc (wstr, buf, 1, &cstate);
2041 if (n == (size_t) -2)
2043 /* Possibly correct character, just not enough
2044 input. */
2045 ++cnt;
2046 assert (cnt < MB_CUR_MAX);
2047 continue;
2049 cnt = 0;
2051 ++wstr;
2052 if ((flags & MALLOC)
2053 && wstr == (wchar_t *) *strptr + strsize)
2055 /* Enlarge the buffer. */
2056 wstr = (wchar_t *) realloc (*strptr,
2057 (2 * strsize
2058 * sizeof (wchar_t)));
2059 if (wstr == NULL)
2061 /* Can't allocate that much. Last-ditch
2062 effort. */
2063 wstr = (wchar_t *)
2064 realloc (*strptr, ((strsize + 1)
2065 * sizeof (wchar_t)));
2066 if (wstr == NULL)
2068 /* We lose. Oh well. Terminate the
2069 string and stop converting,
2070 so at least we don't skip any input. */
2071 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2072 ++done;
2073 conv_error ();
2075 else
2077 *strptr = (char *) wstr;
2078 wstr += strsize;
2079 ++strsize;
2082 else
2084 *strptr = (char *) wstr;
2085 wstr += strsize;
2086 strsize *= 2;
2091 if (--width <= 0)
2092 break;
2094 while (inchar () != EOF);
2096 if (cnt != 0)
2097 /* We stopped in the middle of recognizing another
2098 character. That's a problem. */
2099 encode_error ();
2100 #endif
2102 if (now == read_in)
2103 /* We haven't succesfully read any character. */
2104 conv_error ();
2106 if (!(flags & SUPPRESS))
2108 *wstr++ = L'\0';
2110 if ((flags & MALLOC)
2111 && wstr - (wchar_t *) *strptr != strsize)
2113 wchar_t *cp = (wchar_t *)
2114 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2115 * sizeof(wchar_t)));
2116 if (cp != NULL)
2117 *strptr = (char *) cp;
2120 ++done;
2123 else
2125 size_t now = read_in;
2127 if (inchar () == EOF)
2128 input_error ();
2130 #ifdef COMPILE_WSCANF
2132 memset (&state, '\0', sizeof (state));
2136 wchar_t *runp;
2137 size_t n;
2139 /* Test whether it's in the scanlist. */
2140 runp = tw;
2141 while (runp < wp)
2143 if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
2144 && runp != tw
2145 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2147 /* Match against all characters in between the
2148 first and last character of the sequence. */
2149 wchar_t wc;
2151 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2152 if ((wint_t) wc == c)
2153 break;
2155 if (wc <= runp[1] && !not_in)
2156 break;
2157 if (wc <= runp[1] && not_in)
2159 /* The current character is not in the
2160 scanset. */
2161 ungetc (c, s);
2162 goto out2;
2165 runp += 2;
2167 else
2169 if ((wint_t) *runp == c && !not_in)
2170 break;
2171 if ((wint_t) *runp == c && not_in)
2173 ungetc (c, s);
2174 goto out2;
2177 ++runp;
2181 if (runp == wp && !not_in)
2183 ungetc (c, s);
2184 goto out2;
2187 if (!(flags & SUPPRESS))
2189 if ((flags & MALLOC)
2190 && str + MB_CUR_MAX >= *strptr + strsize)
2192 /* Enlarge the buffer. */
2193 size_t strleng = str - *strptr;
2194 char *newstr;
2196 newstr = (char *) realloc (*strptr, 2 * strsize);
2197 if (newstr == NULL)
2199 /* Can't allocate that much. Last-ditch
2200 effort. */
2201 newstr = (char *) realloc (*strptr,
2202 strleng + MB_CUR_MAX);
2203 if (newstr == NULL)
2205 /* We lose. Oh well. Terminate the string
2206 and stop converting, so at least we don't
2207 skip any input. */
2208 ((char *) (*strptr))[strleng] = '\0';
2209 ++done;
2210 conv_error ();
2212 else
2214 *strptr = newstr;
2215 str = newstr + strleng;
2216 strsize = strleng + MB_CUR_MAX;
2219 else
2221 *strptr = newstr;
2222 str = newstr + strleng;
2223 strsize *= 2;
2228 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2229 if (n == (size_t) -1)
2230 encode_error ();
2232 assert (n <= MB_CUR_MAX);
2233 str += n;
2235 while (--width > 0 && inchar () != WEOF);
2236 out2:
2237 #else
2240 if (wp[c] == not_in)
2242 ungetc_not_eof (c, s);
2243 break;
2246 /* This is easy. */
2247 if (!(flags & SUPPRESS))
2249 *str++ = c;
2250 if ((flags & MALLOC)
2251 && (char *) str == *strptr + strsize)
2253 /* Enlarge the buffer. */
2254 size_t newsize = 2 * strsize;
2256 allocagain:
2257 str = (char *) realloc (*strptr, newsize);
2258 if (str == NULL)
2260 /* Can't allocate that much. Last-ditch
2261 effort. */
2262 if (newsize > strsize + 1)
2264 newsize = strsize + 1;
2265 goto allocagain;
2267 /* We lose. Oh well. Terminate the
2268 string and stop converting,
2269 so at least we don't skip any input. */
2270 ((char *) (*strptr))[strsize - 1] = '\0';
2271 ++done;
2272 conv_error ();
2274 else
2276 *strptr = (char *) str;
2277 str += strsize;
2278 strsize = newsize;
2283 while (--width > 0 && inchar () != EOF);
2284 #endif
2286 if (now == read_in)
2287 /* We haven't succesfully read any character. */
2288 conv_error ();
2290 if (!(flags & SUPPRESS))
2292 #ifdef COMPILE_WSCANF
2293 /* We have to emit the code to get into the initial
2294 state. */
2295 char buf[MB_LEN_MAX];
2296 size_t n = __wcrtomb (buf, L'\0', &state);
2297 if (n > 0 && (flags & MALLOC)
2298 && str + n >= *strptr + strsize)
2300 /* Enlarge the buffer. */
2301 size_t strleng = str - *strptr;
2302 char *newstr;
2304 newstr = (char *) realloc (*strptr, strleng + n + 1);
2305 if (newstr == NULL)
2307 /* We lose. Oh well. Terminate the string
2308 and stop converting, so at least we don't
2309 skip any input. */
2310 ((char *) (*strptr))[strleng] = '\0';
2311 ++done;
2312 conv_error ();
2314 else
2316 *strptr = newstr;
2317 str = newstr + strleng;
2318 strsize = strleng + n + 1;
2322 str = __mempcpy (str, buf, n);
2323 #endif
2324 *str++ = '\0';
2326 if ((flags & MALLOC) && str - *strptr != strsize)
2328 char *cp = (char *) realloc (*strptr, str - *strptr);
2329 if (cp != NULL)
2330 *strptr = cp;
2333 ++done;
2336 break;
2338 case L_('p'): /* Generic pointer. */
2339 base = 16;
2340 /* A PTR must be the same size as a `long int'. */
2341 flags &= ~(SHORT|LONGDBL);
2342 if (need_long)
2343 flags |= LONG;
2344 number_signed = 0;
2345 read_pointer = 1;
2346 goto number;
2348 default:
2349 /* If this is an unknown format character punt. */
2350 conv_error ();
2354 /* The last thing we saw int the format string was a white space.
2355 Consume the last white spaces. */
2356 if (skip_space)
2359 c = inchar ();
2360 while (ISSPACE (c));
2361 ungetc (c, s);
2364 errout:
2365 /* Unlock stream. */
2366 UNLOCK_STREAM (s);
2368 if (errp != NULL)
2369 *errp |= errval;
2371 return done;
2374 #ifdef COMPILE_WSCANF
2376 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2378 return _IO_vfwscanf (s, format, argptr, NULL);
2380 #else
2382 __vfscanf (FILE *s, const char *format, va_list argptr)
2384 return INTUSE(_IO_vfscanf) (s, format, argptr, NULL);
2386 libc_hidden_def (__vfscanf)
2387 #endif
2389 #ifdef COMPILE_WSCANF
2390 weak_alias (__vfwscanf, vfwscanf)
2391 #else
2392 weak_alias (__vfscanf, vfscanf)
2393 INTDEF(_IO_vfscanf)
2394 #endif