diff options
| author | Manuel A. Fernandez Montecelo <manuel.montezelo@gmail.com> | 2016-05-26 16:48:39 +0100 | 
|---|---|---|
| committer | Manuel A. Fernandez Montecelo <manuel.montezelo@gmail.com> | 2016-05-26 16:48:39 +0100 | 
| commit | 8dfc46115527afe3706e9e4225e9ad019c97d695 (patch) | |
| tree | 372d5192b218455834781a0037c57e919a06b488 /lib/printf-parse.c | |
| parent | 2291cf138eb72ad38d8c59b8b6f762875c8c4ff2 (diff) | |
| parent | 5f2b09982312c98863eb9a8dfe2c608b81f58259 (diff) | |
Merge tag 'upstream/0.9.6'
Upstream version 0.9.6
Diffstat (limited to 'lib/printf-parse.c')
| -rw-r--r-- | lib/printf-parse.c | 55 | 
1 files changed, 33 insertions, 22 deletions
| diff --git a/lib/printf-parse.c b/lib/printf-parse.c index d88ddf30..b4592363 100644 --- a/lib/printf-parse.c +++ b/lib/printf-parse.c @@ -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-2015 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 @@ -12,8 +12,7 @@     GNU Lesser General Public License for more details.     You should have received a copy of the GNU Lesser General Public License along -   with this program; if not, write to the Free Software Foundation, -   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */ +   with this program; if not, see <http://www.gnu.org/licenses/>.  */  /* This file can be parametrized with the following macros:       CHAR_T             The element type of the format string. @@ -63,6 +62,9 @@  /* malloc(), realloc(), free().  */  #include <stdlib.h> +/* memcpy().  */ +#include <string.h> +  /* errno.  */  #include <errno.h> @@ -80,23 +82,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 +112,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)                                               \ @@ -206,6 +207,13 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)                    dp->flags |= FLAG_ZERO;                    cp++;                  } +#if __GLIBC__ >= 2 && !defined __UCLIBC__ +              else if (*cp == 'I') +                { +                  dp->flags |= FLAG_LOCALIZED; +                  cp++; +                } +#endif                else                  break;              } @@ -393,7 +401,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)                        cp++;                      }  #if defined __APPLE__ && defined __MACH__ -                  /* On MacOS X 10.3, PRIdMAX is defined as "qd". +                  /* On Mac OS X 10.3, PRIdMAX is defined as "qd".                       We cannot change it to "lld" because PRIdMAX must also                       be understood by the system's printf routines.  */                    else if (*cp == 'q') @@ -412,7 +420,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)                      }  #endif  #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ -                  /* On native Win32, PRIdMAX is defined as "I64d". +                  /* On native Windows, PRIdMAX is defined as "I64d".                       We cannot change it to "lld" because PRIdMAX must also                       be understood by the system's printf routines.  */                    else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') @@ -581,10 +589,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;              }          } @@ -603,19 +615,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;  } | 
