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 | } |