* sysdeps/m68k/dl-machine.h (_dl_start_user): Pass correct
[glibc.git] / stdio-common / vfscanf.c
blobcf3befd39998eada8a7fe03b52b6bc1a81fa95ea
1 /* Copyright (C) 1991-1999, 2000 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 (s->_vtable_offset == 0 && _IO_fwide (s, 1) != 1)\
91 return WEOF
92 # define __strtoll_internal __wcstoll_internal
93 # define __strtoull_internal __wcstoull_internal
94 # define __strtol_internal __wcstol_internal
95 # define __strtoul_internal __wcstoul_internal
96 # define __strtold_internal __wcstold_internal
97 # define __strtod_internal __wcstod_internal
98 # define __strtof_internal __wcstof_internal
100 # define L_(Str) L##Str
101 # define CHAR_T wchar_t
102 # define UCHAR_T unsigned int
103 # define WINT_T wint_t
104 # undef EOF
105 # define EOF WEOF
106 # else
107 # define ungetc(c, s) ((void) ((int) c == EOF \
108 || (--read_in, \
109 _IO_sputbackc (s, (unsigned char) c))))
110 # define ungetc_not_eof(c, s) ((void) (--read_in, \
111 _IO_sputbackc (s, (unsigned char) c)))
112 # define inchar() (c == EOF ? EOF \
113 : ((c = _IO_getc_unlocked (s)), \
114 (void) (c != EOF && ++read_in), c))
115 # define MEMCPY(d, s, n) memcpy (d, s, n)
116 # define ISSPACE(Ch) isspace (Ch)
117 # define ISDIGIT(Ch) isdigit (Ch)
118 # define ISXDIGIT(Ch) isxdigit (Ch)
119 # define TOLOWER(Ch) tolower (Ch)
120 # define ORIENT if (_IO_fwide (s, -1) != -1) return EOF
122 # define L_(Str) Str
123 # define CHAR_T char
124 # define UCHAR_T unsigned char
125 # define WINT_T int
126 # endif
128 # define encode_error() do { \
129 if (errp != NULL) *errp |= 4; \
130 _IO_funlockfile (s); \
131 __libc_cleanup_end (0); \
132 __set_errno (EILSEQ); \
133 return done; \
134 } while (0)
135 # define conv_error() do { \
136 if (errp != NULL) *errp |= 2; \
137 _IO_funlockfile (s); \
138 __libc_cleanup_end (0); \
139 return done; \
140 } while (0)
141 # define input_error() do { \
142 _IO_funlockfile (s); \
143 if (errp != NULL) *errp |= 1; \
144 __libc_cleanup_end (0); \
145 return done ?: EOF; \
146 } while (0)
147 # define memory_error() do { \
148 _IO_funlockfile (s); \
149 __set_errno (ENOMEM); \
150 __libc_cleanup_end (0); \
151 return EOF; \
152 } while (0)
153 # define ARGCHECK(s, format) \
154 do \
156 /* Check file argument for consistence. */ \
157 CHECK_FILE (s, EOF); \
158 if (s->_flags & _IO_NO_READS) \
160 __set_errno (EBADF); \
161 return EOF; \
163 else if (format == NULL) \
165 MAYBE_SET_EINVAL; \
166 return EOF; \
168 } while (0)
169 # define LOCK_STREAM(S) \
170 __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S)); \
171 _IO_flockfile (S)
172 # define UNLOCK_STREAM(S) \
173 _IO_funlockfile (S); \
174 __libc_cleanup_region_end (0)
175 #else
176 # define ungetc(c, s) ((void) (c != EOF && --read_in), ungetc (c, s))
177 # define ungetc_not_eof(c, s) (--read_in, (ungetc) (c, s))
178 # define inchar() (c == EOF ? EOF \
179 : ((c = getc (s)), (void) (c != EOF && ++read_in), c))
180 # define MEMCPY(d, s, n) memcpy (d, s, n)
181 # define ISSPACE(Ch) isspace (Ch)
182 # define ISDIGIT(Ch) isdigit (Ch)
183 # define ISXDIGIT(Ch) isxdigit (Ch)
184 # define TOLOWER(Ch) tolower (Ch)
186 # define L_(Str) Str
187 # define CHAR_T char
188 # define UCHAR_T unsigned char
189 # define WINT_T int
191 # define encode_error() do { \
192 funlockfile (s); \
193 __set_errno (EILSEQ); \
194 return done; \
195 } while (0)
196 # define conv_error() do { \
197 funlockfile (s); \
198 return done; \
199 } while (0)
200 # define input_error() do { \
201 funlockfile (s); \
202 return done ?: EOF; \
203 } while (0)
204 # define memory_error() do { \
205 funlockfile (s); \
206 __set_errno (ENOMEM); \
207 return EOF; \
208 } while (0)
209 # define ARGCHECK(s, format) \
210 do \
212 /* Check file argument for consistence. */ \
213 if (!__validfp (s) || !s->__mode.__read) \
215 __set_errno (EBADF); \
216 return EOF; \
218 else if (format == NULL) \
220 __set_errno (EINVAL); \
221 return EOF; \
223 } while (0)
224 #if 1
225 /* XXX For now !!! */
226 # define flockfile(S) /* nothing */
227 # define funlockfile(S) /* nothing */
228 # define LOCK_STREAM(S)
229 # define UNLOCK_STREAM(S)
230 #else
231 # define LOCK_STREAM(S) \
232 __libc_cleanup_region_start (&__funlockfile, (S)); \
233 __flockfile (S)
234 # define UNLOCK_STREAM(S) \
235 __funlockfile (S); \
236 __libc_cleanup_region_end (0)
237 #endif
238 #endif
241 /* Read formatted input from S according to the format string
242 FORMAT, using the argument list in ARG.
243 Return the number of assignments made, or -1 for an input error. */
244 #ifdef USE_IN_LIBIO
245 # ifdef COMPILE_WSCANF
247 _IO_vfwscanf (s, format, argptr, errp)
248 _IO_FILE *s;
249 const wchar_t *format;
250 _IO_va_list argptr;
251 int *errp;
252 # else
254 _IO_vfscanf (s, format, argptr, errp)
255 _IO_FILE *s;
256 const char *format;
257 _IO_va_list argptr;
258 int *errp;
259 # endif
260 #else
262 __vfscanf (FILE *s, const char *format, va_list argptr)
263 #endif
265 va_list arg;
266 register const CHAR_T *f = format;
267 register UCHAR_T fc; /* Current character of the format. */
268 register size_t done = 0; /* Assignments done. */
269 register size_t read_in = 0; /* Chars read in. */
270 register WINT_T c = 0; /* Last char read. */
271 register int width; /* Maximum field width. */
272 register int flags; /* Modifiers for current format element. */
274 /* Status for reading F-P nums. */
275 char got_dot, got_e, negative;
276 /* If a [...] is a [^...]. */
277 CHAR_T not_in;
278 #define exp_char not_in
279 /* Base for integral numbers. */
280 int base;
281 /* Signedness for integral numbers. */
282 int number_signed;
283 #define is_hexa number_signed
284 /* Decimal point character. */
285 #ifdef COMPILE_WSCANF
286 wchar_t decimal;
287 #else
288 const char *decimal;
289 #endif
290 /* The thousands character of the current locale. */
291 #ifdef COMPILE_WSCANF
292 wchar_t thousands;
293 #else
294 const char *thousands;
295 #endif
296 /* State for the conversions. */
297 mbstate_t state;
298 /* Integral holding variables. */
299 union
301 long long int q;
302 unsigned long long int uq;
303 long int l;
304 unsigned long int ul;
305 } num;
306 /* Character-buffer pointer. */
307 char *str = NULL;
308 wchar_t *wstr = NULL;
309 char **strptr = NULL;
310 size_t strsize = 0;
311 /* We must not react on white spaces immediately because they can
312 possibly be matched even if in the input stream no character is
313 available anymore. */
314 int skip_space = 0;
315 /* Nonzero if we are reading a pointer. */
316 int read_pointer;
317 /* Workspace. */
318 CHAR_T *tw; /* Temporary pointer. */
319 CHAR_T *wp = NULL; /* Workspace. */
320 size_t wpmax = 0; /* Maximal size of workspace. */
321 size_t wpsize; /* Currently used bytes in workspace. */
322 #define ADDW(Ch) \
323 do \
325 if (wpsize == wpmax) \
327 CHAR_T *old = wp; \
328 wpmax = (UCHAR_MAX + 1 > 2 * wpmax ? UCHAR_MAX + 1 : 2 * wpmax); \
329 wp = (CHAR_T *) alloca (wpmax * sizeof (wchar_t)); \
330 if (old != NULL) \
331 MEMCPY (wp, old, wpsize); \
333 wp[wpsize++] = (Ch); \
335 while (0)
337 #ifdef __va_copy
338 __va_copy (arg, argptr);
339 #else
340 arg = (va_list) argptr;
341 #endif
343 #ifdef ORIENT
344 ORIENT;
345 #endif
347 ARGCHECK (s, format);
349 /* Figure out the decimal point character. */
350 #ifdef COMPILE_WSCANF
351 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
352 #else
353 decimal = _NL_CURRENT (LC_NUMERIC, DECIMAL_POINT);
354 #endif
355 /* Figure out the thousands separator character. */
356 #ifdef COMPILE_WSCANF
357 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
358 #else
359 thousands = _NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP);
360 if (*thousands == '\0')
361 thousands = NULL;
362 #endif
364 /* Lock the stream. */
365 LOCK_STREAM (s);
368 #ifndef COMPILE_WSCANF
369 /* From now on we use `state' to convert the format string. */
370 memset (&state, '\0', sizeof (state));
371 #endif
373 /* Run through the format string. */
374 while (*f != '\0')
376 unsigned int argpos;
377 /* Extract the next argument, which is of type TYPE.
378 For a %N$... spec, this is the Nth argument from the beginning;
379 otherwise it is the next argument after the state now in ARG. */
380 #ifdef __va_copy
381 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
382 ({ unsigned int pos = argpos; \
383 va_list arg; \
384 __va_copy (arg, argptr); \
385 while (--pos > 0) \
386 (void) va_arg (arg, void *); \
387 va_arg (arg, type); \
389 #else
390 # if 0
391 /* XXX Possible optimization. */
392 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
393 ({ va_list arg = (va_list) argptr; \
394 arg = (va_list) ((char *) arg \
395 + (argpos - 1) \
396 * __va_rounded_size (void *)); \
397 va_arg (arg, type); \
399 # else
400 # define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
401 ({ unsigned int pos = argpos; \
402 va_list arg = (va_list) argptr; \
403 while (--pos > 0) \
404 (void) va_arg (arg, void *); \
405 va_arg (arg, type); \
407 # endif
408 #endif
410 #ifndef COMPILE_WSCANF
411 if (!isascii ((unsigned char) *f))
413 /* Non-ASCII, may be a multibyte. */
414 int len = __mbrlen (f, strlen (f), &state);
415 if (len > 0)
419 c = inchar ();
420 if (c == EOF)
421 input_error ();
422 else if (c != (unsigned char) *f++)
424 ungetc_not_eof (c, s);
425 conv_error ();
428 while (--len > 0);
429 continue;
432 #endif
434 fc = *f++;
435 if (fc != '%')
437 /* Remember to skip spaces. */
438 if (ISSPACE (fc))
440 skip_space = 1;
441 continue;
444 /* Read a character. */
445 c = inchar ();
447 /* Characters other than format specs must just match. */
448 if (c == EOF)
449 input_error ();
451 /* We saw white space char as the last character in the format
452 string. Now it's time to skip all leading white space. */
453 if (skip_space)
455 while (ISSPACE (c))
456 if (inchar () == EOF && errno == EINTR)
457 conv_error ();
458 skip_space = 0;
461 if (c != fc)
463 ungetc (c, s);
464 conv_error ();
467 continue;
470 /* This is the start of the conversion string. */
471 flags = 0;
473 /* Not yet decided whether we read a pointer or not. */
474 read_pointer = 0;
476 /* Initialize state of modifiers. */
477 argpos = 0;
479 /* Prepare temporary buffer. */
480 wpsize = 0;
482 /* Check for a positional parameter specification. */
483 if (ISDIGIT ((UCHAR_T) *f))
485 argpos = (UCHAR_T) *f++ - L_('0');
486 while (ISDIGIT ((UCHAR_T) *f))
487 argpos = argpos * 10 + ((UCHAR_T) *f++ - L_('0'));
488 if (*f == L_('$'))
489 ++f;
490 else
492 /* Oops; that was actually the field width. */
493 width = argpos;
494 flags |= WIDTH;
495 argpos = 0;
496 goto got_width;
500 /* Check for the assignment-suppressing, the number grouping flag,
501 and the signal to use the locale's digit representation. */
502 while (*f == L_('*') || *f == L_('\'') || *f == L_('I'))
503 switch (*f++)
505 case L_('*'):
506 flags |= SUPPRESS;
507 break;
508 case L_('\''):
509 flags |= GROUP;
510 break;
511 case L_('I'):
512 flags |= I18N;
513 break;
516 /* We have seen width. */
517 if (ISDIGIT ((UCHAR_T) *f))
518 flags |= WIDTH;
520 /* Find the maximum field width. */
521 width = 0;
522 while (ISDIGIT ((UCHAR_T) *f))
524 width *= 10;
525 width += (UCHAR_T) *f++ - L_('0');
527 got_width:
528 if (width == 0)
529 width = -1;
531 /* Check for type modifiers. */
532 switch (*f++)
534 case L_('h'):
535 /* ints are short ints or chars. */
536 if (*f == L_('h'))
538 ++f;
539 flags |= CHAR;
541 else
542 flags |= SHORT;
543 break;
544 case L_('l'):
545 if (*f == L_('l'))
547 /* A double `l' is equivalent to an `L'. */
548 ++f;
549 flags |= LONGDBL | LONG;
551 else
552 /* ints are long ints. */
553 flags |= LONG;
554 break;
555 case L_('q'):
556 case L_('L'):
557 /* doubles are long doubles, and ints are long long ints. */
558 flags |= LONGDBL | LONG;
559 break;
560 case L_('a'):
561 /* The `a' is used as a flag only if followed by `s', `S' or
562 `['. */
563 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
565 --f;
566 break;
568 /* String conversions (%s, %[) take a `char **'
569 arg and fill it in with a malloc'd pointer. */
570 flags |= MALLOC;
571 break;
572 case L_('z'):
573 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
574 flags |= LONGDBL;
575 else if (sizeof (size_t) > sizeof (unsigned int))
576 flags |= LONG;
577 break;
578 case L_('j'):
579 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
580 flags |= LONGDBL;
581 else if (sizeof (uintmax_t) > sizeof (unsigned int))
582 flags |= LONG;
583 break;
584 case L_('t'):
585 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
586 flags |= LONGDBL;
587 else if (sizeof (ptrdiff_t) > sizeof (int))
588 flags |= LONG;
589 break;
590 default:
591 /* Not a recognized modifier. Backup. */
592 --f;
593 break;
596 /* End of the format string? */
597 if (*f == L_('\0'))
598 conv_error ();
600 /* Find the conversion specifier. */
601 fc = *f++;
602 if (skip_space || (fc != L_('[') && fc != L_('c')
603 && fc != L_('C') && fc != L_('n')))
605 /* Eat whitespace. */
606 int save_errno = errno;
607 errno = 0;
609 if (inchar () == EOF && errno == EINTR)
610 input_error ();
611 while (ISSPACE (c));
612 errno = save_errno;
613 ungetc (c, s);
614 skip_space = 0;
617 switch (fc)
619 case L_('%'): /* Must match a literal '%'. */
620 c = inchar ();
621 if (c == EOF)
622 input_error ();
623 if (c != fc)
625 ungetc_not_eof (c, s);
626 conv_error ();
628 break;
630 case L_('n'): /* Answer number of assignments done. */
631 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
632 with the 'n' conversion specifier. */
633 if (!(flags & SUPPRESS))
635 /* Don't count the read-ahead. */
636 if (need_longlong && (flags & LONGDBL))
637 *ARG (long long int *) = read_in;
638 else if (need_long && (flags & LONG))
639 *ARG (long int *) = read_in;
640 else if (flags & SHORT)
641 *ARG (short int *) = read_in;
642 else if (!(flags & CHAR))
643 *ARG (int *) = read_in;
644 else
645 *ARG (char *) = read_in;
647 #ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
648 /* We have a severe problem here. The ISO C standard
649 contradicts itself in explaining the effect of the %n
650 format in `scanf'. While in ISO C:1990 and the ISO C
651 Amendement 1:1995 the result is described as
653 Execution of a %n directive does not effect the
654 assignment count returned at the completion of
655 execution of the f(w)scanf function.
657 in ISO C Corrigendum 1:1994 the following was added:
659 Subclause 7.9.6.2
660 Add the following fourth example:
662 #include <stdio.h>
663 int d1, d2, n1, n2, i;
664 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
665 the value 123 is assigned to d1 and the value3 to n1.
666 Because %n can never get an input failure the value
667 of 3 is also assigned to n2. The value of d2 is not
668 affected. The value 3 is assigned to i.
670 We go for now with the historically correct code from ISO C,
671 i.e., we don't count the %n assignments. When it ever
672 should proof to be wrong just remove the #ifdef above. */
673 ++done;
674 #endif
676 break;
678 case L_('c'): /* Match characters. */
679 if ((flags & LONG) == 0)
681 if (!(flags & SUPPRESS))
683 str = ARG (char *);
684 if (str == NULL)
685 conv_error ();
688 c = inchar ();
689 if (c == EOF)
690 input_error ();
692 if (width == -1)
693 width = 1;
695 #ifdef COMPILE_WSCANF
696 /* We have to convert the wide character(s) into multibyte
697 characters and store the result. */
698 memset (&state, '\0', sizeof (state));
702 size_t n;
704 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
705 if (n == (size_t) -1)
706 /* No valid wide character. */
707 input_error ();
709 /* Increment the output pointer. Even if we don't
710 write anything. */
711 str += n;
713 while (--width > 0 && inchar () != EOF);
714 #else
715 if (!(flags & SUPPRESS))
718 *str++ = c;
719 while (--width > 0 && inchar () != EOF);
721 else
722 while (--width > 0 && inchar () != EOF);
723 #endif
725 if (!(flags & SUPPRESS))
726 ++done;
728 break;
730 /* FALLTHROUGH */
731 case L_('C'):
732 if (!(flags & SUPPRESS))
734 wstr = ARG (wchar_t *);
735 if (wstr == NULL)
736 conv_error ();
739 c = inchar ();
740 if (c == EOF)
741 input_error ();
743 #ifdef COMPILE_WSCANF
744 /* Just store the incoming wide characters. */
745 if (!(flags & SUPPRESS))
748 *wstr++ = c;
749 while (--width > 0 && inchar () != EOF);
751 else
752 while (--width > 0 && inchar () != EOF);
753 #else
755 /* We have to convert the multibyte input sequence to wide
756 characters. */
757 char buf[MB_LEN_MAX];
758 mbstate_t cstate;
760 memset (&cstate, '\0', sizeof (cstate));
764 size_t cnt;
766 /* This is what we present the mbrtowc function first. */
767 buf[0] = c;
768 cnt = 1;
770 while (1)
772 size_t n;
774 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
775 buf, cnt, &cstate);
777 if (n == (size_t) -2)
779 /* Possibly correct character, just not enough
780 input. */
781 assert (cnt < MB_CUR_MAX);
783 if (inchar () == EOF)
784 encode_error ();
786 buf[cnt++] = c;
787 continue;
790 if (n != cnt)
791 encode_error ();
793 /* We have a match. */
794 break;
797 /* Advance the result pointer. */
798 ++wstr;
800 while (--width > 0 && inchar () != EOF);
802 #endif
804 if (!(flags & SUPPRESS))
805 ++done;
807 break;
809 case L_('s'): /* Read a string. */
810 if (!(flags & LONG))
812 #define STRING_ARG(Str, Type) \
813 do if (!(flags & SUPPRESS)) \
815 if (flags & MALLOC) \
817 /* The string is to be stored in a malloc'd buffer. */ \
818 strptr = ARG (char **); \
819 if (strptr == NULL) \
820 conv_error (); \
821 /* Allocate an initial buffer. */ \
822 strsize = 100; \
823 *strptr = (char *) malloc (strsize * sizeof (Type)); \
824 Str = (Type *) *strptr; \
826 else \
827 Str = ARG (Type *); \
828 if (Str == NULL) \
829 conv_error (); \
830 } while (0)
831 STRING_ARG (str, char);
833 c = inchar ();
834 if (c == EOF)
835 input_error ();
837 #ifdef COMPILE_WSCANF
838 memset (&state, '\0', sizeof (state));
839 #endif
843 if (ISSPACE (c))
845 ungetc_not_eof (c, s);
846 break;
849 #ifdef COMPILE_WSCANF
850 /* This is quite complicated. We have to convert the
851 wide characters into multibyte characters and then
852 store them. */
854 size_t n;
856 if (!(flags & SUPPRESS) && (flags & MALLOC)
857 && str + MB_CUR_MAX >= *strptr + strsize)
859 /* We have to enlarge the buffer if the `a' flag
860 was given. */
861 size_t strleng = str - *strptr;
862 char *newstr;
864 newstr = (char *) realloc (*strptr, strsize * 2);
865 if (newstr == NULL)
867 /* Can't allocate that much. Last-ditch
868 effort. */
869 newstr = (char *) realloc (*strptr,
870 strleng + MB_CUR_MAX);
871 if (newstr == NULL)
873 /* We lose. Oh well. Terminate the
874 string and stop converting,
875 so at least we don't skip any input. */
876 ((char *) (*strptr))[strleng] = '\0';
877 ++done;
878 conv_error ();
880 else
882 *strptr = newstr;
883 str = newstr + strleng;
884 strsize = strleng + MB_CUR_MAX;
887 else
889 *strptr = newstr;
890 str = newstr + strleng;
891 strsize *= 2;
895 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
896 &state);
897 if (n == (size_t) -1)
898 encode_error ();
900 assert (n <= MB_CUR_MAX);
901 str += n;
903 #else
904 /* This is easy. */
905 if (!(flags & SUPPRESS))
907 *str++ = c;
908 if ((flags & MALLOC)
909 && (char *) str == *strptr + strsize)
911 /* Enlarge the buffer. */
912 str = (char *) realloc (*strptr, 2 * strsize);
913 if (str == NULL)
915 /* Can't allocate that much. Last-ditch
916 effort. */
917 str = (char *) realloc (*strptr, strsize + 1);
918 if (str == NULL)
920 /* We lose. Oh well. Terminate the
921 string and stop converting,
922 so at least we don't skip any input. */
923 ((char *) (*strptr))[strsize - 1] = '\0';
924 ++done;
925 conv_error ();
927 else
929 *strptr = (char *) str;
930 str += strsize;
931 ++strsize;
934 else
936 *strptr = (char *) str;
937 str += strsize;
938 strsize *= 2;
942 #endif
944 while ((width <= 0 || --width > 0) && inchar () != EOF);
946 if (!(flags & SUPPRESS))
948 #ifdef COMPILE_WSCANF
949 /* We have to emit the code to get into the initial
950 state. */
951 char buf[MB_LEN_MAX];
952 size_t n = __wcrtomb (buf, L'\0', &state);
953 if (n > 0 && (flags & MALLOC)
954 && str + n >= *strptr + strsize)
956 /* Enlarge the buffer. */
957 size_t strleng = str - *strptr;
958 char *newstr;
960 newstr = (char *) realloc (*strptr, strleng + n + 1);
961 if (newstr == NULL)
963 /* We lose. Oh well. Terminate the string
964 and stop converting, so at least we don't
965 skip any input. */
966 ((char *) (*strptr))[strleng] = '\0';
967 ++done;
968 conv_error ();
970 else
972 *strptr = newstr;
973 str = newstr + strleng;
974 strsize = strleng + n + 1;
978 str = __mempcpy (str, buf, n);
979 #endif
980 *str++ = '\0';
982 if ((flags & MALLOC) && str - *strptr != strsize)
984 char *cp = (char *) realloc (*strptr, str - *strptr);
985 if (cp != NULL)
986 *strptr = cp;
989 ++done;
991 break;
993 /* FALLTHROUGH */
995 case L_('S'):
997 #ifndef COMPILE_WSCANF
998 mbstate_t cstate;
999 #endif
1001 /* Wide character string. */
1002 STRING_ARG (wstr, wchar_t);
1004 c = inchar ();
1005 if (c == EOF)
1006 input_error ();
1008 #ifndef COMPILE_WSCANF
1009 memset (&cstate, '\0', sizeof (cstate));
1010 #endif
1014 if (ISSPACE (c))
1016 ungetc_not_eof (c, s);
1017 break;
1020 #ifdef COMPILE_WSCANF
1021 /* This is easy. */
1022 if (!(flags & SUPPRESS))
1024 *wstr++ = c;
1025 if ((flags & MALLOC)
1026 && wstr == (wchar_t *) *strptr + strsize)
1028 /* Enlarge the buffer. */
1029 wstr = (wchar_t *) realloc (*strptr,
1030 (2 * strsize)
1031 * sizeof (wchar_t));
1032 if (wstr == NULL)
1034 /* Can't allocate that much. Last-ditch
1035 effort. */
1036 wstr = (wchar_t *) realloc (*strptr,
1037 (strsize + 1)
1038 * sizeof (wchar_t));
1039 if (wstr == NULL)
1041 /* We lose. Oh well. Terminate the string
1042 and stop converting, so at least we don't
1043 skip any input. */
1044 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1045 ++done;
1046 conv_error ();
1048 else
1050 *strptr = (char *) wstr;
1051 wstr += strsize;
1052 ++strsize;
1055 else
1057 *strptr = (char *) wstr;
1058 wstr += strsize;
1059 strsize *= 2;
1063 #else
1065 char buf[MB_LEN_MAX];
1066 size_t cnt;
1068 buf[0] = c;
1069 cnt = 1;
1071 while (1)
1073 size_t n;
1075 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
1076 buf, cnt, &cstate);
1078 if (n == (size_t) -2)
1080 /* Possibly correct character, just not enough
1081 input. */
1082 assert (cnt < MB_CUR_MAX);
1084 if (inchar () == EOF)
1085 encode_error ();
1087 buf[cnt++] = c;
1088 continue;
1091 if (n != cnt)
1092 encode_error ();
1094 /* We have a match. */
1095 break;
1098 if (!(flags & SUPPRESS) && (flags & MALLOC)
1099 && wstr == (wchar_t *) *strptr + strsize)
1101 /* Enlarge the buffer. */
1102 wstr = (wchar_t *) realloc (*strptr,
1103 (2 * strsize
1104 * sizeof (wchar_t)));
1105 if (wstr == NULL)
1107 /* Can't allocate that much. Last-ditch effort. */
1108 wstr = (wchar_t *) realloc (*strptr,
1109 ((strsize + 1)
1110 * sizeof (wchar_t)));
1111 if (wstr == NULL)
1113 /* We lose. Oh well. Terminate the
1114 string and stop converting, so at
1115 least we don't skip any input. */
1116 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
1117 ++done;
1118 conv_error ();
1120 else
1122 *strptr = (char *) wstr;
1123 wstr += strsize;
1124 ++strsize;
1127 else
1129 *strptr = (char *) wstr;
1130 wstr += strsize;
1131 strsize *= 2;
1135 #endif
1137 while ((width <= 0 || --width > 0) && inchar () != EOF);
1139 if (!(flags & SUPPRESS))
1141 *wstr++ = L'\0';
1143 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1145 wchar_t *cp = (wchar_t *) realloc (*strptr,
1146 ((wstr
1147 - (wchar_t *) *strptr)
1148 * sizeof(wchar_t)));
1149 if (cp != NULL)
1150 *strptr = (char *) cp;
1153 ++done;
1156 break;
1158 case L_('x'): /* Hexadecimal integer. */
1159 case L_('X'): /* Ditto. */
1160 base = 16;
1161 number_signed = 0;
1162 goto number;
1164 case L_('o'): /* Octal integer. */
1165 base = 8;
1166 number_signed = 0;
1167 goto number;
1169 case L_('u'): /* Unsigned decimal integer. */
1170 base = 10;
1171 number_signed = 0;
1172 goto number;
1174 case L_('d'): /* Signed decimal integer. */
1175 base = 10;
1176 number_signed = 1;
1177 goto number;
1179 case L_('i'): /* Generic number. */
1180 base = 0;
1181 number_signed = 1;
1183 number:
1184 c = inchar ();
1185 if (c == EOF)
1186 input_error ();
1188 /* Check for a sign. */
1189 if (c == L_('-') || c == L_('+'))
1191 ADDW (c);
1192 if (width > 0)
1193 --width;
1194 c = inchar ();
1197 /* Look for a leading indication of base. */
1198 if (width != 0 && c == L_('0'))
1200 if (width > 0)
1201 --width;
1203 ADDW (c);
1204 c = inchar ();
1206 if (width != 0 && TOLOWER (c) == L_('x'))
1208 if (base == 0)
1209 base = 16;
1210 if (base == 16)
1212 if (width > 0)
1213 --width;
1214 c = inchar ();
1217 else if (base == 0)
1218 base = 8;
1221 if (base == 0)
1222 base = 10;
1224 if (base == 10 && (flags & I18N) != 0)
1226 int from_level;
1227 int to_level;
1228 int level;
1229 #ifdef COMPILE_WSCANF
1230 const wchar_t *wcdigits[10];
1231 #else
1232 const char *mbdigits[10];
1233 #endif
1234 int n;
1236 from_level = 0;
1237 #ifdef COMPILE_WSCANF
1238 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1239 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1240 #else
1241 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1242 _NL_CTYPE_INDIGITS_MB_LEN) - 1;
1243 #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 wcdigits[n] = (const wchar_t *)
1255 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
1256 wcdigits[n] += from_level;
1258 if (c == *wcdigits[n])
1260 to_level = from_level;
1261 break;
1264 /* Advance the pointer to the next string. */
1265 ++wcdigits[n];
1266 #else
1267 const char *cmpp;
1268 int avail = width > 0 ? width : INT_MAX;
1270 mbdigits[n] = _NL_CURRENT (LC_CTYPE,
1271 _NL_CTYPE_INDIGITS0_MB + n);
1273 for (level = 0; level < from_level; level++)
1274 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1276 cmpp = mbdigits[n];
1277 while ((unsigned char) *cmpp == c && avail > 0)
1279 if (*++cmpp == '\0')
1280 break;
1281 else
1283 if ((c = inchar ()) == EOF)
1284 break;
1285 --avail;
1289 if (*cmpp == '\0')
1291 if (width > 0)
1292 width = avail;
1293 to_level = from_level;
1294 break;
1297 /* We are pushing all read characters back. */
1298 if (cmpp > mbdigits[n])
1300 ungetc (c, s);
1301 while (--cmpp > mbdigits[n])
1302 ungetc_not_eof ((unsigned char) *cmpp, s);
1303 c = (unsigned char) *cmpp;
1306 /* Advance the pointer to the next string. */
1307 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1308 #endif
1311 if (n == 10)
1313 /* Have not yet found the digit. */
1314 for (level = from_level + 1; level <= to_level; ++level)
1316 /* Search all ten digits of this level. */
1317 for (n = 0; n < 10; ++n)
1319 #ifdef COMPILE_WSCANF
1320 if (c == *wcdigits[n])
1321 break;
1323 /* Advance the pointer to the next string. */
1324 ++wcdigits[n];
1325 #else
1326 const char *cmpp;
1327 int avail = width > 0 ? width : INT_MAX;
1329 cmpp = mbdigits[n];
1330 while ((unsigned char) *cmpp == c && avail > 0)
1332 if (*++cmpp == '\0')
1333 break;
1334 else
1336 if ((c = inchar ()) == EOF)
1337 break;
1338 --avail;
1342 if (*cmpp == '\0')
1344 if (width > 0)
1345 width = avail;
1346 break;
1349 /* We are pushing all read characters back. */
1350 if (cmpp > mbdigits[n])
1352 ungetc (c, s);
1353 while (--cmpp > mbdigits[n])
1354 ungetc_not_eof ((unsigned char) *cmpp, s);
1355 c = (unsigned char) *cmpp;
1358 /* Advance the pointer to the next string. */
1359 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1360 #endif
1363 if (n < 10)
1365 /* Found it. */
1366 from_level = level;
1367 to_level = level;
1368 break;
1373 if (n < 10)
1374 c = L_('0') + n;
1375 else if ((flags & GROUP)
1376 #ifdef COMPILE_WSCANF
1377 && thousands != L'\0'
1378 #else
1379 && thousands != NULL
1380 #endif
1383 /* Try matching against the thousands separator. */
1384 #ifdef COMPILE_WSCANF
1385 if (c != thousands)
1386 break;
1387 #else
1388 const char *cmpp = thousands;
1389 int avail = width > 0 ? width : INT_MAX;
1391 while ((unsigned char) *cmpp == c && avail > 0)
1393 ADDW (c);
1394 if (*++cmpp == '\0')
1395 break;
1396 else
1398 if ((c = inchar ()) == EOF)
1399 break;
1400 --avail;
1404 if (*cmpp != '\0')
1406 /* We are pushing all read characters back. */
1407 if (cmpp > thousands)
1409 wpsize -= cmpp - thousands;
1410 ungetc (c, s);
1411 while (--cmpp > thousands)
1412 ungetc_not_eof ((unsigned char) *cmpp, s);
1413 c = (unsigned char) *cmpp;
1415 break;
1418 if (width > 0)
1419 width = avail;
1421 /* The last thousands character will be added back by
1422 the ADDW below. */
1423 --wpsize;
1424 #endif
1426 else
1427 break;
1429 ADDW (c);
1430 if (width > 0)
1431 --width;
1433 c = inchar ();
1436 else
1437 /* Read the number into workspace. */
1438 while (c != EOF && width != 0)
1440 if (base == 16)
1442 if (!ISXDIGIT (c))
1443 break;
1445 else if (!ISDIGIT (c) || c - L_('0') >= base)
1447 if (base == 10 && (flags & GROUP)
1448 #ifdef COMPILE_WSCANF
1449 && thousands != L'\0'
1450 #else
1451 && thousands != NULL
1452 #endif
1455 /* Try matching against the thousands separator. */
1456 #ifdef COMPILE_WSCANF
1457 if (c != thousands)
1458 break;
1459 #else
1460 const char *cmpp = thousands;
1461 int avail = width > 0 ? width : INT_MAX;
1463 while ((unsigned char) *cmpp == c && avail > 0)
1465 ADDW (c);
1466 if (*++cmpp == '\0')
1467 break;
1468 else
1470 if ((c = inchar ()) == EOF)
1471 break;
1472 --avail;
1476 if (*cmpp != '\0')
1478 /* We are pushing all read characters back. */
1479 if (cmpp > thousands)
1481 wpsize -= cmpp - thousands;
1482 ungetc (c, s);
1483 while (--cmpp > thousands)
1484 ungetc_not_eof ((unsigned char) *cmpp, s);
1485 c = (unsigned char) *cmpp;
1487 break;
1490 if (width > 0)
1491 width = avail;
1493 /* The last thousands character will be added back by
1494 the ADDW below. */
1495 --wpsize;
1496 #endif
1498 else
1499 break;
1501 ADDW (c);
1502 if (width > 0)
1503 --width;
1505 c = inchar ();
1508 if (wpsize == 0
1509 || (wpsize == 1 && (wp[0] == L_('+') || wp[0] == L_('-'))))
1511 /* There was no number. If we are supposed to read a pointer
1512 we must recognize "(nil)" as well. */
1513 if (wpsize == 0 && read_pointer && (width < 0 || width >= 0)
1514 && c == '('
1515 && TOLOWER (inchar ()) == L_('n')
1516 && TOLOWER (inchar ()) == L_('i')
1517 && TOLOWER (inchar ()) == L_('l')
1518 && inchar () == L_(')'))
1519 /* We must produce the value of a NULL pointer. A single
1520 '0' digit is enough. */
1521 ADDW (L_('0'));
1522 else
1524 /* The last read character is not part of the number
1525 anymore. */
1526 ungetc (c, s);
1528 conv_error ();
1531 else
1532 /* The just read character is not part of the number anymore. */
1533 ungetc (c, s);
1535 /* Convert the number. */
1536 ADDW (L_('\0'));
1537 if (need_longlong && (flags & LONGDBL))
1539 if (number_signed)
1540 num.q = __strtoll_internal (wp, &tw, base, flags & GROUP);
1541 else
1542 num.uq = __strtoull_internal (wp, &tw, base, flags & GROUP);
1544 else
1546 if (number_signed)
1547 num.l = __strtol_internal (wp, &tw, base, flags & GROUP);
1548 else
1549 num.ul = __strtoul_internal (wp, &tw, base, flags & GROUP);
1551 if (wp == tw)
1552 conv_error ();
1554 if (!(flags & SUPPRESS))
1556 if (! number_signed)
1558 if (need_longlong && (flags & LONGDBL))
1559 *ARG (unsigned LONGLONG int *) = num.uq;
1560 else if (need_long && (flags & LONG))
1561 *ARG (unsigned long int *) = num.ul;
1562 else if (flags & SHORT)
1563 *ARG (unsigned short int *)
1564 = (unsigned short int) num.ul;
1565 else if (!(flags & CHAR))
1566 *ARG (unsigned int *) = (unsigned int) num.ul;
1567 else
1568 *ARG (unsigned char *) = (unsigned char) num.ul;
1570 else
1572 if (need_longlong && (flags & LONGDBL))
1573 *ARG (LONGLONG int *) = num.q;
1574 else if (need_long && (flags & LONG))
1575 *ARG (long int *) = num.l;
1576 else if (flags & SHORT)
1577 *ARG (short int *) = (short int) num.l;
1578 else if (!(flags & CHAR))
1579 *ARG (int *) = (int) num.l;
1580 else
1581 *ARG (signed char *) = (signed char) num.ul;
1583 ++done;
1585 break;
1587 case L_('e'): /* Floating-point numbers. */
1588 case L_('E'):
1589 case L_('f'):
1590 case L_('F'):
1591 case L_('g'):
1592 case L_('G'):
1593 case L_('a'):
1594 case L_('A'):
1595 c = inchar ();
1596 if (c == EOF)
1597 input_error ();
1599 /* Check for a sign. */
1600 if (c == L_('-') || c == L_('+'))
1602 negative = c == L_('-');
1603 if (width == 0 || inchar () == EOF)
1604 /* EOF is only an input error before we read any chars. */
1605 conv_error ();
1606 if (! ISDIGIT (c))
1608 #ifdef COMPILE_WSCANF
1609 if (c != decimal)
1611 /* This is no valid number. */
1612 ungetc (c, s);
1613 conv_error ();
1615 #else
1616 /* Match against the decimal point. At this point
1617 we are taking advantage of the fact that we can
1618 push more than one character back. This is
1619 (almost) never necessary since the decimal point
1620 string hopefully never contains more than one
1621 byte. */
1622 const char *cmpp = decimal;
1623 int avail = width > 0 ? width : INT_MAX;
1625 while ((unsigned char) *cmpp == c && avail > 0)
1626 if (*++cmpp == '\0')
1627 break;
1628 else
1630 if (inchar () == EOF)
1631 break;
1632 --avail;
1635 if (*cmpp != '\0')
1637 /* This is no valid number. */
1638 while (1)
1640 ungetc (c, s);
1641 if (cmpp == decimal)
1642 break;
1643 c = (unsigned char) *--cmpp;
1646 conv_error ();
1648 if (width > 0)
1649 width = avail;
1650 #endif
1652 if (width > 0)
1653 --width;
1655 else
1656 negative = 0;
1658 /* Take care for the special arguments "nan" and "inf". */
1659 if (TOLOWER (c) == L_('n'))
1661 /* Maybe "nan". */
1662 ADDW (c);
1663 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('a'))
1664 input_error ();
1665 if (width > 0)
1666 --width;
1667 ADDW (c);
1668 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1669 input_error ();
1670 if (width > 0)
1671 --width;
1672 ADDW (c);
1673 /* It is "nan". */
1674 goto scan_float;
1676 else if (TOLOWER (c) == L_('i'))
1678 /* Maybe "inf" or "infinity". */
1679 ADDW (c);
1680 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('n'))
1681 input_error ();
1682 if (width > 0)
1683 --width;
1684 ADDW (c);
1685 if (width == 0 || inchar () == EOF || TOLOWER (c) != L_('f'))
1686 input_error ();
1687 if (width > 0)
1688 --width;
1689 ADDW (c);
1690 /* It is as least "inf". */
1691 if (width != 0 && inchar () != EOF)
1693 if (TOLOWER (c) == L_('i'))
1695 if (width > 0)
1696 --width;
1697 /* Now we have to read the rest as well. */
1698 ADDW (c);
1699 if (width == 0 || inchar () == EOF
1700 || TOLOWER (c) != L_('n'))
1701 input_error ();
1702 if (width > 0)
1703 --width;
1704 ADDW (c);
1705 if (width == 0 || inchar () == EOF
1706 || TOLOWER (c) != L_('i'))
1707 input_error ();
1708 if (width > 0)
1709 --width;
1710 ADDW (c);
1711 if (width == 0 || inchar () == EOF
1712 || TOLOWER (c) != L_('t'))
1713 input_error ();
1714 if (width > 0)
1715 --width;
1716 ADDW (c);
1717 if (width == 0 || inchar () == EOF
1718 || TOLOWER (c) != L_('y'))
1719 input_error ();
1720 if (width > 0)
1721 --width;
1722 ADDW (c);
1724 else
1725 /* Never mind. */
1726 ungetc (c, s);
1728 goto scan_float;
1731 is_hexa = 0;
1732 exp_char = L_('e');
1733 if (width != 0 && c == L_('0'))
1735 ADDW (c);
1736 c = inchar ();
1737 if (width > 0)
1738 --width;
1739 if (width != 0 && TOLOWER (c) == L_('x'))
1741 /* It is a number in hexadecimal format. */
1742 ADDW (c);
1744 is_hexa = 1;
1745 exp_char = L_('p');
1747 /* Grouping is not allowed. */
1748 flags &= ~GROUP;
1749 c = inchar ();
1750 if (width > 0)
1751 --width;
1755 got_dot = got_e = 0;
1758 if (ISDIGIT (c))
1759 ADDW (c);
1760 else if (!got_e && is_hexa && ISXDIGIT (c))
1761 ADDW (c);
1762 else if (got_e && wp[wpsize - 1] == exp_char
1763 && (c == L_('-') || c == L_('+')))
1764 ADDW (c);
1765 else if (wpsize > 0 && !got_e && TOLOWER (c) == exp_char)
1767 ADDW (exp_char);
1768 got_e = got_dot = 1;
1770 else
1772 #ifdef COMPILE_WSCANF
1773 if (! got_dot && c == decimal)
1775 ADDW (c);
1776 got_dot = 1;
1778 else if (thousands != L'\0' && ! got_dot && c == thousands)
1779 ADDW (c);
1780 else
1782 /* The last read character is not part of the number
1783 anymore. */
1784 ungetc (c, s);
1785 break;
1787 #else
1788 const char *cmpp = decimal;
1789 int avail = width > 0 ? width : INT_MAX;
1791 if (! got_dot)
1793 while ((unsigned char) *cmpp == c && avail > 0)
1794 if (*++cmpp == '\0')
1795 break;
1796 else
1798 if (inchar () == EOF)
1799 break;
1800 --avail;
1804 if (*cmpp == '\0')
1806 /* Add all the characters. */
1807 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
1808 ADDW ((unsigned char) *cmpp);
1809 if (width > 0)
1810 width = avail;
1811 got_dot = 1;
1813 else
1815 /* Figure out whether it is a thousands separator.
1816 There is one problem: we possibly read more than
1817 one character. We cannot push them back but since
1818 we know that parts of the `decimal' string matched,
1819 we can compare against it. */
1820 const char *cmp2p = thousands;
1822 if (thousands != NULL && ! got_dot)
1824 while (cmp2p < cmpp
1825 && *cmp2p == decimal[cmp2p - thousands])
1826 ++cmp2p;
1827 if (cmp2p == cmpp)
1829 while ((unsigned char) *cmp2p == c && avail > 0)
1830 if (*++cmp2p == '\0')
1831 break;
1832 else
1834 if (inchar () == EOF)
1835 break;
1836 --avail;
1841 if (cmp2p != NULL && *cmp2p == '\0')
1843 /* Add all the characters. */
1844 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
1845 ADDW ((unsigned char) *cmpp);
1846 if (width > 0)
1847 width = avail;
1849 else
1851 /* The last read character is not part of the number
1852 anymore. */
1853 ungetc (c, s);
1854 break;
1857 #endif
1859 if (width > 0)
1860 --width;
1862 while (width != 0 && inchar () != EOF);
1864 /* Have we read any character? If we try to read a number
1865 in hexadecimal notation and we have read only the `0x'
1866 prefix or no exponent this is an error. */
1867 if (wpsize == 0 || (is_hexa && (wpsize == 2 || ! got_e)))
1868 conv_error ();
1870 scan_float:
1871 /* Convert the number. */
1872 ADDW (L_('\0'));
1873 if (flags & LONGDBL)
1875 long double d = __strtold_internal (wp, &tw, flags & GROUP);
1876 if (!(flags & SUPPRESS) && tw != wp)
1877 *ARG (long double *) = negative ? -d : d;
1879 else if (flags & LONG)
1881 double d = __strtod_internal (wp, &tw, flags & GROUP);
1882 if (!(flags & SUPPRESS) && tw != wp)
1883 *ARG (double *) = negative ? -d : d;
1885 else
1887 float d = __strtof_internal (wp, &tw, flags & GROUP);
1888 if (!(flags & SUPPRESS) && tw != wp)
1889 *ARG (float *) = negative ? -d : d;
1892 if (tw == wp)
1893 conv_error ();
1895 if (!(flags & SUPPRESS))
1896 ++done;
1897 break;
1899 case L_('['): /* Character class. */
1900 if (flags & LONG)
1901 STRING_ARG (wstr, wchar_t);
1902 else
1903 STRING_ARG (str, char);
1905 if (*f == L_('^'))
1907 ++f;
1908 not_in = 1;
1910 else
1911 not_in = 0;
1913 if (width < 0)
1914 /* There is no width given so there is also no limit on the
1915 number of characters we read. Therefore we set width to
1916 a very high value to make the algorithm easier. */
1917 width = INT_MAX;
1919 #ifdef COMPILE_WSCANF
1920 /* Find the beginning and the end of the scanlist. We are not
1921 creating a lookup table since it would have to be too large.
1922 Instead we search each time through the string. This is not
1923 a constant lookup time but who uses this feature deserves to
1924 be punished. */
1925 tw = (wchar_t *) f; /* Marks the beginning. */
1927 if (*f == ']' || *f == '-')
1928 ++f;
1930 while ((fc = *f++) != L'\0' && fc != L']');
1932 if (fc == L'\0')
1933 conv_error ();
1934 wp = (wchar_t *) f - 1;
1935 #else
1936 /* Fill WP with byte flags indexed by character.
1937 We will use this flag map for matching input characters. */
1938 if (wpmax < UCHAR_MAX + 1)
1940 wpmax = UCHAR_MAX + 1;
1941 wp = (char *) alloca (wpmax);
1943 memset (wp, '\0', UCHAR_MAX + 1);
1945 fc = *f;
1946 if (fc == ']' || fc == '-')
1948 /* If ] or - appears before any char in the set, it is not
1949 the terminator or separator, but the first char in the
1950 set. */
1951 wp[fc] = 1;
1952 ++f;
1955 while ((fc = *f++) != '\0' && fc != ']')
1956 if (fc == '-' && *f != '\0' && *f != ']'
1957 && (unsigned char) f[-2] <= (unsigned char) *f)
1959 /* Add all characters from the one before the '-'
1960 up to (but not including) the next format char. */
1961 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
1962 wp[fc] = 1;
1964 else
1965 /* Add the character to the flag map. */
1966 wp[fc] = 1;
1968 if (fc == '\0')
1969 conv_error();
1970 #endif
1972 if (flags & LONG)
1974 size_t now = read_in;
1975 #ifdef COMPILE_WSCANF
1976 if (inchar () == WEOF)
1977 input_error ();
1981 wchar_t *runp;
1983 /* Test whether it's in the scanlist. */
1984 runp = tw;
1985 while (runp < wp)
1987 if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']'
1988 && runp != tw
1989 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
1991 /* Match against all characters in between the
1992 first and last character of the sequence. */
1993 wchar_t wc;
1995 for (wc = runp[-1] + 1; wc < runp[1]; ++wc)
1996 if (wc == c)
1997 break;
1999 if (wc == runp[1] && !not_in)
2000 break;
2001 if (wc == runp[1] && not_in)
2003 /* The current character is not in the
2004 scanset. */
2005 ungetwc (c, s);
2006 goto out;
2009 else
2011 if (*runp == runp[1] && !not_in)
2012 break;
2013 if (*runp != runp[1] && not_in)
2015 ungetwc (c ,s);
2016 goto out;
2020 ++runp;
2023 if (!(flags & SUPPRESS))
2025 *wstr++ = c;
2027 if ((flags & MALLOC)
2028 && wstr == (wchar_t *) *strptr + strsize)
2030 /* Enlarge the buffer. */
2031 wstr = (wchar_t *) realloc (*strptr,
2032 (2 * strsize)
2033 * sizeof (wchar_t));
2034 if (wstr == NULL)
2036 /* Can't allocate that much. Last-ditch
2037 effort. */
2038 wstr = (wchar_t *)
2039 realloc (*strptr, (strsize + 1)
2040 * sizeof (wchar_t));
2041 if (wstr == NULL)
2043 /* We lose. Oh well. Terminate the string
2044 and stop converting, so at least we don't
2045 skip any input. */
2046 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2047 ++done;
2048 conv_error ();
2050 else
2052 *strptr = (char *) wstr;
2053 wstr += strsize;
2054 ++strsize;
2057 else
2059 *strptr = (char *) wstr;
2060 wstr += strsize;
2061 strsize *= 2;
2066 while (--width > 0 && inchar () != WEOF);
2067 out:
2068 #else
2069 char buf[MB_LEN_MAX];
2070 size_t cnt = 0;
2071 mbstate_t cstate;
2073 if (inchar () == EOF)
2074 input_error ();
2076 memset (&cstate, '\0', sizeof (cstate));
2080 if (wp[c] == not_in)
2082 ungetc_not_eof (c, s);
2083 break;
2086 /* This is easy. */
2087 if (!(flags & SUPPRESS))
2089 size_t n;
2091 /* Convert it into a wide character. */
2092 n = __mbrtowc (wstr, buf, cnt, &cstate);
2094 if (n == (size_t) -2)
2096 /* Possibly correct character, just not enough
2097 input. */
2098 assert (cnt < MB_CUR_MAX);
2099 continue;
2102 if (n != cnt)
2103 encode_error ();
2105 ++wstr;
2106 if ((flags & MALLOC)
2107 && wstr == (wchar_t *) *strptr + strsize)
2109 /* Enlarge the buffer. */
2110 wstr = (wchar_t *) realloc (*strptr,
2111 (2 * strsize
2112 * sizeof (wchar_t)));
2113 if (wstr == NULL)
2115 /* Can't allocate that much. Last-ditch
2116 effort. */
2117 wstr = (wchar_t *)
2118 realloc (*strptr, ((strsize + 1)
2119 * sizeof (wchar_t)));
2120 if (wstr == NULL)
2122 /* We lose. Oh well. Terminate the
2123 string and stop converting,
2124 so at least we don't skip any input. */
2125 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
2126 ++done;
2127 conv_error ();
2129 else
2131 *strptr = (char *) wstr;
2132 wstr += strsize;
2133 ++strsize;
2136 else
2138 *strptr = (char *) wstr;
2139 wstr += strsize;
2140 strsize *= 2;
2145 if (--width <= 0)
2146 break;
2148 while (inchar () != EOF);
2150 if (cnt != 0)
2151 /* We stopped in the middle of recognizing another
2152 character. That's a problem. */
2153 encode_error ();
2154 #endif
2156 if (now == read_in)
2157 /* We haven't succesfully read any character. */
2158 conv_error ();
2160 if (!(flags & SUPPRESS))
2162 *wstr++ = L'\0';
2164 if ((flags & MALLOC)
2165 && wstr - (wchar_t *) *strptr != strsize)
2167 wchar_t *cp = (wchar_t *)
2168 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2169 * sizeof(wchar_t)));
2170 if (cp != NULL)
2171 *strptr = (char *) cp;
2174 ++done;
2177 else
2179 size_t now = read_in;
2181 if (inchar () == EOF)
2182 input_error ();
2184 #ifdef COMPILE_WSCANF
2186 memset (&state, '\0', sizeof (state));
2190 wchar_t *runp;
2191 size_t n;
2193 /* Test whether it's in the scanlist. */
2194 runp = tw;
2195 while (runp < wp)
2197 if (runp[0] == L'-' && runp[1] != '\0' && runp[1] != ']'
2198 && runp != tw
2199 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2201 /* Match against all characters in between the
2202 first and last character of the sequence. */
2203 wchar_t wc;
2205 for (wc = runp[-1] + 1; wc < runp[1]; ++wc)
2206 if (wc == c)
2207 break;
2209 if (wc == runp[1] && !not_in)
2210 break;
2211 if (wc == runp[1] && not_in)
2213 /* The current character is not in the
2214 scanset. */
2215 ungetwc (c, s);
2216 goto out2;
2219 else
2221 if (*runp == runp[1] && !not_in)
2222 break;
2223 if (*runp != runp[1] && not_in)
2225 ungetwc (c ,s);
2226 goto out2;
2230 ++runp;
2233 if (!(flags & SUPPRESS))
2235 if ((flags & MALLOC)
2236 && str + MB_CUR_MAX >= *strptr + strsize)
2238 /* Enlarge the buffer. */
2239 size_t strleng = str - *strptr;
2240 char *newstr;
2242 newstr = (char *) realloc (*strptr, 2 * strsize);
2243 if (newstr == NULL)
2245 /* Can't allocate that much. Last-ditch
2246 effort. */
2247 newstr = (char *) realloc (*strptr,
2248 strleng + MB_CUR_MAX);
2249 if (newstr == NULL)
2251 /* We lose. Oh well. Terminate the string
2252 and stop converting, so at least we don't
2253 skip any input. */
2254 ((char *) (*strptr))[strleng] = '\0';
2255 ++done;
2256 conv_error ();
2258 else
2260 *strptr = newstr;
2261 str = newstr + strleng;
2262 strsize = strleng + MB_CUR_MAX;
2265 else
2267 *strptr = newstr;
2268 str = newstr + strleng;
2269 strsize *= 2;
2274 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
2275 if (n == (size_t) -1)
2276 encode_error ();
2278 assert (n <= MB_CUR_MAX);
2279 str += n;
2281 while (--width > 0 && inchar () != WEOF);
2282 out2:
2283 #else
2286 if (wp[c] == not_in)
2288 ungetc_not_eof (c, s);
2289 break;
2292 /* This is easy. */
2293 if (!(flags & SUPPRESS))
2295 *str++ = c;
2296 if ((flags & MALLOC)
2297 && (char *) str == *strptr + strsize)
2299 /* Enlarge the buffer. */
2300 str = (char *) realloc (*strptr, 2 * strsize);
2301 if (str == NULL)
2303 /* Can't allocate that much. Last-ditch
2304 effort. */
2305 str = (char *) realloc (*strptr, strsize + 1);
2306 if (str == NULL)
2308 /* We lose. Oh well. Terminate the
2309 string and stop converting,
2310 so at least we don't skip any input. */
2311 ((char *) (*strptr))[strsize - 1] = '\0';
2312 ++done;
2313 conv_error ();
2315 else
2317 *strptr = (char *) str;
2318 str += strsize;
2319 ++strsize;
2322 else
2324 *strptr = (char *) str;
2325 str += strsize;
2326 strsize *= 2;
2331 while (--width > 0 && inchar () != EOF);
2332 #endif
2334 if (now == read_in)
2335 /* We haven't succesfully read any character. */
2336 conv_error ();
2338 if (!(flags & SUPPRESS))
2340 #ifdef COMPILE_WSCANF
2341 /* We have to emit the code to get into the initial
2342 state. */
2343 char buf[MB_LEN_MAX];
2344 size_t n = __wcrtomb (buf, L'\0', &state);
2345 if (n > 0 && (flags & MALLOC)
2346 && str + n >= *strptr + strsize)
2348 /* Enlarge the buffer. */
2349 size_t strleng = str - *strptr;
2350 char *newstr;
2352 newstr = (char *) realloc (*strptr, strleng + n + 1);
2353 if (newstr == NULL)
2355 /* We lose. Oh well. Terminate the string
2356 and stop converting, so at least we don't
2357 skip any input. */
2358 ((char *) (*strptr))[strleng] = '\0';
2359 ++done;
2360 conv_error ();
2362 else
2364 *strptr = newstr;
2365 str = newstr + strleng;
2366 strsize = strleng + n + 1;
2370 str = __mempcpy (str, buf, n);
2371 #endif
2372 *str++ = '\0';
2374 if ((flags & MALLOC) && str - *strptr != strsize)
2376 char *cp = (char *) realloc (*strptr, str - *strptr);
2377 if (cp != NULL)
2378 *strptr = cp;
2381 ++done;
2384 break;
2386 case L_('p'): /* Generic pointer. */
2387 base = 16;
2388 /* A PTR must be the same size as a `long int'. */
2389 flags &= ~(SHORT|LONGDBL);
2390 if (need_long)
2391 flags |= LONG;
2392 number_signed = 0;
2393 read_pointer = 1;
2394 goto number;
2396 default:
2397 /* If this is an unknown format character punt. */
2398 conv_error ();
2402 /* The last thing we saw int the format string was a white space.
2403 Consume the last white spaces. */
2404 if (skip_space)
2407 c = inchar ();
2408 while (ISSPACE (c));
2409 ungetc (c, s);
2412 /* Unlock stream. */
2413 UNLOCK_STREAM (s);
2415 return done;
2418 #ifdef USE_IN_LIBIO
2419 # ifdef COMPILE_WSCANF
2421 __vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
2423 return _IO_vfwscanf (s, format, argptr, NULL);
2425 # else
2427 __vfscanf (FILE *s, const char *format, va_list argptr)
2429 return _IO_vfscanf (s, format, argptr, NULL);
2431 # endif
2432 #endif
2434 #ifdef COMPILE_WSCANF
2435 weak_alias (__vfwscanf, vfwscanf)
2436 #else
2437 weak_alias (__vfscanf, vfscanf)
2438 #endif