3 <<vscanf>>, <<vfscanf>>, <<vsscanf>>---format argument list
15 int vscanf(const char *<[fmt]>, va_list <[list]>);
16 int vfscanf(FILE *<[fp]>, const char *<[fmt]>, va_list <[list]>);
17 int vsscanf(const char *<[str]>, const char *<[fmt]>, va_list <[list]>);
19 int _vscanf_r(void *<[reent]>, const char *<[fmt]>,
21 int _vfscanf_r(void *<[reent]>, FILE *<[fp]>, const char *<[fmt]>,
23 int _vsscanf_r(void *<[reent]>, const char *<[str]>, const char *<[fmt]>,
29 int vscanf( <[fmt]>, <[ist]>)
33 int vfscanf( <[fp]>, <[fmt]>, <[list]>)
38 int vsscanf( <[str]>, <[fmt]>, <[list]>)
43 int _vscanf_r( <[reent]>, <[fmt]>, <[ist]>)
48 int _vfscanf_r( <[reent]>, <[fp]>, <[fmt]>, <[list]>)
54 int _vsscanf_r( <[reent]>, <[str]>, <[fmt]>, <[list]>)
61 <<vscanf>>, <<vfscanf>>, and <<vsscanf>> are (respectively) variants
62 of <<scanf>>, <<fscanf>>, and <<sscanf>>. They differ only in
63 allowing their caller to pass the variable argument list as a
64 <<va_list>> object (initialized by <<va_start>>) rather than
65 directly accepting a variable number of arguments.
68 The return values are consistent with the corresponding functions:
69 <<vscanf>> returns the number of input fields successfully scanned,
70 converted, and stored; the return value does not include scanned
71 fields which were not stored.
73 If <<vscanf>> attempts to read at end-of-file, the return value
76 If no fields were stored, the return value is <<0>>.
78 The routines <<_vscanf_r>>, <<_vfscanf_f>>, and <<_vsscanf_r>> are
79 reentrant versions which take an additional first parameter which points to the
83 These are GNU extensions.
85 Supporting OS subroutines required:
89 * Copyright (c) 1990 The Regents of the University of California.
90 * All rights reserved.
92 * Redistribution and use in source and binary forms are permitted
93 * provided that the above copyright notice and this paragraph are
94 * duplicated in all such forms and that any documentation,
95 * advertising materials, and other materials related to such
96 * distribution and use acknowledge that the software was developed
97 * by the University of California, Berkeley. The name of the
98 * University may not be used to endorse or promote products derived
99 * from this software without specific prior written permission.
100 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
101 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
102 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
119 #ifndef NO_FLOATING_POINT
120 #define FLOATING_POINT
123 #ifdef FLOATING_POINT
126 /* Currently a test is made to see if long double processing is warranted.
127 This could be changed in the future should the _ldtoa_r code be
128 preferred over _dtoa_r. */
130 #if defined WANT_IO_LONG_DBL && (LDBL_MANT_DIG > DBL_MANT_DIG)
132 extern _LONG_DOUBLE _strtold
_PARAMS((char *s
, char **sptr
));
136 #if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
141 #define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
142 /* An upper bound for how long a long prints in decimal. 4 / 13 approximates
143 log (2). Add one char for roundoff compensation and one for the sign. */
144 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2)
150 * Flags used during conversion.
153 #define LONG 0x01 /* l: long or double */
154 #define LONGDBL 0x02 /* L: long double or long long */
155 #define SHORT 0x04 /* h: short */
156 #define SUPPRESS 0x08 /* suppress assignment */
157 #define POINTER 0x10 /* weird %p pointer (`fake hex') */
158 #define NOSKIP 0x20 /* do not skip blanks */
161 * The following are used in numeric conversions only:
162 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
163 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
166 #define SIGNOK 0x40 /* +/- is (still) legal */
167 #define NDIGITS 0x80 /* no digits detected */
169 #define DPTOK 0x100 /* (float) decimal point is still legal */
170 #define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */
172 #define PFXOK 0x100 /* 0x prefix is (still) legal */
173 #define NZDIGITS 0x200 /* no zero digits detected */
175 #define VECTOR 0x400 /* v: vector */
176 #define FIXEDPOINT 0x800 /* r/R: fixed-point */
177 #define SIGNED 0x1000 /* r: signed fixed-point */
183 #define CT_CHAR 0 /* %c conversion */
184 #define CT_CCL 1 /* %[...] conversion */
185 #define CT_STRING 2 /* %s conversion */
186 #define CT_INT 3 /* integer, i.e., strtol or strtoul */
187 #define CT_FLOAT 4 /* floating, i.e., strtod */
190 #define u_char unsigned char
193 #define u_long unsigned long
196 typedef unsigned long long u_long_long
;
201 char c
[16] __attribute__ ((__aligned__ (16)));
208 /*static*/ u_char
*__sccl ();
214 #define BufferEmpty (fp->_r <= 0 && __srefill(fp))
219 _DEFUN (vfscanf
, (fp
, fmt
, ap
),
220 register FILE *fp _AND
221 _CONST
char *fmt _AND
225 return __svfscanf_r (fp
->_data
, fp
, fmt
, ap
);
229 __svfscanf (fp
, fmt0
, ap
)
234 return __svfscanf_r (_REENT
, fp
, fmt0
, ap
);
237 #endif /* !_REENT_ONLY */
240 _DEFUN (_vfscanf_r
, (data
, fp
, fmt
, ap
),
241 struct _reent
*data _AND
242 register FILE *fp _AND
243 _CONST
char *fmt _AND
246 return __svfscanf_r (data
, fp
, fmt
, ap
);
251 __svfscanf_r (rptr
, fp
, fmt0
, ap
)
257 register u_char
*fmt
= (u_char
*) fmt0
;
258 register int c
; /* character from format, or conversion */
259 register int type
; /* conversion type */
260 register size_t width
; /* field width, or 0 */
261 register char *p
; /* points into all kinds of strings */
262 register int n
; /* handy integer */
263 register int flags
; /* flags as defined above */
264 register char *p0
; /* saves original value of p when necessary */
265 int orig_flags
; /* saved flags used when processing vector */
266 int int_width
; /* tmp area to store width when processing int */
267 int nassigned
; /* number of fields assigned */
268 int nread
; /* number of characters consumed from fp */
269 int base
= 0; /* base argument to strtol/strtoul */
270 int nbytes
= 1; /* number of bytes read from fmt string */
271 wchar_t wc
; /* wchar to use to read format string */
272 char vec_sep
; /* vector separator char */
273 char last_space_char
; /* last white-space char eaten - needed for vec support */
274 int vec_read_count
; /* number of vector items to read separately */
275 int looped
; /* has vector processing looped */
276 u_long (*ccfn
) () = 0; /* conversion function (strtol/strtoul) */
277 char ccltab
[256]; /* character class table for %[...] */
278 char buf
[BUF
]; /* buffer for numeric conversions */
280 char *lptr
; /* literal pointer */
282 mbstate_t state
; /* value to keep track of multibyte state */
298 /* `basefix' is used to avoid `if' tests in the integer scanner */
299 static _CONST
short basefix
[17] =
300 {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
309 memset (&state
, '\0', sizeof (state
));
310 nbytes
= _mbtowc_r (rptr
, &wc
, fmt
, MB_CUR_MAX
, &state
);
315 if (nbytes
== 1 && isspace (wc
))
321 if (!isspace (*fp
->_p
))
323 nread
++, fp
->_r
--, fp
->_p
++;
336 * switch on the format. continue if done; break once format
348 for (n
= 0; n
< nbytes
; ++n
)
352 if (*fp
->_p
!= *lptr
)
367 if (flags
== SUPPRESS
|| flags
== 0)
372 continue; /* invalid format, don't process any further */
393 continue; /* invalid format, don't process any further */
400 vec_read_count
= (flags
& SHORT
) ? 8 : ((flags
& LONG
) ? 4 : 16);
413 width
= width
* 10 + c
- '0';
417 * Conversions. Those marked `compat' are for
418 * 4.[123]BSD compatibility.
420 * (According to ANSI, E and X formats are supposed to
421 * the same as e and x. Sorry about that.)
424 case 'D': /* compat */
429 ccfn
= (u_long (*)())_strtol_r
;
435 ccfn
= (u_long (*)())_strtol_r
;
439 case 'O': /* compat */
454 case 'X': /* compat XXX */
456 flags
|= PFXOK
; /* enable 0x prefixing */
462 #ifdef FLOATING_POINT
463 case 'E': /* compat XXX */
464 case 'G': /* compat XXX */
465 /* ANSI says that E,G and X behave the same way as e,g,x */
476 /* treat fixed-point like %f floating point */
493 fmt
= __sccl (ccltab
, fmt
);
504 /* not allowed to have h or l with c specifier */
505 if (flags
& (LONG
| SHORT
))
506 continue; /* invalid format don't process any further */
512 case 'p': /* pointer format is like hex */
513 flags
|= POINTER
| PFXOK
;
520 if (flags
& SUPPRESS
) /* ??? */
525 sp
= va_arg (ap
, short *);
528 else if (flags
& LONG
)
530 lp
= va_arg (ap
, long *);
534 else if (flags
& LONGDBL
)
536 llp
= va_arg (ap
, long long*);
542 ip
= va_arg (ap
, int *);
548 * Disgusting backwards compatibility hacks. XXX
550 case '\0': /* compat */
553 default: /* compat */
557 ccfn
= (u_long (*)())_strtol_r
;
564 * We have a conversion that requires input.
570 * Consume leading white space, except for formats that
573 last_space_char
= '\0';
575 if ((flags
& NOSKIP
) == 0)
577 while (isspace (*fp
->_p
))
579 last_space_char
= *fp
->_p
;
590 * Note that there is at least one character in the
591 * buffer, so conversions that do not set NOSKIP ca
592 * no longer result in an input failure.
596 /* for vector formats process separator characters after first loop */
597 if (looped
&& (flags
& VECTOR
))
600 /* all formats other than default char have a separator char */
601 if (vec_sep
!= ' ' || type
!= CT_CHAR
)
603 if (vec_sep
== ' ' && last_space_char
!= ' ' ||
604 vec_sep
!= ' ' && *fp
->_p
!= vec_sep
)
618 /* after eating the separator char, we must eat any white-space
619 after the separator char that precedes the data to convert */
620 if ((flags
& NOSKIP
) == 0)
622 while (isspace (*fp
->_p
))
624 last_space_char
= *fp
->_p
;
637 else /* save to counter-act changes made to flags when processing */
647 /* scan arbitrary characters (sets NOSKIP) */
650 if (flags
& SUPPRESS
)
656 if ((n
= fp
->_r
) < (int)width
)
690 ch_dest
= va_arg (ap
, char *);
693 /* Kludge city for the moment */
699 *ch_dest
++ = *(fp
->_p
++);
705 size_t r
= fread (ch_dest
, 1, width
, fp
);
712 if (!(flags
& VECTOR
))
718 /* scan a (nonempty) character class (sets NOSKIP) */
720 width
= ~0; /* `infinity' */
721 /* take only those things in the class */
722 if (flags
& SUPPRESS
)
725 while (ccltab
[*fp
->_p
])
727 n
++, fp
->_r
--, fp
->_p
++;
742 p0
= p
= va_arg (ap
, char *);
743 while (ccltab
[*fp
->_p
])
766 /* like CCL, but zero-length string OK, & no NOSKIP */
769 if (flags
& SUPPRESS
)
772 while (!isspace (*fp
->_p
))
774 n
++, fp
->_r
--, fp
->_p
++;
784 p0
= p
= va_arg (ap
, char *);
785 while (!isspace (*fp
->_p
))
801 /* scan an integer as if by strtol/strtoul */
804 if (int_width
== 0 || int_width
> sizeof (buf
) - 1)
805 int_width
= sizeof (buf
) - 1;
807 /* size_t is unsigned, hence this optimisation */
808 if (--int_width
> sizeof (buf
) - 2)
809 int_width
= sizeof (buf
) - 2;
812 flags
|= SIGNOK
| NDIGITS
| NZDIGITS
;
813 for (p
= buf
; int_width
; int_width
--)
817 * Switch on the character; `goto ok' if we
818 * accept it as a part of number.
823 * The digit 0 is always legal, but is special.
824 * For %i conversions, if no digits (zero or nonzero)
825 * have been scanned (only signs), we will have base==0.
826 * In that case, we should set it to 8 and enable 0x
827 * prefixing. Also, if we have not scanned zero digits
828 * before this, do not turn off prefixing (someone else
829 * will turn it off if we have scanned any nonzero digits).
837 if (flags
& NZDIGITS
)
838 flags
&= ~(SIGNOK
| NZDIGITS
| NDIGITS
);
840 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
843 /* 1 through 7 always legal */
851 base
= basefix
[base
];
852 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
855 /* digits 8 and 9 ok iff decimal or hex */
858 base
= basefix
[base
];
860 break; /* not legal here */
861 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
864 /* letters ok iff hex */
877 /* no need to fix base here */
879 break; /* not legal here */
880 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
883 /* sign ok only as first character */
893 /* x ok iff flag still set & 2nd char */
896 if (flags
& PFXOK
&& p
== buf
+ 1)
898 base
= 16;/* if %i */
906 * If we got here, c is not a legal character
907 * for a number. Stop accumulating digits.
912 * c is legal: store it and look at the next.
924 * If we had only a sign, it is no good; push back the sign.
925 * If the number ends in `x', it was [sign] '0' 'x', so push back
926 * the x and treat it as [sign] '0'.
931 _CAST_VOID
ungetc (*(u_char
*)-- p
, fp
);
934 c
= ((u_char
*) p
)[-1];
935 if (c
== 'x' || c
== 'X')
938 /*(void)*/ ungetc (c
, fp
);
940 if ((flags
& SUPPRESS
) == 0)
945 res
= (*ccfn
) (rptr
, buf
, (char **) NULL
, base
);
946 if ((flags
& POINTER
) && !(flags
& VECTOR
))
947 *(va_arg (ap
, _PTR
*)) = (_PTR
) (unsigned _POINTER_INT
) res
;
948 else if (flags
& SHORT
)
950 if (!(flags
& VECTOR
))
951 sp
= va_arg (ap
, short *);
956 else if (flags
& LONG
)
958 if (!(flags
& VECTOR
))
959 lp
= va_arg (ap
, long *);
965 else if (flags
& LONGDBL
)
968 if (ccfn
== _strtoul_r
)
969 resll
= _strtoull_r (rptr
, buf
, (char **) NULL
, base
);
971 resll
= _strtoll_r (rptr
, buf
, (char **) NULL
, base
);
972 llp
= va_arg (ap
, long long*);
978 if (!(flags
& VECTOR
))
980 ip
= va_arg (ap
, int *);
987 *ch_dest
++ = (char)res
;
990 if (!(flags
& VECTOR
))
996 #ifdef FLOATING_POINT
999 /* scan a floating point number as if by strtod */
1000 /* This code used to assume that the number of digits is reasonable.
1001 However, ANSI / ISO C makes no such stipulation; we have to get
1002 exact results even when there is an unreasonable amount of
1004 long leading_zeroes
= 0;
1005 long zeroes
, exp_adjust
;
1006 char *exp_start
= NULL
;
1007 int fl_width
= width
;
1009 if (fl_width
== 0 || fl_width
> sizeof (buf
) - 1)
1010 fl_width
= sizeof (buf
) - 1;
1012 /* size_t is unsigned, hence this optimisation */
1013 if (--fl_width
> sizeof (buf
) - 2)
1014 fl_width
= sizeof (buf
) - 2;
1017 flags
|= SIGNOK
| NDIGITS
| DPTOK
| EXPOK
;
1020 for (p
= buf
; fl_width
; )
1024 * This code mimicks the integer conversion
1025 * code, but is much simpler.
1031 if (flags
& NDIGITS
)
1047 flags
&= ~(SIGNOK
| NDIGITS
);
1061 flags
&= ~(SIGNOK
| DPTOK
);
1062 leading_zeroes
= zeroes
;
1068 /* no exponent without some digits */
1069 if ((flags
& (NDIGITS
| EXPOK
)) == EXPOK
1070 || ((flags
& EXPOK
) && zeroes
))
1072 if (! (flags
& DPTOK
))
1074 exp_adjust
= zeroes
- leading_zeroes
;
1078 (flags
& ~(EXPOK
| DPTOK
)) |
1102 * If no digits, might be missing exponent digits
1103 * (just give back the exponent) or might be missing
1104 * regular digits, but had sign and/or decimal point.
1106 if (flags
& NDIGITS
)
1110 /* no digits at all */
1113 ungetc (*(u_char
*)-- p
, fp
);
1118 /* just a bad exponent (e and maybe sign) */
1119 c
= *(u_char
*)-- p
;
1121 if (c
!= 'e' && c
!= 'E')
1123 _CAST_VOID
ungetc (c
, fp
); /* sign */
1124 c
= *(u_char
*)-- p
;
1127 _CAST_VOID
ungetc (c
, fp
);
1129 if ((flags
& SUPPRESS
) == 0)
1133 #else /* !_NO_LONG_DBL */
1135 #endif /* !_NO_LONG_DBL */
1139 if ((flags
& (DPTOK
| EXPOK
)) == EXPOK
)
1141 exp_adjust
= zeroes
- leading_zeroes
;
1142 new_exp
= -exp_adjust
;
1145 else if (exp_adjust
)
1146 new_exp
= _strtol_r (rptr
, (exp_start
+ 1), NULL
, 10) - exp_adjust
;
1150 /* If there might not be enough space for the new exponent,
1151 truncate some trailing digits to make room. */
1152 if (exp_start
>= buf
+ sizeof (buf
) - MAX_LONG_LEN
)
1153 exp_start
= buf
+ sizeof (buf
) - MAX_LONG_LEN
- 1;
1154 sprintf (exp_start
, "e%ld", new_exp
);
1157 if (flags
& FIXEDPOINT
)
1161 ufix64
= (__uint64_t
)_strtosfix64_r (rptr
, buf
, NULL
);
1163 ufix64
= _strtoufix64_r (rptr
, buf
, NULL
);
1166 __uint16_t
*sp
= va_arg (ap
, __uint16_t
*);
1167 *sp
= (__uint16_t
)(ufix64
>> 48);
1169 else if (flags
& LONG
)
1171 __uint64_t
*llp
= va_arg (ap
, __uint64_t
*);
1176 __uint32_t
*lp
= va_arg (ap
, __uint32_t
*);
1177 *lp
= (__uint32_t
)(ufix64
>> 32);
1183 #endif /* __SPE__ */
1185 res
= _strtod_r (rptr
, buf
, NULL
);
1186 #else /* !_NO_LONGDBL */
1187 res
= _strtold (buf
, NULL
);
1188 #endif /* !_NO_LONGDBL */
1191 dp
= va_arg (ap
, double *);
1194 else if (flags
& LONGDBL
)
1196 ldp
= va_arg (ap
, _LONG_DOUBLE
*);
1201 if (!(flags
& VECTOR
))
1202 flp
= va_arg (ap
, float *);
1207 if (!(flags
& VECTOR
))
1212 #endif /* FLOATING_POINT */
1214 if (vec_read_count
-- > 1)
1222 unsigned long *vp
= va_arg (ap
, unsigned long *);
1223 for (i
= 0; i
< 4; ++i
)
1224 *vp
++ = vec_buf
.l
[i
];
1229 return nassigned
? nassigned
: -1;
1235 * Fill in the given table from the scanset at the given format
1236 * (just after `['). Return a pointer to the character past the
1237 * closing `]'. The table has a 1 wherever characters should be
1238 * considered part of the scanset.
1245 register u_char
*fmt
;
1247 register int c
, n
, v
;
1249 /* first `clear' the whole table */
1250 c
= *fmt
++; /* first char hat => negated scanset */
1253 v
= 1; /* default => accept */
1254 c
= *fmt
++; /* get new first char */
1257 v
= 0; /* default => reject */
1258 /* should probably use memset here */
1259 for (n
= 0; n
< 256; n
++)
1262 return fmt
- 1; /* format ended before closing ] */
1265 * Now set the entries corresponding to the actual scanset to the
1266 * opposite of the above.
1268 * The first character may be ']' (or '-') without being special; the
1269 * last character may be '-'.
1275 tab
[c
] = v
; /* take character c */
1277 n
= *fmt
++; /* and examine the next */
1281 case 0: /* format ended too soon */
1286 * A scanset of the form [01+-] is defined as `the digit 0, the
1287 * digit 1, the character +, the character -', but the effect of a
1288 * scanset such as [a-zA-Z0-9] is implementation defined. The V7
1289 * Unix scanf treats `a-z' as `the letters a through z', but treats
1290 * `a-a' as `the letter a, the character -, and the letter a'.
1292 * For compatibility, the `-' is not considerd to define a range if
1293 * the character following it is either a close bracket (required by
1294 * ANSI) or is not numerically greater than the character we just
1295 * stored in the table (c).
1298 if (n
== ']' || n
< c
)
1301 break; /* resume the for(;;) */
1305 { /* fill in the range */
1309 #if 1 /* XXX another disgusting compatibility hack */
1311 * Alas, the V7 Unix scanf also treats formats such
1312 * as [a-c-e] as `the letters a through e'. This too
1313 * is permitted by the standard....
1327 case ']': /* end of scanset */
1330 default: /* just another character */