Updated to fedora-glibc-20050721T0814
[glibc.git] / stdio-common / vfscanf.c
blobbe008dc6879c322dd9e3bc833bafc99faae7cb76
1 /* Copyright (C) 1991-2002, 2003, 2004, 2005 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 ((unsigned char) (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)
400 input_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 const wchar_t *wcdigits_extended[10];
1167 #else
1168 const char *mbdigits[10];
1169 const char *mbdigits_extended[10];
1170 #endif
1171 /* "to_inpunct" is a map from ASCII digits to their
1172 equivalent in locale. This is defined for locales
1173 which use an extra digits set. */
1174 wctrans_t map = __wctrans ("to_inpunct");
1175 int n;
1177 from_level = 0;
1178 #ifdef COMPILE_WSCANF
1179 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1180 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1181 #else
1182 to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
1183 #endif
1185 /* Get the alternative digit forms if there are any. */
1186 if (__builtin_expect (map != NULL, 0))
1188 /* Adding new level for extra digits set in locale file. */
1189 ++to_level;
1191 for (n = 0; n < 10; ++n)
1193 #ifdef COMPILE_WSCANF
1194 wcdigits[n] = (const wchar_t *)
1195 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1197 wchar_t *wc_extended = (wchar_t *)
1198 alloca ((to_level + 2) * sizeof (wchar_t));
1199 __wmemcpy (wc_extended, wcdigits[n], to_level);
1200 wc_extended[to_level] = __towctrans (L'0' + n, map);
1201 wc_extended[to_level + 1] = '\0';
1202 wcdigits_extended[n] = wc_extended;
1203 #else
1204 mbdigits[n]
1205 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1207 /* Get the equivalent wide char in map. */
1208 wint_t extra_wcdigit = __towctrans (L'0' + n, map);
1210 /* Convert it to multibyte representation. */
1211 mbstate_t state;
1212 memset (&state, '\0', sizeof (state));
1214 char extra_mbdigit[MB_LEN_MAX];
1215 size_t mblen
1216 = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
1218 if (mblen == (size_t) -1)
1220 /* Ignore this new level. */
1221 map = NULL;
1222 break;
1225 /* Calculate the length of mbdigits[n]. */
1226 const char *last_char = mbdigits[n];
1227 for (level = 0; level < to_level; ++level)
1228 last_char = strchr (last_char, '\0') + 1;
1230 size_t mbdigits_len = last_char - mbdigits[n];
1232 /* Allocate memory for extended multibyte digit. */
1233 char *mb_extended;
1234 mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
1236 /* And get the mbdigits + extra_digit string. */
1237 *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
1238 mbdigits_len),
1239 extra_mbdigit, mblen) = '\0';
1240 mbdigits_extended[n] = mb_extended;
1241 #endif
1245 /* Read the number into workspace. */
1246 while (c != EOF && width != 0)
1248 /* In this round we get the pointer to the digit strings
1249 and also perform the first round of comparisons. */
1250 for (n = 0; n < 10; ++n)
1252 /* Get the string for the digits with value N. */
1253 #ifdef COMPILE_WSCANF
1254 if (__builtin_expect (map != NULL, 0))
1255 wcdigits[n] = wcdigits_extended[n];
1256 else
1257 wcdigits[n] = (const wchar_t *)
1258 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1259 wcdigits[n] += from_level;
1261 if (c == (wint_t) *wcdigits[n])
1263 to_level = from_level;
1264 break;
1267 /* Advance the pointer to the next string. */
1268 ++wcdigits[n];
1269 #else
1270 const char *cmpp;
1271 int avail = width > 0 ? width : INT_MAX;
1273 if (__builtin_expect (map != NULL, 0))
1274 mbdigits[n] = mbdigits_extended[n];
1275 else
1276 mbdigits[n]
1277 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
1279 for (level = 0; level < from_level; level++)
1280 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1282 cmpp = mbdigits[n];
1283 while ((unsigned char) *cmpp == c && avail > 0)
1285 if (*++cmpp == '\0')
1286 break;
1287 else
1289 if ((c = inchar ()) == EOF)
1290 break;
1291 --avail;
1295 if (*cmpp == '\0')
1297 if (width > 0)
1298 width = avail;
1299 to_level = from_level;
1300 break;
1303 /* We are pushing all read characters back. */
1304 if (cmpp > mbdigits[n])
1306 ungetc (c, s);
1307 while (--cmpp > mbdigits[n])
1308 ungetc_not_eof ((unsigned char) *cmpp, s);
1309 c = (unsigned char) *cmpp;
1312 /* Advance the pointer to the next string. */
1313 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1314 #endif
1317 if (n == 10)
1319 /* Have not yet found the digit. */
1320 for (level = from_level + 1; level <= to_level; ++level)
1322 /* Search all ten digits of this level. */
1323 for (n = 0; n < 10; ++n)
1325 #ifdef COMPILE_WSCANF
1326 if (c == (wint_t) *wcdigits[n])
1327 break;
1329 /* Advance the pointer to the next string. */
1330 ++wcdigits[n];
1331 #else
1332 const char *cmpp;
1333 int avail = width > 0 ? width : INT_MAX;
1335 cmpp = mbdigits[n];
1336 while ((unsigned char) *cmpp == c && avail > 0)
1338 if (*++cmpp == '\0')
1339 break;
1340 else
1342 if ((c = inchar ()) == EOF)
1343 break;
1344 --avail;
1348 if (*cmpp == '\0')
1350 if (width > 0)
1351 width = avail;
1352 break;
1355 /* We are pushing all read characters back. */
1356 if (cmpp > mbdigits[n])
1358 ungetc (c, s);
1359 while (--cmpp > mbdigits[n])
1360 ungetc_not_eof ((unsigned char) *cmpp, s);
1361 c = (unsigned char) *cmpp;
1364 /* Advance the pointer to the next string. */
1365 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1366 #endif
1369 if (n < 10)
1371 /* Found it. */
1372 from_level = level;
1373 to_level = level;
1374 break;
1379 if (n < 10)
1380 c = L_('0') + n;
1381 else if ((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 else
1443 /* Read the number into workspace. */
1444 while (c != EOF && width != 0)
1446 if (base == 16)
1448 if (!ISXDIGIT (c))
1449 break;
1451 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
1453 if (base == 10 && (flags & GROUP)
1454 #ifdef COMPILE_WSCANF
1455 && thousands != L'\0'
1456 #else
1457 && thousands != NULL
1458 #endif
1461 /* Try matching against the thousands separator. */
1462 #ifdef COMPILE_WSCANF
1463 if (c != thousands)
1464 break;
1465 #else
1466 const char *cmpp = thousands;
1467 int avail = width > 0 ? width : INT_MAX;
1469 while ((unsigned char) *cmpp == c && avail > 0)
1471 ADDW (c);
1472 if (*++cmpp == '\0')
1473 break;
1474 else
1476 if ((c = inchar ()) == EOF)
1477 break;
1478 --avail;
1482 if (*cmpp != '\0')
1484 /* We are pushing all read characters back. */
1485 if (cmpp > thousands)
1487 wpsize -= cmpp - thousands;
1488 ungetc (c, s);
1489 while (--cmpp > thousands)
1490 ungetc_not_eof ((unsigned char) *cmpp, s);
1491 c = (unsigned char) *cmpp;
1493 break;
1496 if (width > 0)
1497 width = avail;
1499 /* The last thousands character will be added back by
1500 the ADDW below. */
1501 --wpsize;
1502 #endif
1504 else
1505 break;
1507 ADDW (c);
1508 if (width > 0)
1509 --width;
1511 c = inchar ();
1514 if (wpsize == 0
1515 || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1517 /* There was no number. If we are supposed to read a pointer
1518 we must recognize "(nil)" as well. */
1519 if (wpsize == 0 && read_pointer && (width < 0 || width >= 0)
1520 && c == '('
1521 && TOLOWER (inchar ()) == L_('n')
1522 && TOLOWER (inchar ()) == L_('i')
1523 && TOLOWER (inchar ()) == L_('l')
1524 && inchar () == L_(')'))
1525 /* We must produce the value of a NULL pointer. A single
1526 '0' digit is enough. */
1527 ADDW (L_('0'));
1528 else
1530 /* The last read character is not part of the number
1531 anymore. */
1532 ungetc (c, s);
1534 conv_error ();
1537 else
1538 /* The just read character is not part of the number anymore. */
1539 ungetc (c, s);
1541 /* Convert the number. */
1542 ADDW (L_('\0'));
1543 if (need_longlong && (flags & LONGDBL))
1545 if (number_signed)
1546 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1547 else
1548 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1550 else
1552 if (number_signed)
1553 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1554 else
1555 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1557 if (wp == tw)
1558 conv_error ();
1560 if (!(flags & SUPPRESS))
1562 if (! number_signed)
1564 if (need_longlong && (flags & LONGDBL))
1565 *ARG (unsigned LONGLONG int *) = num.uq;
1566 else if (need_long && (flags & LONG))
1567 *ARG (unsigned long int *) = num.ul;
1568 else if (flags & SHORT)
1569 *ARG (unsigned short int *)
1570 = (unsigned short int) num.ul;
1571 else if (!(flags & CHAR))
1572 *ARG (unsigned int *) = (unsigned int) num.ul;
1573 else
1574 *ARG (unsigned char *) = (unsigned char) num.ul;
1576 else
1578 if (need_longlong && (flags & LONGDBL))
1579 *ARG (LONGLONG int *) = num.q;
1580 else if (need_long && (flags & LONG))
1581 *ARG (long int *) = num.l;
1582 else if (flags & SHORT)
1583 *ARG (short int *) = (short int) num.l;
1584 else if (!(flags & CHAR))
1585 *ARG (int *) = (int) num.l;
1586 else
1587 *ARG (signed char *) = (signed char) num.ul;
1589 ++done;
1591 break;
1593 case L_('e'): /* Floating-point numbers. */
1594 case L_('E'):
1595 case L_('f'):
1596 case L_('F'):
1597 case L_('g'):
1598 case L_('G'):
1599 case L_('a'):
1600 case L_('A'):
1601 c = inchar ();
1602 if (c == EOF)
1603 input_error ();
1605 got_dot = got_e = 0;
1607 /* Check for a sign. */
1608 if (c == L_('-') || c == L_('+'))
1610 negative = c == L_('-');
1611 if (width == 0 || inchar () == EOF)
1612 /* EOF is only an input error before we read any chars. */
1613 conv_error ();
1614 if (! ISDIGIT (c) && TOLOWER (c) != L_('i')
1615 && TOLOWER (c) != L_('n'))
1617 #ifdef COMPILE_WSCANF
1618 if (c != decimal)
1620 /* This is no valid number. */
1621 ungetc (c, s);
1622 conv_error ();
1624 #else
1625 /* Match against the decimal point. At this point
1626 we are taking advantage of the fact that we can
1627 push more than one character back. This is
1628 (almost) never necessary since the decimal point
1629 string hopefully never contains more than one
1630 byte. */
1631 const char *cmpp = decimal;
1632 int avail = width > 0 ? width : INT_MAX;
1634 while ((unsigned char) *cmpp == c && avail-- > 0)
1635 if (*++cmpp == '\0')
1636 break;
1637 else
1639 if (inchar () == EOF)
1640 break;
1643 if (*cmpp != '\0')
1645 /* This is no valid number. */
1646 while (1)
1648 ungetc (c, s);
1649 if (cmpp == decimal)
1650 break;
1651 c = (unsigned char) *--cmpp;
1654 conv_error ();
1656 else
1658 /* Add all the characters. */
1659 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1660 ADDW ((unsigned char) *cmpp);
1661 if (width > 0)
1662 width = avail;
1663 got_dot = 1;
1665 c = inchar ();
1667 if (width > 0)
1668 width = avail;
1669 #endif
1671 if (width > 0)
1672 --width;
1674 else
1675 negative = 0;
1677 /* Take care for the special arguments "nan" and "inf". */
1678 if (TOLOWER (c) == L_('n'))
1680 /* Maybe "nan". */
1681 ADDW (c);
1682 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('a'))
1683 conv_error ();
1684 if (width > 0)
1685 --width;
1686 ADDW (c);
1687 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1688 conv_error ();
1689 if (width > 0)
1690 --width;
1691 ADDW (c);
1692 /* It is "nan". */
1693 goto scan_float;
1695 else if (TOLOWER (c) == L_('i'))
1697 /* Maybe "inf" or "infinity". */
1698 ADDW (c);
1699 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1700 conv_error ();
1701 if (width > 0)
1702 --width;
1703 ADDW (c);
1704 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('f'))
1705 conv_error ();
1706 if (width > 0)
1707 --width;
1708 ADDW (c);
1709 /* It is as least "inf". */
1710 if (width != 0 && inchar () != EOF)
1712 if (TOLOWER (c) == L_('i'))
1714 if (width > 0)
1715 --width;
1716 /* Now we have to read the rest as well. */
1717 ADDW (c);
1718 if (width == 0 || inchar () == EOF
1719 || TOLOWER (c) != L_('n'))
1720 conv_error ();
1721 if (width > 0)
1722 --width;
1723 ADDW (c);
1724 if (width == 0 || inchar () == EOF
1725 || TOLOWER (c) != L_('i'))
1726 conv_error ();
1727 if (width > 0)
1728 --width;
1729 ADDW (c);
1730 if (width == 0 || inchar () == EOF
1731 || TOLOWER (c) != L_('t'))
1732 conv_error ();
1733 if (width > 0)
1734 --width;
1735 ADDW (c);
1736 if (width == 0 || inchar () == EOF
1737 || TOLOWER (c) != L_('y'))
1738 conv_error ();
1739 if (width > 0)
1740 --width;
1741 ADDW (c);
1743 else
1744 /* Never mind. */
1745 ungetc (c, s);
1747 goto scan_float;
1750 is_hexa = 0;
1751 exp_char = L_('e');
1752 if (width != 0 && c == L_('0'))
1754 ADDW (c);
1755 c = inchar ();
1756 if (width > 0)
1757 --width;
1758 if (width != 0 && TOLOWER (c) == L_('x'))
1760 /* It is a number in hexadecimal format. */
1761 ADDW (c);
1763 is_hexa = 1;
1764 exp_char = L_('p');
1766 /* Grouping is not allowed. */
1767 flags &= ~GROUP;
1768 c = inchar ();
1769 if (width > 0)
1770 --width;
1776 if (ISDIGIT (c))
1777 ADDW (c);
1778 else if (!got_e && is_hexa && ISXDIGIT (c))
1779 ADDW (c);
1780 else if (got_e && wp[wpsize - 1] == exp_char
1781 && (c == L_('-') || c == L_('+')))
1782 ADDW (c);
1783 else if (wpsize > 0 && !got_e
1784 && (CHAR_T) TOLOWER (c) == exp_char)
1786 ADDW (exp_char);
1787 got_e = got_dot = 1;
1789 else
1791 #ifdef COMPILE_WSCANF
1792 if (! got_dot && c == decimal)
1794 ADDW (c);
1795 got_dot = 1;
1797 else if ((flags & GROUP) != 0 && thousands != L'\0'
1798 && ! got_dot && c == thousands)
1799 ADDW (c);
1800 else
1802 /* The last read character is not part of the number
1803 anymore. */
1804 ungetc (c, s);
1805 break;
1807 #else
1808 const char *cmpp = decimal;
1809 int avail = width > 0 ? width : INT_MAX;
1811 if (! got_dot)
1813 while ((unsigned char) *cmpp == c && avail > 0)
1814 if (*++cmpp == '\0')
1815 break;
1816 else
1818 if (inchar () == EOF)
1819 break;
1820 --avail;
1824 if (*cmpp == '\0')
1826 /* Add all the characters. */
1827 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1828 ADDW ((unsigned char) *cmpp);
1829 if (width > 0)
1830 width = avail;
1831 got_dot = 1;
1833 else
1835 /* Figure out whether it is a thousands separator.
1836 There is one problem: we possibly read more than
1837 one character. We cannot push them back but since
1838 we know that parts of the `decimal' string matched,
1839 we can compare against it. */
1840 const char *cmp2p = thousands;
1842 if ((flags & GROUP) != 0 && thousands != NULL
1843 && ! got_dot)
1845 while (cmp2p - thousands < cmpp - decimal
1846 && *cmp2p == decimal[cmp2p - thousands])
1847 ++cmp2p;
1848 if (cmp2p - thousands == cmpp - decimal)
1850 while ((unsigned char) *cmp2p == c && avail > 0)
1851 if (*++cmp2p == '\0')
1852 break;
1853 else
1855 if (inchar () == EOF)
1856 break;
1857 --avail;
1862 if (cmp2p != NULL && *cmp2p == '\0')
1864 /* Add all the characters. */
1865 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
1866 ADDW ((unsigned char) *cmpp);
1867 if (width > 0)
1868 width = avail;
1870 else
1872 /* The last read character is not part of the number
1873 anymore. */
1874 ungetc (c, s);
1875 break;
1878 #endif
1880 if (width > 0)
1881 --width;
1883 while (width != 0 && inchar () != EOF);
1885 /* Have we read any character? If we try to read a number
1886 in hexadecimal notation and we have read only the `0x'
1887 prefix or no exponent this is an error. */
1888 if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
1889 conv_error ();
1891 scan_float:
1892 /* Convert the number. */
1893 ADDW (L_('\0'));
1894 if (flags & LONGDBL)
1896 long double d = __strtold_internal (wp, &tw, flags & GROUP);
1897 if (!(flags & SUPPRESS) && tw != wp)
1898 *ARG (long double *) = negative ? -d : d;
1900 else if (flags & LONG)
1902 double d = __strtod_internal (wp, &tw, flags & GROUP);
1903 if (!(flags & SUPPRESS) && tw != wp)
1904 *ARG (double *) = negative ? -d : d;
1906 else
1908 float d = __strtof_internal (wp, &tw, flags & GROUP);
1909 if (!(flags & SUPPRESS) && tw != wp)
1910 *ARG (float *) = negative ? -d : d;
1913 if (tw == wp)
1914 conv_error ();
1916 if (!(flags & SUPPRESS))
1917 ++done;
1918 break;
1920 case L_('['): /* Character class. */
1921 if (flags & LONG)
1922 STRING_ARG (wstr, wchar_t);
1923 else
1924 STRING_ARG (str, char);
1926 if (*f == L_('^'))
1928 ++f;
1929 not_in = 1;
1931 else
1932 not_in = 0;
1934 if (width < 0)
1935 /* There is no width given so there is also no limit on the
1936 number of characters we read. Therefore we set width to
1937 a very high value to make the algorithm easier. */
1938 width = INT_MAX;
1940 #ifdef COMPILE_WSCANF
1941 /* Find the beginning and the end of the scanlist. We are not
1942 creating a lookup table since it would have to be too large.
1943 Instead we search each time through the string. This is not
1944 a constant lookup time but who uses this feature deserves to
1945 be punished. */
1946 tw = (wchar_t *) f; /* Marks the beginning. */
1948 if (*f == L']')
1949 ++f;
1951 while ((fc = *f++) != L'\0' && fc != L']');
1953 if (fc == L'\0')
1954 conv_error ();
1955 wp = (wchar_t *) f - 1;
1956 #else
1957 /* Fill WP with byte flags indexed by character.
1958 We will use this flag map for matching input characters. */
1959 if (wpmax < UCHAR_MAX + 1)
1961 wpmax = UCHAR_MAX + 1;
1962 wp = (char *) alloca (wpmax);
1964 memset (wp, '\0', UCHAR_MAX + 1);
1966 fc = *f;
1967 if (fc == ']' || fc == '-')
1969 /* If ] or - appears before any char in the set, it is not
1970 the terminator or separator, but the first char in the
1971 set. */
1972 wp[fc] = 1;
1973 ++f;
1976 while ((fc = *f++) != '\0' && fc != ']')
1977 if (fc == '-' && *f != '\0' && *f != ']'
1978 && (unsigned char) f[-2] <= (unsigned char) *f)
1980 /* Add all characters from the one before the '-'
1981 up to (but not including) the next format char. */
1982 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
1983 wp[fc] = 1;
1985 else
1986 /* Add the character to the flag map. */
1987 wp[fc] = 1;
1989 if (fc == '\0')
1990 conv_error();
1991 #endif
1993 if (flags & LONG)
1995 size_t now = read_in;
1996 #ifdef COMPILE_WSCANF
1997 if (inchar () == WEOF)
1998 input_error ();
2002 wchar_t *runp;
2004 /* Test whether it's in the scanlist. */
2005 runp = tw;
2006 while (runp < wp)
2008 if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
2009 && runp != tw
2010 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2012 /* Match against all characters in between the
2013 first and last character of the sequence. */
2014 wchar_t wc;
2016 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2017 if ((wint_t) wc == c)
2018 break;
2020 if (wc <= runp[1] && !not_in)
2021 break;
2022 if (wc <= runp[1] && not_in)
2024 /* The current character is not in the
2025 scanset. */
2026 ungetc (c, s);
2027 goto out;
2030 runp += 2;
2032 else
2034 if ((wint_t) *runp == c && !not_in)
2035 break;
2036 if ((wint_t) *runp == c && not_in)
2038 ungetc (c, s);
2039 goto out;
2042 ++runp;
2046 if (runp == wp && !not_in)
2048 ungetc (c, s);
2049 goto out;
2052 if (!(flags & SUPPRESS))
2054 *wstr++ = c;
2056 if ((flags & MALLOC)
2057 && wstr == (wchar_t *) *strptr + strsize)
2059 /* Enlarge the buffer. */
2060 wstr = (wchar_t *) realloc (*strptr,
2061 (2 * strsize)
2062 * sizeof (wchar_t));
2063 if (wstr == NULL)
2065 /* Can't allocate that much. Last-ditch
2066 effort. */
2067 wstr = (wchar_t *)
2068 realloc (*strptr, (strsize + 1)
2069 * sizeof (wchar_t));
2070 if (wstr == NULL)
2072 /* We lose. Oh well. Terminate the string
2073 and stop converting, so at least we don't
2074 skip any input. */
2075 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2076 ++done;
2077 conv_error ();
2079 else
2081 *strptr = (char *) wstr;
2082 wstr += strsize;
2083 ++strsize;
2086 else
2088 *strptr = (char *) wstr;
2089 wstr += strsize;
2090 strsize *= 2;
2095 while (--width > 0 && inchar () != WEOF);
2096 out:
2097 #else
2098 char buf[MB_LEN_MAX];
2099 size_t cnt = 0;
2100 mbstate_t cstate;
2102 if (inchar () == EOF)
2103 input_error ();
2105 memset (&cstate, '\0', sizeof (cstate));
2109 if (wp[c] == not_in)
2111 ungetc_not_eof (c, s);
2112 break;
2115 /* This is easy. */
2116 if (!(flags & SUPPRESS))
2118 size_t n;
2120 /* Convert it into a wide character. */
2121 buf[0] = c;
2122 n = __mbrtowc (wstr, buf, 1, &cstate);
2124 if (n == (size_t) -2)
2126 /* Possibly correct character, just not enough
2127 input. */
2128 ++cnt;
2129 assert (cnt < MB_CUR_MAX);
2130 continue;
2132 cnt = 0;
2134 ++wstr;
2135 if ((flags & MALLOC)
2136 && wstr == (wchar_t *) *strptr + strsize)
2138 /* Enlarge the buffer. */
2139 wstr = (wchar_t *) realloc (*strptr,
2140 (2 * strsize
2141 * sizeof (wchar_t)));
2142 if (wstr == NULL)
2144 /* Can't allocate that much. Last-ditch
2145 effort. */
2146 wstr = (wchar_t *)
2147 realloc (*strptr, ((strsize + 1)
2148 * sizeof (wchar_t)));
2149 if (wstr == NULL)
2151 /* We lose. Oh well. Terminate the
2152 string and stop converting,
2153 so at least we don't skip any input. */
2154 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2155 ++done;
2156 conv_error ();
2158 else
2160 *strptr = (char *) wstr;
2161 wstr += strsize;
2162 ++strsize;
2165 else
2167 *strptr = (char *) wstr;
2168 wstr += strsize;
2169 strsize *= 2;
2174 if (--width <= 0)
2175 break;
2177 while (inchar () != EOF);
2179 if (cnt != 0)
2180 /* We stopped in the middle of recognizing another
2181 character. That's a problem. */
2182 encode_error ();
2183 #endif
2185 if (now == read_in)
2186 /* We haven't succesfully read any character. */
2187 conv_error ();
2189 if (!(flags & SUPPRESS))
2191 *wstr++ = L'\0';
2193 if ((flags & MALLOC)
2194 && wstr - (wchar_t *) *strptr != strsize)
2196 wchar_t *cp = (wchar_t *)
2197 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2198 * sizeof(wchar_t)));
2199 if (cp != NULL)
2200 *strptr = (char *) cp;
2203 ++done;
2206 else
2208 size_t now = read_in;
2210 if (inchar () == EOF)
2211 input_error ();
2213 #ifdef COMPILE_WSCANF
2215 memset (&state, '\0', sizeof (state));
2219 wchar_t *runp;
2220 size_t n;
2222 /* Test whether it's in the scanlist. */
2223 runp = tw;
2224 while (runp < wp)
2226 if (runp[0] == L'-' && runp[1] != '\0' && runp + 1 != wp
2227 && runp != tw
2228 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2230 /* Match against all characters in between the
2231 first and last character of the sequence. */
2232 wchar_t wc;
2234 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
2235 if ((wint_t) wc == c)
2236 break;
2238 if (wc <= runp[1] && !not_in)
2239 break;
2240 if (wc <= runp[1] && not_in)
2242 /* The current character is not in the
2243 scanset. */
2244 ungetc (c, s);
2245 goto out2;
2248 runp += 2;
2250 else
2252 if ((wint_t) *runp == c && !not_in)
2253 break;
2254 if ((wint_t) *runp == c && not_in)
2256 ungetc (c, s);
2257 goto out2;
2260 ++runp;
2264 if (runp == wp && !not_in)
2266 ungetc (c, s);
2267 goto out2;
2270 if (!(flags & SUPPRESS))
2272 if ((flags & MALLOC)
2273 && str + MB_CUR_MAX >= *strptr + strsize)
2275 /* Enlarge the buffer. */
2276 size_t strleng = str - *strptr;
2277 char *newstr;
2279 newstr = (char *) realloc (*strptr, 2 * strsize);
2280 if (newstr == NULL)
2282 /* Can't allocate that much. Last-ditch
2283 effort. */
2284 newstr = (char *) realloc (*strptr,
2285 strleng + MB_CUR_MAX);
2286 if (newstr == NULL)
2288 /* We lose. Oh well. Terminate the string
2289 and stop converting, so at least we don't
2290 skip any input. */
2291 ((char *) (*strptr))[strleng] = '\0';
2292 ++done;
2293 conv_error ();
2295 else
2297 *strptr = newstr;
2298 str = newstr + strleng;
2299 strsize = strleng + MB_CUR_MAX;
2302 else
2304 *strptr = newstr;
2305 str = newstr + strleng;
2306 strsize *= 2;
2311 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2312 if (n == (size_t) -1)
2313 encode_error ();
2315 assert (n <= MB_CUR_MAX);
2316 str += n;
2318 while (--width > 0 && inchar () != WEOF);
2319 out2:
2320 #else
2323 if (wp[c] == not_in)
2325 ungetc_not_eof (c, s);
2326 break;
2329 /* This is easy. */
2330 if (!(flags & SUPPRESS))
2332 *str++ = c;
2333 if ((flags & MALLOC)
2334 && (char *) str == *strptr + strsize)
2336 /* Enlarge the buffer. */
2337 size_t newsize = 2 * strsize;
2339 allocagain:
2340 str = (char *) realloc (*strptr, newsize);
2341 if (str == NULL)
2343 /* Can't allocate that much. Last-ditch
2344 effort. */
2345 if (newsize > strsize + 1)
2347 newsize = strsize + 1;
2348 goto allocagain;
2350 /* We lose. Oh well. Terminate the
2351 string and stop converting,
2352 so at least we don't skip any input. */
2353 ((char *) (*strptr))[strsize - 1] = '\0';
2354 ++done;
2355 conv_error ();
2357 else
2359 *strptr = (char *) str;
2360 str += strsize;
2361 strsize = newsize;
2366 while (--width > 0 && inchar () != EOF);
2367 #endif
2369 if (now == read_in)
2370 /* We haven't succesfully read any character. */
2371 conv_error ();
2373 if (!(flags & SUPPRESS))
2375 #ifdef COMPILE_WSCANF
2376 /* We have to emit the code to get into the initial
2377 state. */
2378 char buf[MB_LEN_MAX];
2379 size_t n = __wcrtomb (buf, L'\0', &state);
2380 if (n > 0 && (flags & MALLOC)
2381 && str + n >= *strptr + strsize)
2383 /* Enlarge the buffer. */
2384 size_t strleng = str - *strptr;
2385 char *newstr;
2387 newstr = (char *) realloc (*strptr, strleng + n + 1);
2388 if (newstr == NULL)
2390 /* We lose. Oh well. Terminate the string
2391 and stop converting, so at least we don't
2392 skip any input. */
2393 ((char *) (*strptr))[strleng] = '\0';
2394 ++done;
2395 conv_error ();
2397 else
2399 *strptr = newstr;
2400 str = newstr + strleng;
2401 strsize = strleng + n + 1;
2405 str = __mempcpy (str, buf, n);
2406 #endif
2407 *str++ = '\0';
2409 if ((flags & MALLOC) && str - *strptr != strsize)
2411 char *cp = (char *) realloc (*strptr, str - *strptr);
2412 if (cp != NULL)
2413 *strptr = cp;
2416 ++done;
2419 break;
2421 case L_('p'): /* Generic pointer. */
2422 base = 16;
2423 /* A PTR must be the same size as a `long int'. */
2424 flags &= ~(SHORT|LONGDBL);
2425 if (need_long)
2426 flags |= LONG;
2427 number_signed = 0;
2428 read_pointer = 1;
2429 goto number;
2431 default:
2432 /* If this is an unknown format character punt. */
2433 conv_error ();
2437 /* The last thing we saw int the format string was a white space.
2438 Consume the last white spaces. */
2439 if (skip_space)
2442 c = inchar ();
2443 while (ISSPACE (c));
2444 ungetc (c, s);
2447 errout:
2448 /* Unlock stream. */
2449 UNLOCK_STREAM (s);
2451 if (errp != NULL)
2452 *errp |= errval;
2454 return done;
2457 #ifdef COMPILE_WSCANF
2459 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2461 return _IO_vfwscanf (s, format, argptr, NULL);
2463 #else
2465 __vfscanf (FILE *s, const char *format, va_list argptr)
2467 return INTUSE(_IO_vfscanf) (s, format, argptr, NULL);
2469 libc_hidden_def (__vfscanf)
2470 #endif
2472 #ifdef COMPILE_WSCANF
2473 weak_alias (__vfwscanf, vfwscanf)
2474 #else
2475 weak_alias (__vfscanf, vfscanf)
2476 INTDEF(_IO_vfscanf)
2477 #endif