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.
120 #ifndef NO_FLOATING_POINT
121 #define FLOATING_POINT
124 #ifdef FLOATING_POINT
127 /* Currently a test is made to see if long double processing is warranted.
128 This could be changed in the future should the _ldtoa_r code be
129 preferred over _dtoa_r. */
131 #if defined WANT_IO_LONG_DBL && (LDBL_MANT_DIG > DBL_MANT_DIG)
133 extern _LONG_DOUBLE _strtold
_PARAMS((char *s
, char **sptr
));
137 #if defined WANT_PRINTF_LONG_LONG && defined __GNUC__
143 #if ((MAXEXP+MAXFRACT+3) > MB_LEN_MAX)
144 # define BUF (MAXEXP+MAXFRACT+3) /* 3 = sign + decimal point + NUL */
146 # define BUF MB_LEN_MAX
149 /* An upper bound for how long a long prints in decimal. 4 / 13 approximates
150 log (2). Add one char for roundoff compensation and one for the sign. */
151 #define MAX_LONG_LEN ((CHAR_BIT * sizeof (long) - 1) * 4 / 13 + 2)
157 * Flags used during conversion.
160 #define LONG 0x01 /* l: long or double */
161 #define LONGDBL 0x02 /* L/ll: long double or long long */
162 #define SHORT 0x04 /* h: short */
163 #define CHAR 0x08 /* hh: 8 bit integer */
164 #define SUPPRESS 0x10 /* suppress assignment */
165 #define POINTER 0x20 /* weird %p pointer (`fake hex') */
166 #define NOSKIP 0x40 /* do not skip blanks */
169 * The following are used in numeric conversions only:
170 * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point;
171 * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
174 #define SIGNOK 0x80 /* +/- is (still) legal */
175 #define NDIGITS 0x100 /* no digits detected */
177 #define DPTOK 0x200 /* (float) decimal point is still legal */
178 #define EXPOK 0x400 /* (float) exponent (e+3, etc) still legal */
180 #define PFXOK 0x200 /* 0x prefix is (still) legal */
181 #define NZDIGITS 0x400 /* no zero digits detected */
187 #define CT_CHAR 0 /* %c conversion */
188 #define CT_CCL 1 /* %[...] conversion */
189 #define CT_STRING 2 /* %s conversion */
190 #define CT_INT 3 /* integer, i.e., strtol or strtoul */
191 #define CT_FLOAT 4 /* floating, i.e., strtod */
194 #define u_char unsigned char
197 #define u_long unsigned long
200 typedef unsigned long long u_long_long
;
203 /*static*/ u_char
*__sccl ();
209 #define BufferEmpty (fp->_r <= 0 && __srefill(fp))
214 _DEFUN (vfscanf
, (fp
, fmt
, ap
),
215 register FILE *fp _AND
216 _CONST
char *fmt _AND
220 return __svfscanf_r (_REENT
, fp
, fmt
, ap
);
224 __svfscanf (fp
, fmt0
, ap
)
229 return __svfscanf_r (_REENT
, fp
, fmt0
, ap
);
232 #endif /* !_REENT_ONLY */
235 _DEFUN (_vfscanf_r
, (data
, fp
, fmt
, ap
),
236 struct _reent
*data _AND
237 register FILE *fp _AND
238 _CONST
char *fmt _AND
241 return __svfscanf_r (data
, fp
, fmt
, ap
);
246 __svfscanf_r (rptr
, fp
, fmt0
, ap
)
252 register u_char
*fmt
= (u_char
*) fmt0
;
253 register int c
; /* character from format, or conversion */
254 register size_t width
; /* field width, or 0 */
255 register char *p
; /* points into all kinds of strings */
256 register int n
; /* handy integer */
257 register int flags
; /* flags as defined above */
258 register char *p0
; /* saves original value of p when necessary */
259 int nassigned
; /* number of fields assigned */
260 int nread
; /* number of characters consumed from fp */
261 int base
= 0; /* base argument to strtol/strtoul */
262 int nbytes
= 1; /* number of bytes read from fmt string */
263 wchar_t wc
; /* wchar to use to read format string */
264 wchar_t *wcp
; /* handy wide character pointer */
265 size_t mbslen
; /* length of converted multibyte sequence */
266 mbstate_t state
; /* value to keep track of multibyte state */
268 u_long (*ccfn
) () = 0; /* conversion function (strtol/strtoul) */
269 char ccltab
[256]; /* character class table for %[...] */
270 char buf
[BUF
]; /* buffer for numeric conversions */
271 char *lptr
; /* literal pointer */
284 /* `basefix' is used to avoid `if' tests in the integer scanner */
285 static _CONST
short basefix
[17] =
286 {10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
295 memset (&state
, '\0', sizeof (state
));
296 nbytes
= _mbtowc_r (rptr
, &wc
, fmt
, MB_CUR_MAX
, &state
);
301 if (nbytes
== 1 && isspace (wc
))
305 if (BufferEmpty
|| !isspace (*fp
->_p
))
307 nread
++, fp
->_r
--, fp
->_p
++;
317 * switch on the format. continue if done; break once format
329 for (n
= 0; n
< nbytes
; ++n
)
333 if (*fp
->_p
!= *lptr
)
345 if (*fmt
== 'l') /* Check for 'll' = long long (SUSv3) */
357 if (*fmt
== 'h') /* Check for 'hh' = char int (SUSv3) */
376 width
= width
* 10 + c
- '0';
380 * Conversions. Those marked `compat' are for
381 * 4.[123]BSD compatibility.
383 * (According to ANSI, E and X formats are supposed to
384 * the same as e and x. Sorry about that.)
387 case 'D': /* compat */
392 ccfn
= (u_long (*)())_strtol_r
;
398 ccfn
= (u_long (*)())_strtol_r
;
402 case 'O': /* compat */
417 case 'X': /* compat XXX */
419 flags
|= PFXOK
; /* enable 0x prefixing */
425 #ifdef FLOATING_POINT
426 case 'E': /* compat XXX */
427 case 'G': /* compat XXX */
428 /* ANSI says that E,G and X behave the same way as e,g,x */
445 fmt
= __sccl (ccltab
, fmt
);
459 case 'p': /* pointer format is like hex */
460 flags
|= POINTER
| PFXOK
;
467 if (flags
& SUPPRESS
) /* ??? */
471 cp
= va_arg (ap
, char *);
474 else if (flags
& SHORT
)
476 sp
= va_arg (ap
, short *);
479 else if (flags
& LONG
)
481 lp
= va_arg (ap
, long *);
485 else if (flags
& LONGDBL
)
487 llp
= va_arg (ap
, long long*);
493 ip
= va_arg (ap
, int *);
499 * Disgusting backwards compatibility hacks. XXX
501 case '\0': /* compat */
504 default: /* compat */
508 ccfn
= (u_long (*)())_strtol_r
;
514 * We have a conversion that requires input.
520 * Consume leading white space, except for formats that
523 if ((flags
& NOSKIP
) == 0)
525 while (isspace (*fp
->_p
))
535 * Note that there is at least one character in the
536 * buffer, so conversions that do not set NOSKIP ca
537 * no longer result in an input failure.
548 /* scan arbitrary characters (sets NOSKIP) */
553 if ((flags
& SUPPRESS
) == 0)
554 wcp
= va_arg(ap
, wchar_t *);
565 memset((void *)&state
, '\0', sizeof(mbstate_t));
566 if ((mbslen
= _mbrtowc_r(rptr
, wcp
, buf
, n
, &state
))
568 goto input_failure
; /* Invalid sequence */
569 if (mbslen
== 0 && !(flags
& SUPPRESS
))
571 if (mbslen
!= (size_t)-2) /* Incomplete sequence */
575 if (!(flags
& SUPPRESS
))
586 if (!(flags
& SUPPRESS
))
589 else if (flags
& SUPPRESS
)
594 if ((n
= fp
->_r
) < (int)width
)
618 size_t r
= fread ((_PTR
) va_arg (ap
, char *), 1, width
, fp
);
628 /* scan a (nonempty) character class (sets NOSKIP) */
630 width
= ~0; /* `infinity' */
631 /* take only those things in the class */
632 if (flags
& SUPPRESS
)
635 while (ccltab
[*fp
->_p
])
637 n
++, fp
->_r
--, fp
->_p
++;
652 p0
= p
= va_arg (ap
, char *);
653 while (ccltab
[*fp
->_p
])
676 /* like CCL, but zero-length string OK, & no NOSKIP */
681 /* Process %S and %ls placeholders */
682 if ((flags
& SUPPRESS
) == 0)
683 wcp
= va_arg(ap
, wchar_t *);
687 while (!isspace(*fp
->_p
) && width
!= 0)
694 memset((void *)&state
, '\0', sizeof(mbstate_t));
695 if ((mbslen
= _mbrtowc_r(rptr
, wcp
, buf
, n
, &state
))
700 if (mbslen
!= (size_t)-2) /* Incomplete sequence */
705 ungetc(buf
[--n
], fp
);
710 if ((flags
& SUPPRESS
) == 0)
721 if (!(flags
& SUPPRESS
))
727 else if (flags
& SUPPRESS
)
730 while (!isspace (*fp
->_p
))
732 n
++, fp
->_r
--, fp
->_p
++;
742 p0
= p
= va_arg (ap
, char *);
743 while (!isspace (*fp
->_p
))
759 /* scan an integer as if by strtol/strtoul */
761 if (width
== 0 || width
> sizeof (buf
) - 1)
762 width
= sizeof (buf
) - 1;
764 /* size_t is unsigned, hence this optimisation */
765 if (--width
> sizeof (buf
) - 2)
766 width
= sizeof (buf
) - 2;
769 flags
|= SIGNOK
| NDIGITS
| NZDIGITS
;
770 for (p
= buf
; width
; width
--)
774 * Switch on the character; `goto ok' if we
775 * accept it as a part of number.
780 * The digit 0 is always legal, but is special.
781 * For %i conversions, if no digits (zero or nonzero)
782 * have been scanned (only signs), we will have base==0.
783 * In that case, we should set it to 8 and enable 0x
784 * prefixing. Also, if we have not scanned zero digits
785 * before this, do not turn off prefixing (someone else
786 * will turn it off if we have scanned any nonzero digits).
794 if (flags
& NZDIGITS
)
795 flags
&= ~(SIGNOK
| NZDIGITS
| NDIGITS
);
797 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
800 /* 1 through 7 always legal */
808 base
= basefix
[base
];
809 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
812 /* digits 8 and 9 ok iff decimal or hex */
815 base
= basefix
[base
];
817 break; /* not legal here */
818 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
821 /* letters ok iff hex */
834 /* no need to fix base here */
836 break; /* not legal here */
837 flags
&= ~(SIGNOK
| PFXOK
| NDIGITS
);
840 /* sign ok only as first character */
850 /* x ok iff flag still set & 2nd char */
853 if (flags
& PFXOK
&& p
== buf
+ 1)
855 base
= 16;/* if %i */
863 * If we got here, c is not a legal character
864 * for a number. Stop accumulating digits.
869 * c is legal: store it and look at the next.
879 * If we had only a sign, it is no good; push back the sign.
880 * If the number ends in `x', it was [sign] '0' 'x', so push back
881 * the x and treat it as [sign] '0'.
886 _CAST_VOID
ungetc (*(u_char
*)-- p
, fp
);
889 c
= ((u_char
*) p
)[-1];
890 if (c
== 'x' || c
== 'X')
893 /*(void)*/ ungetc (c
, fp
);
895 if ((flags
& SUPPRESS
) == 0)
900 res
= (*ccfn
) (rptr
, buf
, (char **) NULL
, base
);
902 *(va_arg (ap
, _PTR
*)) = (_PTR
) (unsigned _POINTER_INT
) res
;
903 else if (flags
& CHAR
)
905 cp
= va_arg (ap
, char *);
908 else if (flags
& SHORT
)
910 sp
= va_arg (ap
, short *);
913 else if (flags
& LONG
)
915 lp
= va_arg (ap
, long *);
919 else if (flags
& LONGDBL
)
922 if (ccfn
== _strtoul_r
)
923 resll
= _strtoull_r (rptr
, buf
, (char **) NULL
, base
);
925 resll
= _strtoll_r (rptr
, buf
, (char **) NULL
, base
);
926 llp
= va_arg (ap
, long long*);
932 ip
= va_arg (ap
, int *);
940 #ifdef FLOATING_POINT
943 /* scan a floating point number as if by strtod */
944 /* This code used to assume that the number of digits is reasonable.
945 However, ANSI / ISO C makes no such stipulation; we have to get
946 exact results even when there is an unreasonable amount of
948 long leading_zeroes
= 0;
949 long zeroes
, exp_adjust
;
950 char *exp_start
= NULL
;
952 if (width
== 0 || width
> sizeof (buf
) - 1)
953 width
= sizeof (buf
) - 1;
955 /* size_t is unsigned, hence this optimisation */
956 if (--width
> sizeof (buf
) - 2)
957 width
= sizeof (buf
) - 2;
960 flags
|= SIGNOK
| NDIGITS
| DPTOK
| EXPOK
;
963 for (p
= buf
; width
; )
967 * This code mimicks the integer conversion
968 * code, but is much simpler.
990 flags
&= ~(SIGNOK
| NDIGITS
);
1004 flags
&= ~(SIGNOK
| DPTOK
);
1005 leading_zeroes
= zeroes
;
1011 /* no exponent without some digits */
1012 if ((flags
& (NDIGITS
| EXPOK
)) == EXPOK
1013 || ((flags
& EXPOK
) && zeroes
))
1015 if (! (flags
& DPTOK
))
1017 exp_adjust
= zeroes
- leading_zeroes
;
1021 (flags
& ~(EXPOK
| DPTOK
)) |
1043 * If no digits, might be missing exponent digits
1044 * (just give back the exponent) or might be missing
1045 * regular digits, but had sign and/or decimal point.
1047 if (flags
& NDIGITS
)
1051 /* no digits at all */
1054 ungetc (*(u_char
*)-- p
, fp
);
1059 /* just a bad exponent (e and maybe sign) */
1060 c
= *(u_char
*)-- p
;
1062 if (c
!= 'e' && c
!= 'E')
1064 _CAST_VOID
ungetc (c
, fp
); /* sign */
1065 c
= *(u_char
*)-- p
;
1068 _CAST_VOID
ungetc (c
, fp
);
1070 if ((flags
& SUPPRESS
) == 0)
1074 #define QUAD_RES res;
1075 #else /* !_NO_LONG_DBL */
1076 long double qres
= 0;
1077 #define QUAD_RES qres;
1078 #endif /* !_NO_LONG_DBL */
1082 if ((flags
& (DPTOK
| EXPOK
)) == EXPOK
)
1084 exp_adjust
= zeroes
- leading_zeroes
;
1085 new_exp
= -exp_adjust
;
1088 else if (exp_adjust
)
1089 new_exp
= _strtol_r (rptr
, (exp_start
+ 1), NULL
, 10) - exp_adjust
;
1093 /* If there might not be enough space for the new exponent,
1094 truncate some trailing digits to make room. */
1095 if (exp_start
>= buf
+ sizeof (buf
) - MAX_LONG_LEN
)
1096 exp_start
= buf
+ sizeof (buf
) - MAX_LONG_LEN
- 1;
1097 sprintf (exp_start
, "e%ld", new_exp
);
1100 /* Current _strtold routine is markedly slower than
1101 _strtod_r. Only use it if we have a long double
1103 #ifndef _NO_LONGDBL /* !_NO_LONGDBL */
1104 if (flags
& LONGDBL
)
1105 qres
= _strtold (buf
, NULL
);
1108 res
= _strtod_r (rptr
, buf
, NULL
);
1112 dp
= va_arg (ap
, double *);
1115 else if (flags
& LONGDBL
)
1117 ldp
= va_arg (ap
, _LONG_DOUBLE
*);
1122 flp
= va_arg (ap
, float *);
1129 #endif /* FLOATING_POINT */
1133 return nassigned
? nassigned
: -1;
1139 * Fill in the given table from the scanset at the given format
1140 * (just after `['). Return a pointer to the character past the
1141 * closing `]'. The table has a 1 wherever characters should be
1142 * considered part of the scanset.
1149 register u_char
*fmt
;
1151 register int c
, n
, v
;
1153 /* first `clear' the whole table */
1154 c
= *fmt
++; /* first char hat => negated scanset */
1157 v
= 1; /* default => accept */
1158 c
= *fmt
++; /* get new first char */
1161 v
= 0; /* default => reject */
1162 /* should probably use memset here */
1163 for (n
= 0; n
< 256; n
++)
1166 return fmt
- 1; /* format ended before closing ] */
1169 * Now set the entries corresponding to the actual scanset to the
1170 * opposite of the above.
1172 * The first character may be ']' (or '-') without being special; the
1173 * last character may be '-'.
1179 tab
[c
] = v
; /* take character c */
1181 n
= *fmt
++; /* and examine the next */
1185 case 0: /* format ended too soon */
1190 * A scanset of the form [01+-] is defined as `the digit 0, the
1191 * digit 1, the character +, the character -', but the effect of a
1192 * scanset such as [a-zA-Z0-9] is implementation defined. The V7
1193 * Unix scanf treats `a-z' as `the letters a through z', but treats
1194 * `a-a' as `the letter a, the character -, and the letter a'.
1196 * For compatibility, the `-' is not considerd to define a range if
1197 * the character following it is either a close bracket (required by
1198 * ANSI) or is not numerically greater than the character we just
1199 * stored in the table (c).
1202 if (n
== ']' || n
< c
)
1205 break; /* resume the for(;;) */
1209 { /* fill in the range */
1213 #if 1 /* XXX another disgusting compatibility hack */
1215 * Alas, the V7 Unix scanf also treats formats such
1216 * as [a-c-e] as `the letters a through e'. This too
1217 * is permitted by the standard....
1231 case ']': /* end of scanset */
1234 default: /* just another character */