summaryrefslogtreecommitdiffstats
path: root/gl/printf-parse.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/printf-parse.c')
-rw-r--r--gl/printf-parse.c55
1 files changed, 33 insertions, 22 deletions
diff --git a/gl/printf-parse.c b/gl/printf-parse.c
index f612beb..23cacc1 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
80int 82int
81PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a) 83PRINTF_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
605error: 617error:
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
613out_of_memory: 625out_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);
618out_of_memory_1:
619 errno = ENOMEM; 630 errno = ENOMEM;
620 return -1; 631 return -1;
621} 632}