2 * Copyright (c) 1990 The Regents of the University of California.
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.
20 <<vfscanf>>, <<vscanf>>, <<vsscanf>>---format argument list
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]>,
44 int _vfscanf_r(struct _reent *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
46 int _vsscanf_r(struct _reent *<[reent]>, const char *<[str]>,
47 const char *<[fmt]>, va_list <[list]>);
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.
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
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
72 These are GNU extensions.
74 Supporting OS subroutines required:
91 #include "../stdlib/local.h"
94 #define VFSCANF vfiscanf
95 #define _VFSCANF_R _vfiscanf_r
96 #define __SVFSCANF __svfiscanf
98 # define __SVFSCANF_R __ssvfiscanf_r
100 # define __SVFSCANF_R __svfiscanf_r
103 #define VFSCANF vfscanf
104 #define _VFSCANF_R _vfscanf_r
105 #define __SVFSCANF __svfscanf
107 # define __SVFSCANF_R __ssvfscanf_r
109 # define __SVFSCANF_R __svfscanf_r
111 #ifndef NO_FLOATING_POINT
112 #define FLOATING_POINT
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
128 #ifdef FLOATING_POINT
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. */
137 #if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
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)
153 #if defined _WANT_IO_LONG_LONG \
154 && (defined __GNUC__ || __STDC_VERSION__ >= 199901L)
159 #ifdef _WANT_IO_POS_ARGS
162 # define MAX_POS_ARGS NL_ARGMAX
164 # define MAX_POS_ARGS 32
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 */
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
214 typedef unsigned long long u_long_long
;
221 #define BufferEmpty (fp->_r <= 0 && __srefill_r(rptr, fp))
228 VFSCANF (register FILE *fp
,
232 struct _reent
*reent
= _REENT
;
234 CHECK_INIT(reent
, fp
);
235 return __SVFSCANF_R (reent
, fp
, fmt
, ap
);
239 __SVFSCANF (register FILE *fp
,
243 return __SVFSCANF_R (_REENT
, fp
, fmt0
, ap
);
246 #endif /* !_REENT_ONLY */
249 _VFSCANF_R (struct _reent
*data
,
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
,
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.
282 if (fp
->_r
>= fp
->_ub
._size
&& __submore (data
, fp
))
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
)
305 * Create an ungetc buffer.
306 * Initially, we will use the `reserve' buffer.
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];
319 /* String only version of __srefill_r for sscanf family. */
321 __ssrefill_r (struct _reent
* ptr
,
325 * Our only hope of further input is the ungetc buffer.
326 * If there is anything in that buffer to read, return.
331 if ((fp
->_r
= fp
->_ur
) != 0)
338 /* Otherwise we are out of character input. */
339 fp
->_p
= fp
->_bf
._base
;
341 fp
->_flags
|= __SEOF
;
346 _sfread_r (struct _reent
* ptr
,
352 register size_t resid
;
357 if ((resid
= count
* size
) == 0)
363 while (resid
> (r
= fp
->_r
))
365 (void) memcpy ((void *) p
, (void *) fp
->_p
, (size_t) 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
);
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 */
388 __wctob (struct _reent
*rptr
, wint_t wc
)
391 unsigned char pmb
[MB_LEN_MAX
];
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
,
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 */
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? */
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 */
427 mbstate_t state
; /* value to keep track of multibyte state */
429 #ifdef _WANT_IO_C99_FORMATS
430 #define _WANT_IO_POSIX_EXTENSIONS
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? */
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 */
447 #define init_m_ptr() \
452 m_ptr = (struct m_ptrs *) alloca (sizeof *m_ptr); \
453 m_ptr->m_arr = NULL; \
459 #define push_m_ptr(arg) \
462 if (m_ptr->m_cnt >= m_ptr->m_siz) \
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) * \
473 goto match_failure; \
478 m_ptr->m_arr[m_ptr->m_cnt++] = (void **) (arg); \
481 #define alloc_m_ptr(_type, _p, _p0, _p_p, _w) \
483 _p_p = GET_ARG (N, ap, _type **); \
485 goto match_failure; \
486 _p0 = (_type *) malloc ((_w) * sizeof (_type)); \
490 goto match_failure; \
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) \
502 ptrdiff_t _dif = _p - _p0; \
504 ((sizeof (_type) == 2 && _dif >= _nw - 1) \
507 _p0 = (_type *) realloc (_p0, (_nw << 1) * sizeof (_type)); \
511 goto match_failure; \
519 #define shrink_m_ptr(_type, _p_p, _w, _cw) \
522 if (_p_p && _nw < _cw) \
524 _type *_np_p = (_type *) \
525 realloc (*_p_p, _nw * sizeof (_type)); \
530 #define free_m_ptr() \
535 if (nassigned == EOF) \
538 for (i = 0; i < m_ptr->m_cnt; ++i) \
540 free (*m_ptr->m_arr[i]); \
541 *m_ptr->m_arr[i] = NULL; \
545 free (m_ptr->m_arr); \
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 */
560 #ifdef FLOATING_POINT
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 */
576 # define GET_ARG(n, ap, type) \
577 ((type) (is_pos_arg \
580 : get_arg (n, &ap, &numargs, args)) \
581 : (arg_index++ < numargs \
583 : (numargs < MAX_POS_ARGS \
584 ? args[numargs++] = va_arg (ap, void *) \
585 : va_arg (ap, void *)))))
587 # define GET_ARG(n, ap, type) (va_arg (ap, type))
590 _newlib_flockfile_start (fp
);
592 if (ORIENT (fp
, -1) != -1)
601 memset (&state
, 0, sizeof (state
));
609 nbytes
= __MBTOWC (rptr
, &wc
, (char *) fmt
, MB_CUR_MAX
, &state
);
611 wc
= 0xFFFD; /* Unicode replacement character */
613 memset (&state
, 0, sizeof (state
));
620 if (nbytes
== 1 && isspace (wc
))
624 if (BufferEmpty
|| !isspace (*fp
->_p
))
626 nread
++, fp
->_r
--, fp
->_p
++;
640 * switch on the format. continue if done; break once format
652 for (n
= 0; n
< nbytes
; ++n
)
656 if (*fp
->_p
!= *lptr
)
665 if ((flags
& (CHAR
| SHORT
| LONG
| LONGDBL
| SUPPRESS
| MALLOC
))
671 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
))
673 #if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
674 if (*fmt
== 'l') /* Check for 'll' = long long (SUSv3) */
684 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
))
689 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
))
691 #ifdef _WANT_IO_C99_FORMATS
692 if (*fmt
== 'h') /* Check for 'hh' = char int (SUSv3) */
701 #ifdef _WANT_IO_C99_FORMATS
702 case 'j': /* intmax_t */
703 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
))
705 if (sizeof (intmax_t) == sizeof (long))
710 case 't': /* ptrdiff_t */
711 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
))
713 if (sizeof (ptrdiff_t) < sizeof (int))
714 /* POSIX states ptrdiff_t is 16 or more bits, as
717 else if (sizeof (ptrdiff_t) == sizeof (int))
718 /* no flag needed */;
719 else if (sizeof (ptrdiff_t) <= sizeof (long))
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. */
728 case 'z': /* size_t */
729 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
))
731 if (sizeof (size_t) < sizeof (int))
732 /* POSIX states size_t is 16 or more bits, as is short. */
734 else if (sizeof (size_t) == sizeof (int))
735 /* no flag needed */;
736 else if (sizeof (size_t) <= sizeof (long))
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. */
745 #endif /* _WANT_IO_C99_FORMATS */
746 #ifdef _WANT_IO_POSIX_EXTENSIONS
748 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
| MALLOC
))
765 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
| MALLOC
))
767 width
= width
* 10 + c
- '0';
772 if (flags
& (CHAR
| SHORT
| LONG
| LONGDBL
| SUPPRESS
| MALLOC
))
774 if (width
<= MAX_POS_ARGS
)
781 _REENT_ERRNO(rptr
) = EINVAL
;
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 */
798 ccfn
= (u_long (*)CCFN_PARAMS
)_strtol_r
;
804 ccfn
= (u_long (*)CCFN_PARAMS
)_strtol_r
;
808 case 'O': /* compat */
825 flags
|= PFXOK
; /* enable 0x prefixing */
831 #ifdef FLOATING_POINT
832 # ifdef _WANT_IO_C99_FORMATS
846 #ifdef _WANT_IO_C99_FORMATS
857 fmt
= (u_char
*) __sccl (ccltab
, (unsigned char *) fmt
);
862 #ifdef _WANT_IO_C99_FORMATS
873 case 'p': /* pointer format is like hex */
874 flags
|= POINTER
| PFXOK
;
881 if (flags
& SUPPRESS
) /* ??? */
883 #ifdef _WANT_IO_C99_FORMATS
886 cp
= GET_ARG (N
, ap
, char *);
893 sp
= GET_ARG (N
, ap
, short *);
896 else if (flags
& LONG
)
898 lp
= GET_ARG (N
, ap
, long *);
902 else if (flags
& LONGDBL
)
904 llp
= GET_ARG (N
, ap
, long long*);
910 ip
= GET_ARG (N
, ap
, int *);
920 * We have a conversion that requires input.
926 * Consume leading white space, except for formats that
929 if ((flags
& NOSKIP
) == 0)
931 while (isspace (*fp
->_p
))
937 if (__srefill_r (rptr
, fp
))
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.
954 /* scan arbitrary characters (sets NOSKIP) */
957 #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
960 #ifdef _WANT_IO_POSIX_EXTENSIONS
961 wchar_t **wcp_p
= NULL
;
962 wchar_t *wcp0
= NULL
;
966 if (flags
& SUPPRESS
)
968 #ifdef _WANT_IO_POSIX_EXTENSIONS
969 else if (flags
& MALLOC
)
970 wcp_siz
= alloc_m_ptr (wchar_t, wcp
, wcp0
, wcp_p
, 32);
973 wcp
= GET_ARG (N
, ap
, wchar_t *);
982 /* Got a high surrogate, allow low surrogate to slip
984 if (mbslen
!= 3 || state
.__count
!= 4)
985 memset (&state
, 0, sizeof (mbstate_t));
986 if ((mbslen
= _mbrtowc_r (rptr
, wcp
, buf
, n
, &state
))
988 goto input_failure
; /* Invalid sequence */
989 if (mbslen
== 0 && !(flags
& SUPPRESS
))
991 if (mbslen
!= (size_t)-2) /* Incomplete sequence */
994 /* Handle high surrogate */
995 if (mbslen
!= 3 || state
.__count
!= 4)
997 if (!(flags
& SUPPRESS
))
999 #ifdef _WANT_IO_POSIX_EXTENSIONS
1000 wcp_siz
= realloc_m_ptr (wchar_t, wcp
, wcp0
, wcp_p
,
1014 #ifdef _WANT_IO_POSIX_EXTENSIONS
1015 shrink_m_ptr (wchar_t, wcp_p
, wcp
- wcp0
, wcp_siz
);
1017 if (!(flags
& SUPPRESS
))
1021 #endif /* ELIX_LEVEL */
1022 if (flags
& SUPPRESS
)
1027 if ((n
= fp
->_r
) < (int)width
)
1032 if (__srefill_r (rptr
, fp
))
1052 #ifdef _WANT_IO_POSIX_EXTENSIONS
1055 alloc_m_ptr (char, p
, p0
, p_p
, width
);
1058 p
= GET_ARG (N
, ap
, char *);
1059 r
= _fread_r (rptr
, p
, 1, width
, fp
);
1062 #ifdef _WANT_IO_POSIX_EXTENSIONS
1063 shrink_m_ptr (char, p_p
, r
, width
);
1071 /* scan a (nonempty) character class (sets NOSKIP) */
1074 /* take only those things in the class */
1075 #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
1078 #ifdef _WANT_IO_POSIX_EXTENSIONS
1079 wchar_t **wcp_p
= NULL
;
1080 wchar_t *wcp0
= NULL
;
1084 if (flags
& SUPPRESS
)
1086 #ifdef _WANT_IO_POSIX_EXTENSIONS
1087 else if (flags
& MALLOC
)
1088 wcp_siz
= alloc_m_ptr (wchar_t, wcp
, wcp0
, wcp_p
, 32);
1091 wcp
= GET_ARG (N
, ap
, wchar_t *);
1093 while (width
!= 0) {
1094 if (n
== MB_CUR_MAX
)
1099 /* Got a high surrogate, allow low surrogate to slip
1101 if (mbslen
!= 3 || state
.__count
!= 4)
1102 memset (&state
, 0, sizeof (mbstate_t));
1103 if ((mbslen
= _mbrtowc_r (rptr
, wcp
, buf
, n
, &state
))
1108 if (mbslen
!= (size_t)-2) /* Incomplete sequence */
1110 if (!ccltab
[__wctob (rptr
, *wcp
)])
1113 _ungetc_r (rptr
, (unsigned char) buf
[--n
], fp
);
1117 /* Handle high surrogate */
1118 if (mbslen
!= 3 || state
.__count
!= 4)
1120 if ((flags
& SUPPRESS
) == 0)
1123 #ifdef _WANT_IO_POSIX_EXTENSIONS
1124 wcp_siz
= realloc_m_ptr (wchar_t, wcp
, wcp0
, wcp_p
,
1137 if (!(flags
& SUPPRESS
))
1140 #ifdef _WANT_IO_POSIX_EXTENSIONS
1141 shrink_m_ptr (wchar_t, wcp_p
, wcp
- wcp0
+ 1, wcp_siz
);
1147 #endif /* ELIX_LEVEL */
1148 if (flags
& SUPPRESS
)
1151 while (ccltab
[*fp
->_p
])
1153 n
++, fp
->_r
--, fp
->_p
++;
1169 #ifdef _WANT_IO_POSIX_EXTENSIONS
1174 p_siz
= alloc_m_ptr (char, p
, p0
, p_p
, 32);
1177 p0
= p
= GET_ARG (N
, ap
, char *);
1178 while (ccltab
[*fp
->_p
])
1182 #ifdef _WANT_IO_POSIX_EXTENSIONS
1183 p_siz
= realloc_m_ptr (char, p
, p0
, p_p
, p_siz
);
1198 #ifdef _WANT_IO_POSIX_EXTENSIONS
1199 shrink_m_ptr (char, p_p
, n
+ 1, p_siz
);
1207 /* like CCL, but zero-length string OK, & no NOSKIP */
1210 #if !defined(_ELIX_LEVEL) || _ELIX_LEVEL >= 2
1213 #ifdef _WANT_IO_POSIX_EXTENSIONS
1214 wchar_t **wcp_p
= NULL
;
1215 wchar_t *wcp0
= NULL
;
1218 /* Process %S and %ls placeholders */
1220 if (flags
& SUPPRESS
)
1222 #ifdef _WANT_IO_POSIX_EXTENSIONS
1223 else if (flags
& MALLOC
)
1224 wcp_siz
= alloc_m_ptr (wchar_t, wcp
, wcp0
, wcp_p
, 32);
1227 wcp
= GET_ARG (N
, ap
, wchar_t *);
1229 while (!isspace (*fp
->_p
) && width
!= 0)
1231 if (n
== MB_CUR_MAX
)
1236 /* Got a high surrogate, allow low surrogate to slip
1238 if (mbslen
!= 3 || state
.__count
!= 4)
1239 memset (&state
, 0, sizeof (mbstate_t));
1240 if ((mbslen
= _mbrtowc_r (rptr
, wcp
, buf
, n
, &state
))
1245 if (mbslen
!= (size_t)-2) /* Incomplete sequence */
1250 _ungetc_r (rptr
, (unsigned char) buf
[--n
], fp
);
1254 /* Handle high surrogate */
1255 if (mbslen
!= 3 || state
.__count
!= 4)
1257 if ((flags
& SUPPRESS
) == 0)
1260 #ifdef _WANT_IO_POSIX_EXTENSIONS
1261 wcp_siz
= realloc_m_ptr (wchar_t, wcp
, wcp0
, wcp_p
,
1274 if (!(flags
& SUPPRESS
))
1277 #ifdef _WANT_IO_POSIX_EXTENSIONS
1278 shrink_m_ptr (wchar_t, wcp_p
, wcp
- wcp0
+ 1, wcp_siz
);
1285 if (flags
& SUPPRESS
)
1288 while (!isspace (*fp
->_p
))
1290 n
++, fp
->_r
--, fp
->_p
++;
1300 #ifdef _WANT_IO_POSIX_EXTENSIONS
1305 p_siz
= alloc_m_ptr (char, p
, p0
, p_p
, 32);
1308 p0
= GET_ARG (N
, ap
, char *);
1310 while (!isspace (*fp
->_p
))
1314 #ifdef _WANT_IO_POSIX_EXTENSIONS
1315 p_siz
= realloc_m_ptr (char, p
, p0
, p_p
, p_siz
);
1323 #ifdef _WANT_IO_POSIX_EXTENSIONS
1324 shrink_m_ptr (char, p_p
, p
- p0
+ 1, p_siz
);
1333 /* scan an integer as if by strtol/strtoul */
1334 unsigned width_left
= 0;
1337 if (width
== 0 || width
> sizeof (buf
) - 1)
1339 /* size_t is unsigned, hence this optimisation */
1340 if (width
- 1 > sizeof (buf
) - 2)
1343 width_left
= width
- (sizeof (buf
) - 1);
1344 width
= sizeof (buf
) - 1;
1346 flags
|= SIGNOK
| NDIGITS
| NZDIGITS
| NNZDIGITS
;
1347 for (p
= buf
; width
; width
--)
1351 * Switch on the character; `goto ok' if we
1352 * accept it as a part of number.
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).
1366 if (! (flags
& NNZDIGITS
))
1373 if (flags
& NZDIGITS
)
1375 flags
&= ~(SIGNOK
| NZDIGITS
| NDIGITS
);
1378 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
1387 /* 1 through 7 always legal */
1395 base
= basefix
[base
];
1396 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
| NNZDIGITS
);
1399 /* digits 8 and 9 ok iff decimal or hex */
1402 base
= basefix
[base
];
1404 break; /* not legal here */
1405 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
| NNZDIGITS
);
1408 /* letters ok iff hex */
1421 /* no need to fix base here */
1423 break; /* not legal here */
1424 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
| NNZDIGITS
);
1427 /* sign ok only as first character */
1437 /* x ok iff flag still set & single 0 seen */
1440 if ((flags
& (PFXOK
| NZDIGITS
)) == PFXOK
)
1442 base
= 16;/* if %i */
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
;
1454 * If we got here, c is not a legal character
1455 * for a number. Stop accumulating digits.
1460 * c is legal: store it and look at the next.
1467 if (__srefill_r (rptr
, fp
))
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
1478 if (flags
& NDIGITS
)
1481 _ungetc_r (rptr
, *--p
, fp
); /* [-+xX] */
1485 if ((flags
& SUPPRESS
) == 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
))
1498 resll
= _strtoull_r (rptr
, buf
, (char **) NULL
, base
);
1499 *vp
= (void *) (uintptr_t) resll
;
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 *);
1512 else if (flags
& SHORT
)
1514 sp
= GET_ARG (N
, ap
, short *);
1517 else if (flags
& LONG
)
1519 lp
= GET_ARG (N
, ap
, long *);
1522 #ifndef _NO_LONGLONG
1523 else if (flags
& LONGDBL
)
1526 if (ccfn
== _strtoul_r
)
1527 resll
= _strtoull_r (rptr
, buf
, (char **) NULL
, base
);
1529 resll
= _strtoll_r (rptr
, buf
, (char **) NULL
, base
);
1530 llp
= GET_ARG (N
, ap
, long long*);
1536 ip
= GET_ARG (N
, ap
, int *);
1541 nread
+= p
- buf
+ skips
;
1544 #ifdef FLOATING_POINT
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
1552 long leading_zeroes
= 0;
1553 long zeroes
, exp_adjust
;
1554 char *exp_start
= NULL
;
1555 unsigned width_left
= 0;
1558 const char *decpt
= _localeconv_r (rptr
)->decimal_point
;
1563 if (width
== 0 || width
> sizeof (buf
) - 1)
1565 /* size_t is unsigned, hence this optimisation */
1566 if (width
- 1 > sizeof (buf
) - 2)
1569 width_left
= width
- (sizeof (buf
) - 1);
1570 width
= sizeof (buf
) - 1;
1572 flags
|= SIGNOK
| NDIGITS
| DPTOK
| EXPOK
;
1575 for (p
= buf
; width
; )
1579 * This code mimicks the integer conversion
1580 * code, but is much simpler.
1585 if (flags
& NDIGITS
)
1606 if (nancount
+ infcount
== 0)
1608 flags
&= ~(SIGNOK
| NDIGITS
);
1613 /* Chars a, e and f have various special meanings apart from
1614 their hex value. They are handled separately, see below. */
1621 if ((flags
& HEXFLT
) && nancount
+ infcount
== 0)
1623 flags
&= ~(SIGNOK
| NDIGITS
);
1630 /* Did we have exactly one leading zero yet? */
1631 if ((flags
& (SIGNOK
| NDIGITS
| HEXFLT
)) == NDIGITS
1636 /* We skipped the first zero, so we have to add
1637 it now to the buffer. */
1655 if (nancount
== 0 && zeroes
== 0
1656 && (flags
& (NDIGITS
| DPTOK
| EXPOK
)) ==
1657 (NDIGITS
| DPTOK
| EXPOK
))
1659 flags
&= ~(SIGNOK
| DPTOK
| EXPOK
| NDIGITS
);
1668 if (infcount
== 1 || infcount
== 4)
1676 if ((flags
& HEXFLT
) && nancount
+ infcount
== 0)
1678 flags
&= ~(SIGNOK
| NDIGITS
);
1689 if (infcount
== 0 && zeroes
== 0
1690 && (flags
& (NDIGITS
| DPTOK
| EXPOK
)) ==
1691 (NDIGITS
| DPTOK
| EXPOK
))
1693 flags
&= ~(SIGNOK
| DPTOK
| EXPOK
| NDIGITS
);
1697 if (infcount
== 3 || infcount
== 5)
1705 if ((flags
& HEXFLT
) && nancount
+ infcount
== 0)
1707 flags
&= ~(SIGNOK
| NDIGITS
);
1735 /* p is the exponent marker in hex case. */
1736 if (!(flags
& HEXFLT
))
1741 /* e is just a digit in hex case, not the exponent marker. */
1744 if (nancount
+ infcount
== 0)
1746 flags
&= ~(SIGNOK
| NDIGITS
);
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
;
1763 (flags
& ~(EXPOK
| DPTOK
| HEXFLT
)) |
1771 if ((unsigned char) c
== (unsigned char) decpt
[0]
1774 flags
&= ~(SIGNOK
| DPTOK
);
1775 leading_zeroes
= zeroes
;
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
);
1797 else if (__srefill_r (rptr
, fp
))
1803 /* We read part of a multibyte decimal point,
1804 but the rest is invalid or we're at EOF,
1806 while (decptpos
-- > 0)
1808 _ungetc_r (rptr
, (unsigned char) decpt
[decptpos
],
1826 if (__srefill_r (rptr
, fp
))
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
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. */
1846 _ungetc_r (rptr
, *--p
, fp
); /* [-+nNaA] */
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] */
1866 _ungetc_r (rptr
, *--p
, fp
); /* [-+iInN] */
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
)
1881 /* no digits at all */
1884 _ungetc_r (rptr
, *--p
, fp
); /* [-+.] */
1889 /* just a bad exponent (e and maybe sign) */
1892 if (c
!= 'e' && c
!= 'E')
1894 _ungetc_r (rptr
, c
, fp
); /* [-+] */
1898 _ungetc_r (rptr
, c
, fp
); /* [eE] */
1900 if ((flags
& SUPPRESS
) == 0)
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 */
1912 if ((flags
& (DPTOK
| EXPOK
)) == EXPOK
)
1914 exp_adjust
= zeroes
- leading_zeroes
;
1915 new_exp
= -exp_adjust
;
1918 else if (exp_adjust
)
1919 new_exp
= _strtol_r (rptr
, (exp_start
+ 1), NULL
, 10) - 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
1934 #ifndef _NO_LONGDBL /* !_NO_LONGDBL */
1935 if (flags
& LONGDBL
)
1936 qres
= _strtold_r (rptr
, buf
, NULL
);
1939 res
= _strtod_r (rptr
, buf
, NULL
);
1943 dp
= GET_ARG (N
, ap
, double *);
1946 else if (flags
& LONGDBL
)
1948 ldp
= GET_ARG (N
, ap
, _LONG_DOUBLE
*);
1953 flp
= GET_ARG (N
, ap
, float *);
1963 #endif /* FLOATING_POINT */
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
;
1974 /* Return number of matches, which can be 0 on match failure. */
1975 _newlib_flockfile_end (fp
);
1976 #ifdef _WANT_IO_POSIX_EXTENSIONS
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. */
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
;
1995 #endif /* !_NO_POS_ARGS */