diff options
Diffstat (limited to 'gl/printf-parse.c')
| -rw-r--r-- | gl/printf-parse.c | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/gl/printf-parse.c b/gl/printf-parse.c index f612beb5..23cacc1d 100644 --- a/gl/printf-parse.c +++ b/gl/printf-parse.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* Formatted output to strings. | 1 | /* Formatted output to strings. |
| 2 | Copyright (C) 1999-2000, 2002-2003, 2006-2010 Free Software Foundation, Inc. | 2 | Copyright (C) 1999-2000, 2002-2003, 2006-2013 Free Software Foundation, Inc. |
| 3 | 3 | ||
| 4 | This program is free software; you can redistribute it and/or modify | 4 | This program is free software; you can redistribute it and/or modify |
| 5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
| @@ -12,8 +12,7 @@ | |||
| 12 | GNU General Public License for more details. | 12 | GNU General Public License for more details. |
| 13 | 13 | ||
| 14 | You should have received a copy of the GNU General Public License along | 14 | You should have received a copy of the GNU General Public License along |
| 15 | with this program; if not, write to the Free Software Foundation, | 15 | with this program; if not, see <http://www.gnu.org/licenses/>. */ |
| 16 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
| 17 | 16 | ||
| 18 | /* This file can be parametrized with the following macros: | 17 | /* This file can be parametrized with the following macros: |
| 19 | CHAR_T The element type of the format string. | 18 | CHAR_T The element type of the format string. |
| @@ -63,6 +62,9 @@ | |||
| 63 | /* malloc(), realloc(), free(). */ | 62 | /* malloc(), realloc(), free(). */ |
| 64 | #include <stdlib.h> | 63 | #include <stdlib.h> |
| 65 | 64 | ||
| 65 | /* memcpy(). */ | ||
| 66 | #include <string.h> | ||
| 67 | |||
| 66 | /* errno. */ | 68 | /* errno. */ |
| 67 | #include <errno.h> | 69 | #include <errno.h> |
| 68 | 70 | ||
| @@ -80,23 +82,20 @@ STATIC | |||
| 80 | int | 82 | int |
| 81 | PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | 83 | PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) |
| 82 | { | 84 | { |
| 83 | const CHAR_T *cp = format; /* pointer into format */ | 85 | const CHAR_T *cp = format; /* pointer into format */ |
| 84 | size_t arg_posn = 0; /* number of regular arguments consumed */ | 86 | size_t arg_posn = 0; /* number of regular arguments consumed */ |
| 85 | size_t d_allocated; /* allocated elements of d->dir */ | 87 | size_t d_allocated; /* allocated elements of d->dir */ |
| 86 | size_t a_allocated; /* allocated elements of a->arg */ | 88 | size_t a_allocated; /* allocated elements of a->arg */ |
| 87 | size_t max_width_length = 0; | 89 | size_t max_width_length = 0; |
| 88 | size_t max_precision_length = 0; | 90 | size_t max_precision_length = 0; |
| 89 | 91 | ||
| 90 | d->count = 0; | 92 | d->count = 0; |
| 91 | d_allocated = 1; | 93 | d_allocated = N_DIRECT_ALLOC_DIRECTIVES; |
| 92 | d->dir = (DIRECTIVE *) malloc (d_allocated * sizeof (DIRECTIVE)); | 94 | d->dir = d->direct_alloc_dir; |
| 93 | if (d->dir == NULL) | ||
| 94 | /* Out of memory. */ | ||
| 95 | goto out_of_memory_1; | ||
| 96 | 95 | ||
| 97 | a->count = 0; | 96 | a->count = 0; |
| 98 | a_allocated = 0; | 97 | a_allocated = N_DIRECT_ALLOC_ARGUMENTS; |
| 99 | a->arg = NULL; | 98 | a->arg = a->direct_alloc_arg; |
| 100 | 99 | ||
| 101 | #define REGISTER_ARG(_index_,_type_) \ | 100 | #define REGISTER_ARG(_index_,_type_) \ |
| 102 | { \ | 101 | { \ |
| @@ -113,12 +112,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 113 | if (size_overflow_p (memory_size)) \ | 112 | if (size_overflow_p (memory_size)) \ |
| 114 | /* Overflow, would lead to out of memory. */ \ | 113 | /* Overflow, would lead to out of memory. */ \ |
| 115 | goto out_of_memory; \ | 114 | goto out_of_memory; \ |
| 116 | memory = (argument *) (a->arg \ | 115 | memory = (argument *) (a->arg != a->direct_alloc_arg \ |
| 117 | ? realloc (a->arg, memory_size) \ | 116 | ? realloc (a->arg, memory_size) \ |
| 118 | : malloc (memory_size)); \ | 117 | : malloc (memory_size)); \ |
| 119 | if (memory == NULL) \ | 118 | if (memory == NULL) \ |
| 120 | /* Out of memory. */ \ | 119 | /* Out of memory. */ \ |
| 121 | goto out_of_memory; \ | 120 | goto out_of_memory; \ |
| 121 | if (a->arg == a->direct_alloc_arg) \ | ||
| 122 | memcpy (memory, a->arg, a->count * sizeof (argument)); \ | ||
| 122 | a->arg = memory; \ | 123 | a->arg = memory; \ |
| 123 | } \ | 124 | } \ |
| 124 | while (a->count <= n) \ | 125 | while (a->count <= n) \ |
| @@ -206,6 +207,13 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 206 | dp->flags |= FLAG_ZERO; | 207 | dp->flags |= FLAG_ZERO; |
| 207 | cp++; | 208 | cp++; |
| 208 | } | 209 | } |
| 210 | #if __GLIBC__ >= 2 && !defined __UCLIBC__ | ||
| 211 | else if (*cp == 'I') | ||
| 212 | { | ||
| 213 | dp->flags |= FLAG_LOCALIZED; | ||
| 214 | cp++; | ||
| 215 | } | ||
| 216 | #endif | ||
| 209 | else | 217 | else |
| 210 | break; | 218 | break; |
| 211 | } | 219 | } |
| @@ -393,7 +401,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 393 | cp++; | 401 | cp++; |
| 394 | } | 402 | } |
| 395 | #if defined __APPLE__ && defined __MACH__ | 403 | #if defined __APPLE__ && defined __MACH__ |
| 396 | /* On MacOS X 10.3, PRIdMAX is defined as "qd". | 404 | /* On Mac OS X 10.3, PRIdMAX is defined as "qd". |
| 397 | We cannot change it to "lld" because PRIdMAX must also | 405 | We cannot change it to "lld" because PRIdMAX must also |
| 398 | be understood by the system's printf routines. */ | 406 | be understood by the system's printf routines. */ |
| 399 | else if (*cp == 'q') | 407 | else if (*cp == 'q') |
| @@ -412,7 +420,7 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 412 | } | 420 | } |
| 413 | #endif | 421 | #endif |
| 414 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ | 422 | #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ |
| 415 | /* On native Win32, PRIdMAX is defined as "I64d". | 423 | /* On native Windows, PRIdMAX is defined as "I64d". |
| 416 | We cannot change it to "lld" because PRIdMAX must also | 424 | We cannot change it to "lld" because PRIdMAX must also |
| 417 | be understood by the system's printf routines. */ | 425 | be understood by the system's printf routines. */ |
| 418 | else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') | 426 | else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4') |
| @@ -581,10 +589,14 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 581 | if (size_overflow_p (memory_size)) | 589 | if (size_overflow_p (memory_size)) |
| 582 | /* Overflow, would lead to out of memory. */ | 590 | /* Overflow, would lead to out of memory. */ |
| 583 | goto out_of_memory; | 591 | goto out_of_memory; |
| 584 | memory = (DIRECTIVE *) realloc (d->dir, memory_size); | 592 | memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir |
| 593 | ? realloc (d->dir, memory_size) | ||
| 594 | : malloc (memory_size)); | ||
| 585 | if (memory == NULL) | 595 | if (memory == NULL) |
| 586 | /* Out of memory. */ | 596 | /* Out of memory. */ |
| 587 | goto out_of_memory; | 597 | goto out_of_memory; |
| 598 | if (d->dir == d->direct_alloc_dir) | ||
| 599 | memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE)); | ||
| 588 | d->dir = memory; | 600 | d->dir = memory; |
| 589 | } | 601 | } |
| 590 | } | 602 | } |
| @@ -603,19 +615,18 @@ PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) | |||
| 603 | return 0; | 615 | return 0; |
| 604 | 616 | ||
| 605 | error: | 617 | error: |
| 606 | if (a->arg) | 618 | if (a->arg != a->direct_alloc_arg) |
| 607 | free (a->arg); | 619 | free (a->arg); |
| 608 | if (d->dir) | 620 | if (d->dir != d->direct_alloc_dir) |
| 609 | free (d->dir); | 621 | free (d->dir); |
| 610 | errno = EINVAL; | 622 | errno = EINVAL; |
| 611 | return -1; | 623 | return -1; |
| 612 | 624 | ||
| 613 | out_of_memory: | 625 | out_of_memory: |
| 614 | if (a->arg) | 626 | if (a->arg != a->direct_alloc_arg) |
| 615 | free (a->arg); | 627 | free (a->arg); |
| 616 | if (d->dir) | 628 | if (d->dir != d->direct_alloc_dir) |
| 617 | free (d->dir); | 629 | free (d->dir); |
| 618 | out_of_memory_1: | ||
| 619 | errno = ENOMEM; | 630 | errno = ENOMEM; |
| 620 | return -1; | 631 | return -1; |
| 621 | } | 632 | } |
