Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libc / stdio / vfscanf.c
blob71e2c3e2222354ff0d9ec5acfe276d2a9a6ebfe3
1 /*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * and/or other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
19 FUNCTION
20 <<vfscanf>>, <<vscanf>>, <<vsscanf>>---format argument list
22 INDEX
23 vfscanf
24 INDEX
25 _vfscanf_r
26 INDEX
27 vscanf
28 INDEX
29 _vscanf_r
30 INDEX
31 vsscanf
32 INDEX
33 _vsscanf_r
35 SYNOPSIS
36 #include <stdio.h>
37 #include <stdarg.h>
38 int vscanf(const char *<[fmt]>, va_list <[list]>);
39 int vfscanf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
40 int vsscanf(const char *<[str]>, const char *<[fmt]>, va_list <[list]>);
42 int _vscanf_r(struct _reent *<[reent]>, const char *<[fmt]>,
43 va_list <[list]>);
44 int _vfscanf_r(struct _reent *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
45 va_list <[list]>);
46 int _vsscanf_r(struct _reent *<[reent]>, const char *<[str]>,
47 const char *<[fmt]>, va_list <[list]>);
49 DESCRIPTION
50 <<vscanf>>, <<vfscanf>>, and <<vsscanf>> are (respectively) variants
51 of <<scanf>>, <<fscanf>>, and <<sscanf>>. They differ only in
52 allowing their caller to pass the variable argument list as a
53 <<va_list>> object (initialized by <<va_start>>) rather than
54 directly accepting a variable number of arguments.
56 RETURNS
57 The return values are consistent with the corresponding functions:
58 <<vscanf>> returns the number of input fields successfully scanned,
59 converted, and stored; the return value does not include scanned
60 fields which were not stored.
62 If <<vscanf>> attempts to read at end-of-file, the return value
63 is <<EOF>>.
65 If no fields were stored, the return value is <<0>>.
67 The routines <<_vscanf_r>>, <<_vfscanf_f>>, and <<_vsscanf_r>> are
68 reentrant versions which take an additional first parameter which points to the
69 reentrancy structure.
71 PORTABILITY
72 These are GNU extensions.
74 Supporting OS subroutines required:
77 #include <_ansi.h>
78 #include <reent.h>
79 #include <newlib.h>
80 #include <ctype.h>
81 #include <wctype.h>
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <stdint.h>
85 #include <limits.h>
86 #include <wchar.h>
87 #include <string.h>
88 #include <stdarg.h>
89 #include <errno.h>
90 #include "local.h"
91 #include "../stdlib/local.h"
93 #ifdef INTEGER_ONLY
94 #define VFSCANF vfiscanf
95 #define _VFSCANF_R _vfiscanf_r
96 #define __SVFSCANF __svfiscanf
97 #ifdef STRING_ONLY
98 # define __SVFSCANF_R __ssvfiscanf_r
99 #else
100 # define __SVFSCANF_R __svfiscanf_r
101 #endif
102 #else
103 #define VFSCANF vfscanf
104 #define _VFSCANF_R _vfscanf_r
105 #define __SVFSCANF __svfscanf
106 #ifdef STRING_ONLY
107 # define __SVFSCANF_R __ssvfscanf_r
108 #else
109 # define __SVFSCANF_R __svfscanf_r
110 #endif
111 #ifndef NO_FLOATING_POINT
112 #define FLOATING_POINT
113 #endif
114 #endif
116 #ifdef STRING_ONLY
117 #undef _newlib_flockfile_start
118 #undef _newlib_flockfile_exit
119 #undef _newlib_flockfile_end
120 #define _newlib_flockfile_start(x) {}
121 #define _newlib_flockfile_exit(x) {}
122 #define _newlib_flockfile_end(x) {}
123 #define _ungetc_r _sungetc_r
124 #define __srefill_r __ssrefill_r
125 #define _fread_r _sfread_r
126 #endif
128 #ifdef FLOATING_POINT
129 #include <math.h>
130 #include <float.h>
131 #include <locale.h>
133 /* Currently a test is made to see if long double processing is warranted.
134 This could be changed in the future should the _ldtoa_r code be
135 preferred over _dtoa_r. */
136 #define _NO_LONGDBL
137 #if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
138 #undef _NO_LONGDBL
139 #endif
141 #include "floatio.h"
143 #define BUF (MAXEXP+MAXFRACT+MB_LEN_MAX+2) /* decimal point + sign + NUL */
145 /* An upper bound for how long a long prints in decimal. 4 / 13 approximates
146 log (2). Add one char for roundoff compensation and one for the sign. */
147 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2)
148 #else
149 #define BUF 40
150 #endif
152 #define _NO_LONGLONG
153 #if defined _WANT_IO_LONG_LONG \
154 && (defined __GNUC__ || __STDC_VERSION__ >= 199901L)
155 # undef _NO_LONGLONG
156 #endif
158 #define _NO_POS_ARGS
159 #ifdef _WANT_IO_POS_ARGS
160 # undef _NO_POS_ARGS
161 # ifdef NL_ARGMAX
162 # define MAX_POS_ARGS NL_ARGMAX
163 # else
164 # define MAX_POS_ARGS 32
165 # endif
167 static void * get_arg (int, va_list *, int *, void **);
168 #endif /* _WANT_IO_POS_ARGS */
171 * Flags used during conversion.
174 #define LONG 0x01 /* l: long or double */
175 #define LONGDBL 0x02 /* L/ll: long double or long long */
176 #define SHORT 0x04 /* h: short */
177 #define CHAR 0x08 /* hh: 8 bit integer */
178 #define SUPPRESS 0x10 /* suppress assignment */
179 #define POINTER 0x20 /* weird %p pointer (`fake hex') */
180 #define NOSKIP 0x40 /* do not skip blanks */
181 #define MALLOC 0x80 /* handle 'm' modifier */
184 * The following are used in numeric conversions only:
185 * SIGNOK, NDIGITS, DPTOK, EXPOK and HEXFLT are for floating point;
186 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
189 #define SIGNOK 0x80 /* +/- is (still) legal */
190 #define NDIGITS 0x100 /* no digits detected */
192 #define DPTOK 0x200 /* (float) decimal point is still legal */
193 #define EXPOK 0x400 /* (float) exponent (e+3, etc) still legal */
194 #define HEXFLT 0x800 /* (float) hex prefix found, expect hex float */
196 #define PFXOK 0x200 /* 0x prefix is (still) legal */
197 #define NZDIGITS 0x400 /* no zero digits detected */
198 #define NNZDIGITS 0x800 /* no non-zero digits detected */
201 * Conversion types.
204 #define CT_CHAR 0 /* %c conversion */
205 #define CT_CCL 1 /* %[...] conversion */
206 #define CT_STRING 2 /* %s conversion */
207 #define CT_INT 3 /* integer, i.e., strtol or strtoul */
208 #define CT_FLOAT 4 /* floating, i.e., strtod */
210 #define u_char unsigned char
211 #define u_long unsigned long
213 #ifndef _NO_LONGLONG
214 typedef unsigned long long u_long_long;
215 #endif
218 * vfscanf
221 #define BufferEmpty (fp->_r <= 0 && __srefill_r(rptr, fp))
223 #ifndef STRING_ONLY
225 #ifndef _REENT_ONLY
228 VFSCANF (register FILE *fp,
229 const char *fmt,
230 va_list ap)
232 struct _reent *reent = _REENT;
234 CHECK_INIT(reent, fp);
235 return __SVFSCANF_R (reent, fp, fmt, ap);
239 __SVFSCANF (register FILE *fp,
240 char const *fmt0,
241 va_list ap)
243 return __SVFSCANF_R (_REENT, fp, fmt0, ap);
246 #endif /* !_REENT_ONLY */
249 _VFSCANF_R (struct _reent *data,
250 register FILE *fp,
251 const char *fmt,
252 va_list ap)
254 CHECK_INIT(data, fp);
255 return __SVFSCANF_R (data, fp, fmt, ap);
257 #endif /* !STRING_ONLY */
259 #if defined (STRING_ONLY) && defined (INTEGER_ONLY)
260 /* When dealing with the sscanf family, we don't want to use the
261 * regular ungetc which will drag in file I/O items we don't need.
262 * So, we create our own trimmed-down version. */
264 _sungetc_r (struct _reent *data,
265 int c,
266 register FILE *fp)
268 if (c == EOF)
269 return (EOF);
271 /* After ungetc, we won't be at eof anymore */
272 fp->_flags &= ~__SEOF;
273 c = (unsigned char) c;
276 * If we are in the middle of ungetc'ing, just continue.
277 * This may require expanding the current ungetc buffer.
280 if (HASUB (fp))
282 if (fp->_r >= fp->_ub._size && __submore (data, fp))
284 return EOF;
286 *--fp->_p = c;
287 fp->_r++;
288 return c;
292 * If we can handle this by simply backing up, do so,
293 * but never replace the original character.
294 * (This makes sscanf() work when scanning `const' data.)
297 if (fp->_bf._base != NULL && fp->_p > fp->_bf._base && fp->_p[-1] == c)
299 fp->_p--;
300 fp->_r++;
301 return c;
305 * Create an ungetc buffer.
306 * Initially, we will use the `reserve' buffer.
309 fp->_ur = fp->_r;
310 fp->_up = fp->_p;
311 fp->_ub._base = fp->_ubuf;
312 fp->_ub._size = sizeof (fp->_ubuf);
313 fp->_ubuf[sizeof (fp->_ubuf) - 1] = c;
314 fp->_p = &fp->_ubuf[sizeof (fp->_ubuf) - 1];
315 fp->_r = 1;
316 return c;
319 /* String only version of __srefill_r for sscanf family. */
321 __ssrefill_r (struct _reent * ptr,
322 register FILE * fp)
325 * Our only hope of further input is the ungetc buffer.
326 * If there is anything in that buffer to read, return.
328 if (HASUB (fp))
330 FREEUB (ptr, fp);
331 if ((fp->_r = fp->_ur) != 0)
333 fp->_p = fp->_up;
334 return 0;
338 /* Otherwise we are out of character input. */
339 fp->_p = fp->_bf._base;
340 fp->_r = 0;
341 fp->_flags |= __SEOF;
342 return EOF;
345 size_t
346 _sfread_r (struct _reent * ptr,
347 void *buf,
348 size_t size,
349 size_t count,
350 FILE * fp)
352 register size_t resid;
353 register char *p;
354 register int r;
355 size_t total;
357 if ((resid = count * size) == 0)
358 return 0;
360 total = resid;
361 p = buf;
363 while (resid > (r = fp->_r))
365 (void) memcpy ((void *) p, (void *) fp->_p, (size_t) r);
366 fp->_p += r;
367 fp->_r = 0;
368 p += r;
369 resid -= r;
370 if (__ssrefill_r (ptr, fp))
372 /* no more input: return partial result */
373 return (total - resid) / size;
376 (void) memcpy ((void *) p, (void *) fp->_p, resid);
377 fp->_r -= resid;
378 fp->_p += resid;
379 return count;
381 #else /* !STRING_ONLY || !INTEGER_ONLY */
382 int _sungetc_r (struct _reent *, int, register FILE *);
383 int __ssrefill_r (struct _reent *, register FILE *);
384 size_t _sfread_r (struct _reent *, void *buf, size_t, size_t, FILE *);
385 #endif /* !STRING_ONLY || !INTEGER_ONLY */
387 static inline int
388 __wctob (struct _reent *rptr, wint_t wc)
390 mbstate_t mbs;
391 unsigned char pmb[MB_LEN_MAX];
393 if (wc == WEOF)
394 return EOF;
395 memset (&mbs, '\0', sizeof (mbs));
396 return __WCTOMB (rptr, (char *) pmb, wc, &mbs) == 1 ? (int) pmb[0] : 0;
400 __SVFSCANF_R (struct _reent *rptr,
401 register FILE *fp,
402 char const *fmt0,
403 va_list ap)
405 register u_char *fmt = (u_char *) fmt0;
406 register int c; /* character from format, or conversion */
407 register size_t width; /* field width, or 0 */
408 register char *p; /* points into all kinds of strings */
409 register int n; /* handy integer */
410 register int flags; /* flags as defined above */
411 register char *p0; /* saves original value of p when necessary */
412 int nassigned; /* number of fields assigned */
413 int nread; /* number of characters consumed from fp */
414 #ifndef _NO_POS_ARGS
415 int N; /* arg number */
416 int arg_index = 0; /* index into args processed directly */
417 int numargs = 0; /* number of varargs read */
418 void *args[MAX_POS_ARGS]; /* positional args read */
419 int is_pos_arg; /* is current format positional? */
420 #endif
421 int base = 0; /* base argument to strtol/strtoul */
422 int nbytes = 1; /* number of bytes read from fmt string */
423 wchar_t wc; /* wchar to use to read format string */
424 wchar_t *wcp; /* handy wide character pointer */
425 size_t mbslen = 0; /* length of converted multibyte sequence */
426 #ifdef _MB_CAPABLE
427 mbstate_t state; /* value to keep track of multibyte state */
428 #endif
429 #ifdef _WANT_IO_C99_FORMATS
430 #define _WANT_IO_POSIX_EXTENSIONS
431 #endif
432 #ifdef _WANT_IO_POSIX_EXTENSIONS
433 /* POSIX requires that fscanf frees all allocated strings from 'm'
434 conversions in case it returns EOF. m_ptr is used to keep track.
435 It will be allocated on the stack the first time an 'm' conversion
436 takes place, and it will be free'd on return from the function.
437 This implementation tries to save space by only allocating 8
438 pointer slots at a time. Most scenarios should never have to call
439 realloc again. This implementation allows only up to 65528 'm'
440 conversions per fscanf invocation for now. That should be enough
441 for almost all scenarios, right? */
442 struct m_ptrs {
443 void ***m_arr; /* Array of pointer args to 'm' conversion */
444 uint16_t m_siz; /* Number of slots in m_arr */
445 uint16_t m_cnt; /* Number of valid entries in m_arr */
446 } *m_ptr = NULL;
447 #define init_m_ptr() \
448 do \
450 if (!m_ptr) \
452 m_ptr = (struct m_ptrs *) alloca (sizeof *m_ptr); \
453 m_ptr->m_arr = NULL; \
454 m_ptr->m_siz = 0; \
455 m_ptr->m_cnt = 0; \
458 while (0)
459 #define push_m_ptr(arg) \
460 do \
462 if (m_ptr->m_cnt >= m_ptr->m_siz) \
464 void ***n = NULL; \
466 if (m_ptr->m_siz + 8 > 0 && m_ptr->m_siz + 8 < UINT16_MAX) \
467 n = (void ***) realloc (m_ptr->m_arr, \
468 (m_ptr->m_siz + 8) * \
469 sizeof (void **)); \
470 if (!n) \
472 nassigned = EOF; \
473 goto match_failure; \
475 m_ptr->m_arr = n; \
476 m_ptr->m_siz += 8; \
478 m_ptr->m_arr[m_ptr->m_cnt++] = (void **) (arg); \
480 while (0)
481 #define alloc_m_ptr(_type, _p, _p0, _p_p, _w) \
482 ({ \
483 _p_p = GET_ARG (N, ap, _type **); \
484 if (!_p_p) \
485 goto match_failure; \
486 _p0 = (_type *) malloc ((_w) * sizeof (_type)); \
487 if (!_p0) \
489 nassigned = EOF; \
490 goto match_failure; \
492 *_p_p = _p0; \
493 push_m_ptr (_p_p); \
494 _p = _p0; \
495 _w; \
497 /* For systems with wchar_t == 2 (UTF-16) check if there's room for
498 at least 2 wchar_t's (surrogate pairs). */
499 #define realloc_m_ptr(_type, _p, _p0, _p_p, _w) \
500 ({ \
501 size_t _nw = (_w); \
502 ptrdiff_t _dif = _p - _p0; \
503 if (_p_p && \
504 ((sizeof (_type) == 2 && _dif >= _nw - 1) \
505 || _dif >= _nw)) \
507 _p0 = (_type *) realloc (_p0, (_nw << 1) * sizeof (_type)); \
508 if (!_p0) \
510 nassigned = EOF; \
511 goto match_failure; \
513 _p = _p0 + _dif; \
514 *_p_p = _p0; \
515 _nw <<= 1; \
517 _nw; \
519 #define shrink_m_ptr(_type, _p_p, _w, _cw) \
520 ({ \
521 size_t _nw = (_w); \
522 if (_p_p && _nw < _cw) \
524 _type *_np_p = (_type *) \
525 realloc (*_p_p, _nw * sizeof (_type)); \
526 if (_np_p) \
527 *_p_p = _np_p; \
530 #define free_m_ptr() \
531 do \
533 if (m_ptr) \
535 if (nassigned == EOF) \
537 int i; \
538 for (i = 0; i < m_ptr->m_cnt; ++i) \
540 free (*m_ptr->m_arr[i]); \
541 *m_ptr->m_arr[i] = NULL; \
544 if (m_ptr->m_arr) \
545 free (m_ptr->m_arr); \
548 while (0)
549 #endif
551 #define CCFN_PARAMS (struct _reent *, const char *, char **, int)
552 u_long (*ccfn)CCFN_PARAMS=0; /* conversion function (strtol/strtoul) */
553 char ccltab[256]; /* character class table for %[...] */
554 char buf[BUF]; /* buffer for numeric conversions */
555 unsigned char *lptr; /* literal pointer */
557 char *cp;
558 short *sp;
559 int *ip;
560 #ifdef FLOATING_POINT
561 float *flp;
562 _LONG_DOUBLE *ldp;
563 double *dp;
564 #endif
565 long *lp;
566 #ifndef _NO_LONGLONG
567 long long *llp;
568 #endif
570 /* `basefix' is used to avoid `if' tests in the integer scanner */
571 static const short basefix[17] =
572 {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
574 /* Macro to support positional arguments */
575 #ifndef _NO_POS_ARGS
576 # define GET_ARG(n, ap, type) \
577 ((type) (is_pos_arg \
578 ? (n < numargs \
579 ? args[n] \
580 : get_arg (n, &ap, &numargs, args)) \
581 : (arg_index++ < numargs \
582 ? args[n] \
583 : (numargs < MAX_POS_ARGS \
584 ? args[numargs++] = va_arg (ap, void *) \
585 : va_arg (ap, void *)))))
586 #else
587 # define GET_ARG(n, ap, type) (va_arg (ap, type))
588 #endif
590 _newlib_flockfile_start (fp);
592 if (ORIENT (fp, -1) != -1)
594 nassigned = EOF;
595 goto all_done;
598 nassigned = 0;
599 nread = 0;
600 #ifdef _MB_CAPABLE
601 memset (&state, 0, sizeof (state));
602 #endif
604 for (;;)
606 #ifndef _MB_CAPABLE
607 wc = *fmt;
608 #else
609 nbytes = __MBTOWC (rptr, &wc, (char *) fmt, MB_CUR_MAX, &state);
610 if (nbytes < 0) {
611 wc = 0xFFFD; /* Unicode replacement character */
612 nbytes = 1;
613 memset (&state, 0, sizeof (state));
615 #endif
616 fmt += nbytes;
618 if (wc == 0)
619 goto all_done;
620 if (nbytes == 1 && isspace (wc))
622 for (;;)
624 if (BufferEmpty || !isspace (*fp->_p))
625 break;
626 nread++, fp->_r--, fp->_p++;
628 continue;
630 if (wc != '%')
631 goto literal;
632 width = 0;
633 flags = 0;
634 #ifndef _NO_POS_ARGS
635 N = arg_index;
636 is_pos_arg = 0;
637 #endif
640 * switch on the format. continue if done; break once format
641 * type is derived.
644 again:
645 c = *fmt++;
647 switch (c)
649 case '%':
650 literal:
651 lptr = fmt - nbytes;
652 for (n = 0; n < nbytes; ++n)
654 if (BufferEmpty)
655 goto input_failure;
656 if (*fp->_p != *lptr)
657 goto match_failure;
658 fp->_r--, fp->_p++;
659 nread++;
660 ++lptr;
662 continue;
664 case '*':
665 if ((flags & (CHAR | SHORT | LONG | LONGDBL | SUPPRESS | MALLOC))
666 || width)
667 goto match_failure;
668 flags |= SUPPRESS;
669 goto again;
670 case 'l':
671 if (flags & (CHAR | SHORT | LONG | LONGDBL))
672 goto match_failure;
673 #if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
674 if (*fmt == 'l') /* Check for 'll' = long long (SUSv3) */
676 ++fmt;
677 flags |= LONGDBL;
679 else
680 #endif
681 flags |= LONG;
682 goto again;
683 case 'L':
684 if (flags & (CHAR | SHORT | LONG | LONGDBL))
685 goto match_failure;
686 flags |= LONGDBL;
687 goto again;
688 case 'h':
689 if (flags & (CHAR | SHORT | LONG | LONGDBL))
690 goto match_failure;
691 #ifdef _WANT_IO_C99_FORMATS
692 if (*fmt == 'h') /* Check for 'hh' = char int (SUSv3) */
694 ++fmt;
695 flags |= CHAR;
697 else
698 #endif
699 flags |= SHORT;
700 goto again;
701 #ifdef _WANT_IO_C99_FORMATS
702 case 'j': /* intmax_t */
703 if (flags & (CHAR | SHORT | LONG | LONGDBL))
704 goto match_failure;
705 if (sizeof (intmax_t) == sizeof (long))
706 flags |= LONG;
707 else
708 flags |= LONGDBL;
709 goto again;
710 case 't': /* ptrdiff_t */
711 if (flags & (CHAR | SHORT | LONG | LONGDBL))
712 goto match_failure;
713 if (sizeof (ptrdiff_t) < sizeof (int))
714 /* POSIX states ptrdiff_t is 16 or more bits, as
715 is short. */
716 flags |= SHORT;
717 else if (sizeof (ptrdiff_t) == sizeof (int))
718 /* no flag needed */;
719 else if (sizeof (ptrdiff_t) <= sizeof (long))
720 flags |= LONG;
721 else
722 /* POSIX states that at least one programming
723 environment must support ptrdiff_t no wider than
724 long, but that means other environments can
725 have ptrdiff_t as wide as long long. */
726 flags |= LONGDBL;
727 goto again;
728 case 'z': /* size_t */
729 if (flags & (CHAR | SHORT | LONG | LONGDBL))
730 goto match_failure;
731 if (sizeof (size_t) < sizeof (int))
732 /* POSIX states size_t is 16 or more bits, as is short. */
733 flags |= SHORT;
734 else if (sizeof (size_t) == sizeof (int))
735 /* no flag needed */;
736 else if (sizeof (size_t) <= sizeof (long))
737 flags |= LONG;
738 else
739 /* POSIX states that at least one programming
740 environment must support size_t no wider than
741 long, but that means other environments can
742 have size_t as wide as long long. */
743 flags |= LONGDBL;
744 goto again;
745 #endif /* _WANT_IO_C99_FORMATS */
746 #ifdef _WANT_IO_POSIX_EXTENSIONS
747 case 'm':
748 if (flags & (CHAR | SHORT | LONG | LONGDBL | MALLOC))
749 goto match_failure;
750 init_m_ptr ();
751 flags |= MALLOC;
752 goto again;
753 #endif
755 case '0':
756 case '1':
757 case '2':
758 case '3':
759 case '4':
760 case '5':
761 case '6':
762 case '7':
763 case '8':
764 case '9':
765 if (flags & (CHAR | SHORT | LONG | LONGDBL | MALLOC))
766 goto match_failure;
767 width = width * 10 + c - '0';
768 goto again;
770 #ifndef _NO_POS_ARGS
771 case '$':
772 if (flags & (CHAR | SHORT | LONG | LONGDBL | SUPPRESS | MALLOC))
773 goto match_failure;
774 if (width <= MAX_POS_ARGS)
776 N = width - 1;
777 is_pos_arg = 1;
778 width = 0;
779 goto again;
781 _REENT_ERRNO(rptr) = EINVAL;
782 goto input_failure;
783 #endif /* !_NO_POS_ARGS */
786 * Conversions. Those marked `compat' are for
787 * 4.[123]BSD compatibility.
789 * (According to ANSI, E and X formats are supposed to
790 * the same as e and x. Sorry about that.)
793 case 'D': /* compat */
794 flags |= LONG;
795 /* FALLTHROUGH */
796 case 'd':
797 c = CT_INT;
798 ccfn = (u_long (*)CCFN_PARAMS)_strtol_r;
799 base = 10;
800 break;
802 case 'i':
803 c = CT_INT;
804 ccfn = (u_long (*)CCFN_PARAMS)_strtol_r;
805 base = 0;
806 break;
808 case 'O': /* compat */
809 flags |= LONG;
810 /* FALLTHROUGH */
811 case 'o':
812 c = CT_INT;
813 ccfn = _strtoul_r;
814 base = 8;
815 break;
817 case 'u':
818 c = CT_INT;
819 ccfn = _strtoul_r;
820 base = 10;
821 break;
823 case 'X':
824 case 'x':
825 flags |= PFXOK; /* enable 0x prefixing */
826 c = CT_INT;
827 ccfn = _strtoul_r;
828 base = 16;
829 break;
831 #ifdef FLOATING_POINT
832 # ifdef _WANT_IO_C99_FORMATS
833 case 'a':
834 case 'A':
835 case 'F':
836 # endif
837 case 'E':
838 case 'G':
839 case 'e':
840 case 'f':
841 case 'g':
842 c = CT_FLOAT;
843 break;
844 #endif
846 #ifdef _WANT_IO_C99_FORMATS
847 case 'S':
848 flags |= LONG;
849 /* FALLTHROUGH */
850 #endif
852 case 's':
853 c = CT_STRING;
854 break;
856 case '[':
857 fmt = (u_char *) __sccl (ccltab, (unsigned char *) fmt);
858 flags |= NOSKIP;
859 c = CT_CCL;
860 break;
862 #ifdef _WANT_IO_C99_FORMATS
863 case 'C':
864 flags |= LONG;
865 /* FALLTHROUGH */
866 #endif
868 case 'c':
869 flags |= NOSKIP;
870 c = CT_CHAR;
871 break;
873 case 'p': /* pointer format is like hex */
874 flags |= POINTER | PFXOK;
875 c = CT_INT;
876 ccfn = _strtoul_r;
877 base = 16;
878 break;
880 case 'n':
881 if (flags & SUPPRESS) /* ??? */
882 continue;
883 #ifdef _WANT_IO_C99_FORMATS
884 if (flags & CHAR)
886 cp = GET_ARG (N, ap, char *);
887 *cp = nread;
889 else
890 #endif
891 if (flags & SHORT)
893 sp = GET_ARG (N, ap, short *);
894 *sp = nread;
896 else if (flags & LONG)
898 lp = GET_ARG (N, ap, long *);
899 *lp = nread;
901 #ifndef _NO_LONGLONG
902 else if (flags & LONGDBL)
904 llp = GET_ARG (N, ap, long long*);
905 *llp = nread;
907 #endif
908 else
910 ip = GET_ARG (N, ap, int *);
911 *ip = nread;
913 continue;
915 default:
916 goto match_failure;
920 * We have a conversion that requires input.
922 if (BufferEmpty)
923 goto input_failure;
926 * Consume leading white space, except for formats that
927 * suppress this.
929 if ((flags & NOSKIP) == 0)
931 while (isspace (*fp->_p))
933 nread++;
934 if (--fp->_r > 0)
935 fp->_p++;
936 else
937 if (__srefill_r (rptr, fp))
938 goto input_failure;
941 * Note that there is at least one character in the
942 * buffer, so conversions that do not set NOSKIP ca
943 * no longer result in an input failure.
948 * Do the conversion.
950 switch (c)
953 case CT_CHAR:
954 /* scan arbitrary characters (sets NOSKIP) */
955 if (width == 0)
956 width = 1;
957 #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
958 if (flags & LONG)
960 #ifdef _WANT_IO_POSIX_EXTENSIONS
961 wchar_t **wcp_p = NULL;
962 wchar_t *wcp0 = NULL;
963 size_t wcp_siz = 0;
964 #endif
965 mbstate_t state;
966 if (flags & SUPPRESS)
967 wcp = NULL;
968 #ifdef _WANT_IO_POSIX_EXTENSIONS
969 else if (flags & MALLOC)
970 wcp_siz = alloc_m_ptr (wchar_t, wcp, wcp0, wcp_p, 32);
971 #endif
972 else
973 wcp = GET_ARG (N, ap, wchar_t *);
974 n = 0;
975 while (width != 0)
977 if (n == MB_CUR_MAX)
978 goto input_failure;
979 buf[n++] = *fp->_p;
980 fp->_r -= 1;
981 fp->_p += 1;
982 /* Got a high surrogate, allow low surrogate to slip
983 through */
984 if (mbslen != 3 || state.__count != 4)
985 memset (&state, 0, sizeof (mbstate_t));
986 if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state))
987 == (size_t)-1)
988 goto input_failure; /* Invalid sequence */
989 if (mbslen == 0 && !(flags & SUPPRESS))
990 *wcp = L'\0';
991 if (mbslen != (size_t)-2) /* Incomplete sequence */
993 nread += n;
994 /* Handle high surrogate */
995 if (mbslen != 3 || state.__count != 4)
996 width -= 1;
997 if (!(flags & SUPPRESS))
999 #ifdef _WANT_IO_POSIX_EXTENSIONS
1000 wcp_siz = realloc_m_ptr (wchar_t, wcp, wcp0, wcp_p,
1001 wcp_siz);
1002 #endif
1003 wcp++;
1005 n = 0;
1007 if (BufferEmpty)
1009 if (n != 0)
1010 goto input_failure;
1011 break;
1014 #ifdef _WANT_IO_POSIX_EXTENSIONS
1015 shrink_m_ptr (wchar_t, wcp_p, wcp - wcp0, wcp_siz);
1016 #endif
1017 if (!(flags & SUPPRESS))
1018 nassigned++;
1020 else
1021 #endif /* ELIX_LEVEL */
1022 if (flags & SUPPRESS)
1024 size_t sum = 0;
1025 for (;;)
1027 if ((n = fp->_r) < (int)width)
1029 sum += n;
1030 width -= n;
1031 fp->_p += n;
1032 if (__srefill_r (rptr, fp))
1034 if (sum == 0)
1035 goto input_failure;
1036 break;
1039 else
1041 sum += width;
1042 fp->_r -= width;
1043 fp->_p += width;
1044 break;
1047 nread += sum;
1049 else
1051 size_t r;
1052 #ifdef _WANT_IO_POSIX_EXTENSIONS
1053 char **p_p = NULL;
1054 if (flags & MALLOC)
1055 alloc_m_ptr (char, p, p0, p_p, width);
1056 else
1057 #endif
1058 p = GET_ARG (N, ap, char *);
1059 r = _fread_r (rptr, p, 1, width, fp);
1060 if (r == 0)
1061 goto input_failure;
1062 #ifdef _WANT_IO_POSIX_EXTENSIONS
1063 shrink_m_ptr (char, p_p, r, width);
1064 #endif
1065 nread += r;
1066 nassigned++;
1068 break;
1070 case CT_CCL:
1071 /* scan a (nonempty) character class (sets NOSKIP) */
1072 if (width == 0)
1073 width = SIZE_MAX;
1074 /* take only those things in the class */
1075 #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
1076 if (flags & LONG)
1078 #ifdef _WANT_IO_POSIX_EXTENSIONS
1079 wchar_t **wcp_p = NULL;
1080 wchar_t *wcp0 = NULL;
1081 size_t wcp_siz = 0;
1082 #endif
1083 mbstate_t state;
1084 if (flags & SUPPRESS)
1085 wcp = &wc;
1086 #ifdef _WANT_IO_POSIX_EXTENSIONS
1087 else if (flags & MALLOC)
1088 wcp_siz = alloc_m_ptr (wchar_t, wcp, wcp0, wcp_p, 32);
1089 #endif
1090 else
1091 wcp = GET_ARG (N, ap, wchar_t *);
1092 n = 0;
1093 while (width != 0) {
1094 if (n == MB_CUR_MAX)
1095 goto input_failure;
1096 buf[n++] = *fp->_p;
1097 fp->_r -= 1;
1098 fp->_p += 1;
1099 /* Got a high surrogate, allow low surrogate to slip
1100 through */
1101 if (mbslen != 3 || state.__count != 4)
1102 memset (&state, 0, sizeof (mbstate_t));
1103 if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state))
1104 == (size_t)-1)
1105 goto input_failure;
1106 if (mbslen == 0)
1107 *wcp = L'\0';
1108 if (mbslen != (size_t)-2) /* Incomplete sequence */
1110 if (!ccltab[__wctob (rptr, *wcp)])
1112 while (n != 0)
1113 _ungetc_r (rptr, (unsigned char) buf[--n], fp);
1114 break;
1116 nread += n;
1117 /* Handle high surrogate */
1118 if (mbslen != 3 || state.__count != 4)
1119 width -= 1;
1120 if ((flags & SUPPRESS) == 0)
1122 wcp += 1;
1123 #ifdef _WANT_IO_POSIX_EXTENSIONS
1124 wcp_siz = realloc_m_ptr (wchar_t, wcp, wcp0, wcp_p,
1125 wcp_siz);
1126 #endif
1128 n = 0;
1130 if (BufferEmpty)
1132 if (n != 0)
1133 goto input_failure;
1134 break;
1137 if (!(flags & SUPPRESS))
1139 *wcp = L'\0';
1140 #ifdef _WANT_IO_POSIX_EXTENSIONS
1141 shrink_m_ptr (wchar_t, wcp_p, wcp - wcp0 + 1, wcp_siz);
1142 #endif
1143 nassigned++;
1146 else
1147 #endif /* ELIX_LEVEL */
1148 if (flags & SUPPRESS)
1150 n = 0;
1151 while (ccltab[*fp->_p])
1153 n++, fp->_r--, fp->_p++;
1154 if (--width == 0)
1155 break;
1156 if (BufferEmpty)
1158 if (n == 0)
1159 goto input_failure;
1160 break;
1163 if (n == 0)
1164 goto match_failure;
1165 nread += n;
1167 else
1169 #ifdef _WANT_IO_POSIX_EXTENSIONS
1170 char **p_p = NULL;
1171 size_t p_siz = 0;
1173 if (flags & MALLOC)
1174 p_siz = alloc_m_ptr (char, p, p0, p_p, 32);
1175 else
1176 #endif
1177 p0 = p = GET_ARG (N, ap, char *);
1178 while (ccltab[*fp->_p])
1180 fp->_r--;
1181 *p++ = *fp->_p++;
1182 #ifdef _WANT_IO_POSIX_EXTENSIONS
1183 p_siz = realloc_m_ptr (char, p, p0, p_p, p_siz);
1184 #endif
1185 if (--width == 0)
1186 break;
1187 if (BufferEmpty)
1189 if (p == p0)
1190 goto input_failure;
1191 break;
1194 n = p - p0;
1195 if (n == 0)
1196 goto match_failure;
1197 *p = 0;
1198 #ifdef _WANT_IO_POSIX_EXTENSIONS
1199 shrink_m_ptr (char, p_p, n + 1, p_siz);
1200 #endif
1201 nassigned++;
1202 nread += n;
1204 break;
1206 case CT_STRING:
1207 /* like CCL, but zero-length string OK, & no NOSKIP */
1208 if (width == 0)
1209 width = SIZE_MAX;
1210 #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
1211 if (flags & LONG)
1213 #ifdef _WANT_IO_POSIX_EXTENSIONS
1214 wchar_t **wcp_p = NULL;
1215 wchar_t *wcp0 = NULL;
1216 size_t wcp_siz = 0;
1217 #endif
1218 /* Process %S and %ls placeholders */
1219 mbstate_t state;
1220 if (flags & SUPPRESS)
1221 wcp = &wc;
1222 #ifdef _WANT_IO_POSIX_EXTENSIONS
1223 else if (flags & MALLOC)
1224 wcp_siz = alloc_m_ptr (wchar_t, wcp, wcp0, wcp_p, 32);
1225 #endif
1226 else
1227 wcp = GET_ARG (N, ap, wchar_t *);
1228 n = 0;
1229 while (!isspace (*fp->_p) && width != 0)
1231 if (n == MB_CUR_MAX)
1232 goto input_failure;
1233 buf[n++] = *fp->_p;
1234 fp->_r -= 1;
1235 fp->_p += 1;
1236 /* Got a high surrogate, allow low surrogate to slip
1237 through */
1238 if (mbslen != 3 || state.__count != 4)
1239 memset (&state, 0, sizeof (mbstate_t));
1240 if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state))
1241 == (size_t)-1)
1242 goto input_failure;
1243 if (mbslen == 0)
1244 *wcp = L'\0';
1245 if (mbslen != (size_t)-2) /* Incomplete sequence */
1247 if (iswspace(*wcp))
1249 while (n != 0)
1250 _ungetc_r (rptr, (unsigned char) buf[--n], fp);
1251 break;
1253 nread += n;
1254 /* Handle high surrogate */
1255 if (mbslen != 3 || state.__count != 4)
1256 width -= 1;
1257 if ((flags & SUPPRESS) == 0)
1259 wcp += 1;
1260 #ifdef _WANT_IO_POSIX_EXTENSIONS
1261 wcp_siz = realloc_m_ptr (wchar_t, wcp, wcp0, wcp_p,
1262 wcp_siz);
1263 #endif
1265 n = 0;
1267 if (BufferEmpty)
1269 if (n != 0)
1270 goto input_failure;
1271 break;
1274 if (!(flags & SUPPRESS))
1276 *wcp = L'\0';
1277 #ifdef _WANT_IO_POSIX_EXTENSIONS
1278 shrink_m_ptr (wchar_t, wcp_p, wcp - wcp0 + 1, wcp_siz);
1279 #endif
1280 nassigned++;
1283 else
1284 #endif
1285 if (flags & SUPPRESS)
1287 n = 0;
1288 while (!isspace (*fp->_p))
1290 n++, fp->_r--, fp->_p++;
1291 if (--width == 0)
1292 break;
1293 if (BufferEmpty)
1294 break;
1296 nread += n;
1298 else
1300 #ifdef _WANT_IO_POSIX_EXTENSIONS
1301 char **p_p = NULL;
1302 size_t p_siz = 0;
1304 if (flags & MALLOC)
1305 p_siz = alloc_m_ptr (char, p, p0, p_p, 32);
1306 else
1307 #endif
1308 p0 = GET_ARG (N, ap, char *);
1309 p = p0;
1310 while (!isspace (*fp->_p))
1312 fp->_r--;
1313 *p++ = *fp->_p++;
1314 #ifdef _WANT_IO_POSIX_EXTENSIONS
1315 p_siz = realloc_m_ptr (char, p, p0, p_p, p_siz);
1316 #endif
1317 if (--width == 0)
1318 break;
1319 if (BufferEmpty)
1320 break;
1322 *p = 0;
1323 #ifdef _WANT_IO_POSIX_EXTENSIONS
1324 shrink_m_ptr (char, p_p, p - p0 + 1, p_siz);
1325 #endif
1326 nread += p - p0;
1327 nassigned++;
1329 continue;
1331 case CT_INT:
1333 /* scan an integer as if by strtol/strtoul */
1334 unsigned width_left = 0;
1335 int skips = 0;
1336 #ifdef hardway
1337 if (width == 0 || width > sizeof (buf) - 1)
1338 #else
1339 /* size_t is unsigned, hence this optimisation */
1340 if (width - 1 > sizeof (buf) - 2)
1341 #endif
1343 width_left = width - (sizeof (buf) - 1);
1344 width = sizeof (buf) - 1;
1346 flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;
1347 for (p = buf; width; width--)
1349 c = *fp->_p;
1351 * Switch on the character; `goto ok' if we
1352 * accept it as a part of number.
1354 switch (c)
1357 * The digit 0 is always legal, but is special.
1358 * For %i conversions, if no digits (zero or nonzero)
1359 * have been scanned (only signs), we will have base==0.
1360 * In that case, we should set it to 8 and enable 0x
1361 * prefixing. Also, if we have not scanned zero digits
1362 * before this, do not turn off prefixing (someone else
1363 * will turn it off if we have scanned any nonzero digits).
1365 case '0':
1366 if (! (flags & NNZDIGITS))
1367 goto ok;
1368 if (base == 0)
1370 base = 8;
1371 flags |= PFXOK;
1373 if (flags & NZDIGITS)
1375 flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
1376 goto ok;
1378 flags &= ~(SIGNOK | PFXOK | NDIGITS);
1379 if (width_left)
1381 width_left--;
1382 width++;
1384 ++skips;
1385 goto skip;
1387 /* 1 through 7 always legal */
1388 case '1':
1389 case '2':
1390 case '3':
1391 case '4':
1392 case '5':
1393 case '6':
1394 case '7':
1395 base = basefix[base];
1396 flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
1397 goto ok;
1399 /* digits 8 and 9 ok iff decimal or hex */
1400 case '8':
1401 case '9':
1402 base = basefix[base];
1403 if (base <= 8)
1404 break; /* not legal here */
1405 flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
1406 goto ok;
1408 /* letters ok iff hex */
1409 case 'A':
1410 case 'B':
1411 case 'C':
1412 case 'D':
1413 case 'E':
1414 case 'F':
1415 case 'a':
1416 case 'b':
1417 case 'c':
1418 case 'd':
1419 case 'e':
1420 case 'f':
1421 /* no need to fix base here */
1422 if (base <= 10)
1423 break; /* not legal here */
1424 flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
1425 goto ok;
1427 /* sign ok only as first character */
1428 case '+':
1429 case '-':
1430 if (flags & SIGNOK)
1432 flags &= ~SIGNOK;
1433 goto ok;
1435 break;
1437 /* x ok iff flag still set & single 0 seen */
1438 case 'x':
1439 case 'X':
1440 if ((flags & (PFXOK | NZDIGITS)) == PFXOK)
1442 base = 16;/* if %i */
1443 flags &= ~PFXOK;
1444 /* We must reset the NZDIGITS and NDIGITS
1445 flags that would have been unset by seeing
1446 the zero that preceded the X or x. */
1447 flags |= NZDIGITS | NDIGITS;
1448 goto ok;
1450 break;
1454 * If we got here, c is not a legal character
1455 * for a number. Stop accumulating digits.
1457 break;
1460 * c is legal: store it and look at the next.
1462 *p++ = c;
1463 skip:
1464 if (--fp->_r > 0)
1465 fp->_p++;
1466 else
1467 if (__srefill_r (rptr, fp))
1468 break; /* EOF */
1471 * If we had only a sign, it is no good; push back the sign.
1472 * If the number ends in `x', it was [sign] '0' 'x', so push back
1473 * the x and treat it as [sign] '0'.
1474 * Use of ungetc here and below assumes ASCII encoding; we are only
1475 * pushing back 7-bit characters, so casting to unsigned char is
1476 * not necessary.
1478 if (flags & NDIGITS)
1480 if (p > buf)
1481 _ungetc_r (rptr, *--p, fp); /* [-+xX] */
1482 if (p == buf)
1483 goto match_failure;
1485 if ((flags & SUPPRESS) == 0)
1487 u_long res;
1489 *p = 0;
1490 res = (*ccfn) (rptr, buf, (char **) NULL, base);
1491 if (flags & POINTER)
1493 void **vp = GET_ARG (N, ap, void **);
1494 #ifndef _NO_LONGLONG
1495 if (sizeof (uintptr_t) > sizeof (u_long))
1497 u_long_long resll;
1498 resll = _strtoull_r (rptr, buf, (char **) NULL, base);
1499 *vp = (void *) (uintptr_t) resll;
1501 else
1502 #endif /* !_NO_LONGLONG */
1503 *vp = (void *) (uintptr_t) res;
1505 #ifdef _WANT_IO_C99_FORMATS
1506 else if (flags & CHAR)
1508 cp = GET_ARG (N, ap, char *);
1509 *cp = res;
1511 #endif
1512 else if (flags & SHORT)
1514 sp = GET_ARG (N, ap, short *);
1515 *sp = res;
1517 else if (flags & LONG)
1519 lp = GET_ARG (N, ap, long *);
1520 *lp = res;
1522 #ifndef _NO_LONGLONG
1523 else if (flags & LONGDBL)
1525 u_long_long resll;
1526 if (ccfn == _strtoul_r)
1527 resll = _strtoull_r (rptr, buf, (char **) NULL, base);
1528 else
1529 resll = _strtoll_r (rptr, buf, (char **) NULL, base);
1530 llp = GET_ARG (N, ap, long long*);
1531 *llp = resll;
1533 #endif
1534 else
1536 ip = GET_ARG (N, ap, int *);
1537 *ip = res;
1539 nassigned++;
1541 nread += p - buf + skips;
1542 break;
1544 #ifdef FLOATING_POINT
1545 case CT_FLOAT:
1547 /* scan a floating point number as if by strtod */
1548 /* This code used to assume that the number of digits is reasonable.
1549 However, ANSI / ISO C makes no such stipulation; we have to get
1550 exact results even when there is an unreasonable amount of
1551 leading zeroes. */
1552 long leading_zeroes = 0;
1553 long zeroes, exp_adjust;
1554 char *exp_start = NULL;
1555 unsigned width_left = 0;
1556 char nancount = 0;
1557 char infcount = 0;
1558 const char *decpt = _localeconv_r (rptr)->decimal_point;
1559 #ifdef _MB_CAPABLE
1560 int decptpos = 0;
1561 #endif
1562 #ifdef hardway
1563 if (width == 0 || width > sizeof (buf) - 1)
1564 #else
1565 /* size_t is unsigned, hence this optimisation */
1566 if (width - 1 > sizeof (buf) - 2)
1567 #endif
1569 width_left = width - (sizeof (buf) - 1);
1570 width = sizeof (buf) - 1;
1572 flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
1573 zeroes = 0;
1574 exp_adjust = 0;
1575 for (p = buf; width; )
1577 c = *fp->_p;
1579 * This code mimicks the integer conversion
1580 * code, but is much simpler.
1582 switch (c)
1584 case '0':
1585 if (flags & NDIGITS)
1587 flags &= ~SIGNOK;
1588 zeroes++;
1589 if (width_left)
1591 width_left--;
1592 width++;
1594 goto fskip;
1596 /* Fall through. */
1597 case '1':
1598 case '2':
1599 case '3':
1600 case '4':
1601 case '5':
1602 case '6':
1603 case '7':
1604 case '8':
1605 case '9':
1606 if (nancount + infcount == 0)
1608 flags &= ~(SIGNOK | NDIGITS);
1609 goto fok;
1611 break;
1613 /* Chars a, e and f have various special meanings apart from
1614 their hex value. They are handled separately, see below. */
1615 case 'b':
1616 case 'B':
1617 case 'c':
1618 case 'C':
1619 case 'd':
1620 case 'D':
1621 if ((flags & HEXFLT) && nancount + infcount == 0)
1623 flags &= ~(SIGNOK | NDIGITS);
1624 goto fok;
1626 break;
1628 case 'x':
1629 case 'X':
1630 /* Did we have exactly one leading zero yet? */
1631 if ((flags & (SIGNOK | NDIGITS | HEXFLT)) == NDIGITS
1632 && zeroes == 1)
1634 flags |= HEXFLT;
1635 flags &= ~NDIGITS;
1636 /* We skipped the first zero, so we have to add
1637 it now to the buffer. */
1638 *p++ = '0';
1639 width--;
1640 zeroes = 0;
1641 goto fok;
1643 break;
1645 case '+':
1646 case '-':
1647 if (flags & SIGNOK)
1649 flags &= ~SIGNOK;
1650 goto fok;
1652 break;
1653 case 'n':
1654 case 'N':
1655 if (nancount == 0 && zeroes == 0
1656 && (flags & (NDIGITS | DPTOK | EXPOK)) ==
1657 (NDIGITS | DPTOK | EXPOK))
1659 flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
1660 nancount = 1;
1661 goto fok;
1663 if (nancount == 2)
1665 nancount = 3;
1666 goto fok;
1668 if (infcount == 1 || infcount == 4)
1670 infcount++;
1671 goto fok;
1673 break;
1674 case 'a':
1675 case 'A':
1676 if ((flags & HEXFLT) && nancount + infcount == 0)
1678 flags &= ~(SIGNOK | NDIGITS);
1679 goto fok;
1681 if (nancount == 1)
1683 nancount = 2;
1684 goto fok;
1686 break;
1687 case 'i':
1688 case 'I':
1689 if (infcount == 0 && zeroes == 0
1690 && (flags & (NDIGITS | DPTOK | EXPOK)) ==
1691 (NDIGITS | DPTOK | EXPOK))
1693 flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
1694 infcount = 1;
1695 goto fok;
1697 if (infcount == 3 || infcount == 5)
1699 infcount++;
1700 goto fok;
1702 break;
1703 case 'f':
1704 case 'F':
1705 if ((flags & HEXFLT) && nancount + infcount == 0)
1707 flags &= ~(SIGNOK | NDIGITS);
1708 goto fok;
1710 if (infcount == 2)
1712 infcount = 3;
1713 goto fok;
1715 break;
1716 case 't':
1717 case 'T':
1718 if (infcount == 6)
1720 infcount = 7;
1721 goto fok;
1723 break;
1724 case 'y':
1725 case 'Y':
1726 if (infcount == 7)
1728 infcount = 8;
1729 goto fok;
1731 break;
1733 case 'p':
1734 case 'P':
1735 /* p is the exponent marker in hex case. */
1736 if (!(flags & HEXFLT))
1737 break;
1738 goto fexp;
1739 case 'e':
1740 case 'E':
1741 /* e is just a digit in hex case, not the exponent marker. */
1742 if (flags & HEXFLT)
1744 if (nancount + infcount == 0)
1746 flags &= ~(SIGNOK | NDIGITS);
1747 goto fok;
1749 break;
1752 fexp:
1753 /* no exponent without some digits */
1754 if ((flags & (NDIGITS | EXPOK)) == EXPOK
1755 || ((flags & EXPOK) && zeroes))
1757 if (! (flags & DPTOK))
1759 exp_adjust = zeroes - leading_zeroes;
1760 exp_start = p;
1762 flags =
1763 (flags & ~(EXPOK | DPTOK | HEXFLT)) |
1764 SIGNOK | NDIGITS;
1765 zeroes = 0;
1766 goto fok;
1768 break;
1769 default:
1770 #ifndef _MB_CAPABLE
1771 if ((unsigned char) c == (unsigned char) decpt[0]
1772 && (flags & DPTOK))
1774 flags &= ~(SIGNOK | DPTOK);
1775 leading_zeroes = zeroes;
1776 goto fok;
1778 break;
1779 #else
1780 if (flags & DPTOK)
1782 while ((unsigned char) c
1783 == (unsigned char) decpt[decptpos])
1785 if (decpt[++decptpos] == '\0')
1787 /* We read the complete decpt seq. */
1788 flags &= ~(SIGNOK | DPTOK);
1789 leading_zeroes = zeroes;
1790 p = stpncpy (p, decpt, decptpos);
1791 decptpos = 0;
1792 goto fskip;
1794 ++nread;
1795 if (--fp->_r > 0)
1796 fp->_p++;
1797 else if (__srefill_r (rptr, fp))
1798 break; /* EOF */
1799 c = *fp->_p;
1801 if (decptpos > 0)
1803 /* We read part of a multibyte decimal point,
1804 but the rest is invalid or we're at EOF,
1805 so back off. */
1806 while (decptpos-- > 0)
1808 _ungetc_r (rptr, (unsigned char) decpt[decptpos],
1809 fp);
1810 --nread;
1814 break;
1815 #endif
1817 break;
1818 fok:
1819 *p++ = c;
1820 fskip:
1821 width--;
1822 ++nread;
1823 if (--fp->_r > 0)
1824 fp->_p++;
1825 else
1826 if (__srefill_r (rptr, fp))
1827 break; /* EOF */
1829 if (zeroes)
1830 flags &= ~NDIGITS;
1831 /* We may have a 'N' or possibly even [sign] 'N' 'a' as the
1832 start of 'NaN', only to run out of chars before it was
1833 complete (or having encountered a non-matching char). So
1834 check here if we have an outstanding nancount, and if so
1835 put back the chars we did swallow and treat as a failed
1836 match.
1838 FIXME - we still don't handle NAN([0xdigits]). */
1839 if (nancount - 1U < 2U) /* nancount && nancount < 3 */
1841 /* Newlib's ungetc works even if we called __srefill in
1842 the middle of a partial parse, but POSIX does not
1843 guarantee that in all implementations of ungetc. */
1844 while (p > buf)
1846 _ungetc_r (rptr, *--p, fp); /* [-+nNaA] */
1847 --nread;
1849 goto match_failure;
1851 /* Likewise for 'inf' and 'infinity'. But be careful that
1852 'infinite' consumes only 3 characters, leaving the stream
1853 at the second 'i'. */
1854 if (infcount - 1U < 7U) /* infcount && infcount < 8 */
1856 if (infcount >= 3) /* valid 'inf', but short of 'infinity' */
1857 while (infcount-- > 3)
1859 _ungetc_r (rptr, *--p, fp); /* [iInNtT] */
1860 --nread;
1862 else
1864 while (p > buf)
1866 _ungetc_r (rptr, *--p, fp); /* [-+iInN] */
1867 --nread;
1869 goto match_failure;
1873 * If no digits, might be missing exponent digits
1874 * (just give back the exponent) or might be missing
1875 * regular digits, but had sign and/or decimal point.
1877 if (flags & NDIGITS)
1879 if (flags & EXPOK)
1881 /* no digits at all */
1882 while (p > buf)
1884 _ungetc_r (rptr, *--p, fp); /* [-+.] */
1885 --nread;
1887 goto match_failure;
1889 /* just a bad exponent (e and maybe sign) */
1890 c = *--p;
1891 --nread;
1892 if (c != 'e' && c != 'E')
1894 _ungetc_r (rptr, c, fp); /* [-+] */
1895 c = *--p;
1896 --nread;
1898 _ungetc_r (rptr, c, fp); /* [eE] */
1900 if ((flags & SUPPRESS) == 0)
1902 double res = 0;
1903 #ifdef _NO_LONGDBL
1904 #define QUAD_RES res;
1905 #else /* !_NO_LONG_DBL */
1906 long double qres = 0;
1907 #define QUAD_RES qres;
1908 #endif /* !_NO_LONG_DBL */
1909 long new_exp = 0;
1911 *p = 0;
1912 if ((flags & (DPTOK | EXPOK)) == EXPOK)
1914 exp_adjust = zeroes - leading_zeroes;
1915 new_exp = -exp_adjust;
1916 exp_start = p;
1918 else if (exp_adjust)
1919 new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
1920 if (exp_adjust)
1923 /* If there might not be enough space for the new exponent,
1924 truncate some trailing digits to make room. */
1925 if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
1926 exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
1927 sprintf (exp_start, "e%ld", new_exp);
1930 /* FIXME: Is that still true?
1931 Current _strtold routine is markedly slower than
1932 _strtod_r. Only use it if we have a long double
1933 result. */
1934 #ifndef _NO_LONGDBL /* !_NO_LONGDBL */
1935 if (flags & LONGDBL)
1936 qres = _strtold_r (rptr, buf, NULL);
1937 else
1938 #endif
1939 res = _strtod_r (rptr, buf, NULL);
1941 if (flags & LONG)
1943 dp = GET_ARG (N, ap, double *);
1944 *dp = res;
1946 else if (flags & LONGDBL)
1948 ldp = GET_ARG (N, ap, _LONG_DOUBLE *);
1949 *ldp = QUAD_RES;
1951 else
1953 flp = GET_ARG (N, ap, float *);
1954 if (isnan (res))
1955 *flp = nanf ("");
1956 else
1957 *flp = res;
1959 nassigned++;
1961 break;
1963 #endif /* FLOATING_POINT */
1966 input_failure:
1967 /* On read failure, return EOF failure regardless of matches; errno
1968 should have been set prior to here. On EOF failure (including
1969 invalid format string), return EOF if no matches yet, else number
1970 of matches made prior to failure. */
1971 nassigned = nassigned && !(fp->_flags & __SERR) ? nassigned : EOF;
1972 match_failure:
1973 all_done:
1974 /* Return number of matches, which can be 0 on match failure. */
1975 _newlib_flockfile_end (fp);
1976 #ifdef _WANT_IO_POSIX_EXTENSIONS
1977 free_m_ptr ();
1978 #endif
1979 return nassigned;
1982 #ifndef _NO_POS_ARGS
1983 /* Process all intermediate arguments. Fortunately, with scanf, all
1984 intermediate arguments are sizeof(void*), so we don't need to scan
1985 ahead in the format string. */
1986 static void *
1987 get_arg (int n, va_list *ap, int *numargs_p, void **args)
1989 int numargs = *numargs_p;
1990 while (n >= numargs)
1991 args[numargs++] = va_arg (*ap, void *);
1992 *numargs_p = numargs;
1993 return args[n];
1995 #endif /* !_NO_POS_ARGS */