Turn the errors for use of strstr and similar into conditional warnings.
[gnulib.git] / lib / printf-parse.c
index fceb5c9..f5cdb6e 100644 (file)
@@ -1,5 +1,5 @@
 /* Formatted output to strings.
-   Copyright (C) 1999-2000, 2002-2003 Free Software Foundation, Inc.
+   Copyright (C) 1999-2000, 2002-2003, 2006-2007 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include <config.h>
 
 /* Specification.  */
 #if WIDE_CHAR_VERSION
@@ -29,9 +27,6 @@
 /* Get size_t, NULL.  */
 #include <stddef.h>
 
-/* Get ssize_t.  */
-#include <sys/types.h>
-
 /* Get intmax_t.  */
 #if HAVE_STDINT_H_WITH_UINTMAX
 # include <stdint.h>
 /* Checked size_t computations.  */
 #include "xsize.h"
 
-#ifndef SSIZE_MAX
-# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
-#endif
-
 #if WIDE_CHAR_VERSION
 # define PRINTF_PARSE wprintf_parse
 # define CHAR_T wchar_t
@@ -69,7 +60,7 @@ int
 PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
 {
   const CHAR_T *cp = format;           /* pointer into format */
-  ssize_t arg_posn = 0;                /* number of regular arguments consumed */
+  size_t arg_posn = 0;         /* number of regular arguments consumed */
   size_t d_allocated;                  /* allocated elements of d->dir */
   size_t a_allocated;                  /* allocated elements of a->arg */
   size_t max_width_length = 0;
@@ -77,7 +68,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
 
   d->count = 0;
   d_allocated = 1;
-  d->dir = malloc (d_allocated * sizeof (DIRECTIVE));
+  d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
   if (d->dir == NULL)
     /* Out of memory.  */
     return -1;
@@ -101,9 +92,9 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
        if (size_overflow_p (memory_size))                              \
          /* Overflow, would lead to out of memory.  */                 \
          goto error;                                                   \
-       memory = (a->arg                                                \
-                 ? realloc (a->arg, memory_size)                       \
-                 : malloc (memory_size));                              \
+       memory = (argument *) (a->arg                                   \
+                              ? realloc (a->arg, memory_size)          \
+                              : malloc (memory_size));                 \
        if (memory == NULL)                                             \
          /* Out of memory.  */                                         \
          goto error;                                                   \
@@ -123,7 +114,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
       CHAR_T c = *cp++;
       if (c == '%')
        {
-         ssize_t arg_index = -1;
+         size_t arg_index = ARG_NONE;
          DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */
 
          /* Initialize the next directive.  */
@@ -131,11 +122,11 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
          dp->flags = 0;
          dp->width_start = NULL;
          dp->width_end = NULL;
-         dp->width_arg_index = -1;
+         dp->width_arg_index = ARG_NONE;
          dp->precision_start = NULL;
          dp->precision_end = NULL;
-         dp->precision_arg_index = -1;
-         dp->arg_index = -1;
+         dp->precision_arg_index = ARG_NONE;
+         dp->arg_index = ARG_NONE;
 
          /* Test for positional argument.  */
          if (*cp >= '0' && *cp <= '9')
@@ -153,7 +144,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                  if (n == 0)
                    /* Positional argument 0.  */
                    goto error;
-                 if (size_overflow_p (n) || n - 1 > SSIZE_MAX)
+                 if (size_overflow_p (n))
                    /* n too large, would lead to out of memory later.  */
                    goto error;
                  arg_index = n - 1;
@@ -223,18 +214,18 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                      if (n == 0)
                        /* Positional argument 0.  */
                        goto error;
-                     if (size_overflow_p (n) || n - 1 > SSIZE_MAX)
+                     if (size_overflow_p (n))
                        /* n too large, would lead to out of memory later.  */
                        goto error;
                      dp->width_arg_index = n - 1;
                      cp = np + 1;
                    }
                }
-             if (dp->width_arg_index < 0)
+             if (dp->width_arg_index == ARG_NONE)
                {
                  dp->width_arg_index = arg_posn++;
-                 if (dp->width_arg_index < 0)
-                   /* arg_posn wrapped around at SSIZE_MAX.  */
+                 if (dp->width_arg_index == ARG_NONE)
+                   /* arg_posn wrapped around.  */
                    goto error;
                }
              REGISTER_ARG (dp->width_arg_index, TYPE_INT);
@@ -280,7 +271,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                          if (n == 0)
                            /* Positional argument 0.  */
                            goto error;
-                         if (size_overflow_p (n) || n - 1 > SSIZE_MAX)
+                         if (size_overflow_p (n))
                            /* n too large, would lead to out of memory
                               later.  */
                            goto error;
@@ -288,11 +279,11 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                          cp = np + 1;
                        }
                    }
-                 if (dp->precision_arg_index < 0)
+                 if (dp->precision_arg_index == ARG_NONE)
                    {
                      dp->precision_arg_index = arg_posn++;
-                     if (dp->precision_arg_index < 0)
-                       /* arg_posn wrapped around at SSIZE_MAX.  */
+                     if (dp->precision_arg_index == ARG_NONE)
+                       /* arg_posn wrapped around.  */
                        goto error;
                    }
                  REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
@@ -335,7 +326,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                      flags += 8;
                      cp++;
                    }
-#ifdef HAVE_INTMAX_T
+#if HAVE_INTMAX_T
                  else if (*cp == 'j')
                    {
                      if (sizeof (intmax_t) > sizeof (long))
@@ -391,11 +382,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
              switch (c)
                {
                case 'd': case 'i':
-#ifdef HAVE_LONG_LONG
+#if HAVE_LONG_LONG_INT
+                 /* If 'long long' exists and is larger than 'long':  */
                  if (flags >= 16 || (flags & 4))
                    type = TYPE_LONGLONGINT;
                  else
 #endif
+                 /* If 'long long' exists and is the same as 'long', we parse
+                    "lld" into TYPE_LONGINT.  */
                  if (flags >= 8)
                    type = TYPE_LONGINT;
                  else if (flags & 2)
@@ -406,11 +400,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                    type = TYPE_INT;
                  break;
                case 'o': case 'u': case 'x': case 'X':
-#ifdef HAVE_LONG_LONG
+#if HAVE_LONG_LONG_INT
+                 /* If 'long long' exists and is larger than 'long':  */
                  if (flags >= 16 || (flags & 4))
                    type = TYPE_ULONGLONGINT;
                  else
 #endif
+                 /* If 'unsigned long long' exists and is the same as
+                    'unsigned long', we parse "llu" into TYPE_ULONGINT.  */
                  if (flags >= 8)
                    type = TYPE_ULONGINT;
                  else if (flags & 2)
@@ -422,7 +419,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                  break;
                case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
                case 'a': case 'A':
-#ifdef HAVE_LONG_DOUBLE
+#if HAVE_LONG_DOUBLE
                  if (flags >= 16 || (flags & 4))
                    type = TYPE_LONGDOUBLE;
                  else
@@ -431,7 +428,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                  break;
                case 'c':
                  if (flags >= 8)
-#ifdef HAVE_WINT_T
+#if HAVE_WINT_T
                    type = TYPE_WIDE_CHAR;
 #else
                    goto error;
@@ -439,7 +436,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                  else
                    type = TYPE_CHAR;
                  break;
-#ifdef HAVE_WINT_T
+#if HAVE_WINT_T
                case 'C':
                  type = TYPE_WIDE_CHAR;
                  c = 'c';
@@ -447,7 +444,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
 #endif
                case 's':
                  if (flags >= 8)
-#ifdef HAVE_WCHAR_T
+#if HAVE_WCHAR_T
                    type = TYPE_WIDE_STRING;
 #else
                    goto error;
@@ -455,7 +452,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                  else
                    type = TYPE_STRING;
                  break;
-#ifdef HAVE_WCHAR_T
+#if HAVE_WCHAR_T
                case 'S':
                  type = TYPE_WIDE_STRING;
                  c = 's';
@@ -465,11 +462,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
                  type = TYPE_POINTER;
                  break;
                case 'n':
-#ifdef HAVE_LONG_LONG
+#if HAVE_LONG_LONG_INT
+                 /* If 'long long' exists and is larger than 'long':  */
                  if (flags >= 16 || (flags & 4))
                    type = TYPE_COUNT_LONGLONGINT_POINTER;
                  else
 #endif
+                 /* If 'long long' exists and is the same as 'long', we parse
+                    "lln" into TYPE_COUNT_LONGINT_POINTER.  */
                  if (flags >= 8)
                    type = TYPE_COUNT_LONGINT_POINTER;
                  else if (flags & 2)
@@ -491,11 +491,11 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
            if (type != TYPE_NONE)
              {
                dp->arg_index = arg_index;
-               if (dp->arg_index < 0)
+               if (dp->arg_index == ARG_NONE)
                  {
                    dp->arg_index = arg_posn++;
-                   if (dp->arg_index < 0)
-                     /* arg_posn wrapped around at SSIZE_MAX.  */
+                   if (dp->arg_index == ARG_NONE)
+                     /* arg_posn wrapped around.  */
                      goto error;
                  }
                REGISTER_ARG (dp->arg_index, type);
@@ -511,14 +511,11 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
              DIRECTIVE *memory;
 
              d_allocated = xtimes (d_allocated, 2);
-             if (size_overflow_p (d_allocated))
-               /* Overflow, would lead to out of memory.  */
-               goto error;
              memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
              if (size_overflow_p (memory_size))
                /* Overflow, would lead to out of memory.  */
                goto error;
-             memory = realloc (d->dir, memory_size);
+             memory = (DIRECTIVE *) realloc (d->dir, memory_size);
              if (memory == NULL)
                /* Out of memory.  */
                goto error;