Update Gnulib; add new modules.
[bpt/guile.git] / lib / printf-parse.c
index 8c68fda..0143861 100644 (file)
@@ -1,5 +1,5 @@
 /* Formatted output to strings.
-   Copyright (C) 1999-2000, 2002-2003, 2006-2010 Free Software Foundation, Inc.
+   Copyright (C) 1999-2000, 2002-2003, 2006-2011 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
@@ -63,6 +63,9 @@
 /* malloc(), realloc(), free().  */
 #include <stdlib.h>
 
+/* memcpy().  */
+#include <string.h>
+
 /* errno.  */
 #include <errno.h>
 
@@ -80,23 +83,20 @@ STATIC
 int
 PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
 {
-  const CHAR_T *cp = format;            /* pointer into format */
+  const CHAR_T *cp = format;    /* pointer into format */
   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 d_allocated;           /* allocated elements of d->dir */
+  size_t a_allocated;           /* allocated elements of a->arg */
   size_t max_width_length = 0;
   size_t max_precision_length = 0;
 
   d->count = 0;
-  d_allocated = 1;
-  d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE));
-  if (d->dir == NULL)
-    /* Out of memory.  */
-    goto out_of_memory_1;
+  d_allocated = N_DIRECT_ALLOC_DIRECTIVES;
+  d->dir = d->direct_alloc_dir;
 
   a->count = 0;
-  a_allocated = 0;
-  a->arg = NULL;
+  a_allocated = N_DIRECT_ALLOC_ARGUMENTS;
+  a->arg = a->direct_alloc_arg;
 
 #define REGISTER_ARG(_index_,_type_) \
   {                                                                     \
@@ -113,12 +113,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
         if (size_overflow_p (memory_size))                              \
           /* Overflow, would lead to out of memory.  */                 \
           goto out_of_memory;                                           \
-        memory = (argument *) (a->arg                                   \
+        memory = (argument *) (a->arg != a->direct_alloc_arg            \
                                ? realloc (a->arg, memory_size)          \
                                : malloc (memory_size));                 \
         if (memory == NULL)                                             \
           /* Out of memory.  */                                         \
           goto out_of_memory;                                           \
+        if (a->arg == a->direct_alloc_arg)                              \
+          memcpy (memory, a->arg, a->count * sizeof (argument));        \
         a->arg = memory;                                                \
       }                                                                 \
     while (a->count <= n)                                               \
@@ -588,10 +590,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
               if (size_overflow_p (memory_size))
                 /* Overflow, would lead to out of memory.  */
                 goto out_of_memory;
-              memory = (DIRECTIVE *) realloc (d->dir, memory_size);
+              memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir
+                                      ? realloc (d->dir, memory_size)
+                                      : malloc (memory_size));
               if (memory == NULL)
                 /* Out of memory.  */
                 goto out_of_memory;
+              if (d->dir == d->direct_alloc_dir)
+                memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE));
               d->dir = memory;
             }
         }
@@ -610,19 +616,18 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
   return 0;
 
 error:
-  if (a->arg)
+  if (a->arg != a->direct_alloc_arg)
     free (a->arg);
-  if (d->dir)
+  if (d->dir != d->direct_alloc_dir)
     free (d->dir);
   errno = EINVAL;
   return -1;
 
 out_of_memory:
-  if (a->arg)
+  if (a->arg != a->direct_alloc_arg)
     free (a->arg);
-  if (d->dir)
+  if (d->dir != d->direct_alloc_dir)
     free (d->dir);
-out_of_memory_1:
   errno = ENOMEM;
   return -1;
 }