]> sourceware.org Git - newlib-cygwin.git/commitdiff
* libc/stdio/vfscanf.c (__SVFSCANF_R): Support scanf(%1$s).
authorEric Blake <eblake@redhat.com>
Wed, 23 May 2007 20:36:28 +0000 (20:36 +0000)
committerEric Blake <eblake@redhat.com>
Wed, 23 May 2007 20:36:28 +0000 (20:36 +0000)
Avoid warning when !FLOATING_POINT.
* libc/stdio/vfprintf.c (_VFPRINTF_R): Simplify _NO_POS_ARGS
slightly.

newlib/ChangeLog
newlib/libc/stdio/vfprintf.c
newlib/libc/stdio/vfscanf.c

index 0566b8a30fff87ab9657b7f0894d31e1fc3ca596..a72b01318926f01b39c4a6c8896286eccd94fa13 100644 (file)
@@ -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>
 
        * libc/argz/argz_create_sep.c (argz_create_sep): Initialize *argz_len
index 72bd7e89e3273cfe9f81d37c95ff7383dfd3db85..e734cb19c40c38c2edc8861839b9b8f96d047ce2 100644 (file)
@@ -125,8 +125,8 @@ static char *rcsid = "$Id$";
 # endif
 #endif
 
-#define _NO_POS_ARGS 
-#if defined _WANT_IO_POS_ARGS
+#define _NO_POS_ARGS
+#ifdef _WANT_IO_POS_ARGS
 # undef _NO_POS_ARGS
 #endif
 
@@ -385,9 +385,9 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
        register struct __siov *iovp;/* for PRINT macro */
        register int flags;     /* flags as above */
        char *fmt_anchor;       /* current format spec being processed */
+#ifndef _NO_POS_ARGS
        int N;                  /* arg number */
        int arg_index;          /* index into args processed directly */
-#ifndef _NO_POS_ARGS
        int numargs;            /* number of varargs read */
        char *saved_fmt;        /* saved fmt pointer */
        union arg_val args[MAX_POS_ARGS];
@@ -472,21 +472,21 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
 
        /* Macros to support positional arguments */
 #ifndef _NO_POS_ARGS
-#define GET_ARG(n, ap, type) \
-  ( is_pos_arg \
-      ? n < numargs \
-         ? args[n].val_##type \
-         : get_arg (data, n, fmt_anchor, &ap, &numargs, args, arg_type, &saved_fmt)->val_##type \
-      : arg_index++ < numargs \
-         ? args[n].val_##type \
-         : numargs < MAX_POS_ARGS \
-           ? args[numargs++].val_##type = va_arg (ap, type) \
-           : va_arg (ap, type) \
-  )
+# define GET_ARG(n, ap, type)                                          \
+       (is_pos_arg                                                     \
+        ? (n < numargs                                                 \
+           ? args[n].val_##type                                        \
+           : get_arg (data, n, fmt_anchor, &ap, &numargs, args,        \
+                      arg_type, &saved_fmt)->val_##type)               \
+        : (arg_index++ < numargs                                       \
+           ? args[n].val_##type                                        \
+           : (numargs < MAX_POS_ARGS                                   \
+              ? args[numargs++].val_##type = va_arg (ap, type)         \
+              : va_arg (ap, type))))
 #else
-#define GET_ARG(n, ap, type) (va_arg (ap, type))
+# define GET_ARG(n, ap, type) (va_arg (ap, type))
 #endif
-    
+
        /*
         * To extend shorts properly, we need both signed and unsigned
         * argument extraction methods.
@@ -538,8 +538,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
        uio.uio_resid = 0;
        uio.uio_iovcnt = 0;
        ret = 0;
-       arg_index = 0;
 #ifndef _NO_POS_ARGS
+       arg_index = 0;
        saved_fmt = NULL;
        arg_type[0] = -1;
        numargs = 0;
@@ -580,8 +580,8 @@ _DEFUN(_VFPRINTF_R, (data, fp, fmt0, ap),
                width = 0;
                prec = -1;
                sign = '\0';
-               N = arg_index;
 #ifndef _NO_POS_ARGS
+               N = arg_index;
                is_pos_arg = 0;
 #endif
 
@@ -609,9 +609,9 @@ reswitch:   switch (ch) {
                        flags |= ALT;
                        goto rflag;
                case '*':
-                       n = N;
 #ifndef _NO_POS_ARGS
                        /* we must check for positional arg used for dynamic width */
+                       n = N;
                        old_is_pos_arg = is_pos_arg;
                        is_pos_arg = 0;
                        if (is_digit (*fmt)) {
@@ -661,9 +661,9 @@ reswitch:   switch (ch) {
                        goto rflag;
                case '.':
                        if ((ch = *fmt++) == '*') {
-                               n = N;
 #ifndef _NO_POS_ARGS
                                /* we must check for positional arg used for dynamic width */
+                               n = N;
                                old_is_pos_arg = is_pos_arg;
                                is_pos_arg = 0;
                                if (is_digit (*fmt)) {
index bd597b39583f4216b2dd4944e22183539eaa31ce..e73e8764f327de2b16ece6b55d74abb8863f5fd7 100644 (file)
@@ -113,11 +113,8 @@ Supporting OS subroutines required:
 #include <limits.h>
 #include <wchar.h>
 #include <string.h>
-#ifdef _HAVE_STDC
 #include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
+#include <errno.h>
 #include "local.h"
 
 #ifdef INTEGER_ONLY
@@ -169,6 +166,18 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
 # undef _NO_LONGLONG
 #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.
  */
@@ -276,6 +285,13 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
   register char *p0;           /* saves original value of p when necessary */
   int nassigned;               /* number of fields assigned */
   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 nbytes = 1;               /* number of bytes read from fmt string */
   wchar_t wc;                   /* wchar to use to read format string */
@@ -291,9 +307,11 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
   char *cp;
   short *sp;
   int *ip;
+#ifdef FLOATING_POINT
   float *flp;
   _LONG_DOUBLE *ldp;
   double *dp;
+#endif
   long *lp;
 #ifndef _NO_LONGLONG
   long long *llp;
@@ -303,6 +321,22 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
   static _CONST short basefix[17] =
     {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);
  
   nassigned = 0;
@@ -332,6 +366,10 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
        goto literal;
       width = 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
@@ -439,6 +477,19 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
          width = width * 10 + c - '0';
          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
           * 4.[123]BSD compatibility.
@@ -540,31 +591,31 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
 #ifdef _WANT_IO_C99_FORMATS
          if (flags & CHAR)
            {
-             cp = va_arg (ap, char *);
+             cp = GET_ARG (N, ap, char *);
              *cp = nread;
            }
          else
 #endif
          if (flags & SHORT)
            {
-             sp = va_arg (ap, short *);
+             sp = GET_ARG (N, ap, short *);
              *sp = nread;
            }
          else if (flags & LONG)
            {
-             lp = va_arg (ap, long *);
+             lp = GET_ARG (N, ap, long *);
              *lp = nread;
            }
 #ifndef _NO_LONGLONG
          else if (flags & LONGDBL)
            {
-             llp = va_arg (ap, long long*);
+             llp = GET_ARG (N, ap, long long*);
              *llp = nread;
            }
 #endif
          else
            {
-             ip = va_arg (ap, int *);
+             ip = GET_ARG (N, ap, int *);
              *ip = nread;
            }
          continue;
@@ -626,7 +677,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
           if (flags & LONG) 
             {
               if ((flags & SUPPRESS) == 0)
-                wcp = va_arg (ap, wchar_t *);
+                wcp = GET_ARG (N, ap, wchar_t *);
               else
                 wcp = NULL;
               n = 0;
@@ -690,7 +741,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
            }
          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)
                goto input_failure;
@@ -724,7 +775,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
            }
          else
            {
-             p0 = p = va_arg (ap, char *);
+             p0 = p = GET_ARG (N, ap, char *);
              while (ccltab[*fp->_p])
                {
                  fp->_r--;
@@ -755,7 +806,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
             {
               /* Process %S and %ls placeholders */
               if ((flags & SUPPRESS) == 0)
-                wcp = va_arg (ap, wchar_t *);
+                wcp = GET_ARG (N, ap, wchar_t *);
               else
                 wcp = &wc;
               n = 0;
@@ -814,7 +865,7 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
            }
          else
            {
-             p0 = p = va_arg (ap, char *);
+             p0 = p = GET_ARG (N, ap, char *);
              while (!isspace (*fp->_p))
                {
                  fp->_r--;
@@ -993,22 +1044,22 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
              *p = 0;
              res = (*ccfn) (rptr, buf, (char **) NULL, base);
              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
              else if (flags & CHAR)
                {
-                 cp = va_arg (ap, char *);
+                 cp = GET_ARG (N, ap, char *);
                  *cp = res;
                }
 #endif
              else if (flags & SHORT)
                {
-                 sp = va_arg (ap, short *);
+                 sp = GET_ARG (N, ap, short *);
                  *sp = res;
                }
              else if (flags & LONG)
                {
-                 lp = va_arg (ap, long *);
+                 lp = GET_ARG (N, ap, long *);
                  *lp = res;
                }
 #ifndef _NO_LONGLONG
@@ -1019,13 +1070,13 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
                    resll = _strtoull_r (rptr, buf, (char **) NULL, base);
                  else
                    resll = _strtoll_r (rptr, buf, (char **) NULL, base);
-                 llp = va_arg (ap, long long*);
+                 llp = GET_ARG (N, ap, long long*);
                  *llp = resll;
                }
 #endif
              else
                {
-                 ip = va_arg (ap, int *);
+                 ip = GET_ARG (N, ap, int *);
                  *ip = res;
                }
              nassigned++;
@@ -1257,17 +1308,17 @@ _DEFUN(__SVFSCANF_R, (rptr, fp, fmt0, ap),
 
              if (flags & LONG)
                {
-                 dp = va_arg (ap, double *);
+                 dp = GET_ARG (N, ap, double *);
                  *dp = res;
                }
              else if (flags & LONGDBL)
                {
-                 ldp = va_arg (ap, _LONG_DOUBLE *);
+                 ldp = GET_ARG (N, ap, _LONG_DOUBLE *);
                  *ldp = QUAD_RES;
                }
              else
                {
-                 flp = va_arg (ap, float *);
+                 flp = GET_ARG (N, ap, float *);
                  if (isnan (res))
                    *flp = nanf (NULL);
                  else
@@ -1288,3 +1339,18 @@ all_done:
   _funlockfile (fp);
   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 */
This page took 0.063572 seconds and 5 git commands to generate.