Update.
[glibc.git] / stdio-common / vfscanf.c
blobd63fd364a52e88bced5cd96e97e24816cb826b99
1 /* Copyright (C) 1991-1999, 2000, 2001 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 Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 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 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 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 #ifdef USE_IN_LIBIO
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 _IO_sputbackwc (s, c))))
79 # define ungetc_not_eof(c, s) ((void) (--read_in, \
80 _IO_sputbackwc (s, c)))
81 # define inchar() (c == WEOF ? WEOF \
82 : ((c = _IO_getwc_unlocked (s)), \
83 (void) (c != WEOF && ++read_in), c))
85 # define MEMCPY(d, s, n) __wmemcpy (d, s, n)
86 # define ISSPACE(Ch) iswspace (Ch)
87 # define ISDIGIT(Ch) iswdigit (Ch)
88 # define ISXDIGIT(Ch) iswxdigit (Ch)
89 # define TOLOWER(Ch) towlower (Ch)
90 # define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
91 # define __strtoll_internal __wcstoll_internal
92 # define __strtoull_internal __wcstoull_internal
93 # define __strtol_internal __wcstol_internal
94 # define __strtoul_internal __wcstoul_internal
95 # define __strtold_internal __wcstold_internal
96 # define __strtod_internal __wcstod_internal
97 # define __strtof_internal __wcstof_internal
99 # define L_(Str) L##Str
100 # define CHAR_T wchar_t
101 # define UCHAR_T unsigned int
102 # define WINT_T wint_t
103 # undef EOF
104 # define EOF WEOF
105 # else
106 # define ungetc(c, s) ((void) ((int) c == EOF \
107 || (--read_in, \
108 _IO_sputbackc (s, (unsigned char) c))))
109 # define ungetc_not_eof(c, s) ((void) (--read_in, \
110 _IO_sputbackc (s, (unsigned char) c)))
111 # define inchar() (c == EOF ? EOF \
112 : ((c = _IO_getc_unlocked (s)), \
113 (void) (c != EOF && ++read_in), c))
114 # define MEMCPY(d, s, n) memcpy (d, s, n)
115 # define ISSPACE(Ch) isspace (Ch)
116 # define ISDIGIT(Ch) isdigit (Ch)
117 # define ISXDIGIT(Ch) isxdigit (Ch)
118 # define TOLOWER(Ch) tolower (Ch)
119 # define ORIENT if (s->_vtable_offset == 0 \
120 && _IO_fwide (s, -1) != -1) \
121 return EOF
123 # define L_(Str) Str
124 # define CHAR_T char
125 # define UCHAR_T unsigned char
126 # define WINT_T int
127 # endif
129 # define encode_error() do { \
130 if (errp != NULL) *errp |= 4; \
131 _IO_funlockfile (s); \
132 __libc_cleanup_end (0); \
133 __set_errno (EILSEQ); \
134 return done; \
135 } while (0)
136 # define conv_error() do { \
137 if (errp != NULL) *errp |= 2; \
138 _IO_funlockfile (s); \
139 __libc_cleanup_end (0); \
140 return done; \
141 } while (0)
142 # define input_error() do { \
143 _IO_funlockfile (s); \
144 if (errp != NULL) *errp |= 1; \
145 __libc_cleanup_end (0); \
146 return done ?: EOF; \
147 } while (0)
148 # define memory_error() do { \
149 _IO_funlockfile (s); \
150 __set_errno (ENOMEM); \
151 __libc_cleanup_end (0); \
152 return EOF; \
153 } while (0)
154 # define ARGCHECK(s, format) \
155 do \
157 /* Check file argument for consistence. */ \
158 CHECK_FILE (s, EOF); \
159 if (s->_flags & _IO_NO_READS) \
161 __set_errno (EBADF); \
162 return EOF; \
164 else if (format == NULL) \
166 MAYBE_SET_EINVAL; \
167 return EOF; \
169 } while (0)
170 # define LOCK_STREAM(S) \
171 __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S)); \
172 _IO_flockfile (S)
173 # define UNLOCK_STREAM(S) \
174 _IO_funlockfile (S); \
175 __libc_cleanup_region_end (0)
176 #else
177 # define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
178 # define ungetc_not_eof(c, s) (--read_in, (ungetc) (c, s))
179 # define inchar() (c == EOF ? EOF \
180 : ((c = getc (s)), (void) (c != EOF && ++read_in), c))
181 # define MEMCPY(d, s, n) memcpy (d, s, n)
182 # define ISSPACE(Ch) isspace (Ch)
183 # define ISDIGIT(Ch) isdigit (Ch)
184 # define ISXDIGIT(Ch) isxdigit (Ch)
185 # define TOLOWER(Ch) tolower (Ch)
187 # define L_(Str) Str
188 # define CHAR_T char
189 # define UCHAR_T unsigned char
190 # define WINT_T int
192 # define encode_error() do { \
193 funlockfile (s); \
194 __set_errno (EILSEQ); \
195 return done; \
196 } while (0)
197 # define conv_error() do { \
198 funlockfile (s); \
199 return done; \
200 } while (0)
201 # define input_error() do { \
202 funlockfile (s); \
203 return done ?: EOF; \
204 } while (0)
205 # define memory_error() do { \
206 funlockfile (s); \
207 __set_errno (ENOMEM); \
208 return EOF; \
209 } while (0)
210 # define ARGCHECK(s, format) \
211 do \
213 /* Check file argument for consistence. */ \
214 if (!__validfp (s) || !s->__mode.__read) \
216 __set_errno (EBADF); \
217 return EOF; \
219 else if (format == NULL) \
221 __set_errno (EINVAL); \
222 return EOF; \
224 } while (0)
225 #if 1
226 /* XXX For now !!! */
227 # define flockfile(S) /* nothing */
228 # define funlockfile(S) /* nothing */
229 # define LOCK_STREAM(S)
230 # define UNLOCK_STREAM(S)
231 #else
232 # define LOCK_STREAM(S) \
233 __libc_cleanup_region_start (&__funlockfile, (S)); \
234 __flockfile (S)
235 # define UNLOCK_STREAM(S) \
236 __funlockfile (S); \
237 __libc_cleanup_region_end (0)
238 #endif
239 #endif
242 /* Read formatted input from S according to the format string
243 FORMAT, using the argument list in ARG.
244 Return the number of assignments made, or -1 for an input error. */
245 #ifdef USE_IN_LIBIO
246 # ifdef COMPILE_WSCANF
248 _IO_vfwscanf (s, format, argptr, errp)
249 _IO_FILE *s;
250 const wchar_t *format;
251 _IO_va_list argptr;
252 int *errp;
253 # else
255 _IO_vfscanf (s, format, argptr, errp)
256 _IO_FILE *s;
257 const char *format;
258 _IO_va_list argptr;
259 int *errp;
260 # endif
261 #else
263 __vfscanf (FILE *s, const char *format, va_list argptr)
264 #endif
266 va_list arg;
267 register const CHAR_T *f = format;
268 register UCHAR_T fc; /* Current character of the format. */
269 register WINT_T done = 0; /* Assignments done. */
270 register size_t read_in = 0; /* Chars read in. */
271 register WINT_T c = 0; /* Last char read. */
272 register int width; /* Maximum field width. */
273 register int flags; /* Modifiers for current format element. */
275 /* Status for reading F-P nums. */
276 char got_dot, got_e, negative;
277 /* If a [...] is a [^...]. */
278 CHAR_T not_in;
279 #define exp_char not_in
280 /* Base for integral numbers. */
281 int base;
282 /* Signedness for integral numbers. */
283 int number_signed;
284 #define is_hexa number_signed
285 /* Decimal point character. */
286 #ifdef COMPILE_WSCANF
287 wchar_t decimal;
288 #else
289 const char *decimal;
290 #endif
291 /* The thousands character of the current locale. */
292 #ifdef COMPILE_WSCANF
293 wchar_t thousands;
294 #else
295 const char *thousands;
296 #endif
297 /* State for the conversions. */
298 mbstate_t state;
299 /* Integral holding variables. */
300 union
302 long long int q;
303 unsigned long long int uq;
304 long int l;
305 unsigned long int ul;
306 } num;
307 /* Character-buffer pointer. */
308 char *str = NULL;
309 wchar_t *wstr = NULL;
310 char **strptr = NULL;
311 ssize_t strsize = 0;
312 /* We must not react on white spaces immediately because they can
313 possibly be matched even if in the input stream no character is
314 available anymore. */
315 int skip_space = 0;
316 /* Nonzero if we are reading a pointer. */
317 int read_pointer;
318 /* Workspace. */
319 CHAR_T *tw; /* Temporary pointer. */
320 CHAR_T *wp = NULL; /* Workspace. */
321 size_t wpmax = 0; /* Maximal size of workspace. */
322 size_t wpsize; /* Currently used bytes in workspace. */
323 #define ADDW(Ch) \
324 do \
326 if (wpsize == wpmax) \
328 CHAR_T *old = wp; \
329 wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
330 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
331 if (old != NULL) \
332 MEMCPY (wp, old, wpsize); \
334 wp[wpsize++] = (Ch); \
336 while (0)
338 #ifdef __va_copy
339 __va_copy (arg, argptr);
340 #else
341 arg = (va_list) argptr;
342 #endif
344 #ifdef ORIENT
345 ORIENT;
346 #endif
348 ARGCHECK (s, format);
350 /* Figure out the decimal point character. */
351 #ifdef COMPILE_WSCANF
352 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
353 #else
354 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
355 #endif
356 /* Figure out the thousands separator character. */
357 #ifdef COMPILE_WSCANF
358 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
359 #else
360 thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
361 if (*thousands == '\0')
362 thousands = NULL;
363 #endif
365 /* Lock the stream. */
366 LOCK_STREAM (s);
369 #ifndef COMPILE_WSCANF
370 /* From now on we use `state' to convert the format string. */
371 memset (&state, '\0', sizeof (state));
372 #endif
374 /* Run through the format string. */
375 while (*f != '\0')
377 unsigned int argpos;
378 /* Extract the next argument, which is of type TYPE.
379 For a %N$... spec, this is the Nth argument from the beginning;
380 otherwise it is the next argument after the state now in ARG. */
381 #ifdef __va_copy
382 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
383 ({ unsigned int pos = argpos; \
384 va_list arg; \
385 __va_copy (arg, argptr); \
386 while (--pos > 0) \
387 (void) va_arg (arg, void *); \
388 va_arg (arg, type); \
390 #else
391 # if 0
392 /* XXX Possible optimization. */
393 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
394 ({ va_list arg = (va_list) argptr; \
395 arg = (va_list) ((char *) arg \
396 + (argpos - 1) \
397 * __va_rounded_size (void *)); \
398 va_arg (arg, type); \
400 # else
401 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
402 ({ unsigned int pos = argpos; \
403 va_list arg = (va_list) argptr; \
404 while (--pos > 0) \
405 (void) va_arg (arg, void *); \
406 va_arg (arg, type); \
408 # endif
409 #endif
411 #ifndef COMPILE_WSCANF
412 if (!isascii ((unsigned char) *f))
414 /* Non-ASCII, may be a multibyte. */
415 int len = __mbrlen (f, strlen (f), &state);
416 if (len > 0)
420 c = inchar ();
421 if (c == EOF)
422 input_error ();
423 else if (c != (unsigned char) *f++)
425 ungetc_not_eof (c, s);
426 conv_error ();
429 while (--len > 0);
430 continue;
433 #endif
435 fc = *f++;
436 if (fc != '%')
438 /* Remember to skip spaces. */
439 if (ISSPACE (fc))
441 skip_space = 1;
442 continue;
445 /* Read a character. */
446 c = inchar ();
448 /* Characters other than format specs must just match. */
449 if (c == EOF)
450 input_error ();
452 /* We saw white space char as the last character in the format
453 string. Now it's time to skip all leading white space. */
454 if (skip_space)
456 while (ISSPACE (c))
457 if (inchar () == EOF && errno == EINTR)
458 conv_error ();
459 skip_space = 0;
462 if (c != fc)
464 ungetc (c, s);
465 conv_error ();
468 continue;
471 /* This is the start of the conversion string. */
472 flags = 0;
474 /* Not yet decided whether we read a pointer or not. */
475 read_pointer = 0;
477 /* Initialize state of modifiers. */
478 argpos = 0;
480 /* Prepare temporary buffer. */
481 wpsize = 0;
483 /* Check for a positional parameter specification. */
484 if (ISDIGIT ((UCHAR_T) *f))
486 argpos = (UCHAR_T) *f++ - L_('0');
487 while (ISDIGIT ((UCHAR_T) *f))
488 argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
489 if (*f == L_('$'))
490 ++f;
491 else
493 /* Oops; that was actually the field width. */
494 width = argpos;
495 flags |= WIDTH;
496 argpos = 0;
497 goto got_width;
501 /* Check for the assignment-suppressing, the number grouping flag,
502 and the signal to use the locale's digit representation. */
503 while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
504 switch (*f++)
506 case L_('*'):
507 flags |= SUPPRESS;
508 break;
509 case L_('\''):
510 flags |= GROUP;
511 break;
512 case L_('I'):
513 flags |= I18N;
514 break;
517 /* We have seen width. */
518 if (ISDIGIT ((UCHAR_T) *f))
519 flags |= WIDTH;
521 /* Find the maximum field width. */
522 width = 0;
523 while (ISDIGIT ((UCHAR_T) *f))
525 width *= 10;
526 width += (UCHAR_T) *f++ - L_('0');
528 got_width:
529 if (width == 0)
530 width = -1;
532 /* Check for type modifiers. */
533 switch (*f++)
535 case L_('h'):
536 /* ints are short ints or chars. */
537 if (*f == L_('h'))
539 ++f;
540 flags |= CHAR;
542 else
543 flags |= SHORT;
544 break;
545 case L_('l'):
546 if (*f == L_('l'))
548 /* A double `l' is equivalent to an `L'. */
549 ++f;
550 flags |= LONGDBL | LONG;
552 else
553 /* ints are long ints. */
554 flags |= LONG;
555 break;
556 case L_('q'):
557 case L_('L'):
558 /* doubles are long doubles, and ints are long long ints. */
559 flags |= LONGDBL | LONG;
560 break;
561 case L_('a'):
562 /* The `a' is used as a flag only if followed by `s', `S' or
563 `['. */
564 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
566 --f;
567 break;
569 /* String conversions (%s, %[) take a `char **'
570 arg and fill it in with a malloc'd pointer. */
571 flags |= MALLOC;
572 break;
573 case L_('z'):
574 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
575 flags |= LONGDBL;
576 else if (sizeof (size_t) > sizeof (unsigned int))
577 flags |= LONG;
578 break;
579 case L_('j'):
580 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
581 flags |= LONGDBL;
582 else if (sizeof (uintmax_t) > sizeof (unsigned int))
583 flags |= LONG;
584 break;
585 case L_('t'):
586 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
587 flags |= LONGDBL;
588 else if (sizeof (ptrdiff_t) > sizeof (int))
589 flags |= LONG;
590 break;
591 default:
592 /* Not a recognized modifier. Backup. */
593 --f;
594 break;
597 /* End of the format string? */
598 if (*f == L_('\0'))
599 conv_error ();
601 /* Find the conversion specifier. */
602 fc = *f++;
603 if (skip_space || (fc != L_('[') && fc != L_('c')
604 && fc != L_('C') && fc != L_('n')))
606 /* Eat whitespace. */
607 int save_errno = errno;
608 errno = 0;
610 if (inchar () == EOF && errno == EINTR)
611 input_error ();
612 while (ISSPACE (c));
613 errno = save_errno;
614 ungetc (c, s);
615 skip_space = 0;
618 switch (fc)
620 case L_('%'): /* Must match a literal '%'. */
621 c = inchar ();
622 if (c == EOF)
623 input_error ();
624 if (c != fc)
626 ungetc_not_eof (c, s);
627 conv_error ();
629 break;
631 case L_('n'): /* Answer number of assignments done. */
632 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
633 with the 'n' conversion specifier. */
634 if (!(flags & SUPPRESS))
636 /* Don't count the read-ahead. */
637 if (need_longlong && (flags & LONGDBL))
638 *ARG (long long int *) = read_in;
639 else if (need_long && (flags & LONG))
640 *ARG (long int *) = read_in;
641 else if (flags & SHORT)
642 *ARG (short int *) = read_in;
643 else if (!(flags & CHAR))
644 *ARG (int *) = read_in;
645 else
646 *ARG (char *) = read_in;
648 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
649 /* We have a severe problem here. The ISO C standard
650 contradicts itself in explaining the effect of the %n
651 format in `scanf'. While in ISO C:1990 and the ISO C
652 Amendement 1:1995 the result is described as
654 Execution of a %n directive does not effect the
655 assignment count returned at the completion of
656 execution of the f(w)scanf function.
658 in ISO C Corrigendum 1:1994 the following was added:
660 Subclause 7.9.6.2
661 Add the following fourth example:
663 #include <stdio.h>
664 int d1, d2, n1, n2, i;
665 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
666 the value 123 is assigned to d1 and the value3 to n1.
667 Because %n can never get an input failure the value
668 of 3 is also assigned to n2. The value of d2 is not
669 affected. The value 3 is assigned to i.
671 We go for now with the historically correct code from ISO C,
672 i.e., we don't count the %n assignments. When it ever
673 should proof to be wrong just remove the #ifdef above. */
674 ++done;
675 #endif
677 break;
679 case L_('c'): /* Match characters. */
680 if ((flags & LONG) == 0)
682 if (!(flags & SUPPRESS))
684 str = ARG (char *);
685 if (str == NULL)
686 conv_error ();
689 c = inchar ();
690 if (c == EOF)
691 input_error ();
693 if (width == -1)
694 width = 1;
696 #ifdef COMPILE_WSCANF
697 /* We have to convert the wide character(s) into multibyte
698 characters and store the result. */
699 memset (&state, '\0', sizeof (state));
703 size_t n;
705 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
706 if (n == (size_t) -1)
707 /* No valid wide character. */
708 input_error ();
710 /* Increment the output pointer. Even if we don't
711 write anything. */
712 str += n;
714 while (--width > 0 && inchar () != EOF);
715 #else
716 if (!(flags & SUPPRESS))
719 *str++ = c;
720 while (--width > 0 && inchar () != EOF);
722 else
723 while (--width > 0 && inchar () != EOF);
724 #endif
726 if (!(flags & SUPPRESS))
727 ++done;
729 break;
731 /* FALLTHROUGH */
732 case L_('C'):
733 if (!(flags & SUPPRESS))
735 wstr = ARG (wchar_t *);
736 if (wstr == NULL)
737 conv_error ();
740 c = inchar ();
741 if (c == EOF)
742 input_error ();
744 #ifdef COMPILE_WSCANF
745 /* Just store the incoming wide characters. */
746 if (!(flags & SUPPRESS))
749 *wstr++ = c;
750 while (--width > 0 && inchar () != EOF);
752 else
753 while (--width > 0 && inchar () != EOF);
754 #else
756 /* We have to convert the multibyte input sequence to wide
757 characters. */
758 char buf[MB_LEN_MAX];
759 mbstate_t cstate;
761 memset (&cstate, '\0', sizeof (cstate));
765 size_t cnt;
767 /* This is what we present the mbrtowc function first. */
768 buf[0] = c;
769 cnt = 1;
771 while (1)
773 size_t n;
775 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
776 buf, cnt, &cstate);
778 if (n == (size_t) -2)
780 /* Possibly correct character, just not enough
781 input. */
782 assert (cnt < MB_CUR_MAX);
784 if (inchar () == EOF)
785 encode_error ();
787 buf[cnt++] = c;
788 continue;
791 if (n != cnt)
792 encode_error ();
794 /* We have a match. */
795 break;
798 /* Advance the result pointer. */
799 ++wstr;
801 while (--width > 0 && inchar () != EOF);
803 #endif
805 if (!(flags & SUPPRESS))
806 ++done;
808 break;
810 case L_('s'): /* Read a string. */
811 if (!(flags & LONG))
813 #define STRING_ARG(Str, Type) \
814 do if (!(flags & SUPPRESS)) \
816 if (flags & MALLOC) \
818 /* The string is to be stored in a malloc'd buffer. */ \
819 strptr = ARG (char **); \
820 if (strptr == NULL) \
821 conv_error (); \
822 /* Allocate an initial buffer. */ \
823 strsize = 100; \
824 *strptr = (char *) malloc (strsize * sizeof (Type)); \
825 Str = (Type *) *strptr; \
827 else \
828 Str = ARG (Type *); \
829 if (Str == NULL) \
830 conv_error (); \
831 } while (0)
832 STRING_ARG (str, char);
834 c = inchar ();
835 if (c == EOF)
836 input_error ();
838 #ifdef COMPILE_WSCANF
839 memset (&state, '\0', sizeof (state));
840 #endif
844 if (ISSPACE (c))
846 ungetc_not_eof (c, s);
847 break;
850 #ifdef COMPILE_WSCANF
851 /* This is quite complicated. We have to convert the
852 wide characters into multibyte characters and then
853 store them. */
855 size_t n;
857 if (!(flags & SUPPRESS) && (flags & MALLOC)
858 && str + MB_CUR_MAX >= *strptr + strsize)
860 /* We have to enlarge the buffer if the `a' flag
861 was given. */
862 size_t strleng = str - *strptr;
863 char *newstr;
865 newstr = (char *) realloc (*strptr, strsize * 2);
866 if (newstr == NULL)
868 /* Can't allocate that much. Last-ditch
869 effort. */
870 newstr = (char *) realloc (*strptr,
871 strleng + MB_CUR_MAX);
872 if (newstr == NULL)
874 /* We lose. Oh well. Terminate the
875 string and stop converting,
876 so at least we don't skip any input. */
877 ((char *) (*strptr))[strleng] = '\0';
878 ++done;
879 conv_error ();
881 else
883 *strptr = newstr;
884 str = newstr + strleng;
885 strsize = strleng + MB_CUR_MAX;
888 else
890 *strptr = newstr;
891 str = newstr + strleng;
892 strsize *= 2;
896 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
897 &state);
898 if (n == (size_t) -1)
899 encode_error ();
901 assert (n <= MB_CUR_MAX);
902 str += n;
904 #else
905 /* This is easy. */
906 if (!(flags & SUPPRESS))
908 *str++ = c;
909 if ((flags & MALLOC)
910 && (char *) str == *strptr + strsize)
912 /* Enlarge the buffer. */
913 str = (char *) realloc (*strptr, 2 * strsize);
914 if (str == NULL)
916 /* Can't allocate that much. Last-ditch
917 effort. */
918 str = (char *) realloc (*strptr, strsize + 1);
919 if (str == NULL)
921 /* We lose. Oh well. Terminate the
922 string and stop converting,
923 so at least we don't skip any input. */
924 ((char *) (*strptr))[strsize - 1] = '\0';
925 ++done;
926 conv_error ();
928 else
930 *strptr = (char *) str;
931 str += strsize;
932 ++strsize;
935 else
937 *strptr = (char *) str;
938 str += strsize;
939 strsize *= 2;
943 #endif
945 while ((width <= 0 || --width > 0) && inchar () != EOF);
947 if (!(flags & SUPPRESS))
949 #ifdef COMPILE_WSCANF
950 /* We have to emit the code to get into the initial
951 state. */
952 char buf[MB_LEN_MAX];
953 size_t n = __wcrtomb (buf, L'\0', &state);
954 if (n > 0 && (flags & MALLOC)
955 && str + n >= *strptr + strsize)
957 /* Enlarge the buffer. */
958 size_t strleng = str - *strptr;
959 char *newstr;
961 newstr = (char *) realloc (*strptr, strleng + n + 1);
962 if (newstr == NULL)
964 /* We lose. Oh well. Terminate the string
965 and stop converting, so at least we don't
966 skip any input. */
967 ((char *) (*strptr))[strleng] = '\0';
968 ++done;
969 conv_error ();
971 else
973 *strptr = newstr;
974 str = newstr + strleng;
975 strsize = strleng + n + 1;
979 str = __mempcpy (str, buf, n);
980 #endif
981 *str++ = '\0';
983 if ((flags & MALLOC) && str - *strptr != strsize)
985 char *cp = (char *) realloc (*strptr, str - *strptr);
986 if (cp != NULL)
987 *strptr = cp;
990 ++done;
992 break;
994 /* FALLTHROUGH */
996 case L_('S'):
998 #ifndef COMPILE_WSCANF
999 mbstate_t cstate;
1000 #endif
1002 /* Wide character string. */
1003 STRING_ARG (wstr, wchar_t);
1005 c = inchar ();
1006 if (c == EOF)
1007 input_error ();
1009 #ifndef COMPILE_WSCANF
1010 memset (&cstate, '\0', sizeof (cstate));
1011 #endif
1015 if (ISSPACE (c))
1017 ungetc_not_eof (c, s);
1018 break;
1021 #ifdef COMPILE_WSCANF
1022 /* This is easy. */
1023 if (!(flags & SUPPRESS))
1025 *wstr++ = c;
1026 if ((flags & MALLOC)
1027 && wstr == (wchar_t *) *strptr + strsize)
1029 /* Enlarge the buffer. */
1030 wstr = (wchar_t *) realloc (*strptr,
1031 (2 * strsize)
1032 * sizeof (wchar_t));
1033 if (wstr == NULL)
1035 /* Can't allocate that much. Last-ditch
1036 effort. */
1037 wstr = (wchar_t *) realloc (*strptr,
1038 (strsize + 1)
1039 * sizeof (wchar_t));
1040 if (wstr == NULL)
1042 /* We lose. Oh well. Terminate the string
1043 and stop converting, so at least we don't
1044 skip any input. */
1045 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1046 ++done;
1047 conv_error ();
1049 else
1051 *strptr = (char *) wstr;
1052 wstr += strsize;
1053 ++strsize;
1056 else
1058 *strptr = (char *) wstr;
1059 wstr += strsize;
1060 strsize *= 2;
1064 #else
1066 char buf[MB_LEN_MAX];
1067 size_t cnt;
1069 buf[0] = c;
1070 cnt = 1;
1072 while (1)
1074 size_t n;
1076 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1077 buf, cnt, &cstate);
1079 if (n == (size_t) -2)
1081 /* Possibly correct character, just not enough
1082 input. */
1083 assert (cnt < MB_CUR_MAX);
1085 if (inchar () == EOF)
1086 encode_error ();
1088 buf[cnt++] = c;
1089 continue;
1092 if (n != cnt)
1093 encode_error ();
1095 /* We have a match. */
1096 break;
1099 if (!(flags & SUPPRESS) && (flags & MALLOC)
1100 && wstr == (wchar_t *) *strptr + strsize)
1102 /* Enlarge the buffer. */
1103 wstr = (wchar_t *) realloc (*strptr,
1104 (2 * strsize
1105 * sizeof (wchar_t)));
1106 if (wstr == NULL)
1108 /* Can't allocate that much. Last-ditch effort. */
1109 wstr = (wchar_t *) realloc (*strptr,
1110 ((strsize + 1)
1111 * sizeof (wchar_t)));
1112 if (wstr == NULL)
1114 /* We lose. Oh well. Terminate the
1115 string and stop converting, so at
1116 least we don't skip any input. */
1117 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1118 ++done;
1119 conv_error ();
1121 else
1123 *strptr = (char *) wstr;
1124 wstr += strsize;
1125 ++strsize;
1128 else
1130 *strptr = (char *) wstr;
1131 wstr += strsize;
1132 strsize *= 2;
1136 #endif
1138 while ((width <= 0 || --width > 0) && inchar () != EOF);
1140 if (!(flags & SUPPRESS))
1142 *wstr++ = L'\0';
1144 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1146 wchar_t *cp = (wchar_t *) realloc (*strptr,
1147 ((wstr
1148 - (wchar_t *) *strptr)
1149 * sizeof(wchar_t)));
1150 if (cp != NULL)
1151 *strptr = (char *) cp;
1154 ++done;
1157 break;
1159 case L_('x'): /* Hexadecimal integer. */
1160 case L_('X'): /* Ditto. */
1161 base = 16;
1162 number_signed = 0;
1163 goto number;
1165 case L_('o'): /* Octal integer. */
1166 base = 8;
1167 number_signed = 0;
1168 goto number;
1170 case L_('u'): /* Unsigned decimal integer. */
1171 base = 10;
1172 number_signed = 0;
1173 goto number;
1175 case L_('d'): /* Signed decimal integer. */
1176 base = 10;
1177 number_signed = 1;
1178 goto number;
1180 case L_('i'): /* Generic number. */
1181 base = 0;
1182 number_signed = 1;
1184 number:
1185 c = inchar ();
1186 if (c == EOF)
1187 input_error ();
1189 /* Check for a sign. */
1190 if (c == L_('-') || c == L_('+'))
1192 ADDW (c);
1193 if (width > 0)
1194 --width;
1195 c = inchar ();
1198 /* Look for a leading indication of base. */
1199 if (width != 0 && c == L_('0'))
1201 if (width > 0)
1202 --width;
1204 ADDW (c);
1205 c = inchar ();
1207 if (width != 0 && TOLOWER (c) == L_('x'))
1209 if (base == 0)
1210 base = 16;
1211 if (base == 16)
1213 if (width > 0)
1214 --width;
1215 c = inchar ();
1218 else if (base == 0)
1219 base = 8;
1222 if (base == 0)
1223 base = 10;
1225 if (base == 10 && (flags & I18N) != 0)
1227 int from_level;
1228 int to_level;
1229 int level;
1230 #ifdef COMPILE_WSCANF
1231 const wchar_t *wcdigits[10];
1232 #else
1233 const char *mbdigits[10];
1234 #endif
1235 int n;
1237 from_level = 0;
1238 #ifdef COMPILE_WSCANF
1239 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1240 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1241 #else
1242 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1243 _NL_CTYPE_INDIGITS_MB_LEN) - 1;
1244 #endif
1246 /* Read the number into workspace. */
1247 while (c != EOF && width != 0)
1249 /* In this round we get the pointer to the digit strings
1250 and also perform the first round of comparisons. */
1251 for (n = 0; n < 10; ++n)
1253 /* Get the string for the digits with value N. */
1254 #ifdef COMPILE_WSCANF
1255 wcdigits[n] = (const wchar_t *)
1256 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1257 wcdigits[n] += from_level;
1259 if (c == *wcdigits[n])
1261 to_level = from_level;
1262 break;
1265 /* Advance the pointer to the next string. */
1266 ++wcdigits[n];
1267 #else
1268 const char *cmpp;
1269 int avail = width > 0 ? width : INT_MAX;
1271 mbdigits[n] = _NL_CURRENT (LC_CTYPE,
1272 _NL_CTYPE_INDIGITS0_MB + n);
1274 for (level = 0; level < from_level; level++)
1275 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1277 cmpp = mbdigits[n];
1278 while ((unsigned char) *cmpp == c && avail > 0)
1280 if (*++cmpp == '\0')
1281 break;
1282 else
1284 if ((c = inchar ()) == EOF)
1285 break;
1286 --avail;
1290 if (*cmpp == '\0')
1292 if (width > 0)
1293 width = avail;
1294 to_level = from_level;
1295 break;
1298 /* We are pushing all read characters back. */
1299 if (cmpp > mbdigits[n])
1301 ungetc (c, s);
1302 while (--cmpp > mbdigits[n])
1303 ungetc_not_eof ((unsigned char) *cmpp, s);
1304 c = (unsigned char) *cmpp;
1307 /* Advance the pointer to the next string. */
1308 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1309 #endif
1312 if (n == 10)
1314 /* Have not yet found the digit. */
1315 for (level = from_level + 1; level <= to_level; ++level)
1317 /* Search all ten digits of this level. */
1318 for (n = 0; n < 10; ++n)
1320 #ifdef COMPILE_WSCANF
1321 if (c == *wcdigits[n])
1322 break;
1324 /* Advance the pointer to the next string. */
1325 ++wcdigits[n];
1326 #else
1327 const char *cmpp;
1328 int avail = width > 0 ? width : INT_MAX;
1330 cmpp = mbdigits[n];
1331 while ((unsigned char) *cmpp == c && avail > 0)
1333 if (*++cmpp == '\0')
1334 break;
1335 else
1337 if ((c = inchar ()) == EOF)
1338 break;
1339 --avail;
1343 if (*cmpp == '\0')
1345 if (width > 0)
1346 width = avail;
1347 break;
1350 /* We are pushing all read characters back. */
1351 if (cmpp > mbdigits[n])
1353 ungetc (c, s);
1354 while (--cmpp > mbdigits[n])
1355 ungetc_not_eof ((unsigned char) *cmpp, s);
1356 c = (unsigned char) *cmpp;
1359 /* Advance the pointer to the next string. */
1360 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1361 #endif
1364 if (n < 10)
1366 /* Found it. */
1367 from_level = level;
1368 to_level = level;
1369 break;
1374 if (n < 10)
1375 c = L_('0') + n;
1376 else if ((flags & GROUP)
1377 #ifdef COMPILE_WSCANF
1378 && thousands != L'\0'
1379 #else
1380 && thousands != NULL
1381 #endif
1384 /* Try matching against the thousands separator. */
1385 #ifdef COMPILE_WSCANF
1386 if (c != thousands)
1387 break;
1388 #else
1389 const char *cmpp = thousands;
1390 int avail = width > 0 ? width : INT_MAX;
1392 while ((unsigned char) *cmpp == c && avail > 0)
1394 ADDW (c);
1395 if (*++cmpp == '\0')
1396 break;
1397 else
1399 if ((c = inchar ()) == EOF)
1400 break;
1401 --avail;
1405 if (*cmpp != '\0')
1407 /* We are pushing all read characters back. */
1408 if (cmpp > thousands)
1410 wpsize -= cmpp - thousands;
1411 ungetc (c, s);
1412 while (--cmpp > thousands)
1413 ungetc_not_eof ((unsigned char) *cmpp, s);
1414 c = (unsigned char) *cmpp;
1416 break;
1419 if (width > 0)
1420 width = avail;
1422 /* The last thousands character will be added back by
1423 the ADDW below. */
1424 --wpsize;
1425 #endif
1427 else
1428 break;
1430 ADDW (c);
1431 if (width > 0)
1432 --width;
1434 c = inchar ();
1437 else
1438 /* Read the number into workspace. */
1439 while (c != EOF && width != 0)
1441 if (base == 16)
1443 if (!ISXDIGIT (c))
1444 break;
1446 else if (!ISDIGIT (c) || c - L_('0') >= base)
1448 if (base == 10 && (flags & GROUP)
1449 #ifdef COMPILE_WSCANF
1450 && thousands != L'\0'
1451 #else
1452 && thousands != NULL
1453 #endif
1456 /* Try matching against the thousands separator. */
1457 #ifdef COMPILE_WSCANF
1458 if (c != thousands)
1459 break;
1460 #else
1461 const char *cmpp = thousands;
1462 int avail = width > 0 ? width : INT_MAX;
1464 while ((unsigned char) *cmpp == c && avail > 0)
1466 ADDW (c);
1467 if (*++cmpp == '\0')
1468 break;
1469 else
1471 if ((c = inchar ()) == EOF)
1472 break;
1473 --avail;
1477 if (*cmpp != '\0')
1479 /* We are pushing all read characters back. */
1480 if (cmpp > thousands)
1482 wpsize -= cmpp - thousands;
1483 ungetc (c, s);
1484 while (--cmpp > thousands)
1485 ungetc_not_eof ((unsigned char) *cmpp, s);
1486 c = (unsigned char) *cmpp;
1488 break;
1491 if (width > 0)
1492 width = avail;
1494 /* The last thousands character will be added back by
1495 the ADDW below. */
1496 --wpsize;
1497 #endif
1499 else
1500 break;
1502 ADDW (c);
1503 if (width > 0)
1504 --width;
1506 c = inchar ();
1509 if (wpsize == 0
1510 || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1512 /* There was no number. If we are supposed to read a pointer
1513 we must recognize "(nil)" as well. */
1514 if (wpsize == 0 && read_pointer && (width < 0 || width >= 0)
1515 && c == '('
1516 && TOLOWER (inchar ()) == L_('n')
1517 && TOLOWER (inchar ()) == L_('i')
1518 && TOLOWER (inchar ()) == L_('l')
1519 && inchar () == L_(')'))
1520 /* We must produce the value of a NULL pointer. A single
1521 '0' digit is enough. */
1522 ADDW (L_('0'));
1523 else
1525 /* The last read character is not part of the number
1526 anymore. */
1527 ungetc (c, s);
1529 conv_error ();
1532 else
1533 /* The just read character is not part of the number anymore. */
1534 ungetc (c, s);
1536 /* Convert the number. */
1537 ADDW (L_('\0'));
1538 if (need_longlong && (flags & LONGDBL))
1540 if (number_signed)
1541 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1542 else
1543 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1545 else
1547 if (number_signed)
1548 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1549 else
1550 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1552 if (wp == tw)
1553 conv_error ();
1555 if (!(flags & SUPPRESS))
1557 if (! number_signed)
1559 if (need_longlong && (flags & LONGDBL))
1560 *ARG (unsigned LONGLONG int *) = num.uq;
1561 else if (need_long && (flags & LONG))
1562 *ARG (unsigned long int *) = num.ul;
1563 else if (flags & SHORT)
1564 *ARG (unsigned short int *)
1565 = (unsigned short int) num.ul;
1566 else if (!(flags & CHAR))
1567 *ARG (unsigned int *) = (unsigned int) num.ul;
1568 else
1569 *ARG (unsigned char *) = (unsigned char) num.ul;
1571 else
1573 if (need_longlong && (flags & LONGDBL))
1574 *ARG (LONGLONG int *) = num.q;
1575 else if (need_long && (flags & LONG))
1576 *ARG (long int *) = num.l;
1577 else if (flags & SHORT)
1578 *ARG (short int *) = (short int) num.l;
1579 else if (!(flags & CHAR))
1580 *ARG (int *) = (int) num.l;
1581 else
1582 *ARG (signed char *) = (signed char) num.ul;
1584 ++done;
1586 break;
1588 case L_('e'): /* Floating-point numbers. */
1589 case L_('E'):
1590 case L_('f'):
1591 case L_('F'):
1592 case L_('g'):
1593 case L_('G'):
1594 case L_('a'):
1595 case L_('A'):
1596 c = inchar ();
1597 if (c == EOF)
1598 input_error ();
1600 /* Check for a sign. */
1601 if (c == L_('-') || c == L_('+'))
1603 negative = c == L_('-');
1604 if (width == 0 || inchar () == EOF)
1605 /* EOF is only an input error before we read any chars. */
1606 conv_error ();
1607 if (! ISDIGIT (c))
1609 #ifdef COMPILE_WSCANF
1610 if (c != decimal)
1612 /* This is no valid number. */
1613 ungetc (c, s);
1614 conv_error ();
1616 #else
1617 /* Match against the decimal point. At this point
1618 we are taking advantage of the fact that we can
1619 push more than one character back. This is
1620 (almost) never necessary since the decimal point
1621 string hopefully never contains more than one
1622 byte. */
1623 const char *cmpp = decimal;
1624 int avail = width > 0 ? width : INT_MAX;
1626 while ((unsigned char) *cmpp == c && avail > 0)
1627 if (*++cmpp == '\0')
1628 break;
1629 else
1631 if (inchar () == EOF)
1632 break;
1633 --avail;
1636 if (*cmpp != '\0')
1638 /* This is no valid number. */
1639 while (1)
1641 ungetc (c, s);
1642 if (cmpp == decimal)
1643 break;
1644 c = (unsigned char) *--cmpp;
1647 conv_error ();
1649 if (width > 0)
1650 width = avail;
1651 #endif
1653 if (width > 0)
1654 --width;
1656 else
1657 negative = 0;
1659 /* Take care for the special arguments "nan" and "inf". */
1660 if (TOLOWER (c) == L_('n'))
1662 /* Maybe "nan". */
1663 ADDW (c);
1664 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('a'))
1665 input_error ();
1666 if (width > 0)
1667 --width;
1668 ADDW (c);
1669 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1670 input_error ();
1671 if (width > 0)
1672 --width;
1673 ADDW (c);
1674 /* It is "nan". */
1675 goto scan_float;
1677 else if (TOLOWER (c) == L_('i'))
1679 /* Maybe "inf" or "infinity". */
1680 ADDW (c);
1681 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1682 input_error ();
1683 if (width > 0)
1684 --width;
1685 ADDW (c);
1686 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('f'))
1687 input_error ();
1688 if (width > 0)
1689 --width;
1690 ADDW (c);
1691 /* It is as least "inf". */
1692 if (width != 0 && inchar () != EOF)
1694 if (TOLOWER (c) == L_('i'))
1696 if (width > 0)
1697 --width;
1698 /* Now we have to read the rest as well. */
1699 ADDW (c);
1700 if (width == 0 || inchar () == EOF
1701 || TOLOWER (c) != L_('n'))
1702 input_error ();
1703 if (width > 0)
1704 --width;
1705 ADDW (c);
1706 if (width == 0 || inchar () == EOF
1707 || TOLOWER (c) != L_('i'))
1708 input_error ();
1709 if (width > 0)
1710 --width;
1711 ADDW (c);
1712 if (width == 0 || inchar () == EOF
1713 || TOLOWER (c) != L_('t'))
1714 input_error ();
1715 if (width > 0)
1716 --width;
1717 ADDW (c);
1718 if (width == 0 || inchar () == EOF
1719 || TOLOWER (c) != L_('y'))
1720 input_error ();
1721 if (width > 0)
1722 --width;
1723 ADDW (c);
1725 else
1726 /* Never mind. */
1727 ungetc (c, s);
1729 goto scan_float;
1732 is_hexa = 0;
1733 exp_char = L_('e');
1734 if (width != 0 && c == L_('0'))
1736 ADDW (c);
1737 c = inchar ();
1738 if (width > 0)
1739 --width;
1740 if (width != 0 && TOLOWER (c) == L_('x'))
1742 /* It is a number in hexadecimal format. */
1743 ADDW (c);
1745 is_hexa = 1;
1746 exp_char = L_('p');
1748 /* Grouping is not allowed. */
1749 flags &= ~GROUP;
1750 c = inchar ();
1751 if (width > 0)
1752 --width;
1756 got_dot = got_e = 0;
1759 if (ISDIGIT (c))
1760 ADDW (c);
1761 else if (!got_e && is_hexa && ISXDIGIT (c))
1762 ADDW (c);
1763 else if (got_e && wp[wpsize - 1] == exp_char
1764 && (c == L_('-') || c == L_('+')))
1765 ADDW (c);
1766 else if (wpsize > 0 && !got_e && TOLOWER (c) == exp_char)
1768 ADDW (exp_char);
1769 got_e = got_dot = 1;
1771 else
1773 #ifdef COMPILE_WSCANF
1774 if (! got_dot && c == decimal)
1776 ADDW (c);
1777 got_dot = 1;
1779 else if (thousands != L'\0' && ! got_dot && c == thousands)
1780 ADDW (c);
1781 else
1783 /* The last read character is not part of the number
1784 anymore. */
1785 ungetc (c, s);
1786 break;
1788 #else
1789 const char *cmpp = decimal;
1790 int avail = width > 0 ? width : INT_MAX;
1792 if (! got_dot)
1794 while ((unsigned char) *cmpp == c && avail > 0)
1795 if (*++cmpp == '\0')
1796 break;
1797 else
1799 if (inchar () == EOF)
1800 break;
1801 --avail;
1805 if (*cmpp == '\0')
1807 /* Add all the characters. */
1808 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1809 ADDW ((unsigned char) *cmpp);
1810 if (width > 0)
1811 width = avail;
1812 got_dot = 1;
1814 else
1816 /* Figure out whether it is a thousands separator.
1817 There is one problem: we possibly read more than
1818 one character. We cannot push them back but since
1819 we know that parts of the `decimal' string matched,
1820 we can compare against it. */
1821 const char *cmp2p = thousands;
1823 if (thousands != NULL && ! got_dot)
1825 while (cmp2p < cmpp
1826 && *cmp2p == decimal[cmp2p - thousands])
1827 ++cmp2p;
1828 if (cmp2p == cmpp)
1830 while ((unsigned char) *cmp2p == c && avail > 0)
1831 if (*++cmp2p == '\0')
1832 break;
1833 else
1835 if (inchar () == EOF)
1836 break;
1837 --avail;
1842 if (cmp2p != NULL && *cmp2p == '\0')
1844 /* Add all the characters. */
1845 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
1846 ADDW ((unsigned char) *cmpp);
1847 if (width > 0)
1848 width = avail;
1850 else
1852 /* The last read character is not part of the number
1853 anymore. */
1854 ungetc (c, s);
1855 break;
1858 #endif
1860 if (width > 0)
1861 --width;
1863 while (width != 0 && inchar () != EOF);
1865 /* Have we read any character? If we try to read a number
1866 in hexadecimal notation and we have read only the `0x'
1867 prefix or no exponent this is an error. */
1868 if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
1869 conv_error ();
1871 scan_float:
1872 /* Convert the number. */
1873 ADDW (L_('\0'));
1874 if (flags & LONGDBL)
1876 long double d = __strtold_internal (wp, &tw, flags & GROUP);
1877 if (!(flags & SUPPRESS) && tw != wp)
1878 *ARG (long double *) = negative ? -d : d;
1880 else if (flags & LONG)
1882 double d = __strtod_internal (wp, &tw, flags & GROUP);
1883 if (!(flags & SUPPRESS) && tw != wp)
1884 *ARG (double *) = negative ? -d : d;
1886 else
1888 float d = __strtof_internal (wp, &tw, flags & GROUP);
1889 if (!(flags & SUPPRESS) && tw != wp)
1890 *ARG (float *) = negative ? -d : d;
1893 if (tw == wp)
1894 conv_error ();
1896 if (!(flags & SUPPRESS))
1897 ++done;
1898 break;
1900 case L_('['): /* Character class. */
1901 if (flags & LONG)
1902 STRING_ARG (wstr, wchar_t);
1903 else
1904 STRING_ARG (str, char);
1906 if (*f == L_('^'))
1908 ++f;
1909 not_in = 1;
1911 else
1912 not_in = 0;
1914 if (width < 0)
1915 /* There is no width given so there is also no limit on the
1916 number of characters we read. Therefore we set width to
1917 a very high value to make the algorithm easier. */
1918 width = INT_MAX;
1920 #ifdef COMPILE_WSCANF
1921 /* Find the beginning and the end of the scanlist. We are not
1922 creating a lookup table since it would have to be too large.
1923 Instead we search each time through the string. This is not
1924 a constant lookup time but who uses this feature deserves to
1925 be punished. */
1926 tw = (wchar_t *) f; /* Marks the beginning. */
1928 if (*f == ']' || *f == '-')
1929 ++f;
1931 while ((fc = *f++) != L'\0' && fc != L']');
1933 if (fc == L'\0')
1934 conv_error ();
1935 wp = (wchar_t *) f - 1;
1936 #else
1937 /* Fill WP with byte flags indexed by character.
1938 We will use this flag map for matching input characters. */
1939 if (wpmax < UCHAR_MAX + 1)
1941 wpmax = UCHAR_MAX + 1;
1942 wp = (char *) alloca (wpmax);
1944 memset (wp, '\0', UCHAR_MAX + 1);
1946 fc = *f;
1947 if (fc == ']' || fc == '-')
1949 /* If ] or - appears before any char in the set, it is not
1950 the terminator or separator, but the first char in the
1951 set. */
1952 wp[fc] = 1;
1953 ++f;
1956 while ((fc = *f++) != '\0' && fc != ']')
1957 if (fc == '-' && *f != '\0' && *f != ']'
1958 && (unsigned char) f[-2] <= (unsigned char) *f)
1960 /* Add all characters from the one before the '-'
1961 up to (but not including) the next format char. */
1962 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
1963 wp[fc] = 1;
1965 else
1966 /* Add the character to the flag map. */
1967 wp[fc] = 1;
1969 if (fc == '\0')
1970 conv_error();
1971 #endif
1973 if (flags & LONG)
1975 size_t now = read_in;
1976 #ifdef COMPILE_WSCANF
1977 if (inchar () == WEOF)
1978 input_error ();
1982 wchar_t *runp;
1984 /* Test whether it's in the scanlist. */
1985 runp = tw;
1986 while (runp < wp)
1988 if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']'
1989 && runp != tw
1990 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
1992 /* Match against all characters in between the
1993 first and last character of the sequence. */
1994 wchar_t wc;
1996 for (wc = runp[-1] + 1; wc < runp[1]; ++wc)
1997 if (wc == c)
1998 break;
2000 if (wc == runp[1] && !not_in)
2001 break;
2002 if (wc == runp[1] && not_in)
2004 /* The current character is not in the
2005 scanset. */
2006 ungetwc (c, s);
2007 goto out;
2010 else
2012 if (*runp == runp[1] && !not_in)
2013 break;
2014 if (*runp != runp[1] && not_in)
2016 ungetwc (c ,s);
2017 goto out;
2021 ++runp;
2024 if (!(flags & SUPPRESS))
2026 *wstr++ = c;
2028 if ((flags & MALLOC)
2029 && wstr == (wchar_t *) *strptr + strsize)
2031 /* Enlarge the buffer. */
2032 wstr = (wchar_t *) realloc (*strptr,
2033 (2 * strsize)
2034 * sizeof (wchar_t));
2035 if (wstr == NULL)
2037 /* Can't allocate that much. Last-ditch
2038 effort. */
2039 wstr = (wchar_t *)
2040 realloc (*strptr, (strsize + 1)
2041 * sizeof (wchar_t));
2042 if (wstr == NULL)
2044 /* We lose. Oh well. Terminate the string
2045 and stop converting, so at least we don't
2046 skip any input. */
2047 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2048 ++done;
2049 conv_error ();
2051 else
2053 *strptr = (char *) wstr;
2054 wstr += strsize;
2055 ++strsize;
2058 else
2060 *strptr = (char *) wstr;
2061 wstr += strsize;
2062 strsize *= 2;
2067 while (--width > 0 && inchar () != WEOF);
2068 out:
2069 #else
2070 char buf[MB_LEN_MAX];
2071 size_t cnt = 0;
2072 mbstate_t cstate;
2074 if (inchar () == EOF)
2075 input_error ();
2077 memset (&cstate, '\0', sizeof (cstate));
2081 if (wp[c] == not_in)
2083 ungetc_not_eof (c, s);
2084 break;
2087 /* This is easy. */
2088 if (!(flags & SUPPRESS))
2090 size_t n;
2092 /* Convert it into a wide character. */
2093 n = __mbrtowc (wstr, buf, cnt, &cstate);
2095 if (n == (size_t) -2)
2097 /* Possibly correct character, just not enough
2098 input. */
2099 assert (cnt < MB_CUR_MAX);
2100 continue;
2103 if (n != cnt)
2104 encode_error ();
2106 ++wstr;
2107 if ((flags & MALLOC)
2108 && wstr == (wchar_t *) *strptr + strsize)
2110 /* Enlarge the buffer. */
2111 wstr = (wchar_t *) realloc (*strptr,
2112 (2 * strsize
2113 * sizeof (wchar_t)));
2114 if (wstr == NULL)
2116 /* Can't allocate that much. Last-ditch
2117 effort. */
2118 wstr = (wchar_t *)
2119 realloc (*strptr, ((strsize + 1)
2120 * sizeof (wchar_t)));
2121 if (wstr == NULL)
2123 /* We lose. Oh well. Terminate the
2124 string and stop converting,
2125 so at least we don't skip any input. */
2126 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2127 ++done;
2128 conv_error ();
2130 else
2132 *strptr = (char *) wstr;
2133 wstr += strsize;
2134 ++strsize;
2137 else
2139 *strptr = (char *) wstr;
2140 wstr += strsize;
2141 strsize *= 2;
2146 if (--width <= 0)
2147 break;
2149 while (inchar () != EOF);
2151 if (cnt != 0)
2152 /* We stopped in the middle of recognizing another
2153 character. That's a problem. */
2154 encode_error ();
2155 #endif
2157 if (now == read_in)
2158 /* We haven't succesfully read any character. */
2159 conv_error ();
2161 if (!(flags & SUPPRESS))
2163 *wstr++ = L'\0';
2165 if ((flags & MALLOC)
2166 && wstr - (wchar_t *) *strptr != strsize)
2168 wchar_t *cp = (wchar_t *)
2169 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2170 * sizeof(wchar_t)));
2171 if (cp != NULL)
2172 *strptr = (char *) cp;
2175 ++done;
2178 else
2180 size_t now = read_in;
2182 if (inchar () == EOF)
2183 input_error ();
2185 #ifdef COMPILE_WSCANF
2187 memset (&state, '\0', sizeof (state));
2191 wchar_t *runp;
2192 size_t n;
2194 /* Test whether it's in the scanlist. */
2195 runp = tw;
2196 while (runp < wp)
2198 if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']'
2199 && runp != tw
2200 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2202 /* Match against all characters in between the
2203 first and last character of the sequence. */
2204 wchar_t wc;
2206 for (wc = runp[-1] + 1; wc < runp[1]; ++wc)
2207 if (wc == c)
2208 break;
2210 if (wc == runp[1] && !not_in)
2211 break;
2212 if (wc == runp[1] && not_in)
2214 /* The current character is not in the
2215 scanset. */
2216 ungetwc (c, s);
2217 goto out2;
2220 else
2222 if (*runp == runp[1] && !not_in)
2223 break;
2224 if (*runp != runp[1] && not_in)
2226 ungetwc (c ,s);
2227 goto out2;
2231 ++runp;
2234 if (!(flags & SUPPRESS))
2236 if ((flags & MALLOC)
2237 && str + MB_CUR_MAX >= *strptr + strsize)
2239 /* Enlarge the buffer. */
2240 size_t strleng = str - *strptr;
2241 char *newstr;
2243 newstr = (char *) realloc (*strptr, 2 * strsize);
2244 if (newstr == NULL)
2246 /* Can't allocate that much. Last-ditch
2247 effort. */
2248 newstr = (char *) realloc (*strptr,
2249 strleng + MB_CUR_MAX);
2250 if (newstr == NULL)
2252 /* We lose. Oh well. Terminate the string
2253 and stop converting, so at least we don't
2254 skip any input. */
2255 ((char *) (*strptr))[strleng] = '\0';
2256 ++done;
2257 conv_error ();
2259 else
2261 *strptr = newstr;
2262 str = newstr + strleng;
2263 strsize = strleng + MB_CUR_MAX;
2266 else
2268 *strptr = newstr;
2269 str = newstr + strleng;
2270 strsize *= 2;
2275 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2276 if (n == (size_t) -1)
2277 encode_error ();
2279 assert (n <= MB_CUR_MAX);
2280 str += n;
2282 while (--width > 0 && inchar () != WEOF);
2283 out2:
2284 #else
2287 if (wp[c] == not_in)
2289 ungetc_not_eof (c, s);
2290 break;
2293 /* This is easy. */
2294 if (!(flags & SUPPRESS))
2296 *str++ = c;
2297 if ((flags & MALLOC)
2298 && (char *) str == *strptr + strsize)
2300 /* Enlarge the buffer. */
2301 str = (char *) realloc (*strptr, 2 * strsize);
2302 if (str == NULL)
2304 /* Can't allocate that much. Last-ditch
2305 effort. */
2306 str = (char *) realloc (*strptr, strsize + 1);
2307 if (str == NULL)
2309 /* We lose. Oh well. Terminate the
2310 string and stop converting,
2311 so at least we don't skip any input. */
2312 ((char *) (*strptr))[strsize - 1] = '\0';
2313 ++done;
2314 conv_error ();
2316 else
2318 *strptr = (char *) str;
2319 str += strsize;
2320 ++strsize;
2323 else
2325 *strptr = (char *) str;
2326 str += strsize;
2327 strsize *= 2;
2332 while (--width > 0 && inchar () != EOF);
2333 #endif
2335 if (now == read_in)
2336 /* We haven't succesfully read any character. */
2337 conv_error ();
2339 if (!(flags & SUPPRESS))
2341 #ifdef COMPILE_WSCANF
2342 /* We have to emit the code to get into the initial
2343 state. */
2344 char buf[MB_LEN_MAX];
2345 size_t n = __wcrtomb (buf, L'\0', &state);
2346 if (n > 0 && (flags & MALLOC)
2347 && str + n >= *strptr + strsize)
2349 /* Enlarge the buffer. */
2350 size_t strleng = str - *strptr;
2351 char *newstr;
2353 newstr = (char *) realloc (*strptr, strleng + n + 1);
2354 if (newstr == NULL)
2356 /* We lose. Oh well. Terminate the string
2357 and stop converting, so at least we don't
2358 skip any input. */
2359 ((char *) (*strptr))[strleng] = '\0';
2360 ++done;
2361 conv_error ();
2363 else
2365 *strptr = newstr;
2366 str = newstr + strleng;
2367 strsize = strleng + n + 1;
2371 str = __mempcpy (str, buf, n);
2372 #endif
2373 *str++ = '\0';
2375 if ((flags & MALLOC) && str - *strptr != strsize)
2377 char *cp = (char *) realloc (*strptr, str - *strptr);
2378 if (cp != NULL)
2379 *strptr = cp;
2382 ++done;
2385 break;
2387 case L_('p'): /* Generic pointer. */
2388 base = 16;
2389 /* A PTR must be the same size as a `long int'. */
2390 flags &= ~(SHORT|LONGDBL);
2391 if (need_long)
2392 flags |= LONG;
2393 number_signed = 0;
2394 read_pointer = 1;
2395 goto number;
2397 default:
2398 /* If this is an unknown format character punt. */
2399 conv_error ();
2403 /* The last thing we saw int the format string was a white space.
2404 Consume the last white spaces. */
2405 if (skip_space)
2408 c = inchar ();
2409 while (ISSPACE (c));
2410 ungetc (c, s);
2413 /* Unlock stream. */
2414 UNLOCK_STREAM (s);
2416 return done;
2419 #ifdef USE_IN_LIBIO
2420 # ifdef COMPILE_WSCANF
2422 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2424 return _IO_vfwscanf (s, format, argptr, NULL);
2426 # else
2428 __vfscanf (FILE *s, const char *format, va_list argptr)
2430 return _IO_vfscanf (s, format, argptr, NULL);
2432 # endif
2433 #endif
2435 #ifdef COMPILE_WSCANF
2436 weak_alias (__vfwscanf, vfwscanf)
2437 #else
2438 weak_alias (__vfscanf, vfscanf)
2439 #endif