* libc/stdio/vfscanf.c (__SVFSCANF_R): Support scanf(%1$s).
Avoid warning when !FLOATING_POINT. * libc/stdio/vfprintf.c (_VFPRINTF_R): Simplify _NO_POS_ARGS slightly.
This commit is contained in:
parent
fc2000254c
commit
9a3ec8622b
|
@ -1,3 +1,10 @@
|
||||||
|
2007-05-23 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
|
* libc/stdio/vfscanf.c (__SVFSCANF_R): Support scanf(%1$s).
|
||||||
|
Avoid warning when !FLOATING_POINT.
|
||||||
|
* libc/stdio/vfprintf.c (_VFPRINTF_R): Simplify _NO_POS_ARGS
|
||||||
|
slightly.
|
||||||
|
|
||||||
2007-05-23 Corinna Vinschen <vinschen@redhat.com>
|
2007-05-23 Corinna Vinschen <vinschen@redhat.com>
|
||||||
|
|
||||||
* libc/argz/argz_create_sep.c (argz_create_sep): Initialize *argz_len
|
* libc/argz/argz_create_sep.c (argz_create_sep): Initialize *argz_len
|
||||||
|
|
|
@ -126,7 +126,7 @@ static char *rcsid = "$Id$";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _NO_POS_ARGS
|
#define _NO_POS_ARGS
|
||||||
#if defined _WANT_IO_POS_ARGS
|
#ifdef _WANT_IO_POS_ARGS
|
||||||
# undef _NO_POS_ARGS
|
# undef _NO_POS_ARGS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -385,9 +385,9 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
|
||||||
register struct __siov *iovp;/* for PRINT macro */
|
register struct __siov *iovp;/* for PRINT macro */
|
||||||
register int flags; /* flags as above */
|
register int flags; /* flags as above */
|
||||||
char *fmt_anchor; /* current format spec being processed */
|
char *fmt_anchor; /* current format spec being processed */
|
||||||
|
#ifndef _NO_POS_ARGS
|
||||||
int N; /* arg number */
|
int N; /* arg number */
|
||||||
int arg_index; /* index into args processed directly */
|
int arg_index; /* index into args processed directly */
|
||||||
#ifndef _NO_POS_ARGS
|
|
||||||
int numargs; /* number of varargs read */
|
int numargs; /* number of varargs read */
|
||||||
char *saved_fmt; /* saved fmt pointer */
|
char *saved_fmt; /* saved fmt pointer */
|
||||||
union arg_val args[MAX_POS_ARGS];
|
union arg_val args[MAX_POS_ARGS];
|
||||||
|
@ -474,15 +474,15 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
|
||||||
#ifndef _NO_POS_ARGS
|
#ifndef _NO_POS_ARGS
|
||||||
# define GET_ARG(n, ap, type) \
|
# define GET_ARG(n, ap, type) \
|
||||||
(is_pos_arg \
|
(is_pos_arg \
|
||||||
? n < numargs \
|
? (n < numargs \
|
||||||
? args[n].val_##type \
|
? args[n].val_##type \
|
||||||
: get_arg (data, n, fmt_anchor, &ap, &numargs, args, arg_type, &saved_fmt)->val_##type \
|
: get_arg (data, n, fmt_anchor, &ap, &numargs, args, \
|
||||||
: arg_index++ < numargs \
|
arg_type, &saved_fmt)->val_##type) \
|
||||||
|
: (arg_index++ < numargs \
|
||||||
? args[n].val_##type \
|
? args[n].val_##type \
|
||||||
: numargs < MAX_POS_ARGS \
|
: (numargs < MAX_POS_ARGS \
|
||||||
? args[numargs++].val_##type = va_arg (ap, type) \
|
? args[numargs++].val_##type = va_arg (ap, type) \
|
||||||
: va_arg (ap, type) \
|
: va_arg (ap, type))))
|
||||||
)
|
|
||||||
#else
|
#else
|
||||||
# define GET_ARG(n, ap, type) (va_arg (ap, type))
|
# define GET_ARG(n, ap, type) (va_arg (ap, type))
|
||||||
#endif
|
#endif
|
||||||
|
@ -538,8 +538,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
|
||||||
uio.uio_resid = 0;
|
uio.uio_resid = 0;
|
||||||
uio.uio_iovcnt = 0;
|
uio.uio_iovcnt = 0;
|
||||||
ret = 0;
|
ret = 0;
|
||||||
arg_index = 0;
|
|
||||||
#ifndef _NO_POS_ARGS
|
#ifndef _NO_POS_ARGS
|
||||||
|
arg_index = 0;
|
||||||
saved_fmt = NULL;
|
saved_fmt = NULL;
|
||||||
arg_type[0] = -1;
|
arg_type[0] = -1;
|
||||||
numargs = 0;
|
numargs = 0;
|
||||||
|
@ -580,8 +580,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
|
||||||
width = 0;
|
width = 0;
|
||||||
prec = -1;
|
prec = -1;
|
||||||
sign = '\0';
|
sign = '\0';
|
||||||
N = arg_index;
|
|
||||||
#ifndef _NO_POS_ARGS
|
#ifndef _NO_POS_ARGS
|
||||||
|
N = arg_index;
|
||||||
is_pos_arg = 0;
|
is_pos_arg = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -609,9 +609,9 @@ reswitch: switch (ch) {
|
||||||
flags |= ALT;
|
flags |= ALT;
|
||||||
goto rflag;
|
goto rflag;
|
||||||
case '*':
|
case '*':
|
||||||
n = N;
|
|
||||||
#ifndef _NO_POS_ARGS
|
#ifndef _NO_POS_ARGS
|
||||||
/* we must check for positional arg used for dynamic width */
|
/* we must check for positional arg used for dynamic width */
|
||||||
|
n = N;
|
||||||
old_is_pos_arg = is_pos_arg;
|
old_is_pos_arg = is_pos_arg;
|
||||||
is_pos_arg = 0;
|
is_pos_arg = 0;
|
||||||
if (is_digit (*fmt)) {
|
if (is_digit (*fmt)) {
|
||||||
|
@ -661,9 +661,9 @@ reswitch: switch (ch) {
|
||||||
goto rflag;
|
goto rflag;
|
||||||
case '.':
|
case '.':
|
||||||
if ((ch = *fmt++) == '*') {
|
if ((ch = *fmt++) == '*') {
|
||||||
n = N;
|
|
||||||
#ifndef _NO_POS_ARGS
|
#ifndef _NO_POS_ARGS
|
||||||
/* we must check for positional arg used for dynamic width */
|
/* we must check for positional arg used for dynamic width */
|
||||||
|
n = N;
|
||||||
old_is_pos_arg = is_pos_arg;
|
old_is_pos_arg = is_pos_arg;
|
||||||
is_pos_arg = 0;
|
is_pos_arg = 0;
|
||||||
if (is_digit (*fmt)) {
|
if (is_digit (*fmt)) {
|
||||||
|
|
|
@ -113,11 +113,8 @@ Supporting OS subroutines required:
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef _HAVE_STDC
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#else
|
#include <errno.h>
|
||||||
#include <varargs.h>
|
|
||||||
#endif
|
|
||||||
#include "local.h"
|
#include "local.h"
|
||||||
|
|
||||||
#ifdef INTEGER_ONLY
|
#ifdef INTEGER_ONLY
|
||||||
|
@ -169,6 +166,18 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
|
||||||
# undef _NO_LONGLONG
|
# undef _NO_LONGLONG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _NO_POS_ARGS
|
||||||
|
#ifdef _WANT_IO_POS_ARGS
|
||||||
|
# undef _NO_POS_ARGS
|
||||||
|
# ifdef NL_ARGMAX
|
||||||
|
# define MAX_POS_ARGS NL_ARGMAX
|
||||||
|
# else
|
||||||
|
# define MAX_POS_ARGS 32
|
||||||
|
# endif
|
||||||
|
|
||||||
|
static void * get_arg (int, va_list *, int *, void **);
|
||||||
|
#endif /* _WANT_IO_POS_ARGS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags used during conversion.
|
* Flags used during conversion.
|
||||||
*/
|
*/
|
||||||
|
@ -276,6 +285,13 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
register char *p0; /* saves original value of p when necessary */
|
register char *p0; /* saves original value of p when necessary */
|
||||||
int nassigned; /* number of fields assigned */
|
int nassigned; /* number of fields assigned */
|
||||||
int nread; /* number of characters consumed from fp */
|
int nread; /* number of characters consumed from fp */
|
||||||
|
#ifndef _NO_POS_ARGS
|
||||||
|
int N; /* arg number */
|
||||||
|
int arg_index = 0; /* index into args processed directly */
|
||||||
|
int numargs = 0; /* number of varargs read */
|
||||||
|
void *args[MAX_POS_ARGS]; /* positional args read */
|
||||||
|
int is_pos_arg; /* is current format positional? */
|
||||||
|
#endif
|
||||||
int base = 0; /* base argument to strtol/strtoul */
|
int base = 0; /* base argument to strtol/strtoul */
|
||||||
int nbytes = 1; /* number of bytes read from fmt string */
|
int nbytes = 1; /* number of bytes read from fmt string */
|
||||||
wchar_t wc; /* wchar to use to read format string */
|
wchar_t wc; /* wchar to use to read format string */
|
||||||
|
@ -291,9 +307,11 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
char *cp;
|
char *cp;
|
||||||
short *sp;
|
short *sp;
|
||||||
int *ip;
|
int *ip;
|
||||||
|
#ifdef FLOATING_POINT
|
||||||
float *flp;
|
float *flp;
|
||||||
_LONG_DOUBLE *ldp;
|
_LONG_DOUBLE *ldp;
|
||||||
double *dp;
|
double *dp;
|
||||||
|
#endif
|
||||||
long *lp;
|
long *lp;
|
||||||
#ifndef _NO_LONGLONG
|
#ifndef _NO_LONGLONG
|
||||||
long long *llp;
|
long long *llp;
|
||||||
|
@ -303,6 +321,22 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
static _CONST short basefix[17] =
|
static _CONST short basefix[17] =
|
||||||
{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
|
||||||
|
|
||||||
|
/* Macro to support positional arguments */
|
||||||
|
#ifndef _NO_POS_ARGS
|
||||||
|
# define GET_ARG(n, ap, type) \
|
||||||
|
((type) (is_pos_arg \
|
||||||
|
? (n < numargs \
|
||||||
|
? args[n] \
|
||||||
|
: get_arg (n, &ap, &numargs, args)) \
|
||||||
|
: (arg_index++ < numargs \
|
||||||
|
? args[n] \
|
||||||
|
: (numargs < MAX_POS_ARGS \
|
||||||
|
? args[numargs++] = va_arg (ap, void *) \
|
||||||
|
: va_arg (ap, void *)))))
|
||||||
|
#else
|
||||||
|
# define GET_ARG(n, ap, type) (va_arg (ap, type))
|
||||||
|
#endif
|
||||||
|
|
||||||
_flockfile (fp);
|
_flockfile (fp);
|
||||||
|
|
||||||
nassigned = 0;
|
nassigned = 0;
|
||||||
|
@ -332,6 +366,10 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
goto literal;
|
goto literal;
|
||||||
width = 0;
|
width = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
|
#ifndef _NO_POS_ARGS
|
||||||
|
N = arg_index;
|
||||||
|
is_pos_arg = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* switch on the format. continue if done; break once format
|
* switch on the format. continue if done; break once format
|
||||||
|
@ -439,6 +477,19 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
width = width * 10 + c - '0';
|
width = width * 10 + c - '0';
|
||||||
goto again;
|
goto again;
|
||||||
|
|
||||||
|
#ifndef _NO_POS_ARGS
|
||||||
|
case '$':
|
||||||
|
if (width <= MAX_POS_ARGS)
|
||||||
|
{
|
||||||
|
N = width - 1;
|
||||||
|
is_pos_arg = 1;
|
||||||
|
width = 0;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
rptr->_errno = EINVAL;
|
||||||
|
goto input_failure;
|
||||||
|
#endif /* !_NO_POS_ARGS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Conversions. Those marked `compat' are for
|
* Conversions. Those marked `compat' are for
|
||||||
* 4.[123]BSD compatibility.
|
* 4.[123]BSD compatibility.
|
||||||
|
@ -540,31 +591,31 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
#ifdef _WANT_IO_C99_FORMATS
|
#ifdef _WANT_IO_C99_FORMATS
|
||||||
if (flags & CHAR)
|
if (flags & CHAR)
|
||||||
{
|
{
|
||||||
cp = va_arg (ap, char *);
|
cp = GET_ARG (N, ap, char *);
|
||||||
*cp = nread;
|
*cp = nread;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (flags & SHORT)
|
if (flags & SHORT)
|
||||||
{
|
{
|
||||||
sp = va_arg (ap, short *);
|
sp = GET_ARG (N, ap, short *);
|
||||||
*sp = nread;
|
*sp = nread;
|
||||||
}
|
}
|
||||||
else if (flags & LONG)
|
else if (flags & LONG)
|
||||||
{
|
{
|
||||||
lp = va_arg (ap, long *);
|
lp = GET_ARG (N, ap, long *);
|
||||||
*lp = nread;
|
*lp = nread;
|
||||||
}
|
}
|
||||||
#ifndef _NO_LONGLONG
|
#ifndef _NO_LONGLONG
|
||||||
else if (flags & LONGDBL)
|
else if (flags & LONGDBL)
|
||||||
{
|
{
|
||||||
llp = va_arg (ap, long long*);
|
llp = GET_ARG (N, ap, long long*);
|
||||||
*llp = nread;
|
*llp = nread;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ip = va_arg (ap, int *);
|
ip = GET_ARG (N, ap, int *);
|
||||||
*ip = nread;
|
*ip = nread;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -626,7 +677,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
if (flags & LONG)
|
if (flags & LONG)
|
||||||
{
|
{
|
||||||
if ((flags & SUPPRESS) == 0)
|
if ((flags & SUPPRESS) == 0)
|
||||||
wcp = va_arg (ap, wchar_t *);
|
wcp = GET_ARG (N, ap, wchar_t *);
|
||||||
else
|
else
|
||||||
wcp = NULL;
|
wcp = NULL;
|
||||||
n = 0;
|
n = 0;
|
||||||
|
@ -690,7 +741,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t r = fread ((_PTR) va_arg (ap, char *), 1, width, fp);
|
size_t r = fread ((_PTR) GET_ARG (N, ap, char *), 1, width, fp);
|
||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
goto input_failure;
|
goto input_failure;
|
||||||
|
@ -724,7 +775,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p0 = p = va_arg (ap, char *);
|
p0 = p = GET_ARG (N, ap, char *);
|
||||||
while (ccltab[*fp->_p])
|
while (ccltab[*fp->_p])
|
||||||
{
|
{
|
||||||
fp->_r--;
|
fp->_r--;
|
||||||
|
@ -755,7 +806,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
{
|
{
|
||||||
/* Process %S and %ls placeholders */
|
/* Process %S and %ls placeholders */
|
||||||
if ((flags & SUPPRESS) == 0)
|
if ((flags & SUPPRESS) == 0)
|
||||||
wcp = va_arg (ap, wchar_t *);
|
wcp = GET_ARG (N, ap, wchar_t *);
|
||||||
else
|
else
|
||||||
wcp = &wc;
|
wcp = &wc;
|
||||||
n = 0;
|
n = 0;
|
||||||
|
@ -814,7 +865,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p0 = p = va_arg (ap, char *);
|
p0 = p = GET_ARG (N, ap, char *);
|
||||||
while (!isspace (*fp->_p))
|
while (!isspace (*fp->_p))
|
||||||
{
|
{
|
||||||
fp->_r--;
|
fp->_r--;
|
||||||
|
@ -993,22 +1044,22 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
*p = 0;
|
*p = 0;
|
||||||
res = (*ccfn) (rptr, buf, (char **) NULL, base);
|
res = (*ccfn) (rptr, buf, (char **) NULL, base);
|
||||||
if (flags & POINTER)
|
if (flags & POINTER)
|
||||||
*(va_arg (ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
|
*(GET_ARG (N, ap, _PTR *)) = (_PTR) (unsigned _POINTER_INT) res;
|
||||||
#ifdef _WANT_IO_C99_FORMATS
|
#ifdef _WANT_IO_C99_FORMATS
|
||||||
else if (flags & CHAR)
|
else if (flags & CHAR)
|
||||||
{
|
{
|
||||||
cp = va_arg (ap, char *);
|
cp = GET_ARG (N, ap, char *);
|
||||||
*cp = res;
|
*cp = res;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (flags & SHORT)
|
else if (flags & SHORT)
|
||||||
{
|
{
|
||||||
sp = va_arg (ap, short *);
|
sp = GET_ARG (N, ap, short *);
|
||||||
*sp = res;
|
*sp = res;
|
||||||
}
|
}
|
||||||
else if (flags & LONG)
|
else if (flags & LONG)
|
||||||
{
|
{
|
||||||
lp = va_arg (ap, long *);
|
lp = GET_ARG (N, ap, long *);
|
||||||
*lp = res;
|
*lp = res;
|
||||||
}
|
}
|
||||||
#ifndef _NO_LONGLONG
|
#ifndef _NO_LONGLONG
|
||||||
|
@ -1019,13 +1070,13 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
resll = _strtoull_r (rptr, buf, (char **) NULL, base);
|
resll = _strtoull_r (rptr, buf, (char **) NULL, base);
|
||||||
else
|
else
|
||||||
resll = _strtoll_r (rptr, buf, (char **) NULL, base);
|
resll = _strtoll_r (rptr, buf, (char **) NULL, base);
|
||||||
llp = va_arg (ap, long long*);
|
llp = GET_ARG (N, ap, long long*);
|
||||||
*llp = resll;
|
*llp = resll;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ip = va_arg (ap, int *);
|
ip = GET_ARG (N, ap, int *);
|
||||||
*ip = res;
|
*ip = res;
|
||||||
}
|
}
|
||||||
nassigned++;
|
nassigned++;
|
||||||
|
@ -1257,17 +1308,17 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
|
||||||
|
|
||||||
if (flags & LONG)
|
if (flags & LONG)
|
||||||
{
|
{
|
||||||
dp = va_arg (ap, double *);
|
dp = GET_ARG (N, ap, double *);
|
||||||
*dp = res;
|
*dp = res;
|
||||||
}
|
}
|
||||||
else if (flags & LONGDBL)
|
else if (flags & LONGDBL)
|
||||||
{
|
{
|
||||||
ldp = va_arg (ap, _LONG_DOUBLE *);
|
ldp = GET_ARG (N, ap, _LONG_DOUBLE *);
|
||||||
*ldp = QUAD_RES;
|
*ldp = QUAD_RES;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flp = va_arg (ap, float *);
|
flp = GET_ARG (N, ap, float *);
|
||||||
if (isnan (res))
|
if (isnan (res))
|
||||||
*flp = nanf (NULL);
|
*flp = nanf (NULL);
|
||||||
else
|
else
|
||||||
|
@ -1288,3 +1339,18 @@ all_done:
|
||||||
_funlockfile (fp);
|
_funlockfile (fp);
|
||||||
return nassigned;
|
return nassigned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _NO_POS_ARGS
|
||||||
|
/* Process all intermediate arguments. Fortunately, with scanf, all
|
||||||
|
intermediate arguments are sizeof(void*), so we don't need to scan
|
||||||
|
ahead in the format string. */
|
||||||
|
static void *
|
||||||
|
get_arg (int n, va_list *ap, int *numargs_p, void **args)
|
||||||
|
{
|
||||||
|
int numargs = *numargs_p;
|
||||||
|
while (n >= numargs)
|
||||||
|
args[numargs++] = va_arg (*ap, void *);
|
||||||
|
*numargs_p = numargs;
|
||||||
|
return args[n];
|
||||||
|
}
|
||||||
|
#endif /* !_NO_POS_ARGS */
|
||||||
|
|
Loading…
Reference in New Issue