]> git.ipfire.org Git - thirdparty/glibc.git/blame - stdio-common/vfscanf.c
Use “copy "es_BO"” in LC_TIME of es_CU, es_CL, and es_EC
[thirdparty/glibc.git] / stdio-common / vfscanf.c
CommitLineData
688903eb 1/* Copyright (C) 1991-2018 Free Software Foundation, Inc.
2c6fe0bd 2 This file is part of the GNU C Library.
28f540f4 3
2c6fe0bd 4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
28f540f4 8
2c6fe0bd
UD
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
41bdb6e2 12 Lesser General Public License for more details.
28f540f4 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
28f540f4 17
d64b6ad0 18#include <assert.h>
28f540f4
RM
19#include <errno.h>
20#include <limits.h>
21#include <ctype.h>
22#include <stdarg.h>
bea9b193 23#include <stdbool.h>
28f540f4 24#include <stdio.h>
e852e889 25#include <stdint.h>
28f540f4
RM
26#include <stdlib.h>
27#include <string.h>
8d8c6efa 28#include <wchar.h>
2c6fe0bd 29#include <wctype.h>
9090848d 30#include <libc-diag.h>
ec999b8e 31#include <libc-lock.h>
14ea22e9 32#include <locale/localeinfo.h>
95e83974 33#include <scratch_buffer.h>
28f540f4 34
28f540f4 35#ifdef __GNUC__
14ea22e9
UD
36# define HAVE_LONGLONG
37# define LONGLONG long long
28f540f4 38#else
14ea22e9 39# define LONGLONG long
28f540f4
RM
40#endif
41
96d0213e
UD
42/* Determine whether we have to handle `long long' at all. */
43#if LONG_MAX == LONG_LONG_MAX
44# define need_longlong 0
45#else
46# define need_longlong 1
47#endif
48
859a09cf
UD
49/* Determine whether we have to handle `long'. */
50#if INT_MAX == LONG_MAX
51# define need_long 0
52#else
e4899e7b 53# define need_long 1
859a09cf
UD
54#endif
55
96aa2d94 56/* Those are flags in the conversion format. */
4c02bf1a
UD
57#define LONG 0x0001 /* l: long or double */
58#define LONGDBL 0x0002 /* L: long long or long double */
59#define SHORT 0x0004 /* h: short */
60#define SUPPRESS 0x0008 /* *: suppress assignment */
61#define POINTER 0x0010 /* weird %p pointer (`fake hex') */
62#define NOSKIP 0x0020 /* do not skip blanks */
63#define NUMBER_SIGNED 0x0040 /* signed integer */
64#define GROUP 0x0080 /* ': group numbers */
267c54dc 65#define GNU_MALLOC 0x0100 /* a: malloc strings */
4c02bf1a
UD
66#define CHAR 0x0200 /* hh: char */
67#define I18N 0x0400 /* I: use locale's digits */
68#define HEXA_FLOAT 0x0800 /* hexadecimal float */
69#define READ_POINTER 0x1000 /* this is a pointer value */
267c54dc
UD
70#define POSIX_MALLOC 0x2000 /* m: malloc strings */
71#define MALLOC (GNU_MALLOC | POSIX_MALLOC)
96aa2d94 72
e3b22ad3
UD
73#include <locale/localeinfo.h>
74#include <libioP.h>
05be689b 75
e3b22ad3
UD
76#ifdef COMPILE_WSCANF
77# define ungetc(c, s) ((void) (c == WEOF \
d64b6ad0 78 || (--read_in, \
d18ea0c5 79 _IO_sputbackwc (s, c))))
e3b22ad3 80# define ungetc_not_eof(c, s) ((void) (--read_in, \
d18ea0c5 81 _IO_sputbackwc (s, c)))
e3b22ad3 82# define inchar() (c == WEOF ? ((errno = inchar_errno), WEOF) \
d64b6ad0 83 : ((c = _IO_getwc_unlocked (s)), \
7d68a8ec 84 (void) (c != WEOF \
6dd67bd5
UD
85 ? ++read_in \
86 : (size_t) (inchar_errno = errno)), c))
d64b6ad0 87
e3b22ad3
UD
88# define ISSPACE(Ch) iswspace (Ch)
89# define ISDIGIT(Ch) iswdigit (Ch)
90# define ISXDIGIT(Ch) iswxdigit (Ch)
91# define TOLOWER(Ch) towlower (Ch)
92# define ORIENT if (_IO_fwide (s, 1) != 1) return WEOF
93# define __strtoll_internal __wcstoll_internal
94# define __strtoull_internal __wcstoull_internal
95# define __strtol_internal __wcstol_internal
96# define __strtoul_internal __wcstoul_internal
97# define __strtold_internal __wcstold_internal
98# define __strtod_internal __wcstod_internal
99# define __strtof_internal __wcstof_internal
100
101# define L_(Str) L##Str
e4899e7b 102# define CHAR_T wchar_t
e3b22ad3 103# define UCHAR_T unsigned int
e4899e7b 104# define WINT_T wint_t
e3b22ad3
UD
105# undef EOF
106# define EOF WEOF
107#else
108# define ungetc(c, s) ((void) ((int) c == EOF \
c764b9a7 109 || (--read_in, \
d18ea0c5 110 _IO_sputbackc (s, (unsigned char) c))))
e3b22ad3 111# define ungetc_not_eof(c, s) ((void) (--read_in, \
d18ea0c5 112 _IO_sputbackc (s, (unsigned char) c)))
e3b22ad3 113# define inchar() (c == EOF ? ((errno = inchar_errno), EOF) \
b112c02f 114 : ((c = _IO_getc_unlocked (s)), \
7d68a8ec 115 (void) (c != EOF \
6dd67bd5
UD
116 ? ++read_in \
117 : (size_t) (inchar_errno = errno)), c))
e3b22ad3
UD
118# define ISSPACE(Ch) __isspace_l (Ch, loc)
119# define ISDIGIT(Ch) __isdigit_l (Ch, loc)
120# define ISXDIGIT(Ch) __isxdigit_l (Ch, loc)
68dc4dcb 121# define TOLOWER(Ch) __tolower_l ((unsigned char) (Ch), loc)
e3b22ad3 122# define ORIENT if (_IO_vtable_offset (s) == 0 \
6b3f2b3d 123 && _IO_fwide (s, -1) != -1) \
411adb10 124 return EOF
d64b6ad0 125
e3b22ad3 126# define L_(Str) Str
e4899e7b 127# define CHAR_T char
e3b22ad3
UD
128# define UCHAR_T unsigned char
129# define WINT_T int
130#endif
d64b6ad0 131
726d48ec
GG
132#include "printf-parse.h" /* Use read_int. */
133
e3b22ad3
UD
134#define encode_error() do { \
135 errval = 4; \
2c6fe0bd 136 __set_errno (EILSEQ); \
e3b22ad3 137 goto errout; \
2c6fe0bd 138 } while (0)
e3b22ad3
UD
139#define conv_error() do { \
140 errval = 2; \
141 goto errout; \
7c713e28 142 } while (0)
e3b22ad3
UD
143#define input_error() do { \
144 errval = 1; \
145 if (done == 0) done = EOF; \
146 goto errout; \
7c713e28 147 } while (0)
267c54dc
UD
148#define add_ptr_to_free(ptr) \
149 do \
150 { \
151 if (ptrs_to_free == NULL \
152 || ptrs_to_free->count == (sizeof (ptrs_to_free->ptrs) \
153 / sizeof (ptrs_to_free->ptrs[0]))) \
154 { \
155 struct ptrs_to_free *new_ptrs = alloca (sizeof (*ptrs_to_free)); \
156 new_ptrs->count = 0; \
157 new_ptrs->next = ptrs_to_free; \
158 ptrs_to_free = new_ptrs; \
159 } \
160 ptrs_to_free->ptrs[ptrs_to_free->count++] = (ptr); \
161 } \
162 while (0)
e3b22ad3 163#define ARGCHECK(s, format) \
7c713e28
RM
164 do \
165 { \
166 /* Check file argument for consistence. */ \
167 CHECK_FILE (s, EOF); \
f8b87ef0
UD
168 if (s->_flags & _IO_NO_READS) \
169 { \
170 __set_errno (EBADF); \
171 return EOF; \
172 } \
173 else if (format == NULL) \
174 { \
30bfee26 175 __set_errno (EINVAL); \
f8b87ef0
UD
176 return EOF; \
177 } \
96aa2d94 178 } while (0)
e3b22ad3 179#define LOCK_STREAM(S) \
0dce3d15 180 __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \
edf5b2d7 181 _IO_flockfile (S)
e3b22ad3 182#define UNLOCK_STREAM(S) \
c0fb8a56
UD
183 _IO_funlockfile (S); \
184 __libc_cleanup_region_end (0)
28f540f4 185
267c54dc
UD
186struct ptrs_to_free
187{
188 size_t count;
189 struct ptrs_to_free *next;
190 char **ptrs[32];
191};
28f540f4 192
95e83974
FW
193struct char_buffer {
194 CHAR_T *current;
195 CHAR_T *end;
196 struct scratch_buffer scratch;
197};
198
199/* Returns a pointer to the first CHAR_T object in the buffer. Only
200 valid if char_buffer_add (BUFFER, CH) has been called and
201 char_buffer_error (BUFFER) is false. */
202static inline CHAR_T *
203char_buffer_start (const struct char_buffer *buffer)
204{
205 return (CHAR_T *) buffer->scratch.data;
206}
207
208/* Returns the number of CHAR_T objects in the buffer. Only valid if
209 char_buffer_error (BUFFER) is false. */
210static inline size_t
211char_buffer_size (const struct char_buffer *buffer)
212{
213 return buffer->current - char_buffer_start (buffer);
214}
215
216/* Reinitializes BUFFER->current and BUFFER->end to cover the entire
217 scratch buffer. */
218static inline void
219char_buffer_rewind (struct char_buffer *buffer)
220{
221 buffer->current = char_buffer_start (buffer);
222 buffer->end = buffer->current + buffer->scratch.length / sizeof (CHAR_T);
223}
224
225/* Returns true if a previous call to char_buffer_add (BUFFER, CH)
226 failed. */
227static inline bool
228char_buffer_error (const struct char_buffer *buffer)
229{
230 return __glibc_unlikely (buffer->current == NULL);
231}
232
233/* Slow path for char_buffer_add. */
234static void
235char_buffer_add_slow (struct char_buffer *buffer, CHAR_T ch)
236{
237 if (char_buffer_error (buffer))
238 return;
239 size_t offset = buffer->end - (CHAR_T *) buffer->scratch.data;
240 if (!scratch_buffer_grow_preserve (&buffer->scratch))
241 {
242 buffer->current = NULL;
243 buffer->end = NULL;
244 return;
245 }
246 char_buffer_rewind (buffer);
247 buffer->current += offset;
248 *buffer->current++ = ch;
249}
250
251/* Adds CH to BUFFER. This function does not report any errors, check
252 for them with char_buffer_error. */
253static inline void
254char_buffer_add (struct char_buffer *buffer, CHAR_T ch)
255 __attribute__ ((always_inline));
256static inline void
257char_buffer_add (struct char_buffer *buffer, CHAR_T ch)
258{
259 if (__glibc_unlikely (buffer->current == buffer->end))
260 char_buffer_add_slow (buffer, ch);
261 else
262 *buffer->current++ = ch;
263}
264
28f540f4
RM
265/* Read formatted input from S according to the format string
266 FORMAT, using the argument list in ARG.
267 Return the number of assignments made, or -1 for an input error. */
e3b22ad3 268#ifdef COMPILE_WSCANF
d64b6ad0 269int
9964a145 270_IO_vfwscanf (FILE *s, const wchar_t *format, va_list argptr,
c6251f03 271 int *errp)
e3b22ad3 272#else
28f540f4 273int
9964a145 274_IO_vfscanf_internal (FILE *s, const char *format, va_list argptr,
c6251f03 275 int *errp)
96aa2d94 276#endif
28f540f4 277{
4cca6b86 278 va_list arg;
2e09a79a
JM
279 const CHAR_T *f = format;
280 UCHAR_T fc; /* Current character of the format. */
281 WINT_T done = 0; /* Assignments done. */
282 size_t read_in = 0; /* Chars read in. */
283 WINT_T c = 0; /* Last char read. */
284 int width; /* Maximum field width. */
285 int flags; /* Modifiers for current format element. */
e3b22ad3
UD
286 int errval = 0;
287#ifndef COMPILE_WSCANF
af85385f 288 locale_t loc = _NL_CURRENT_LOCALE;
f095bb72 289 struct __locale_data *const curctype = loc->__locales[LC_CTYPE];
e3b22ad3 290#endif
0793d348 291
7d68a8ec
UD
292 /* Errno of last failed inchar call. */
293 int inchar_errno = 0;
28f540f4 294 /* Status for reading F-P nums. */
6ecec3b6 295 char got_digit, got_dot, got_e, negative;
28f540f4 296 /* If a [...] is a [^...]. */
d64b6ad0 297 CHAR_T not_in;
377a515b 298#define exp_char not_in
28f540f4
RM
299 /* Base for integral numbers. */
300 int base;
77a58cad 301 /* Decimal point character. */
72acaddf 302#ifdef COMPILE_WSCANF
52a7f7c0 303 wint_t decimal;
72acaddf
UD
304#else
305 const char *decimal;
306#endif
0793d348 307 /* The thousands character of the current locale. */
72acaddf 308#ifdef COMPILE_WSCANF
52a7f7c0 309 wint_t thousands;
72acaddf
UD
310#else
311 const char *thousands;
312#endif
267c54dc 313 struct ptrs_to_free *ptrs_to_free = NULL;
8d8c6efa
UD
314 /* State for the conversions. */
315 mbstate_t state;
28f540f4 316 /* Integral holding variables. */
f0bf9cb9
RM
317 union
318 {
319 long long int q;
320 unsigned long long int uq;
321 long int l;
322 unsigned long int ul;
323 } num;
28f540f4 324 /* Character-buffer pointer. */
ba1ffaa1 325 char *str = NULL;
2c6fe0bd 326 wchar_t *wstr = NULL;
ba1ffaa1 327 char **strptr = NULL;
54188057 328 ssize_t strsize = 0;
05be689b
RM
329 /* We must not react on white spaces immediately because they can
330 possibly be matched even if in the input stream no character is
331 available anymore. */
332 int skip_space = 0;
28f540f4 333 /* Workspace. */
d64b6ad0 334 CHAR_T *tw; /* Temporary pointer. */
95e83974
FW
335 struct char_buffer charbuf;
336 scratch_buffer_init (&charbuf.scratch);
28f540f4 337
4cca6b86
UD
338#ifdef __va_copy
339 __va_copy (arg, argptr);
340#else
341 arg = (va_list) argptr;
342#endif
343
d64b6ad0
UD
344#ifdef ORIENT
345 ORIENT;
346#endif
347
96aa2d94 348 ARGCHECK (s, format);
28f540f4 349
e3b22ad3
UD
350 {
351#ifndef COMPILE_WSCANF
f095bb72 352 struct __locale_data *const curnumeric = loc->__locales[LC_NUMERIC];
e3b22ad3
UD
353#endif
354
355 /* Figure out the decimal point character. */
72acaddf 356#ifdef COMPILE_WSCANF
e3b22ad3 357 decimal = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_DECIMAL_POINT_WC);
72acaddf 358#else
e3b22ad3 359 decimal = curnumeric->values[_NL_ITEM_INDEX (DECIMAL_POINT)].string;
72acaddf 360#endif
e3b22ad3 361 /* Figure out the thousands separator character. */
72acaddf 362#ifdef COMPILE_WSCANF
e3b22ad3 363 thousands = _NL_CURRENT_WORD (LC_NUMERIC, _NL_NUMERIC_THOUSANDS_SEP_WC);
72acaddf 364#else
e3b22ad3
UD
365 thousands = curnumeric->values[_NL_ITEM_INDEX (THOUSANDS_SEP)].string;
366 if (*thousands == '\0')
367 thousands = NULL;
72acaddf 368#endif
e3b22ad3 369 }
28f540f4 370
7c713e28 371 /* Lock the stream. */
edf5b2d7 372 LOCK_STREAM (s);
aa1075ea 373
8d8c6efa 374
72acaddf 375#ifndef COMPILE_WSCANF
8d8c6efa
UD
376 /* From now on we use `state' to convert the format string. */
377 memset (&state, '\0', sizeof (state));
d64b6ad0 378#endif
8d8c6efa 379
28f540f4
RM
380 /* Run through the format string. */
381 while (*f != '\0')
382 {
be69ea41
RM
383 unsigned int argpos;
384 /* Extract the next argument, which is of type TYPE.
385 For a %N$... spec, this is the Nth argument from the beginning;
386 otherwise it is the next argument after the state now in ARG. */
4cca6b86 387#ifdef __va_copy
96aa2d94 388# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
4cca6b86
UD
389 ({ unsigned int pos = argpos; \
390 va_list arg; \
391 __va_copy (arg, argptr); \
392 while (--pos > 0) \
393 (void) va_arg (arg, void *); \
394 va_arg (arg, type); \
395 }))
396#else
397# if 0
398 /* XXX Possible optimization. */
399# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
96aa2d94
RM
400 ({ va_list arg = (va_list) argptr; \
401 arg = (va_list) ((char *) arg \
402 + (argpos - 1) \
403 * __va_rounded_size (void *)); \
404 va_arg (arg, type); \
405 }))
4cca6b86
UD
406# else
407# define ARG(type) (argpos == 0 ? va_arg (arg, type) : \
be69ea41
RM
408 ({ unsigned int pos = argpos; \
409 va_list arg = (va_list) argptr; \
410 while (--pos > 0) \
411 (void) va_arg (arg, void *); \
412 va_arg (arg, type); \
413 }))
4cca6b86 414# endif
96aa2d94 415#endif
be69ea41 416
72acaddf 417#ifndef COMPILE_WSCANF
44f8759b 418 if (!isascii ((unsigned char) *f))
28f540f4
RM
419 {
420 /* Non-ASCII, may be a multibyte. */
8d8c6efa 421 int len = __mbrlen (f, strlen (f), &state);
28f540f4
RM
422 if (len > 0)
423 {
3867ee64
RM
424 do
425 {
426 c = inchar ();
a1ffb40e 427 if (__glibc_unlikely (c == EOF))
3867ee64 428 input_error ();
44f8759b 429 else if (c != (unsigned char) *f++)
3867ee64 430 {
44f8759b 431 ungetc_not_eof (c, s);
3867ee64
RM
432 conv_error ();
433 }
434 }
435 while (--len > 0);
28f540f4
RM
436 continue;
437 }
438 }
d64b6ad0 439#endif
28f540f4
RM
440
441 fc = *f++;
442 if (fc != '%')
443 {
05be689b 444 /* Remember to skip spaces. */
d64b6ad0 445 if (ISSPACE (fc))
05be689b
RM
446 {
447 skip_space = 1;
448 continue;
449 }
450
3867ee64
RM
451 /* Read a character. */
452 c = inchar ();
453
28f540f4 454 /* Characters other than format specs must just match. */
a1ffb40e 455 if (__glibc_unlikely (c == EOF))
96aa2d94 456 input_error ();
05be689b 457
2114e10a
RM
458 /* We saw white space char as the last character in the format
459 string. Now it's time to skip all leading white space. */
05be689b 460 if (skip_space)
28f540f4 461 {
d64b6ad0 462 while (ISSPACE (c))
a1ffb40e 463 if (__glibc_unlikely (inchar () == EOF))
d3b52028 464 input_error ();
05be689b 465 skip_space = 0;
28f540f4 466 }
05be689b 467
a1ffb40e 468 if (__glibc_unlikely (c != fc))
3867ee64 469 {
655c0697 470 ungetc (c, s);
3867ee64
RM
471 conv_error ();
472 }
05be689b 473
28f540f4
RM
474 continue;
475 }
476
05be689b 477 /* This is the start of the conversion string. */
96aa2d94 478 flags = 0;
96aa2d94 479
be69ea41
RM
480 /* Initialize state of modifiers. */
481 argpos = 0;
be69ea41 482
05be689b 483 /* Prepare temporary buffer. */
95e83974 484 char_buffer_rewind (&charbuf);
05be689b 485
be69ea41 486 /* Check for a positional parameter specification. */
44f8759b 487 if (ISDIGIT ((UCHAR_T) *f))
be69ea41 488 {
726d48ec 489 argpos = read_int ((const UCHAR_T **) &f);
d64b6ad0 490 if (*f == L_('$'))
be69ea41
RM
491 ++f;
492 else
493 {
494 /* Oops; that was actually the field width. */
495 width = argpos;
496 argpos = 0;
497 goto got_width;
498 }
499 }
500
a1d84548
UD
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'))
f0bf9cb9
RM
504 switch (*f++)
505 {
d64b6ad0 506 case L_('*'):
0793d348 507 flags |= SUPPRESS;
f0bf9cb9 508 break;
d64b6ad0 509 case L_('\''):
3979024a
UD
510#ifdef COMPILE_WSCANF
511 if (thousands != L'\0')
512#else
513 if (thousands != NULL)
514#endif
515 flags |= GROUP;
f0bf9cb9 516 break;
a1d84548
UD
517 case L_('I'):
518 flags |= I18N;
519 break;
f0bf9cb9
RM
520 }
521
28f540f4
RM
522 /* Find the maximum field width. */
523 width = 0;
726d48ec
GG
524 if (ISDIGIT ((UCHAR_T) *f))
525 width = read_int ((const UCHAR_T **) &f);
be69ea41 526 got_width:
28f540f4
RM
527 if (width == 0)
528 width = -1;
529
530 /* Check for type modifiers. */
c3966b88
UD
531 switch (*f++)
532 {
d64b6ad0 533 case L_('h'):
c3966b88 534 /* ints are short ints or chars. */
d64b6ad0 535 if (*f == L_('h'))
c3966b88
UD
536 {
537 ++f;
538 flags |= CHAR;
539 }
540 else
541 flags |= SHORT;
542 break;
d64b6ad0
UD
543 case L_('l'):
544 if (*f == L_('l'))
c3966b88
UD
545 {
546 /* A double `l' is equivalent to an `L'. */
547 ++f;
859a09cf 548 flags |= LONGDBL | LONG;
c3966b88
UD
549 }
550 else
551 /* ints are long ints. */
552 flags |= LONG;
553 break;
d64b6ad0
UD
554 case L_('q'):
555 case L_('L'):
c3966b88 556 /* doubles are long doubles, and ints are long long ints. */
859a09cf 557 flags |= LONGDBL | LONG;
c3966b88 558 break;
d64b6ad0 559 case L_('a'):
c3966b88
UD
560 /* The `a' is used as a flag only if followed by `s', `S' or
561 `['. */
d64b6ad0 562 if (*f != L_('s') && *f != L_('S') && *f != L_('['))
c3966b88
UD
563 {
564 --f;
565 break;
566 }
874aa523
UD
567 /* In __isoc99_*scanf %as, %aS and %a[ extension is not
568 supported at all. */
569 if (s->_flags2 & _IO_FLAGS2_SCANF_STD)
570 {
571 --f;
572 break;
573 }
c3966b88
UD
574 /* String conversions (%s, %[) take a `char **'
575 arg and fill it in with a malloc'd pointer. */
267c54dc 576 flags |= GNU_MALLOC;
c3966b88 577 break;
874aa523
UD
578 case L_('m'):
579 flags |= POSIX_MALLOC;
580 if (*f == L_('l'))
581 {
582 ++f;
583 flags |= LONG;
584 }
585 break;
d64b6ad0 586 case L_('z'):
96d0213e 587 if (need_longlong && sizeof (size_t) > sizeof (unsigned long int))
c3966b88
UD
588 flags |= LONGDBL;
589 else if (sizeof (size_t) > sizeof (unsigned int))
590 flags |= LONG;
591 break;
d64b6ad0 592 case L_('j'):
96d0213e 593 if (need_longlong && sizeof (uintmax_t) > sizeof (unsigned long int))
c3966b88
UD
594 flags |= LONGDBL;
595 else if (sizeof (uintmax_t) > sizeof (unsigned int))
596 flags |= LONG;
597 break;
d64b6ad0 598 case L_('t'):
96d0213e 599 if (need_longlong && sizeof (ptrdiff_t) > sizeof (long int))
c3966b88
UD
600 flags |= LONGDBL;
601 else if (sizeof (ptrdiff_t) > sizeof (int))
602 flags |= LONG;
603 break;
604 default:
605 /* Not a recognized modifier. Backup. */
606 --f;
607 break;
608 }
28f540f4
RM
609
610 /* End of the format string? */
a1ffb40e 611 if (__glibc_unlikely (*f == L_('\0')))
96aa2d94 612 conv_error ();
28f540f4
RM
613
614 /* Find the conversion specifier. */
28f540f4 615 fc = *f++;
d64b6ad0 616 if (skip_space || (fc != L_('[') && fc != L_('c')
f9a06dc1 617 && fc != L_('C') && fc != L_('n')))
05be689b
RM
618 {
619 /* Eat whitespace. */
14ea22e9 620 int save_errno = errno;
0923a2c8 621 __set_errno (0);
3867ee64 622 do
0923a2c8
UD
623 /* We add the additional test for EOF here since otherwise
624 inchar will restore the old errno value which might be
625 EINTR but does not indicate an interrupt since nothing
626 was read at this time. */
627 if (__builtin_expect ((c == EOF || inchar () == EOF)
628 && errno == EINTR, 0))
f8b87ef0 629 input_error ();
d64b6ad0 630 while (ISSPACE (c));
0923a2c8 631 __set_errno (save_errno);
655c0697 632 ungetc (c, s);
05be689b
RM
633 skip_space = 0;
634 }
635
28f540f4
RM
636 switch (fc)
637 {
d64b6ad0 638 case L_('%'): /* Must match a literal '%'. */
14ea22e9 639 c = inchar ();
a1ffb40e 640 if (__glibc_unlikely (c == EOF))
dc30f461 641 input_error ();
a1ffb40e 642 if (__glibc_unlikely (c != fc))
3867ee64 643 {
44f8759b 644 ungetc_not_eof (c, s);
3867ee64
RM
645 conv_error ();
646 }
28f540f4
RM
647 break;
648
d64b6ad0 649 case L_('n'): /* Answer number of assignments done. */
01cdeca0
RM
650 /* Corrigendum 1 to ISO C 1990 describes the allowed flags
651 with the 'n' conversion specifier. */
0793d348 652 if (!(flags & SUPPRESS))
5290baf0
UD
653 {
654 /* Don't count the read-ahead. */
96d0213e 655 if (need_longlong && (flags & LONGDBL))
5290baf0 656 *ARG (long long int *) = read_in;
859a09cf 657 else if (need_long && (flags & LONG))
5290baf0
UD
658 *ARG (long int *) = read_in;
659 else if (flags & SHORT)
660 *ARG (short int *) = read_in;
859a09cf 661 else if (!(flags & CHAR))
5290baf0 662 *ARG (int *) = read_in;
859a09cf
UD
663 else
664 *ARG (char *) = read_in;
8d57beea
UD
665
666#ifdef NO_BUG_IN_ISO_C_CORRIGENDUM_1
667 /* We have a severe problem here. The ISO C standard
668 contradicts itself in explaining the effect of the %n
669 format in `scanf'. While in ISO C:1990 and the ISO C
670 Amendement 1:1995 the result is described as
671
672 Execution of a %n directive does not effect the
673 assignment count returned at the completion of
674 execution of the f(w)scanf function.
675
676 in ISO C Corrigendum 1:1994 the following was added:
677
678 Subclause 7.9.6.2
679 Add the following fourth example:
680 In:
681 #include <stdio.h>
682 int d1, d2, n1, n2, i;
683 i = sscanf("123", "%d%n%n%d", &d1, &n1, &n2, &d2);
684 the value 123 is assigned to d1 and the value3 to n1.
685 Because %n can never get an input failure the value
686 of 3 is also assigned to n2. The value of d2 is not
687 affected. The value 3 is assigned to i.
688
14ea22e9 689 We go for now with the historically correct code from ISO C,
8d57beea
UD
690 i.e., we don't count the %n assignments. When it ever
691 should proof to be wrong just remove the #ifdef above. */
5290baf0 692 ++done;
8d57beea 693#endif
5290baf0 694 }
28f540f4
RM
695 break;
696
d64b6ad0 697 case L_('c'): /* Match characters. */
2c6fe0bd 698 if ((flags & LONG) == 0)
28f540f4 699 {
874aa523
UD
700 if (width == -1)
701 width = 1;
702
703#define STRING_ARG(Str, Type, Width) \
704 do if (!(flags & SUPPRESS)) \
705 { \
706 if (flags & MALLOC) \
707 { \
708 /* The string is to be stored in a malloc'd buffer. */ \
709 /* For %mS using char ** is actually wrong, but \
710 shouldn't make a difference on any arch glibc \
711 supports and would unnecessarily complicate \
712 things. */ \
713 strptr = ARG (char **); \
714 if (strptr == NULL) \
715 conv_error (); \
716 /* Allocate an initial buffer. */ \
717 strsize = Width; \
718 *strptr = (char *) malloc (strsize * sizeof (Type)); \
719 Str = (Type *) *strptr; \
720 if (Str != NULL) \
721 add_ptr_to_free (strptr); \
722 else if (flags & POSIX_MALLOC) \
3f8cc204
UD
723 { \
724 done = EOF; \
725 goto errout; \
726 } \
874aa523
UD
727 } \
728 else \
729 Str = ARG (Type *); \
730 if (Str == NULL) \
731 conv_error (); \
732 } while (0)
733#ifdef COMPILE_WSCANF
734 STRING_ARG (str, char, 100);
735#else
736 STRING_ARG (str, char, (width > 1024 ? 1024 : width));
737#endif
28f540f4 738
14ea22e9 739 c = inchar ();
a1ffb40e 740 if (__glibc_unlikely (c == EOF))
2c6fe0bd 741 input_error ();
28f540f4 742
72acaddf 743#ifdef COMPILE_WSCANF
d64b6ad0
UD
744 /* We have to convert the wide character(s) into multibyte
745 characters and store the result. */
746 memset (&state, '\0', sizeof (state));
747
748 do
749 {
750 size_t n;
751
874aa523 752 if (!(flags & SUPPRESS) && (flags & POSIX_MALLOC)
9dd87afb 753 && *strptr + strsize - str <= MB_LEN_MAX)
874aa523
UD
754 {
755 /* We have to enlarge the buffer if the `m' flag
756 was given. */
757 size_t strleng = str - *strptr;
758 char *newstr;
759
760 newstr = (char *) realloc (*strptr, strsize * 2);
761 if (newstr == NULL)
762 {
763 /* Can't allocate that much. Last-ditch effort. */
764 newstr = (char *) realloc (*strptr,
9dd87afb 765 strleng + MB_LEN_MAX);
874aa523 766 if (newstr == NULL)
3f8cc204
UD
767 {
768 /* c can't have `a' flag, only `m'. */
769 done = EOF;
770 goto errout;
771 }
874aa523
UD
772 else
773 {
774 *strptr = newstr;
775 str = newstr + strleng;
9dd87afb 776 strsize = strleng + MB_LEN_MAX;
874aa523
UD
777 }
778 }
779 else
780 {
781 *strptr = newstr;
782 str = newstr + strleng;
783 strsize *= 2;
784 }
785 }
786
4aebaa6b 787 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
a1ffb40e 788 if (__glibc_unlikely (n == (size_t) -1))
d64b6ad0
UD
789 /* No valid wide character. */
790 input_error ();
791
792 /* Increment the output pointer. Even if we don't
793 write anything. */
794 str += n;
795 }
796 while (--width > 0 && inchar () != EOF);
797#else
2c6fe0bd
UD
798 if (!(flags & SUPPRESS))
799 {
800 do
874aa523
UD
801 {
802 if ((flags & MALLOC)
803 && (char *) str == *strptr + strsize)
804 {
805 /* Enlarge the buffer. */
806 size_t newsize
807 = strsize
808 + (strsize >= width ? width - 1 : strsize);
809
810 str = (char *) realloc (*strptr, newsize);
811 if (str == NULL)
812 {
813 /* Can't allocate that much. Last-ditch
814 effort. */
815 str = (char *) realloc (*strptr, strsize + 1);
816 if (str == NULL)
3f8cc204
UD
817 {
818 /* c can't have `a' flag, only `m'. */
819 done = EOF;
820 goto errout;
821 }
874aa523
UD
822 else
823 {
824 *strptr = (char *) str;
825 str += strsize;
826 ++strsize;
827 }
828 }
829 else
830 {
831 *strptr = (char *) str;
832 str += strsize;
833 strsize = newsize;
834 }
835 }
836 *str++ = c;
837 }
2c6fe0bd
UD
838 while (--width > 0 && inchar () != EOF);
839 }
840 else
841 while (--width > 0 && inchar () != EOF);
d64b6ad0 842#endif
2c6fe0bd 843
2c6fe0bd 844 if (!(flags & SUPPRESS))
874aa523
UD
845 {
846 if ((flags & MALLOC) && str - *strptr != strsize)
847 {
848 char *cp = (char *) realloc (*strptr, str - *strptr);
849 if (cp != NULL)
850 *strptr = cp;
851 }
852 strptr = NULL;
853 ++done;
854 }
2c6fe0bd
UD
855
856 break;
28f540f4 857 }
2c6fe0bd 858 /* FALLTHROUGH */
d64b6ad0 859 case L_('C'):
874aa523
UD
860 if (width == -1)
861 width = 1;
862
863 STRING_ARG (wstr, wchar_t, (width > 1024 ? 1024 : width));
d64b6ad0
UD
864
865 c = inchar ();
a1ffb40e 866 if (__glibc_unlikely (c == EOF))
d64b6ad0
UD
867 input_error ();
868
72acaddf 869#ifdef COMPILE_WSCANF
d64b6ad0
UD
870 /* Just store the incoming wide characters. */
871 if (!(flags & SUPPRESS))
872 {
873 do
874aa523
UD
874 {
875 if ((flags & MALLOC)
876 && wstr == (wchar_t *) *strptr + strsize)
877 {
878 size_t newsize
879 = strsize + (strsize > width ? width - 1 : strsize);
880 /* Enlarge the buffer. */
881 wstr = (wchar_t *) realloc (*strptr,
882 newsize * sizeof (wchar_t));
883 if (wstr == NULL)
884 {
885 /* Can't allocate that much. Last-ditch effort. */
886 wstr = (wchar_t *) realloc (*strptr,
887 (strsize + 1)
888 * sizeof (wchar_t));
889 if (wstr == NULL)
3f8cc204
UD
890 {
891 /* C or lc can't have `a' flag, only `m'
892 flag. */
893 done = EOF;
894 goto errout;
895 }
874aa523
UD
896 else
897 {
898 *strptr = (char *) wstr;
899 wstr += strsize;
900 ++strsize;
901 }
902 }
903 else
904 {
905 *strptr = (char *) wstr;
906 wstr += strsize;
907 strsize = newsize;
908 }
909 }
910 *wstr++ = c;
911 }
d64b6ad0
UD
912 while (--width > 0 && inchar () != EOF);
913 }
914 else
915 while (--width > 0 && inchar () != EOF);
916#else
2c6fe0bd 917 {
d64b6ad0
UD
918 /* We have to convert the multibyte input sequence to wide
919 characters. */
68bd3326 920 char buf[1];
d64b6ad0 921 mbstate_t cstate;
28f540f4 922
d64b6ad0 923 memset (&cstate, '\0', sizeof (cstate));
edf5b2d7 924
2c6fe0bd
UD
925 do
926 {
d64b6ad0
UD
927 /* This is what we present the mbrtowc function first. */
928 buf[0] = c;
d64b6ad0 929
874aa523
UD
930 if (!(flags & SUPPRESS) && (flags & MALLOC)
931 && wstr == (wchar_t *) *strptr + strsize)
932 {
933 size_t newsize
934 = strsize + (strsize > width ? width - 1 : strsize);
935 /* Enlarge the buffer. */
936 wstr = (wchar_t *) realloc (*strptr,
937 newsize * sizeof (wchar_t));
938 if (wstr == NULL)
939 {
940 /* Can't allocate that much. Last-ditch effort. */
941 wstr = (wchar_t *) realloc (*strptr,
942 ((strsize + 1)
943 * sizeof (wchar_t)));
944 if (wstr == NULL)
3f8cc204
UD
945 {
946 /* C or lc can't have `a' flag, only `m' flag. */
947 done = EOF;
948 goto errout;
949 }
874aa523
UD
950 else
951 {
952 *strptr = (char *) wstr;
953 wstr += strsize;
954 ++strsize;
955 }
956 }
957 else
958 {
959 *strptr = (char *) wstr;
960 wstr += strsize;
961 strsize = newsize;
962 }
963 }
964
d64b6ad0
UD
965 while (1)
966 {
967 size_t n;
968
969 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
2f278c94 970 buf, 1, &cstate);
d64b6ad0
UD
971
972 if (n == (size_t) -2)
973 {
974 /* Possibly correct character, just not enough
975 input. */
a1ffb40e 976 if (__glibc_unlikely (inchar () == EOF))
d64b6ad0
UD
977 encode_error ();
978
2f278c94 979 buf[0] = c;
d64b6ad0
UD
980 continue;
981 }
982
a1ffb40e 983 if (__glibc_unlikely (n != 1))
d64b6ad0
UD
984 encode_error ();
985
986 /* We have a match. */
987 break;
988 }
989
990 /* Advance the result pointer. */
991 ++wstr;
992 }
993 while (--width > 0 && inchar () != EOF);
2c6fe0bd 994 }
d64b6ad0 995#endif
28f540f4 996
d64b6ad0 997 if (!(flags & SUPPRESS))
874aa523
UD
998 {
999 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1000 {
1001 wchar_t *cp = (wchar_t *) realloc (*strptr,
1002 ((wstr
1003 - (wchar_t *) *strptr)
1004 * sizeof (wchar_t)));
1005 if (cp != NULL)
1006 *strptr = (char *) cp;
1007 }
1008 strptr = NULL;
1009
1010 ++done;
1011 }
2c6fe0bd 1012
d64b6ad0
UD
1013 break;
1014
1015 case L_('s'): /* Read a string. */
1016 if (!(flags & LONG))
1017 {
874aa523 1018 STRING_ARG (str, char, 100);
28f540f4 1019
d64b6ad0 1020 c = inchar ();
a1ffb40e 1021 if (__glibc_unlikely (c == EOF))
d64b6ad0 1022 input_error ();
28f540f4 1023
72acaddf 1024#ifdef COMPILE_WSCANF
d64b6ad0
UD
1025 memset (&state, '\0', sizeof (state));
1026#endif
1027
1028 do
3867ee64 1029 {
d64b6ad0
UD
1030 if (ISSPACE (c))
1031 {
44f8759b 1032 ungetc_not_eof (c, s);
d64b6ad0
UD
1033 break;
1034 }
1035
72acaddf 1036#ifdef COMPILE_WSCANF
d64b6ad0
UD
1037 /* This is quite complicated. We have to convert the
1038 wide characters into multibyte characters and then
1039 store them. */
1040 {
1041 size_t n;
1042
1043 if (!(flags & SUPPRESS) && (flags & MALLOC)
9dd87afb 1044 && *strptr + strsize - str <= MB_LEN_MAX)
d64b6ad0 1045 {
874aa523
UD
1046 /* We have to enlarge the buffer if the `a' or `m'
1047 flag was given. */
d90e1b42
UD
1048 size_t strleng = str - *strptr;
1049 char *newstr;
1050
1051 newstr = (char *) realloc (*strptr, strsize * 2);
1052 if (newstr == NULL)
d64b6ad0
UD
1053 {
1054 /* Can't allocate that much. Last-ditch
1055 effort. */
d90e1b42 1056 newstr = (char *) realloc (*strptr,
9dd87afb 1057 strleng + MB_LEN_MAX);
d90e1b42 1058 if (newstr == NULL)
d64b6ad0 1059 {
267c54dc 1060 if (flags & POSIX_MALLOC)
3f8cc204
UD
1061 {
1062 done = EOF;
1063 goto errout;
1064 }
d64b6ad0
UD
1065 /* We lose. Oh well. Terminate the
1066 string and stop converting,
1067 so at least we don't skip any input. */
d90e1b42 1068 ((char *) (*strptr))[strleng] = '\0';
267c54dc 1069 strptr = NULL;
d64b6ad0
UD
1070 ++done;
1071 conv_error ();
1072 }
1073 else
1074 {
d90e1b42
UD
1075 *strptr = newstr;
1076 str = newstr + strleng;
9dd87afb 1077 strsize = strleng + MB_LEN_MAX;
d64b6ad0
UD
1078 }
1079 }
1080 else
1081 {
d90e1b42
UD
1082 *strptr = newstr;
1083 str = newstr + strleng;
d64b6ad0
UD
1084 strsize *= 2;
1085 }
1086 }
1087
4aebaa6b
UD
1088 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c,
1089 &state);
a1ffb40e 1090 if (__glibc_unlikely (n == (size_t) -1))
d64b6ad0
UD
1091 encode_error ();
1092
9dd87afb 1093 assert (n <= MB_LEN_MAX);
d64b6ad0
UD
1094 str += n;
1095 }
1096#else
1097 /* This is easy. */
1098 if (!(flags & SUPPRESS))
1099 {
1100 *str++ = c;
1101 if ((flags & MALLOC)
1102 && (char *) str == *strptr + strsize)
1103 {
1104 /* Enlarge the buffer. */
1105 str = (char *) realloc (*strptr, 2 * strsize);
1106 if (str == NULL)
1107 {
1108 /* Can't allocate that much. Last-ditch
1109 effort. */
1110 str = (char *) realloc (*strptr, strsize + 1);
1111 if (str == NULL)
1112 {
267c54dc 1113 if (flags & POSIX_MALLOC)
3f8cc204
UD
1114 {
1115 done = EOF;
1116 goto errout;
1117 }
d64b6ad0
UD
1118 /* We lose. Oh well. Terminate the
1119 string and stop converting,
1120 so at least we don't skip any input. */
1121 ((char *) (*strptr))[strsize - 1] = '\0';
267c54dc 1122 strptr = NULL;
d64b6ad0
UD
1123 ++done;
1124 conv_error ();
1125 }
1126 else
1127 {
1128 *strptr = (char *) str;
1129 str += strsize;
1130 ++strsize;
1131 }
1132 }
1133 else
1134 {
1135 *strptr = (char *) str;
1136 str += strsize;
1137 strsize *= 2;
1138 }
1139 }
1140 }
1141#endif
28f540f4 1142 }
d64b6ad0 1143 while ((width <= 0 || --width > 0) && inchar () != EOF);
28f540f4 1144
d64b6ad0
UD
1145 if (!(flags & SUPPRESS))
1146 {
72acaddf 1147#ifdef COMPILE_WSCANF
44f8759b 1148 /* We have to emit the code to get into the initial
d64b6ad0
UD
1149 state. */
1150 char buf[MB_LEN_MAX];
4aebaa6b 1151 size_t n = __wcrtomb (buf, L'\0', &state);
d64b6ad0
UD
1152 if (n > 0 && (flags & MALLOC)
1153 && str + n >= *strptr + strsize)
1154 {
1155 /* Enlarge the buffer. */
d90e1b42
UD
1156 size_t strleng = str - *strptr;
1157 char *newstr;
1158
1159 newstr = (char *) realloc (*strptr, strleng + n + 1);
1160 if (newstr == NULL)
d64b6ad0 1161 {
267c54dc 1162 if (flags & POSIX_MALLOC)
3f8cc204
UD
1163 {
1164 done = EOF;
1165 goto errout;
1166 }
d64b6ad0
UD
1167 /* We lose. Oh well. Terminate the string
1168 and stop converting, so at least we don't
1169 skip any input. */
d90e1b42 1170 ((char *) (*strptr))[strleng] = '\0';
267c54dc 1171 strptr = NULL;
d64b6ad0
UD
1172 ++done;
1173 conv_error ();
1174 }
1175 else
1176 {
d90e1b42
UD
1177 *strptr = newstr;
1178 str = newstr + strleng;
1179 strsize = strleng + n + 1;
d64b6ad0
UD
1180 }
1181 }
1182
1183 str = __mempcpy (str, buf, n);
1184#endif
d90e1b42 1185 *str++ = '\0';
d64b6ad0
UD
1186
1187 if ((flags & MALLOC) && str - *strptr != strsize)
1188 {
1189 char *cp = (char *) realloc (*strptr, str - *strptr);
1190 if (cp != NULL)
1191 *strptr = cp;
1192 }
267c54dc 1193 strptr = NULL;
d64b6ad0
UD
1194
1195 ++done;
1196 }
1197 break;
28f540f4 1198 }
d64b6ad0 1199 /* FALLTHROUGH */
28f540f4 1200
d64b6ad0 1201 case L_('S'):
2c6fe0bd 1202 {
72acaddf 1203#ifndef COMPILE_WSCANF
d64b6ad0
UD
1204 mbstate_t cstate;
1205#endif
1206
1207 /* Wide character string. */
874aa523 1208 STRING_ARG (wstr, wchar_t, 100);
2c6fe0bd 1209
d64b6ad0 1210 c = inchar ();
694b49ca 1211 if (__builtin_expect (c == EOF, 0))
d64b6ad0
UD
1212 input_error ();
1213
72acaddf 1214#ifndef COMPILE_WSCANF
d64b6ad0
UD
1215 memset (&cstate, '\0', sizeof (cstate));
1216#endif
1217
2c6fe0bd
UD
1218 do
1219 {
d64b6ad0 1220 if (ISSPACE (c))
2c6fe0bd 1221 {
44f8759b 1222 ungetc_not_eof (c, s);
2c6fe0bd
UD
1223 break;
1224 }
1225
72acaddf 1226#ifdef COMPILE_WSCANF
d64b6ad0
UD
1227 /* This is easy. */
1228 if (!(flags & SUPPRESS))
1229 {
1230 *wstr++ = c;
1231 if ((flags & MALLOC)
1232 && wstr == (wchar_t *) *strptr + strsize)
1233 {
1234 /* Enlarge the buffer. */
1235 wstr = (wchar_t *) realloc (*strptr,
1236 (2 * strsize)
1237 * sizeof (wchar_t));
1238 if (wstr == NULL)
1239 {
1240 /* Can't allocate that much. Last-ditch
874aa523 1241 effort. */
d64b6ad0 1242 wstr = (wchar_t *) realloc (*strptr,
d90e1b42
UD
1243 (strsize + 1)
1244 * sizeof (wchar_t));
d64b6ad0
UD
1245 if (wstr == NULL)
1246 {
267c54dc 1247 if (flags & POSIX_MALLOC)
3f8cc204
UD
1248 {
1249 done = EOF;
1250 goto errout;
1251 }
d64b6ad0
UD
1252 /* We lose. Oh well. Terminate the string
1253 and stop converting, so at least we don't
1254 skip any input. */
1255 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
267c54dc 1256 strptr = NULL;
d64b6ad0
UD
1257 ++done;
1258 conv_error ();
1259 }
1260 else
1261 {
1262 *strptr = (char *) wstr;
1263 wstr += strsize;
1264 ++strsize;
1265 }
1266 }
1267 else
1268 {
1269 *strptr = (char *) wstr;
1270 wstr += strsize;
1271 strsize *= 2;
1272 }
1273 }
1274 }
1275#else
1276 {
68bd3326 1277 char buf[1];
d64b6ad0
UD
1278
1279 buf[0] = c;
d64b6ad0
UD
1280
1281 while (1)
1282 {
1283 size_t n;
1284
1285 n = __mbrtowc (!(flags & SUPPRESS) ? wstr : NULL,
2f278c94 1286 buf, 1, &cstate);
d64b6ad0
UD
1287
1288 if (n == (size_t) -2)
1289 {
1290 /* Possibly correct character, just not enough
1291 input. */
a1ffb40e 1292 if (__glibc_unlikely (inchar () == EOF))
d64b6ad0
UD
1293 encode_error ();
1294
2f278c94 1295 buf[0] = c;
d64b6ad0
UD
1296 continue;
1297 }
1298
a1ffb40e 1299 if (__glibc_unlikely (n != 1))
d64b6ad0
UD
1300 encode_error ();
1301
1302 /* We have a match. */
2f278c94 1303 ++wstr;
d64b6ad0
UD
1304 break;
1305 }
1306
1307 if (!(flags & SUPPRESS) && (flags & MALLOC)
1308 && wstr == (wchar_t *) *strptr + strsize)
1309 {
1310 /* Enlarge the buffer. */
1311 wstr = (wchar_t *) realloc (*strptr,
1312 (2 * strsize
1313 * sizeof (wchar_t)));
1314 if (wstr == NULL)
1315 {
1316 /* Can't allocate that much. Last-ditch effort. */
1317 wstr = (wchar_t *) realloc (*strptr,
1318 ((strsize + 1)
1319 * sizeof (wchar_t)));
1320 if (wstr == NULL)
1321 {
267c54dc 1322 if (flags & POSIX_MALLOC)
3f8cc204
UD
1323 {
1324 done = EOF;
1325 goto errout;
1326 }
d64b6ad0
UD
1327 /* We lose. Oh well. Terminate the
1328 string and stop converting, so at
1329 least we don't skip any input. */
1330 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
267c54dc 1331 strptr = NULL;
d64b6ad0
UD
1332 ++done;
1333 conv_error ();
1334 }
1335 else
1336 {
1337 *strptr = (char *) wstr;
1338 wstr += strsize;
1339 ++strsize;
1340 }
1341 }
1342 else
1343 {
1344 *strptr = (char *) wstr;
1345 wstr += strsize;
1346 strsize *= 2;
1347 }
1348 }
1349 }
1350#endif
2c6fe0bd 1351 }
d64b6ad0 1352 while ((width <= 0 || --width > 0) && inchar () != EOF);
2c6fe0bd
UD
1353
1354 if (!(flags & SUPPRESS))
1355 {
d64b6ad0
UD
1356 *wstr++ = L'\0';
1357
1358 if ((flags & MALLOC) && wstr - (wchar_t *) *strptr != strsize)
1359 {
1360 wchar_t *cp = (wchar_t *) realloc (*strptr,
1361 ((wstr
1362 - (wchar_t *) *strptr)
1363 * sizeof(wchar_t)));
1364 if (cp != NULL)
1365 *strptr = (char *) cp;
1366 }
267c54dc 1367 strptr = NULL;
d64b6ad0 1368
2c6fe0bd
UD
1369 ++done;
1370 }
1371 }
1372 break;
1373
d64b6ad0
UD
1374 case L_('x'): /* Hexadecimal integer. */
1375 case L_('X'): /* Ditto. */
28f540f4 1376 base = 16;
28f540f4
RM
1377 goto number;
1378
d64b6ad0 1379 case L_('o'): /* Octal integer. */
28f540f4 1380 base = 8;
28f540f4
RM
1381 goto number;
1382
d64b6ad0 1383 case L_('u'): /* Unsigned decimal integer. */
28f540f4 1384 base = 10;
28f540f4
RM
1385 goto number;
1386
d64b6ad0 1387 case L_('d'): /* Signed decimal integer. */
28f540f4 1388 base = 10;
3979024a 1389 flags |= NUMBER_SIGNED;
28f540f4
RM
1390 goto number;
1391
d64b6ad0 1392 case L_('i'): /* Generic number. */
28f540f4 1393 base = 0;
3979024a 1394 flags |= NUMBER_SIGNED;
28f540f4
RM
1395
1396 number:
14ea22e9 1397 c = inchar ();
a1ffb40e 1398 if (__glibc_unlikely (c == EOF))
96aa2d94 1399 input_error ();
28f540f4
RM
1400
1401 /* Check for a sign. */
d64b6ad0 1402 if (c == L_('-') || c == L_('+'))
28f540f4 1403 {
95e83974 1404 char_buffer_add (&charbuf, c);
28f540f4
RM
1405 if (width > 0)
1406 --width;
3867ee64 1407 c = inchar ();
28f540f4
RM
1408 }
1409
1410 /* Look for a leading indication of base. */
d64b6ad0 1411 if (width != 0 && c == L_('0'))
28f540f4
RM
1412 {
1413 if (width > 0)
1414 --width;
28f540f4 1415
95e83974 1416 char_buffer_add (&charbuf, c);
3867ee64 1417 c = inchar ();
28f540f4 1418
d64b6ad0 1419 if (width != 0 && TOLOWER (c) == L_('x'))
28f540f4
RM
1420 {
1421 if (base == 0)
1422 base = 16;
1423 if (base == 16)
1424 {
1425 if (width > 0)
1426 --width;
3867ee64 1427 c = inchar ();
28f540f4
RM
1428 }
1429 }
1430 else if (base == 0)
1431 base = 8;
1432 }
1433
1434 if (base == 0)
1435 base = 10;
1436
694b49ca 1437 if (base == 10 && __builtin_expect ((flags & I18N) != 0, 0))
28f540f4 1438 {
a1d84548
UD
1439 int from_level;
1440 int to_level;
eac4282f 1441 int level;
72acaddf 1442#ifdef COMPILE_WSCANF
e87f0c33 1443 const wchar_t *wcdigits[10];
f448d449 1444 const wchar_t *wcdigits_extended[10];
a1d84548
UD
1445#else
1446 const char *mbdigits[10];
f448d449 1447 const char *mbdigits_extended[10];
a1d84548 1448#endif
f448d449
UD
1449 /* "to_inpunct" is a map from ASCII digits to their
1450 equivalent in locale. This is defined for locales
1451 which use an extra digits set. */
1452 wctrans_t map = __wctrans ("to_inpunct");
a1d84548 1453 int n;
05be689b 1454
a1d84548 1455 from_level = 0;
72acaddf 1456#ifdef COMPILE_WSCANF
a1d84548
UD
1457 to_level = _NL_CURRENT_WORD (LC_CTYPE,
1458 _NL_CTYPE_INDIGITS_WC_LEN) - 1;
1459#else
e3b22ad3 1460 to_level = (uint32_t) curctype->values[_NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN)].word - 1;
a1d84548
UD
1461#endif
1462
f448d449 1463 /* Get the alternative digit forms if there are any. */
a1ffb40e 1464 if (__glibc_unlikely (map != NULL))
f448d449
UD
1465 {
1466 /* Adding new level for extra digits set in locale file. */
1467 ++to_level;
1468
1469 for (n = 0; n < 10; ++n)
1470 {
1471#ifdef COMPILE_WSCANF
1472 wcdigits[n] = (const wchar_t *)
f095bb72 1473 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
f448d449
UD
1474
1475 wchar_t *wc_extended = (wchar_t *)
1476 alloca ((to_level + 2) * sizeof (wchar_t));
1477 __wmemcpy (wc_extended, wcdigits[n], to_level);
1478 wc_extended[to_level] = __towctrans (L'0' + n, map);
1479 wc_extended[to_level + 1] = '\0';
1480 wcdigits_extended[n] = wc_extended;
1481#else
1482 mbdigits[n]
f095bb72 1483 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
f448d449
UD
1484
1485 /* Get the equivalent wide char in map. */
1486 wint_t extra_wcdigit = __towctrans (L'0' + n, map);
1487
1488 /* Convert it to multibyte representation. */
1489 mbstate_t state;
1490 memset (&state, '\0', sizeof (state));
1491
1492 char extra_mbdigit[MB_LEN_MAX];
1493 size_t mblen
1494 = __wcrtomb (extra_mbdigit, extra_wcdigit, &state);
1495
1496 if (mblen == (size_t) -1)
1497 {
1498 /* Ignore this new level. */
1499 map = NULL;
1500 break;
1501 }
1502
1503 /* Calculate the length of mbdigits[n]. */
1504 const char *last_char = mbdigits[n];
1505 for (level = 0; level < to_level; ++level)
1506 last_char = strchr (last_char, '\0') + 1;
1507
1508 size_t mbdigits_len = last_char - mbdigits[n];
1509
1510 /* Allocate memory for extended multibyte digit. */
1511 char *mb_extended;
1512 mb_extended = (char *) alloca (mbdigits_len + mblen + 1);
1513
1514 /* And get the mbdigits + extra_digit string. */
1515 *(char *) __mempcpy (__mempcpy (mb_extended, mbdigits[n],
1516 mbdigits_len),
1517 extra_mbdigit, mblen) = '\0';
1518 mbdigits_extended[n] = mb_extended;
1519#endif
1520 }
1521 }
1522
eac4282f
UD
1523 /* Read the number into workspace. */
1524 while (c != EOF && width != 0)
a1d84548 1525 {
eac4282f
UD
1526 /* In this round we get the pointer to the digit strings
1527 and also perform the first round of comparisons. */
1528 for (n = 0; n < 10; ++n)
1529 {
1530 /* Get the string for the digits with value N. */
72acaddf 1531#ifdef COMPILE_WSCANF
2a9feb92
CM
1532
1533 /* wcdigits_extended[] is fully set in the loop
1534 above, but the test for "map != NULL" is done
1535 inside the loop here and outside the loop there. */
1536 DIAG_PUSH_NEEDS_COMMENT;
1537 DIAG_IGNORE_NEEDS_COMMENT (4.7, "-Wmaybe-uninitialized");
1538
a1ffb40e 1539 if (__glibc_unlikely (map != NULL))
f448d449
UD
1540 wcdigits[n] = wcdigits_extended[n];
1541 else
1542 wcdigits[n] = (const wchar_t *)
1543 _NL_CURRENT (LC_CTYPE, _NL_CTYPE_INDIGITS0_WC + n);
eac4282f 1544 wcdigits[n] += from_level;
a1d84548 1545
2a9feb92
CM
1546 DIAG_POP_NEEDS_COMMENT;
1547
52a7f7c0 1548 if (c == (wint_t) *wcdigits[n])
eac4282f
UD
1549 {
1550 to_level = from_level;
1551 break;
1552 }
1553
1554 /* Advance the pointer to the next string. */
1555 ++wcdigits[n];
a1d84548 1556#else
eac4282f
UD
1557 const char *cmpp;
1558 int avail = width > 0 ? width : INT_MAX;
e87f0c33 1559
a1ffb40e 1560 if (__glibc_unlikely (map != NULL))
f448d449
UD
1561 mbdigits[n] = mbdigits_extended[n];
1562 else
1563 mbdigits[n]
1564 = curctype->values[_NL_CTYPE_INDIGITS0_MB + n].string;
a1d84548 1565
eac4282f
UD
1566 for (level = 0; level < from_level; level++)
1567 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
a1d84548 1568
eac4282f 1569 cmpp = mbdigits[n];
ecb72bd5 1570 while ((unsigned char) *cmpp == c && avail >= 0)
eac4282f
UD
1571 {
1572 if (*++cmpp == '\0')
1573 break;
1574 else
1575 {
ecb72bd5 1576 if (avail == 0 || inchar () == EOF)
eac4282f
UD
1577 break;
1578 --avail;
1579 }
1580 }
1581
1582 if (*cmpp == '\0')
1583 {
1584 if (width > 0)
1585 width = avail;
1586 to_level = from_level;
1587 break;
1588 }
a1d84548 1589
eac4282f
UD
1590 /* We are pushing all read characters back. */
1591 if (cmpp > mbdigits[n])
1592 {
1593 ungetc (c, s);
1594 while (--cmpp > mbdigits[n])
44f8759b
UD
1595 ungetc_not_eof ((unsigned char) *cmpp, s);
1596 c = (unsigned char) *cmpp;
eac4282f
UD
1597 }
1598
1599 /* Advance the pointer to the next string. */
1600 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
a1d84548 1601#endif
eac4282f 1602 }
a1d84548 1603
eac4282f 1604 if (n == 10)
a1d84548 1605 {
eac4282f
UD
1606 /* Have not yet found the digit. */
1607 for (level = from_level + 1; level <= to_level; ++level)
a1d84548 1608 {
eac4282f
UD
1609 /* Search all ten digits of this level. */
1610 for (n = 0; n < 10; ++n)
1611 {
72acaddf 1612#ifdef COMPILE_WSCANF
52a7f7c0 1613 if (c == (wint_t) *wcdigits[n])
eac4282f 1614 break;
a1d84548 1615
eac4282f
UD
1616 /* Advance the pointer to the next string. */
1617 ++wcdigits[n];
a1d84548 1618#else
eac4282f
UD
1619 const char *cmpp;
1620 int avail = width > 0 ? width : INT_MAX;
1621
1622 cmpp = mbdigits[n];
ecb72bd5 1623 while ((unsigned char) *cmpp == c && avail >= 0)
eac4282f
UD
1624 {
1625 if (*++cmpp == '\0')
1626 break;
1627 else
1628 {
ecb72bd5 1629 if (avail == 0 || inchar () == EOF)
eac4282f
UD
1630 break;
1631 --avail;
1632 }
1633 }
a1d84548 1634
eac4282f
UD
1635 if (*cmpp == '\0')
1636 {
1637 if (width > 0)
1638 width = avail;
1639 break;
1640 }
1641
1642 /* We are pushing all read characters back. */
1643 if (cmpp > mbdigits[n])
1644 {
1645 ungetc (c, s);
1646 while (--cmpp > mbdigits[n])
44f8759b
UD
1647 ungetc_not_eof ((unsigned char) *cmpp, s);
1648 c = (unsigned char) *cmpp;
eac4282f
UD
1649 }
1650
1651 /* Advance the pointer to the next string. */
1652 mbdigits[n] = strchr (mbdigits[n], '\0') + 1;
1653#endif
1654 }
1655
1656 if (n < 10)
a1d84548 1657 {
eac4282f
UD
1658 /* Found it. */
1659 from_level = level;
1660 to_level = level;
1661 break;
a1d84548 1662 }
eac4282f
UD
1663 }
1664 }
a1d84548 1665
eac4282f
UD
1666 if (n < 10)
1667 c = L_('0') + n;
3979024a 1668 else if (flags & GROUP)
eac4282f
UD
1669 {
1670 /* Try matching against the thousands separator. */
1671#ifdef COMPILE_WSCANF
1672 if (c != thousands)
1673 break;
1674#else
1675 const char *cmpp = thousands;
1676 int avail = width > 0 ? width : INT_MAX;
1677
ecb72bd5 1678 while ((unsigned char) *cmpp == c && avail >= 0)
eac4282f 1679 {
95e83974 1680 char_buffer_add (&charbuf, c);
eac4282f 1681 if (*++cmpp == '\0')
a1d84548 1682 break;
eac4282f
UD
1683 else
1684 {
ecb72bd5 1685 if (avail == 0 || inchar () == EOF)
eac4282f
UD
1686 break;
1687 --avail;
1688 }
1689 }
a1d84548 1690
95e83974
FW
1691 if (char_buffer_error (&charbuf))
1692 {
1693 __set_errno (ENOMEM);
1694 done = EOF;
1695 goto errout;
1696 }
1697
eac4282f
UD
1698 if (*cmpp != '\0')
1699 {
1700 /* We are pushing all read characters back. */
1701 if (cmpp > thousands)
1702 {
95e83974 1703 charbuf.current -= cmpp - thousands;
eac4282f
UD
1704 ungetc (c, s);
1705 while (--cmpp > thousands)
44f8759b
UD
1706 ungetc_not_eof ((unsigned char) *cmpp, s);
1707 c = (unsigned char) *cmpp;
eac4282f
UD
1708 }
1709 break;
a1d84548
UD
1710 }
1711
eac4282f
UD
1712 if (width > 0)
1713 width = avail;
a1d84548 1714
eac4282f 1715 /* The last thousands character will be added back by
95e83974 1716 the char_buffer_add below. */
996b03dc 1717 --charbuf.current;
eac4282f 1718#endif
a1d84548 1719 }
eac4282f
UD
1720 else
1721 break;
a1d84548 1722
95e83974 1723 char_buffer_add (&charbuf, c);
eac4282f
UD
1724 if (width > 0)
1725 --width;
a1d84548 1726
eac4282f
UD
1727 c = inchar ();
1728 }
7752137a 1729 }
a1d84548
UD
1730 else
1731 /* Read the number into workspace. */
1732 while (c != EOF && width != 0)
1733 {
72acaddf
UD
1734 if (base == 16)
1735 {
1736 if (!ISXDIGIT (c))
1737 break;
1738 }
52a7f7c0 1739 else if (!ISDIGIT (c) || (int) (c - L_('0')) >= base)
72acaddf 1740 {
3979024a 1741 if (base == 10 && (flags & GROUP))
72acaddf
UD
1742 {
1743 /* Try matching against the thousands separator. */
1744#ifdef COMPILE_WSCANF
1745 if (c != thousands)
1746 break;
1747#else
1748 const char *cmpp = thousands;
1749 int avail = width > 0 ? width : INT_MAX;
1750
ecb72bd5 1751 while ((unsigned char) *cmpp == c && avail >= 0)
eac4282f 1752 {
95e83974 1753 char_buffer_add (&charbuf, c);
eac4282f
UD
1754 if (*++cmpp == '\0')
1755 break;
1756 else
1757 {
ecb72bd5 1758 if (avail == 0 || inchar () == EOF)
eac4282f
UD
1759 break;
1760 --avail;
1761 }
1762 }
72acaddf 1763
95e83974
FW
1764 if (char_buffer_error (&charbuf))
1765 {
1766 __set_errno (ENOMEM);
1767 done = EOF;
1768 goto errout;
1769 }
1770
72acaddf
UD
1771 if (*cmpp != '\0')
1772 {
eac4282f 1773 /* We are pushing all read characters back. */
72acaddf
UD
1774 if (cmpp > thousands)
1775 {
95e83974 1776 charbuf.current -= cmpp - thousands;
72acaddf
UD
1777 ungetc (c, s);
1778 while (--cmpp > thousands)
44f8759b
UD
1779 ungetc_not_eof ((unsigned char) *cmpp, s);
1780 c = (unsigned char) *cmpp;
72acaddf
UD
1781 }
1782 break;
1783 }
eac4282f 1784
72acaddf 1785 if (width > 0)
eac4282f
UD
1786 width = avail;
1787
1788 /* The last thousands character will be added back by
95e83974
FW
1789 the char_buffer_add below. */
1790 --charbuf.current;
72acaddf
UD
1791#endif
1792 }
1793 else
1794 break;
1795 }
95e83974 1796 char_buffer_add (&charbuf, c);
a1d84548
UD
1797 if (width > 0)
1798 --width;
1799
1800 c = inchar ();
1801 }
28f540f4 1802
95e83974
FW
1803 if (char_buffer_error (&charbuf))
1804 {
1805 __set_errno (ENOMEM);
1806 done = EOF;
1807 goto errout;
1808 }
1809
1810 if (char_buffer_size (&charbuf) == 0
1811 || (char_buffer_size (&charbuf) == 1
1812 && (char_buffer_start (&charbuf)[0] == L_('+')
1813 || char_buffer_start (&charbuf)[0] == L_('-'))))
c53a89d4
UD
1814 {
1815 /* There was no number. If we are supposed to read a pointer
1816 we must recognize "(nil)" as well. */
95e83974 1817 if (__builtin_expect (char_buffer_size (&charbuf) == 0
4c02bf1a 1818 && (flags & READ_POINTER)
728dab0e 1819 && (width < 0 || width >= 5)
694b49ca
UD
1820 && c == '('
1821 && TOLOWER (inchar ()) == L_('n')
1822 && TOLOWER (inchar ()) == L_('i')
1823 && TOLOWER (inchar ()) == L_('l')
1824 && inchar () == L_(')'), 1))
c53a89d4
UD
1825 /* We must produce the value of a NULL pointer. A single
1826 '0' digit is enough. */
95e83974 1827 char_buffer_add (&charbuf, L_('0'));
c53a89d4
UD
1828 else
1829 {
1830 /* The last read character is not part of the number
1831 anymore. */
655c0697 1832 ungetc (c, s);
c53a89d4
UD
1833
1834 conv_error ();
1835 }
1836 }
1837 else
1838 /* The just read character is not part of the number anymore. */
655c0697 1839 ungetc (c, s);
28f540f4
RM
1840
1841 /* Convert the number. */
95e83974
FW
1842 char_buffer_add (&charbuf, L_('\0'));
1843 if (char_buffer_error (&charbuf))
1844 {
1845 __set_errno (ENOMEM);
1846 done = EOF;
1847 goto errout;
1848 }
96d0213e 1849 if (need_longlong && (flags & LONGDBL))
f0bf9cb9 1850 {
3979024a 1851 if (flags & NUMBER_SIGNED)
95e83974
FW
1852 num.q = __strtoll_internal
1853 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
f0bf9cb9 1854 else
95e83974
FW
1855 num.uq = __strtoull_internal
1856 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
f0bf9cb9 1857 }
28f540f4 1858 else
f0bf9cb9 1859 {
3979024a 1860 if (flags & NUMBER_SIGNED)
95e83974
FW
1861 num.l = __strtol_internal
1862 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
f0bf9cb9 1863 else
95e83974
FW
1864 num.ul = __strtoul_internal
1865 (char_buffer_start (&charbuf), &tw, base, flags & GROUP);
f0bf9cb9 1866 }
95e83974 1867 if (__glibc_unlikely (char_buffer_start (&charbuf) == tw))
28f540f4
RM
1868 conv_error ();
1869
0793d348 1870 if (!(flags & SUPPRESS))
28f540f4 1871 {
3979024a 1872 if (flags & NUMBER_SIGNED)
28f540f4 1873 {
96d0213e 1874 if (need_longlong && (flags & LONGDBL))
3979024a 1875 *ARG (LONGLONG int *) = num.q;
859a09cf 1876 else if (need_long && (flags & LONG))
3979024a 1877 *ARG (long int *) = num.l;
0793d348 1878 else if (flags & SHORT)
3979024a 1879 *ARG (short int *) = (short int) num.l;
859a09cf 1880 else if (!(flags & CHAR))
3979024a 1881 *ARG (int *) = (int) num.l;
859a09cf 1882 else
3979024a 1883 *ARG (signed char *) = (signed char) num.ul;
28f540f4
RM
1884 }
1885 else
1886 {
96d0213e 1887 if (need_longlong && (flags & LONGDBL))
3979024a 1888 *ARG (unsigned LONGLONG int *) = num.uq;
859a09cf 1889 else if (need_long && (flags & LONG))
3979024a 1890 *ARG (unsigned long int *) = num.ul;
0793d348 1891 else if (flags & SHORT)
3979024a
UD
1892 *ARG (unsigned short int *)
1893 = (unsigned short int) num.ul;
859a09cf 1894 else if (!(flags & CHAR))
3979024a 1895 *ARG (unsigned int *) = (unsigned int) num.ul;
859a09cf 1896 else
3979024a 1897 *ARG (unsigned char *) = (unsigned char) num.ul;
28f540f4
RM
1898 }
1899 ++done;
1900 }
1901 break;
1902
d64b6ad0
UD
1903 case L_('e'): /* Floating-point numbers. */
1904 case L_('E'):
1905 case L_('f'):
233f5f68 1906 case L_('F'):
d64b6ad0
UD
1907 case L_('g'):
1908 case L_('G'):
1909 case L_('a'):
1910 case L_('A'):
14ea22e9 1911 c = inchar ();
ac2ca022
UD
1912 if (width > 0)
1913 --width;
a1ffb40e 1914 if (__glibc_unlikely (c == EOF))
96aa2d94 1915 input_error ();
28f540f4 1916
6ecec3b6 1917 got_digit = got_dot = got_e = 0;
918b198d 1918
28f540f4 1919 /* Check for a sign. */
d64b6ad0 1920 if (c == L_('-') || c == L_('+'))
28f540f4 1921 {
d64b6ad0 1922 negative = c == L_('-');
a1ffb40e 1923 if (__glibc_unlikely (width == 0 || inchar () == EOF))
28f540f4 1924 /* EOF is only an input error before we read any chars. */
96aa2d94 1925 conv_error ();
28f540f4
RM
1926 if (width > 0)
1927 --width;
1928 }
01cdeca0
RM
1929 else
1930 negative = 0;
28f540f4 1931
9b26f5c4 1932 /* Take care for the special arguments "nan" and "inf". */
d64b6ad0 1933 if (TOLOWER (c) == L_('n'))
9b26f5c4
UD
1934 {
1935 /* Maybe "nan". */
95e83974 1936 char_buffer_add (&charbuf, c);
694b49ca
UD
1937 if (__builtin_expect (width == 0
1938 || inchar () == EOF
1939 || TOLOWER (c) != L_('a'), 0))
f4efd068 1940 conv_error ();
9df54168
UD
1941 if (width > 0)
1942 --width;
95e83974 1943 char_buffer_add (&charbuf, c);
694b49ca
UD
1944 if (__builtin_expect (width == 0
1945 || inchar () == EOF
1946 || TOLOWER (c) != L_('n'), 0))
f4efd068 1947 conv_error ();
9df54168
UD
1948 if (width > 0)
1949 --width;
95e83974 1950 char_buffer_add (&charbuf, c);
9b26f5c4
UD
1951 /* It is "nan". */
1952 goto scan_float;
1953 }
d64b6ad0 1954 else if (TOLOWER (c) == L_('i'))
9b26f5c4
UD
1955 {
1956 /* Maybe "inf" or "infinity". */
95e83974 1957 char_buffer_add (&charbuf, c);
694b49ca
UD
1958 if (__builtin_expect (width == 0
1959 || inchar () == EOF
1960 || TOLOWER (c) != L_('n'), 0))
f4efd068 1961 conv_error ();
9df54168
UD
1962 if (width > 0)
1963 --width;
95e83974 1964 char_buffer_add (&charbuf, c);
694b49ca
UD
1965 if (__builtin_expect (width == 0
1966 || inchar () == EOF
1967 || TOLOWER (c) != L_('f'), 0))
f4efd068 1968 conv_error ();
9df54168
UD
1969 if (width > 0)
1970 --width;
95e83974 1971 char_buffer_add (&charbuf, c);
9b26f5c4 1972 /* It is as least "inf". */
9df54168 1973 if (width != 0 && inchar () != EOF)
9b26f5c4 1974 {
d64b6ad0 1975 if (TOLOWER (c) == L_('i'))
9b26f5c4 1976 {
9df54168
UD
1977 if (width > 0)
1978 --width;
8d8c6efa 1979 /* Now we have to read the rest as well. */
95e83974 1980 char_buffer_add (&charbuf, c);
694b49ca
UD
1981 if (__builtin_expect (width == 0
1982 || inchar () == EOF
1983 || TOLOWER (c) != L_('n'), 0))
f4efd068 1984 conv_error ();
9df54168
UD
1985 if (width > 0)
1986 --width;
95e83974 1987 char_buffer_add (&charbuf, c);
694b49ca
UD
1988 if (__builtin_expect (width == 0
1989 || inchar () == EOF
1990 || TOLOWER (c) != L_('i'), 0))
f4efd068 1991 conv_error ();
9df54168
UD
1992 if (width > 0)
1993 --width;
95e83974 1994 char_buffer_add (&charbuf, c);
694b49ca
UD
1995 if (__builtin_expect (width == 0
1996 || inchar () == EOF
1997 || TOLOWER (c) != L_('t'), 0))
f4efd068 1998 conv_error ();
9df54168
UD
1999 if (width > 0)
2000 --width;
95e83974 2001 char_buffer_add (&charbuf, c);
694b49ca
UD
2002 if (__builtin_expect (width == 0
2003 || inchar () == EOF
2004 || TOLOWER (c) != L_('y'), 0))
f4efd068 2005 conv_error ();
9df54168
UD
2006 if (width > 0)
2007 --width;
95e83974 2008 char_buffer_add (&charbuf, c);
9b26f5c4
UD
2009 }
2010 else
2011 /* Never mind. */
655c0697 2012 ungetc (c, s);
9b26f5c4
UD
2013 }
2014 goto scan_float;
2015 }
2016
d64b6ad0 2017 exp_char = L_('e');
9df54168 2018 if (width != 0 && c == L_('0'))
377a515b 2019 {
95e83974 2020 char_buffer_add (&charbuf, c);
63551311 2021 c = inchar ();
9df54168
UD
2022 if (width > 0)
2023 --width;
2024 if (width != 0 && TOLOWER (c) == L_('x'))
63551311
UD
2025 {
2026 /* It is a number in hexadecimal format. */
95e83974 2027 char_buffer_add (&charbuf, c);
377a515b 2028
3979024a 2029 flags |= HEXA_FLOAT;
d64b6ad0 2030 exp_char = L_('p');
377a515b 2031
63551311
UD
2032 /* Grouping is not allowed. */
2033 flags &= ~GROUP;
2034 c = inchar ();
9df54168
UD
2035 if (width > 0)
2036 --width;
63551311 2037 }
a4966c61
AS
2038 else
2039 got_digit = 1;
377a515b
UD
2040 }
2041
ac2ca022 2042 while (1)
28f540f4 2043 {
95e83974
FW
2044 if (char_buffer_error (&charbuf))
2045 {
2046 __set_errno (ENOMEM);
2047 done = EOF;
2048 goto errout;
2049 }
d64b6ad0 2050 if (ISDIGIT (c))
6ecec3b6 2051 {
95e83974 2052 char_buffer_add (&charbuf, c);
6ecec3b6
AS
2053 got_digit = 1;
2054 }
3979024a 2055 else if (!got_e && (flags & HEXA_FLOAT) && ISXDIGIT (c))
6ecec3b6 2056 {
95e83974 2057 char_buffer_add (&charbuf, c);
6ecec3b6
AS
2058 got_digit = 1;
2059 }
95e83974 2060 else if (got_e && charbuf.current[-1] == exp_char
d64b6ad0 2061 && (c == L_('-') || c == L_('+')))
95e83974 2062 char_buffer_add (&charbuf, c);
6ecec3b6 2063 else if (got_digit && !got_e
52a7f7c0 2064 && (CHAR_T) TOLOWER (c) == exp_char)
28f540f4 2065 {
95e83974 2066 char_buffer_add (&charbuf, exp_char);
28f540f4
RM
2067 got_e = got_dot = 1;
2068 }
28f540f4 2069 else
377a515b 2070 {
72acaddf
UD
2071#ifdef COMPILE_WSCANF
2072 if (! got_dot && c == decimal)
2073 {
95e83974 2074 char_buffer_add (&charbuf, c);
72acaddf
UD
2075 got_dot = 1;
2076 }
3979024a 2077 else if ((flags & GROUP) != 0 && ! got_dot && c == thousands)
95e83974 2078 char_buffer_add (&charbuf, c);
72acaddf
UD
2079 else
2080 {
2081 /* The last read character is not part of the number
2082 anymore. */
2083 ungetc (c, s);
2084 break;
2085 }
2086#else
2087 const char *cmpp = decimal;
2088 int avail = width > 0 ? width : INT_MAX;
2089
2090 if (! got_dot)
2091 {
ecb72bd5 2092 while ((unsigned char) *cmpp == c && avail >= 0)
72acaddf
UD
2093 if (*++cmpp == '\0')
2094 break;
2095 else
2096 {
ecb72bd5 2097 if (avail == 0 || inchar () == EOF)
72acaddf
UD
2098 break;
2099 --avail;
2100 }
2101 }
2102
2103 if (*cmpp == '\0')
2104 {
2105 /* Add all the characters. */
2106 for (cmpp = decimal; *cmpp != '\0'; ++cmpp)
95e83974 2107 char_buffer_add (&charbuf, (unsigned char) *cmpp);
72acaddf 2108 if (width > 0)
eac4282f 2109 width = avail;
72acaddf
UD
2110 got_dot = 1;
2111 }
2112 else
2113 {
2114 /* Figure out whether it is a thousands separator.
2115 There is one problem: we possibly read more than
2116 one character. We cannot push them back but since
2117 we know that parts of the `decimal' string matched,
2118 we can compare against it. */
2119 const char *cmp2p = thousands;
2120
3979024a 2121 if ((flags & GROUP) != 0 && ! got_dot)
72acaddf 2122 {
eb35b097 2123 while (cmp2p - thousands < cmpp - decimal
72acaddf
UD
2124 && *cmp2p == decimal[cmp2p - thousands])
2125 ++cmp2p;
eb35b097 2126 if (cmp2p - thousands == cmpp - decimal)
72acaddf 2127 {
ecb72bd5 2128 while ((unsigned char) *cmp2p == c && avail >= 0)
72acaddf
UD
2129 if (*++cmp2p == '\0')
2130 break;
2131 else
2132 {
ecb72bd5 2133 if (avail == 0 || inchar () == EOF)
72acaddf
UD
2134 break;
2135 --avail;
2136 }
2137 }
2138 }
2139
2140 if (cmp2p != NULL && *cmp2p == '\0')
2141 {
2142 /* Add all the characters. */
2143 for (cmpp = thousands; *cmpp != '\0'; ++cmpp)
95e83974 2144 char_buffer_add (&charbuf, (unsigned char) *cmpp);
72acaddf 2145 if (width > 0)
eac4282f 2146 width = avail;
72acaddf
UD
2147 }
2148 else
2149 {
2150 /* The last read character is not part of the number
2151 anymore. */
2152 ungetc (c, s);
2153 break;
2154 }
2155 }
2156#endif
377a515b 2157 }
ac2ca022
UD
2158
2159 if (width == 0 || inchar () == EOF)
2160 break;
2161
28f540f4
RM
2162 if (width > 0)
2163 --width;
01cdeca0 2164 }
3867ee64 2165
95e83974
FW
2166 if (char_buffer_error (&charbuf))
2167 {
2168 __set_errno (ENOMEM);
2169 done = EOF;
2170 goto errout;
2171 }
2172
ecb72bd5
UD
2173 wctrans_t map;
2174 if (__builtin_expect ((flags & I18N) != 0, 0)
2175 /* Hexadecimal floats make no sense, fixing localized
2176 digits with ASCII letters. */
3979024a 2177 && !(flags & HEXA_FLOAT)
ecb72bd5 2178 /* Minimum requirement. */
95e83974 2179 && (char_buffer_size (&charbuf) == 0 || got_dot)
ecb72bd5
UD
2180 && (map = __wctrans ("to_inpunct")) != NULL)
2181 {
2182 /* Reget the first character. */
2183 inchar ();
2184
2185 /* Localized digits, decimal points, and thousands
2186 separator. */
2187 wint_t wcdigits[12];
2188
2189 /* First get decimal equivalent to check if we read it
2190 or not. */
2191 wcdigits[11] = __towctrans (L'.', map);
2192
2193 /* If we have not read any character or have just read
f095bb72
UD
2194 locale decimal point which matches the decimal point
2195 for localized FP numbers, then we may have localized
2196 digits. Note, we test GOT_DOT above. */
ecb72bd5 2197#ifdef COMPILE_WSCANF
95e83974
FW
2198 if (char_buffer_size (&charbuf) == 0
2199 || (char_buffer_size (&charbuf) == 1
2200 && wcdigits[11] == decimal))
ecb72bd5
UD
2201#else
2202 char mbdigits[12][MB_LEN_MAX + 1];
2203
2204 mbstate_t state;
2205 memset (&state, '\0', sizeof (state));
2206
95e83974 2207 bool match_so_far = char_buffer_size (&charbuf) == 0;
ecb72bd5
UD
2208 size_t mblen = __wcrtomb (mbdigits[11], wcdigits[11], &state);
2209 if (mblen != (size_t) -1)
2210 {
2211 mbdigits[11][mblen] = '\0';
95e83974
FW
2212 match_so_far |=
2213 (char_buffer_size (&charbuf) == strlen (decimal)
2214 && strcmp (decimal, mbdigits[11]) == 0);
ecb72bd5
UD
2215 }
2216 else
2217 {
2218 size_t decimal_len = strlen (decimal);
2219 /* This should always be the case but the data comes
2220 from a file. */
2221 if (decimal_len <= MB_LEN_MAX)
2222 {
95e83974 2223 match_so_far |= char_buffer_size (&charbuf) == decimal_len;
ecb72bd5
UD
2224 memcpy (mbdigits[11], decimal, decimal_len + 1);
2225 }
2226 else
2227 match_so_far = false;
2228 }
2229
2230 if (match_so_far)
2231#endif
2232 {
3979024a
UD
2233 bool have_locthousands = (flags & GROUP) != 0;
2234
ecb72bd5 2235 /* Now get the digits and the thousands-sep equivalents. */
f095bb72 2236 for (int n = 0; n < 11; ++n)
ecb72bd5
UD
2237 {
2238 if (n < 10)
2239 wcdigits[n] = __towctrans (L'0' + n, map);
2240 else if (n == 10)
3979024a
UD
2241 {
2242 wcdigits[10] = __towctrans (L',', map);
2243 have_locthousands &= wcdigits[10] != L'\0';
2244 }
ecb72bd5
UD
2245
2246#ifndef COMPILE_WSCANF
2247 memset (&state, '\0', sizeof (state));
2248
2249 size_t mblen = __wcrtomb (mbdigits[n], wcdigits[n],
2250 &state);
2251 if (mblen == (size_t) -1)
2252 {
2253 if (n == 10)
2254 {
3979024a 2255 if (have_locthousands)
ecb72bd5
UD
2256 {
2257 size_t thousands_len = strlen (thousands);
2258 if (thousands_len <= MB_LEN_MAX)
2259 memcpy (mbdigits[10], thousands,
2260 thousands_len + 1);
2261 else
2262 have_locthousands = false;
2263 }
2264 }
2265 else
2266 /* Ignore checking against localized digits. */
2267 goto no_i18nflt;
2268 }
2269 else
2270 mbdigits[n][mblen] = '\0';
2271#endif
2272 }
2273
2274 /* Start checking against localized digits, if
382466e0 2275 conversion is done correctly. */
ecb72bd5
UD
2276 while (1)
2277 {
95e83974
FW
2278 if (char_buffer_error (&charbuf))
2279 {
2280 __set_errno (ENOMEM);
2281 done = EOF;
2282 goto errout;
2283 }
2284 if (got_e && charbuf.current[-1] == exp_char
ecb72bd5 2285 && (c == L_('-') || c == L_('+')))
95e83974
FW
2286 char_buffer_add (&charbuf, c);
2287 else if (char_buffer_size (&charbuf) > 0 && !got_e
ecb72bd5
UD
2288 && (CHAR_T) TOLOWER (c) == exp_char)
2289 {
95e83974 2290 char_buffer_add (&charbuf, exp_char);
ecb72bd5
UD
2291 got_e = got_dot = 1;
2292 }
2293 else
2294 {
2295 /* Check against localized digits, decimal point,
2296 and thousands separator. */
2297 int n;
2298 for (n = 0; n < 12; ++n)
2299 {
2300#ifdef COMPILE_WSCANF
2301 if (c == wcdigits[n])
2302 {
2303 if (n < 10)
95e83974 2304 char_buffer_add (&charbuf, L_('0') + n);
ecb72bd5
UD
2305 else if (n == 11 && !got_dot)
2306 {
95e83974 2307 char_buffer_add (&charbuf, decimal);
ecb72bd5
UD
2308 got_dot = 1;
2309 }
2310 else if (n == 10 && have_locthousands
2311 && ! got_dot)
95e83974 2312 char_buffer_add (&charbuf, thousands);
ecb72bd5
UD
2313 else
2314 /* The last read character is not part
2315 of the number anymore. */
2316 n = 12;
2317
2318 break;
2319 }
2320#else
2321 const char *cmpp = mbdigits[n];
2322 int avail = width > 0 ? width : INT_MAX;
2323
2324 while ((unsigned char) *cmpp == c && avail >= 0)
2325 if (*++cmpp == '\0')
2326 break;
2327 else
2328 {
2329 if (avail == 0 || inchar () == EOF)
2330 break;
2331 --avail;
2332 }
2333 if (*cmpp == '\0')
2334 {
2335 if (width > 0)
2336 width = avail;
2337
2338 if (n < 10)
95e83974 2339 char_buffer_add (&charbuf, L_('0') + n);
ecb72bd5
UD
2340 else if (n == 11 && !got_dot)
2341 {
2342 /* Add all the characters. */
2343 for (cmpp = decimal; *cmpp != '\0';
2344 ++cmpp)
95e83974
FW
2345 char_buffer_add (&charbuf,
2346 (unsigned char) *cmpp);
ecb72bd5
UD
2347
2348 got_dot = 1;
2349 }
2350 else if (n == 10 && (flags & GROUP) != 0
4c02bf1a 2351 && ! got_dot)
ecb72bd5
UD
2352 {
2353 /* Add all the characters. */
2354 for (cmpp = thousands; *cmpp != '\0';
2355 ++cmpp)
95e83974
FW
2356 char_buffer_add (&charbuf,
2357 (unsigned char) *cmpp);
ecb72bd5
UD
2358 }
2359 else
2360 /* The last read character is not part
2361 of the number anymore. */
2362 n = 12;
2363
2364 break;
2365 }
2366
2367 /* We are pushing all read characters back. */
2368 if (cmpp > mbdigits[n])
2369 {
2370 ungetc (c, s);
2371 while (--cmpp > mbdigits[n])
2372 ungetc_not_eof ((unsigned char) *cmpp, s);
2373 c = (unsigned char) *cmpp;
2374 }
2375#endif
2376 }
2377
2378 if (n >= 12)
2379 {
2380 /* The last read character is not part
2381 of the number anymore. */
2382 ungetc (c, s);
2383 break;
2384 }
2385 }
2386
2387 if (width == 0 || inchar () == EOF)
2388 break;
2389
2390 if (width > 0)
2391 --width;
2392 }
2393 }
2394
2395#ifndef COMPILE_WSCANF
2396 no_i18nflt:
2397 ;
2398#endif
2399 }
2400
95e83974
FW
2401 if (char_buffer_error (&charbuf))
2402 {
2403 __set_errno (ENOMEM);
2404 done = EOF;
2405 goto errout;
2406 }
2407
377a515b
UD
2408 /* Have we read any character? If we try to read a number
2409 in hexadecimal notation and we have read only the `0x'
bd9be679 2410 prefix this is an error. */
95e83974
FW
2411 if (__glibc_unlikely (char_buffer_size (&charbuf) == 0
2412 || ((flags & HEXA_FLOAT)
2413 && char_buffer_size (&charbuf) == 2)))
96aa2d94 2414 conv_error ();
28f540f4 2415
9b26f5c4 2416 scan_float:
28f540f4 2417 /* Convert the number. */
95e83974
FW
2418 char_buffer_add (&charbuf, L_('\0'));
2419 if (char_buffer_error (&charbuf))
2420 {
2421 __set_errno (ENOMEM);
2422 done = EOF;
2423 goto errout;
2424 }
c6251f03 2425 if ((flags & LONGDBL) && !__ldbl_is_dbl)
28f540f4 2426 {
95e83974
FW
2427 long double d = __strtold_internal
2428 (char_buffer_start (&charbuf), &tw, flags & GROUP);
2429 if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
01cdeca0 2430 *ARG (long double *) = negative ? -d : d;
28f540f4 2431 }
c6251f03 2432 else if (flags & (LONG | LONGDBL))
28f540f4 2433 {
95e83974
FW
2434 double d = __strtod_internal
2435 (char_buffer_start (&charbuf), &tw, flags & GROUP);
2436 if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
01cdeca0 2437 *ARG (double *) = negative ? -d : d;
28f540f4
RM
2438 }
2439 else
2440 {
95e83974
FW
2441 float d = __strtof_internal
2442 (char_buffer_start (&charbuf), &tw, flags & GROUP);
2443 if (!(flags & SUPPRESS) && tw != char_buffer_start (&charbuf))
01cdeca0 2444 *ARG (float *) = negative ? -d : d;
28f540f4
RM
2445 }
2446
95e83974 2447 if (__glibc_unlikely (tw == char_buffer_start (&charbuf)))
28f540f4
RM
2448 conv_error ();
2449
0793d348 2450 if (!(flags & SUPPRESS))
28f540f4
RM
2451 ++done;
2452 break;
2453
d64b6ad0 2454 case L_('['): /* Character class. */
2c6fe0bd 2455 if (flags & LONG)
874aa523 2456 STRING_ARG (wstr, wchar_t, 100);
2c6fe0bd 2457 else
874aa523 2458 STRING_ARG (str, char, 100);
28f540f4 2459
d64b6ad0 2460 if (*f == L_('^'))
28f540f4
RM
2461 {
2462 ++f;
2463 not_in = 1;
2464 }
2465 else
2466 not_in = 0;
2467
d64b6ad0
UD
2468 if (width < 0)
2469 /* There is no width given so there is also no limit on the
2470 number of characters we read. Therefore we set width to
2471 a very high value to make the algorithm easier. */
2472 width = INT_MAX;
2473
72acaddf 2474#ifdef COMPILE_WSCANF
d64b6ad0
UD
2475 /* Find the beginning and the end of the scanlist. We are not
2476 creating a lookup table since it would have to be too large.
2477 Instead we search each time through the string. This is not
2478 a constant lookup time but who uses this feature deserves to
2479 be punished. */
2480 tw = (wchar_t *) f; /* Marks the beginning. */
2481
cc7f258f 2482 if (*f == L']')
d64b6ad0
UD
2483 ++f;
2484
2485 while ((fc = *f++) != L'\0' && fc != L']');
2486
a1ffb40e 2487 if (__glibc_unlikely (fc == L'\0'))
d64b6ad0 2488 conv_error ();
4c6b2202 2489 wchar_t *twend = (wchar_t *) f - 1;
d64b6ad0 2490#else
b17178fc
RM
2491 /* Fill WP with byte flags indexed by character.
2492 We will use this flag map for matching input characters. */
95e83974
FW
2493 if (!scratch_buffer_set_array_size
2494 (&charbuf.scratch, UCHAR_MAX + 1, 1))
b17178fc 2495 {
95e83974
FW
2496 done = EOF;
2497 goto errout;
b17178fc 2498 }
95e83974 2499 memset (charbuf.scratch.data, '\0', UCHAR_MAX + 1);
b17178fc
RM
2500
2501 fc = *f;
2502 if (fc == ']' || fc == '-')
2503 {
2504 /* If ] or - appears before any char in the set, it is not
2505 the terminator or separator, but the first char in the
2506 set. */
95e83974 2507 ((char *)charbuf.scratch.data)[fc] = 1;
b17178fc
RM
2508 ++f;
2509 }
02ac66c5 2510
28f540f4 2511 while ((fc = *f++) != '\0' && fc != ']')
3f651a4d 2512 if (fc == '-' && *f != '\0' && *f != ']'
d64b6ad0
UD
2513 && (unsigned char) f[-2] <= (unsigned char) *f)
2514 {
2515 /* Add all characters from the one before the '-'
2516 up to (but not including) the next format char. */
44f8759b 2517 for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc)
95e83974 2518 ((char *)charbuf.scratch.data)[fc] = 1;
d64b6ad0
UD
2519 }
2520 else
2521 /* Add the character to the flag map. */
95e83974 2522 ((char *)charbuf.scratch.data)[fc] = 1;
d64b6ad0 2523
a1ffb40e 2524 if (__glibc_unlikely (fc == '\0'))
d64b6ad0
UD
2525 conv_error();
2526#endif
28f540f4 2527
2c6fe0bd 2528 if (flags & LONG)
28f540f4 2529 {
d64b6ad0 2530 size_t now = read_in;
72acaddf 2531#ifdef COMPILE_WSCANF
a1ffb40e 2532 if (__glibc_unlikely (inchar () == WEOF))
d64e603a
UD
2533 input_error ();
2534
d64b6ad0
UD
2535 do
2536 {
2537 wchar_t *runp;
2538
d64b6ad0
UD
2539 /* Test whether it's in the scanlist. */
2540 runp = tw;
4c6b2202 2541 while (runp < twend)
d64b6ad0 2542 {
4c6b2202
UD
2543 if (runp[0] == L'-' && runp[1] != '\0'
2544 && runp + 1 != twend
d64b6ad0
UD
2545 && runp != tw
2546 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2547 {
2548 /* Match against all characters in between the
2549 first and last character of the sequence. */
2550 wchar_t wc;
2551
cc7f258f 2552 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
52a7f7c0 2553 if ((wint_t) wc == c)
d64b6ad0
UD
2554 break;
2555
cc7f258f 2556 if (wc <= runp[1] && !not_in)
d64b6ad0 2557 break;
cc7f258f 2558 if (wc <= runp[1] && not_in)
d64b6ad0
UD
2559 {
2560 /* The current character is not in the
f095bb72 2561 scanset. */
73f1b067 2562 ungetc (c, s);
d64b6ad0
UD
2563 goto out;
2564 }
cc7f258f
UD
2565
2566 runp += 2;
d64b6ad0
UD
2567 }
2568 else
2569 {
52a7f7c0 2570 if ((wint_t) *runp == c && !not_in)
d64b6ad0 2571 break;
52a7f7c0 2572 if ((wint_t) *runp == c && not_in)
d64b6ad0 2573 {
73f1b067 2574 ungetc (c, s);
d64b6ad0
UD
2575 goto out;
2576 }
cc7f258f
UD
2577
2578 ++runp;
d64b6ad0 2579 }
cc7f258f 2580 }
d64b6ad0 2581
4c6b2202 2582 if (runp == twend && !not_in)
cc7f258f 2583 {
73f1b067 2584 ungetc (c, s);
cc7f258f 2585 goto out;
d64b6ad0
UD
2586 }
2587
2588 if (!(flags & SUPPRESS))
2589 {
2590 *wstr++ = c;
2591
2592 if ((flags & MALLOC)
2593 && wstr == (wchar_t *) *strptr + strsize)
2594 {
2595 /* Enlarge the buffer. */
2596 wstr = (wchar_t *) realloc (*strptr,
2597 (2 * strsize)
2598 * sizeof (wchar_t));
2599 if (wstr == NULL)
2600 {
2601 /* Can't allocate that much. Last-ditch
2602 effort. */
2603 wstr = (wchar_t *)
d90e1b42
UD
2604 realloc (*strptr, (strsize + 1)
2605 * sizeof (wchar_t));
d64b6ad0
UD
2606 if (wstr == NULL)
2607 {
267c54dc 2608 if (flags & POSIX_MALLOC)
3f8cc204
UD
2609 {
2610 done = EOF;
2611 goto errout;
2612 }
d64b6ad0
UD
2613 /* We lose. Oh well. Terminate the string
2614 and stop converting, so at least we don't
2615 skip any input. */
2616 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
267c54dc 2617 strptr = NULL;
d64b6ad0
UD
2618 ++done;
2619 conv_error ();
2620 }
2621 else
2622 {
2623 *strptr = (char *) wstr;
2624 wstr += strsize;
2625 ++strsize;
2626 }
2627 }
2628 else
2629 {
2630 *strptr = (char *) wstr;
2631 wstr += strsize;
2632 strsize *= 2;
2633 }
2634 }
2635 }
2636 }
d64e603a 2637 while (--width > 0 && inchar () != WEOF);
d64b6ad0
UD
2638 out:
2639#else
2640 char buf[MB_LEN_MAX];
2641 size_t cnt = 0;
2642 mbstate_t cstate;
2643
a1ffb40e 2644 if (__glibc_unlikely (inchar () == EOF))
d64e603a
UD
2645 input_error ();
2646
d64b6ad0 2647 memset (&cstate, '\0', sizeof (cstate));
2c6fe0bd
UD
2648
2649 do
3867ee64 2650 {
95e83974 2651 if (((char *) charbuf.scratch.data)[c] == not_in)
2c6fe0bd 2652 {
44f8759b 2653 ungetc_not_eof (c, s);
2c6fe0bd
UD
2654 break;
2655 }
d64b6ad0
UD
2656
2657 /* This is easy. */
2658 if (!(flags & SUPPRESS))
2659 {
2660 size_t n;
2661
2662 /* Convert it into a wide character. */
bed38142
UD
2663 buf[0] = c;
2664 n = __mbrtowc (wstr, buf, 1, &cstate);
d64b6ad0
UD
2665
2666 if (n == (size_t) -2)
2667 {
2668 /* Possibly correct character, just not enough
2669 input. */
bed38142 2670 ++cnt;
9dd87afb 2671 assert (cnt < MB_LEN_MAX);
d64e603a 2672 continue;
d64b6ad0 2673 }
0f740059 2674 cnt = 0;
d64b6ad0 2675
d64b6ad0
UD
2676 ++wstr;
2677 if ((flags & MALLOC)
2678 && wstr == (wchar_t *) *strptr + strsize)
2679 {
2680 /* Enlarge the buffer. */
2681 wstr = (wchar_t *) realloc (*strptr,
2682 (2 * strsize
2683 * sizeof (wchar_t)));
2684 if (wstr == NULL)
2685 {
2686 /* Can't allocate that much. Last-ditch
2687 effort. */
2688 wstr = (wchar_t *)
2689 realloc (*strptr, ((strsize + 1)
2690 * sizeof (wchar_t)));
2691 if (wstr == NULL)
2692 {
267c54dc 2693 if (flags & POSIX_MALLOC)
3f8cc204
UD
2694 {
2695 done = EOF;
2696 goto errout;
2697 }
d64b6ad0
UD
2698 /* We lose. Oh well. Terminate the
2699 string and stop converting,
2700 so at least we don't skip any input. */
2701 ((wchar_t *) (*strptr))[strsize - 1] = L'\0';
267c54dc 2702 strptr = NULL;
d64b6ad0
UD
2703 ++done;
2704 conv_error ();
2705 }
2706 else
2707 {
2708 *strptr = (char *) wstr;
2709 wstr += strsize;
2710 ++strsize;
2711 }
2712 }
2713 else
2714 {
2715 *strptr = (char *) wstr;
2716 wstr += strsize;
2717 strsize *= 2;
2718 }
2719 }
2720 }
d64e603a
UD
2721
2722 if (--width <= 0)
2723 break;
3867ee64 2724 }
d64e603a 2725 while (inchar () != EOF);
d64b6ad0 2726
a1ffb40e 2727 if (__glibc_unlikely (cnt != 0))
d64b6ad0
UD
2728 /* We stopped in the middle of recognizing another
2729 character. That's a problem. */
2730 encode_error ();
2731#endif
3867ee64 2732
a1ffb40e 2733 if (__glibc_unlikely (now == read_in))
d64b6ad0 2734 /* We haven't succesfully read any character. */
2c6fe0bd 2735 conv_error ();
28f540f4 2736
2c6fe0bd
UD
2737 if (!(flags & SUPPRESS))
2738 {
d64b6ad0
UD
2739 *wstr++ = L'\0';
2740
2741 if ((flags & MALLOC)
2742 && wstr - (wchar_t *) *strptr != strsize)
2743 {
2744 wchar_t *cp = (wchar_t *)
2745 realloc (*strptr, ((wstr - (wchar_t *) *strptr)
2746 * sizeof(wchar_t)));
2747 if (cp != NULL)
2748 *strptr = (char *) cp;
2749 }
267c54dc 2750 strptr = NULL;
d64b6ad0 2751
2c6fe0bd
UD
2752 ++done;
2753 }
2754 }
2755 else
28f540f4 2756 {
d64b6ad0 2757 size_t now = read_in;
d64e603a 2758
a1ffb40e 2759 if (__glibc_unlikely (inchar () == EOF))
d64e603a
UD
2760 input_error ();
2761
72acaddf 2762#ifdef COMPILE_WSCANF
d64b6ad0
UD
2763
2764 memset (&state, '\0', sizeof (state));
2765
2766 do
2767 {
2768 wchar_t *runp;
2769 size_t n;
2770
d64b6ad0
UD
2771 /* Test whether it's in the scanlist. */
2772 runp = tw;
4c6b2202 2773 while (runp < twend)
d64b6ad0 2774 {
4c6b2202
UD
2775 if (runp[0] == L'-' && runp[1] != '\0'
2776 && runp + 1 != twend
d64b6ad0
UD
2777 && runp != tw
2778 && (unsigned int) runp[-1] <= (unsigned int) runp[1])
2779 {
2780 /* Match against all characters in between the
2781 first and last character of the sequence. */
2782 wchar_t wc;
2783
cc7f258f 2784 for (wc = runp[-1] + 1; wc <= runp[1]; ++wc)
52a7f7c0 2785 if ((wint_t) wc == c)
d64b6ad0
UD
2786 break;
2787
cc7f258f 2788 if (wc <= runp[1] && !not_in)
d64b6ad0 2789 break;
cc7f258f 2790 if (wc <= runp[1] && not_in)
d64b6ad0
UD
2791 {
2792 /* The current character is not in the
f095bb72 2793 scanset. */
73f1b067 2794 ungetc (c, s);
d64b6ad0
UD
2795 goto out2;
2796 }
cc7f258f
UD
2797
2798 runp += 2;
d64b6ad0
UD
2799 }
2800 else
2801 {
52a7f7c0 2802 if ((wint_t) *runp == c && !not_in)
d64b6ad0 2803 break;
52a7f7c0 2804 if ((wint_t) *runp == c && not_in)
d64b6ad0 2805 {
73f1b067 2806 ungetc (c, s);
d64b6ad0
UD
2807 goto out2;
2808 }
cc7f258f
UD
2809
2810 ++runp;
d64b6ad0 2811 }
cc7f258f 2812 }
d64b6ad0 2813
4c6b2202 2814 if (runp == twend && !not_in)
cc7f258f 2815 {
73f1b067 2816 ungetc (c, s);
cc7f258f 2817 goto out2;
d64b6ad0
UD
2818 }
2819
2820 if (!(flags & SUPPRESS))
2821 {
2822 if ((flags & MALLOC)
9dd87afb 2823 && *strptr + strsize - str <= MB_LEN_MAX)
d64b6ad0
UD
2824 {
2825 /* Enlarge the buffer. */
d90e1b42
UD
2826 size_t strleng = str - *strptr;
2827 char *newstr;
2828
2829 newstr = (char *) realloc (*strptr, 2 * strsize);
2830 if (newstr == NULL)
d64b6ad0
UD
2831 {
2832 /* Can't allocate that much. Last-ditch
2833 effort. */
d90e1b42 2834 newstr = (char *) realloc (*strptr,
9dd87afb 2835 strleng + MB_LEN_MAX);
d90e1b42 2836 if (newstr == NULL)
d64b6ad0 2837 {
267c54dc 2838 if (flags & POSIX_MALLOC)
3f8cc204
UD
2839 {
2840 done = EOF;
2841 goto errout;
2842 }
d64b6ad0
UD
2843 /* We lose. Oh well. Terminate the string
2844 and stop converting, so at least we don't
2845 skip any input. */
d90e1b42 2846 ((char *) (*strptr))[strleng] = '\0';
267c54dc 2847 strptr = NULL;
d64b6ad0
UD
2848 ++done;
2849 conv_error ();
2850 }
2851 else
2852 {
d90e1b42
UD
2853 *strptr = newstr;
2854 str = newstr + strleng;
9dd87afb 2855 strsize = strleng + MB_LEN_MAX;
d64b6ad0
UD
2856 }
2857 }
2858 else
2859 {
d90e1b42
UD
2860 *strptr = newstr;
2861 str = newstr + strleng;
d64b6ad0
UD
2862 strsize *= 2;
2863 }
2864 }
2865 }
2866
4aebaa6b 2867 n = __wcrtomb (!(flags & SUPPRESS) ? str : NULL, c, &state);
a1ffb40e 2868 if (__glibc_unlikely (n == (size_t) -1))
d64b6ad0
UD
2869 encode_error ();
2870
9dd87afb 2871 assert (n <= MB_LEN_MAX);
d64b6ad0
UD
2872 str += n;
2873 }
d64e603a 2874 while (--width > 0 && inchar () != WEOF);
d64b6ad0
UD
2875 out2:
2876#else
2c6fe0bd
UD
2877 do
2878 {
95e83974 2879 if (((char *) charbuf.scratch.data)[c] == not_in)
2c6fe0bd 2880 {
44f8759b 2881 ungetc_not_eof (c, s);
2c6fe0bd
UD
2882 break;
2883 }
d64b6ad0
UD
2884
2885 /* This is easy. */
2886 if (!(flags & SUPPRESS))
2887 {
2888 *str++ = c;
2889 if ((flags & MALLOC)
2890 && (char *) str == *strptr + strsize)
2891 {
2892 /* Enlarge the buffer. */
e3b22ad3
UD
2893 size_t newsize = 2 * strsize;
2894
2895 allocagain:
2896 str = (char *) realloc (*strptr, newsize);
d64b6ad0
UD
2897 if (str == NULL)
2898 {
2899 /* Can't allocate that much. Last-ditch
2900 effort. */
e3b22ad3 2901 if (newsize > strsize + 1)
d64b6ad0 2902 {
e3b22ad3
UD
2903 newsize = strsize + 1;
2904 goto allocagain;
d64b6ad0 2905 }
267c54dc 2906 if (flags & POSIX_MALLOC)
3f8cc204
UD
2907 {
2908 done = EOF;
2909 goto errout;
2910 }
e3b22ad3
UD
2911 /* We lose. Oh well. Terminate the
2912 string and stop converting,
2913 so at least we don't skip any input. */
2914 ((char *) (*strptr))[strsize - 1] = '\0';
267c54dc 2915 strptr = NULL;
e3b22ad3
UD
2916 ++done;
2917 conv_error ();
d64b6ad0
UD
2918 }
2919 else
2920 {
2921 *strptr = (char *) str;
2922 str += strsize;
e3b22ad3 2923 strsize = newsize;
d64b6ad0
UD
2924 }
2925 }
2926 }
2c6fe0bd 2927 }
d64e603a 2928 while (--width > 0 && inchar () != EOF);
d64b6ad0 2929#endif
2c6fe0bd 2930
a1ffb40e 2931 if (__glibc_unlikely (now == read_in))
d64b6ad0 2932 /* We haven't succesfully read any character. */
2c6fe0bd
UD
2933 conv_error ();
2934
2935 if (!(flags & SUPPRESS))
2936 {
72acaddf 2937#ifdef COMPILE_WSCANF
44f8759b 2938 /* We have to emit the code to get into the initial
d64b6ad0
UD
2939 state. */
2940 char buf[MB_LEN_MAX];
4aebaa6b 2941 size_t n = __wcrtomb (buf, L'\0', &state);
d64b6ad0
UD
2942 if (n > 0 && (flags & MALLOC)
2943 && str + n >= *strptr + strsize)
2944 {
2945 /* Enlarge the buffer. */
d90e1b42
UD
2946 size_t strleng = str - *strptr;
2947 char *newstr;
2948
2949 newstr = (char *) realloc (*strptr, strleng + n + 1);
2950 if (newstr == NULL)
d64b6ad0 2951 {
267c54dc 2952 if (flags & POSIX_MALLOC)
3f8cc204
UD
2953 {
2954 done = EOF;
2955 goto errout;
2956 }
d64b6ad0
UD
2957 /* We lose. Oh well. Terminate the string
2958 and stop converting, so at least we don't
2959 skip any input. */
d90e1b42 2960 ((char *) (*strptr))[strleng] = '\0';
267c54dc 2961 strptr = NULL;
d64b6ad0
UD
2962 ++done;
2963 conv_error ();
2964 }
2965 else
2966 {
d90e1b42
UD
2967 *strptr = newstr;
2968 str = newstr + strleng;
2969 strsize = strleng + n + 1;
d64b6ad0
UD
2970 }
2971 }
2972
2973 str = __mempcpy (str, buf, n);
2974#endif
d90e1b42 2975 *str++ = '\0';
d64b6ad0
UD
2976
2977 if ((flags & MALLOC) && str - *strptr != strsize)
2978 {
2979 char *cp = (char *) realloc (*strptr, str - *strptr);
2980 if (cp != NULL)
2981 *strptr = cp;
2982 }
267c54dc 2983 strptr = NULL;
d64b6ad0 2984
2c6fe0bd
UD
2985 ++done;
2986 }
28f540f4
RM
2987 }
2988 break;
2989
d64b6ad0 2990 case L_('p'): /* Generic pointer. */
28f540f4
RM
2991 base = 16;
2992 /* A PTR must be the same size as a `long int'. */
0793d348 2993 flags &= ~(SHORT|LONGDBL);
859a09cf
UD
2994 if (need_long)
2995 flags |= LONG;
4c02bf1a 2996 flags |= READ_POINTER;
28f540f4 2997 goto number;
47b856a9
UD
2998
2999 default:
3000 /* If this is an unknown format character punt. */
27658f20 3001 conv_error ();
28f540f4
RM
3002 }
3003 }
3004
14ea22e9 3005 /* The last thing we saw int the format string was a white space.
05be689b
RM
3006 Consume the last white spaces. */
3007 if (skip_space)
3867ee64
RM
3008 {
3009 do
3010 c = inchar ();
655c0697 3011 while (ISSPACE (c));
3867ee64
RM
3012 ungetc (c, s);
3013 }
05be689b 3014
e3b22ad3 3015 errout:
7c713e28 3016 /* Unlock stream. */
c0fb8a56 3017 UNLOCK_STREAM (s);
aa1075ea 3018
95e83974 3019 scratch_buffer_free (&charbuf.scratch);
e3b22ad3
UD
3020 if (errp != NULL)
3021 *errp |= errval;
3022
a1ffb40e 3023 if (__glibc_unlikely (done == EOF))
267c54dc 3024 {
a1ffb40e 3025 if (__glibc_unlikely (ptrs_to_free != NULL))
267c54dc
UD
3026 {
3027 struct ptrs_to_free *p = ptrs_to_free;
3028 while (p != NULL)
3029 {
3030 for (size_t cnt = 0; cnt < p->count; ++cnt)
3031 {
3032 free (*p->ptrs[cnt]);
3033 *p->ptrs[cnt] = NULL;
3034 }
3035 p = p->next;
267c54dc
UD
3036 ptrs_to_free = p;
3037 }
3038 }
267c54dc 3039 }
a1ffb40e 3040 else if (__glibc_unlikely (strptr != NULL))
267c54dc
UD
3041 {
3042 free (*strptr);
3043 *strptr = NULL;
3044 }
3867ee64 3045 return done;
28f540f4
RM
3046}
3047
e3b22ad3 3048#ifdef COMPILE_WSCANF
d64b6ad0
UD
3049int
3050__vfwscanf (FILE *s, const wchar_t *format, va_list argptr)
3051{
3052 return _IO_vfwscanf (s, format, argptr, NULL);
3053}
c6251f03 3054ldbl_weak_alias (__vfwscanf, vfwscanf)
e3b22ad3 3055#else
b2518f55 3056int
c6251f03 3057___vfscanf (FILE *s, const char *format, va_list argptr)
b2518f55 3058{
c6251f03 3059 return _IO_vfscanf_internal (s, format, argptr, NULL);
b2518f55 3060}
c6251f03 3061ldbl_strong_alias (_IO_vfscanf_internal, _IO_vfscanf)
d18ea0c5 3062ldbl_hidden_def (_IO_vfscanf_internal, _IO_vfscanf)
c6251f03
RM
3063ldbl_strong_alias (___vfscanf, __vfscanf)
3064ldbl_hidden_def (___vfscanf, __vfscanf)
3065ldbl_weak_alias (___vfscanf, vfscanf)
d64b6ad0 3066#endif