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 * advertising materials, and 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 <<vscanf>>, <<vfscanf>>, <<vsscanf>>---format argument list
32 int vscanf(const char *<[fmt]>, va_list <[list]>);
33 int vfscanf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
34 int vsscanf(const char *<[str]>, const char *<[fmt]>, va_list <[list]>);
36 int _vscanf_r(struct _reent *<[reent]>, const char *<[fmt]>,
38 int _vfscanf_r(struct _reent *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
40 int _vsscanf_r(struct _reent *<[reent]>, const char *<[str]>,
41 const char *<[fmt]>, va_list <[list]>);
46 int vscanf( <[fmt]>, <[ist]>)
50 int vfscanf( <[fp]>, <[fmt]>, <[list]>)
55 int vsscanf( <[str]>, <[fmt]>, <[list]>)
60 int _vscanf_r( <[reent]>, <[fmt]>, <[ist]>)
61 struct _reent *<[reent]>;
65 int _vfscanf_r( <[reent]>, <[fp]>, <[fmt]>, <[list]>)
66 struct _reent *<[reent]>;
71 int _vsscanf_r( <[reent]>, <[str]>, <[fmt]>, <[list]>)
72 struct _reent *<[reent]>;
78 <<vscanf>>, <<vfscanf>>, and <<vsscanf>> are (respectively) variants
79 of <<scanf>>, <<fscanf>>, and <<sscanf>>. They differ only in
80 allowing their caller to pass the variable argument list as a
81 <<va_list>> object (initialized by <<va_start>>) rather than
82 directly accepting a variable number of arguments.
85 The return values are consistent with the corresponding functions:
86 <<vscanf>> returns the number of input fields successfully scanned,
87 converted, and stored; the return value does not include scanned
88 fields which were not stored.
90 If <<vscanf>> attempts to read at end-of-file, the return value
93 If no fields were stored, the return value is <<0>>.
95 The routines <<_vscanf_r>>, <<_vfscanf_f>>, and <<_vsscanf_r>> are
96 reentrant versions which take an additional first parameter which points to the
100 These are GNU extensions.
102 Supporting OS subroutines required:
121 #define VFSCANF vfiscanf
122 #define _VFSCANF_R _vfiscanf_r
123 #define __SVFSCANF __svfiscanf
124 #define __SVFSCANF_R __svfiscanf_r
126 #define VFSCANF vfscanf
127 #define _VFSCANF_R _vfscanf_r
128 #define __SVFSCANF __svfscanf
129 #define __SVFSCANF_R __svfscanf_r
130 #ifndef NO_FLOATING_POINT
131 #define FLOATING_POINT
135 #ifdef FLOATING_POINT
139 /* Currently a test is made to see if long double processing is warranted.
140 This could be changed in the future should the _ldtoa_r code be
141 preferred over _dtoa_r. */
143 #if defined _WANT_IO_LONG_DOUBLE && (LDBL_MANT_DIG > DBL_MANT_DIG)
145 extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
150 #if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
151 # define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
153 # define BUF MB_LEN_MAX
156 /* An upper bound for how long a long prints in decimal. 4 / 13 approximates
157 log (2). Add one char for roundoff compensation and one for the sign. */
158 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2)
164 #if defined _WANT_IO_LONG_LONG \
165 && (defined __GNUC__ || __STDC_VERSION__ >= 199901L)
170 #ifdef _WANT_IO_POS_ARGS
173 # define MAX_POS_ARGS NL_ARGMAX
175 # define MAX_POS_ARGS 32
178 static void * get_arg (int, va_list *, int *, void **);
179 #endif /* _WANT_IO_POS_ARGS */
182 * Flags used during conversion.
185 #define LONG 0x01 /* l: long or double */
186 #define LONGDBL 0x02 /* L/ll: long double or long long */
187 #define SHORT 0x04 /* h: short */
188 #define CHAR 0x08 /* hh: 8 bit integer */
189 #define SUPPRESS 0x10 /* suppress assignment */
190 #define POINTER 0x20 /* weird %p pointer (`fake hex') */
191 #define NOSKIP 0x40 /* do not skip blanks */
194 * The following are used in numeric conversions only:
195 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
196 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
199 #define SIGNOK 0x80 /* +/- is (still) legal */
200 #define NDIGITS 0x100 /* no digits detected */
202 #define DPTOK 0x200 /* (float) decimal point is still legal */
203 #define EXPOK 0x400 /* (float) exponent (e+3, etc) still legal */
205 #define PFXOK 0x200 /* 0x prefix is (still) legal */
206 #define NZDIGITS 0x400 /* no zero digits detected */
207 #define NNZDIGITS 0x800 /* no non-zero digits detected */
213 #define CT_CHAR 0 /* %c conversion */
214 #define CT_CCL 1 /* %[...] conversion */
215 #define CT_STRING 2 /* %s conversion */
216 #define CT_INT 3 /* integer, i.e., strtol or strtoul */
217 #define CT_FLOAT 4 /* floating, i.e., strtod */
220 #define u_char unsigned char
223 #define u_long unsigned long
226 typedef unsigned long long u_long_long;
229 /*static*/ u_char *__sccl ();
235 #define BufferEmpty (fp->_r <= 0 && __srefill_r(rptr, fp))
240 _DEFUN(VFSCANF, (fp, fmt, ap),
241 register FILE *fp _AND
242 _CONST char *fmt _AND
245 CHECK_INIT(_REENT, fp);
246 return __SVFSCANF_R (_REENT, fp, fmt, ap);
250 _DEFUN(__SVFSCANF, (fp, fmt0, ap),
251 register FILE *fp _AND
252 char _CONST *fmt0 _AND
255 return __SVFSCANF_R (_REENT, fp, fmt0, ap);
258 #endif /* !_REENT_ONLY */
261 _DEFUN(_VFSCANF_R, (data, fp, fmt, ap),
262 struct _reent *data _AND
263 register FILE *fp _AND
264 _CONST char *fmt _AND
267 CHECK_INIT(data, fp);
268 return __SVFSCANF_R (data, fp, fmt, ap);
273 _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
274 struct _reent *rptr _AND
275 register FILE *fp _AND
276 char _CONST *fmt0 _AND
279 register u_char *fmt = (u_char *) fmt0;
280 register int c; /* character from format, or conversion */
281 register size_t width; /* field width, or 0 */
282 register char *p; /* points into all kinds of strings */
283 register int n; /* handy integer */
284 register int flags; /* flags as defined above */
285 register char *p0; /* saves original value of p when necessary */
286 int nassigned; /* number of fields assigned */
287 int nread; /* number of characters consumed from fp */
289 int N; /* arg number */
290 int arg_index = 0; /* index into args processed directly */
291 int numargs = 0; /* number of varargs read */
292 void *args[MAX_POS_ARGS]; /* positional args read */
293 int is_pos_arg; /* is current format positional? */
295 int base = 0; /* base argument to strtol/strtoul */
296 int nbytes = 1; /* number of bytes read from fmt string */
297 wchar_t wc; /* wchar to use to read format string */
298 wchar_t *wcp; /* handy wide character pointer */
299 size_t mbslen; /* length of converted multibyte sequence */
300 mbstate_t state; /* value to keep track of multibyte state */
302 u_long (*ccfn) () = 0; /* conversion function (strtol/strtoul) */
303 char ccltab[256]; /* character class table for %[...] */
304 char buf[BUF]; /* buffer for numeric conversions */
305 char *lptr; /* literal pointer */
310 #ifdef FLOATING_POINT
320 /* `basefix' is used to avoid `if' tests in the integer scanner */
321 static _CONST short basefix[17] =
322 {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
324 /* Macro to support positional arguments */
326 # define GET_ARG(n, ap, type) \
327 ((type) (is_pos_arg \
330 : get_arg (n, &ap, &numargs, args)) \
331 : (arg_index++ < numargs \
333 : (numargs < MAX_POS_ARGS \
334 ? args[numargs++] = va_arg (ap, void *) \
335 : va_arg (ap, void *)))))
337 # define GET_ARG(n, ap, type) (va_arg (ap, type))
349 memset (&state, '\0', sizeof (state));
350 nbytes = _mbtowc_r (rptr, &wc, fmt, MB_CUR_MAX, &state);
355 if (nbytes == 1 && isspace (wc))
359 if (BufferEmpty || !isspace (*fp->_p))
361 nread++, fp->_r--, fp->_p++;
375 * switch on the format. continue if done; break once format
387 for (n = 0; n < nbytes; ++n)
391 if (*fp->_p != *lptr)
403 #if defined _WANT_IO_C99_FORMATS || !defined _NO_LONGLONG
404 if (*fmt == 'l') /* Check for 'll' = long long (SUSv3) */
417 #ifdef _WANT_IO_C99_FORMATS
418 if (*fmt == 'h') /* Check for 'hh' = char int (SUSv3) */
427 #ifdef _WANT_IO_C99_FORMATS
428 case 'j': /* intmax_t */
429 if (sizeof (intmax_t) == sizeof (long))
434 case 't': /* ptrdiff_t */
435 if (sizeof (ptrdiff_t) < sizeof (int))
436 /* POSIX states ptrdiff_t is 16 or more bits, as
439 else if (sizeof (ptrdiff_t) == sizeof (int))
440 /* no flag needed */;
441 else if (sizeof (ptrdiff_t) <= sizeof (long))
444 /* POSIX states that at least one programming
445 environment must support ptrdiff_t no wider than
446 long, but that means other environments can
447 have ptrdiff_t as wide as long long. */
450 case 'z': /* size_t */
451 if (sizeof (size_t) < sizeof (int))
452 /* POSIX states size_t is 16 or more bits, as is short. */
454 else if (sizeof (size_t) == sizeof (int))
455 /* no flag needed */;
456 else if (sizeof (size_t) <= sizeof (long))
459 /* POSIX states that at least one programming
460 environment must support size_t no wider than
461 long, but that means other environments can
462 have size_t as wide as long long. */
465 #endif /* _WANT_IO_C99_FORMATS */
477 width = width * 10 + c - '0';
482 if (width <= MAX_POS_ARGS)
489 rptr->_errno = EINVAL;
491 #endif /* !_NO_POS_ARGS */
494 * Conversions. Those marked `compat' are for
495 * 4.[123]BSD compatibility.
497 * (According to ANSI, E and X formats are supposed to
498 * the same as e and x. Sorry about that.)
501 case 'D': /* compat */
506 ccfn = (u_long (*)())_strtol_r;
512 ccfn = (u_long (*)())_strtol_r;
516 case 'O': /* compat */
533 flags |= PFXOK; /* enable 0x prefixing */
539 #ifdef FLOATING_POINT
540 # ifdef _WANT_IO_C99_FORMATS
554 #ifdef _WANT_IO_C99_FORMATS
565 fmt = __sccl (ccltab, fmt);
570 #ifdef _WANT_IO_C99_FORMATS
581 case 'p': /* pointer format is like hex */
582 flags |= POINTER | PFXOK;
589 if (flags & SUPPRESS) /* ??? */
591 #ifdef _WANT_IO_C99_FORMATS
594 cp = GET_ARG (N, ap, char *);
601 sp = GET_ARG (N, ap, short *);
604 else if (flags & LONG)
606 lp = GET_ARG (N, ap, long *);
610 else if (flags & LONGDBL)
612 llp = GET_ARG (N, ap, long long*);
618 ip = GET_ARG (N, ap, int *);
624 * Disgusting backwards compatibility hacks. XXX
626 case '\0': /* compat */
630 default: /* compat */
634 ccfn = (u_long (*)())_strtol_r;
640 * We have a conversion that requires input.
646 * Consume leading white space, except for formats that
649 if ((flags & NOSKIP) == 0)
651 while (isspace (*fp->_p))
657 if (__srefill_r (rptr, fp))
661 * Note that there is at least one character in the
662 * buffer, so conversions that do not set NOSKIP ca
663 * no longer result in an input failure.
674 /* scan arbitrary characters (sets NOSKIP) */
679 if ((flags & SUPPRESS) == 0)
680 wcp = GET_ARG (N, ap, wchar_t *);
691 memset ((_PTR)&state, '\0', sizeof (mbstate_t));
692 if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state))
694 goto input_failure; /* Invalid sequence */
695 if (mbslen == 0 && !(flags & SUPPRESS))
697 if (mbslen != (size_t)-2) /* Incomplete sequence */
701 if (!(flags & SUPPRESS))
712 if (!(flags & SUPPRESS))
715 else if (flags & SUPPRESS)
720 if ((n = fp->_r) < (int)width)
725 if (__srefill_r (rptr, fp))
744 size_t r = fread ((_PTR) GET_ARG (N, ap, char *), 1, width, fp);
754 /* scan a (nonempty) character class (sets NOSKIP) */
756 width = ~0; /* `infinity' */
757 /* take only those things in the class */
758 if (flags & SUPPRESS)
761 while (ccltab[*fp->_p])
763 n++, fp->_r--, fp->_p++;
778 p0 = p = GET_ARG (N, ap, char *);
779 while (ccltab[*fp->_p])
802 /* like CCL, but zero-length string OK, & no NOSKIP */
807 /* Process %S and %ls placeholders */
808 if ((flags & SUPPRESS) == 0)
809 wcp = GET_ARG (N, ap, wchar_t *);
813 while (!isspace (*fp->_p) && width != 0)
820 memset ((_PTR)&state, '\0', sizeof (mbstate_t));
821 if ((mbslen = _mbrtowc_r (rptr, wcp, buf, n, &state))
826 if (mbslen != (size_t)-2) /* Incomplete sequence */
831 ungetc (buf[--n], fp);
836 if ((flags & SUPPRESS) == 0)
847 if (!(flags & SUPPRESS))
853 else if (flags & SUPPRESS)
856 while (!isspace (*fp->_p))
858 n++, fp->_r--, fp->_p++;
868 p0 = p = GET_ARG (N, ap, char *);
869 while (!isspace (*fp->_p))
886 /* scan an integer as if by strtol/strtoul */
887 unsigned width_left = 0;
890 if (width == 0 || width > sizeof (buf) - 1)
892 /* size_t is unsigned, hence this optimisation */
893 if (width - 1 > sizeof (buf) - 2)
896 width_left = width - (sizeof (buf) - 1);
897 width = sizeof (buf) - 1;
899 flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;
900 for (p = buf; width; width--)
904 * Switch on the character; `goto ok' if we
905 * accept it as a part of number.
910 * The digit 0 is always legal, but is special.
911 * For %i conversions, if no digits (zero or nonzero)
912 * have been scanned (only signs), we will have base==0.
913 * In that case, we should set it to 8 and enable 0x
914 * prefixing. Also, if we have not scanned zero digits
915 * before this, do not turn off prefixing (someone else
916 * will turn it off if we have scanned any nonzero digits).
919 if (! (flags & NNZDIGITS))
926 if (flags & NZDIGITS)
928 flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
931 flags &= ~(SIGNOK | PFXOK | NDIGITS);
940 /* 1 through 7 always legal */
948 base = basefix[base];
949 flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
952 /* digits 8 and 9 ok iff decimal or hex */
955 base = basefix[base];
957 break; /* not legal here */
958 flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
961 /* letters ok iff hex */
974 /* no need to fix base here */
976 break; /* not legal here */
977 flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
980 /* sign ok only as first character */
990 /* x ok iff flag still set & 2nd char */
993 if (flags & PFXOK && p == buf + 1)
995 base = 16;/* if %i */
997 /* We must reset the NZDIGITS and NDIGITS
998 flags that would have been unset by seeing
999 the zero that preceded the X or x. */
1000 flags |= NZDIGITS | NDIGITS;
1007 * If we got here, c is not a legal character
1008 * for a number. Stop accumulating digits.
1013 * c is legal: store it and look at the next.
1020 if (__srefill_r (rptr, fp))
1024 * If we had only a sign, it is no good; push back the sign.
1025 * If the number ends in `x', it was [sign] '0' 'x', so push back
1026 * the x and treat it as [sign] '0'.
1028 if (flags & NDIGITS)
1031 _CAST_VOID ungetc (*(u_char *)-- p, fp);
1034 c = ((u_char *) p)[-1];
1035 if (c == 'x' || c == 'X')
1038 /*(void)*/ ungetc (c, fp);
1040 if ((flags & SUPPRESS) == 0)
1045 res = (*ccfn) (rptr, buf, (char **) NULL, base);
1046 if (flags & POINTER)
1047 *(GET_ARG (N, ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
1048 #ifdef _WANT_IO_C99_FORMATS
1049 else if (flags & CHAR)
1051 cp = GET_ARG (N, ap, char *);
1055 else if (flags & SHORT)
1057 sp = GET_ARG (N, ap, short *);
1060 else if (flags & LONG)
1062 lp = GET_ARG (N, ap, long *);
1065 #ifndef _NO_LONGLONG
1066 else if (flags & LONGDBL)
1069 if (ccfn == _strtoul_r)
1070 resll = _strtoull_r (rptr, buf, (char **) NULL, base);
1072 resll = _strtoll_r (rptr, buf, (char **) NULL, base);
1073 llp = GET_ARG (N, ap, long long*);
1079 ip = GET_ARG (N, ap, int *);
1084 nread += p - buf + skips;
1087 #ifdef FLOATING_POINT
1090 /* scan a floating point number as if by strtod */
1091 /* This code used to assume that the number of digits is reasonable.
1092 However, ANSI / ISO C makes no such stipulation; we have to get
1093 exact results even when there is an unreasonable amount of
1095 long leading_zeroes = 0;
1096 long zeroes, exp_adjust;
1097 char *exp_start = NULL;
1098 unsigned width_left = 0;
1101 if (width == 0 || width > sizeof (buf) - 1)
1103 /* size_t is unsigned, hence this optimisation */
1104 if (width - 1 > sizeof (buf) - 2)
1107 width_left = width - (sizeof (buf) - 1);
1108 width = sizeof (buf) - 1;
1110 flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
1113 for (p = buf; width; )
1117 * This code mimicks the integer conversion
1118 * code, but is much simpler.
1123 if (flags & NDIGITS)
1146 flags &= ~(SIGNOK | NDIGITS);
1162 && (flags & (SIGNOK | NDIGITS | DPTOK | EXPOK)) ==
1163 (SIGNOK | NDIGITS | DPTOK | EXPOK))
1165 flags &= ~(SIGNOK | DPTOK | EXPOK | NDIGITS);
1169 else if (nancount == 2)
1186 flags &= ~(SIGNOK | DPTOK);
1187 leading_zeroes = zeroes;
1193 /* no exponent without some digits */
1194 if ((flags & (NDIGITS | EXPOK)) == EXPOK
1195 || ((flags & EXPOK) && zeroes))
1197 if (! (flags & DPTOK))
1199 exp_adjust = zeroes - leading_zeroes;
1203 (flags & ~(EXPOK | DPTOK)) |
1219 if (__srefill_r (rptr, fp))
1224 /* We may have a 'N' or possibly even a 'Na' as the start of 'NaN',
1225 only to run out of chars before it was complete (or having
1226 encountered a non- matching char). So check here if we have an
1227 outstanding nancount, and if so put back the chars we did
1228 swallow and treat as a failed match. */
1229 if (nancount && nancount != 3)
1231 /* Ok... what are we supposed to do in the event that the
1232 __srefill call above was triggered in the middle of the partial
1233 'NaN' and so we can't put it all back? */
1234 while (nancount-- && (p > buf))
1236 ungetc (*(u_char *)--p, fp);
1242 * If no digits, might be missing exponent digits
1243 * (just give back the exponent) or might be missing
1244 * regular digits, but had sign and/or decimal point.
1246 if (flags & NDIGITS)
1250 /* no digits at all */
1253 ungetc (*(u_char *)--p, fp);
1258 /* just a bad exponent (e and maybe sign) */
1259 c = *(u_char *)-- p;
1261 if (c != 'e' && c != 'E')
1263 _CAST_VOID ungetc (c, fp); /* sign */
1264 c = *(u_char *)-- p;
1267 _CAST_VOID ungetc (c, fp);
1269 if ((flags & SUPPRESS) == 0)
1273 #define QUAD_RES res;
1274 #else /* !_NO_LONG_DBL */
1275 long double qres = 0;
1276 #define QUAD_RES qres;
1277 #endif /* !_NO_LONG_DBL */
1281 if ((flags & (DPTOK | EXPOK)) == EXPOK)
1283 exp_adjust = zeroes - leading_zeroes;
1284 new_exp = -exp_adjust;
1287 else if (exp_adjust)
1288 new_exp = _strtol_r (rptr, (exp_start + 1), NULL, 10) - exp_adjust;
1292 /* If there might not be enough space for the new exponent,
1293 truncate some trailing digits to make room. */
1294 if (exp_start >= buf + sizeof (buf) - MAX_LONG_LEN)
1295 exp_start = buf + sizeof (buf) - MAX_LONG_LEN - 1;
1296 sprintf (exp_start, "e%ld", new_exp);
1299 /* Current _strtold routine is markedly slower than
1300 _strtod_r. Only use it if we have a long double
1302 #ifndef _NO_LONGDBL /* !_NO_LONGDBL */
1303 if (flags & LONGDBL)
1304 qres = _strtold (buf, NULL);
1307 res = _strtod_r (rptr, buf, NULL);
1311 dp = GET_ARG (N, ap, double *);
1314 else if (flags & LONGDBL)
1316 ldp = GET_ARG (N, ap, _LONG_DOUBLE *);
1321 flp = GET_ARG (N, ap, float *);
1331 #endif /* FLOATING_POINT */
1336 return nassigned ? nassigned : -1;
1343 #ifndef _NO_POS_ARGS
1344 /* Process all intermediate arguments. Fortunately, with scanf, all
1345 intermediate arguments are sizeof(void*), so we don't need to scan
1346 ahead in the format string. */
1348 get_arg (int n, va_list *ap, int *numargs_p, void **args)
1350 int numargs = *numargs_p;
1351 while (n >= numargs)
1352 args[numargs++] = va_arg (*ap, void *);
1353 *numargs_p = numargs;
1356 #endif /* !_NO_POS_ARGS */