1 /* Formatted output to strings.
2 Copyright (C) 1999-2000, 2002-2003, 2006-2007 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published
6 by the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 /* This file can be parametrized with the following macros:
20 CHAR_T The element type of the format string.
21 CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
22 in the format string are ASCII.
23 DIRECTIVE Structure denoting a format directive.
25 DIRECTIVES Structure denoting the set of format directives of a
26 format string. Depends on CHAR_T.
27 PRINTF_PARSE Function that parses a format string.
29 STATIC Set to 'static' to declare the function static.
30 ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */
38 # include "printf-parse.h"
41 /* Default parameters. */
43 # define PRINTF_PARSE printf_parse
45 # define DIRECTIVE char_directive
46 # define DIRECTIVES char_directives
49 /* Get size_t, NULL. */
53 #if defined IN_LIBINTL || defined IN_LIBASPRINTF
54 # if HAVE_STDINT_H_WITH_UINTMAX
57 # if HAVE_INTTYPES_H_WITH_UINTMAX
58 # include <inttypes.h>
64 /* malloc(), realloc(), free(). */
70 /* Checked size_t computations. */
82 PRINTF_PARSE (const CHAR_T
*format
, DIRECTIVES
*d
, arguments
*a
)
84 const CHAR_T
*cp
= format
; /* pointer into format */
85 size_t arg_posn
= 0; /* number of regular arguments consumed */
86 size_t d_allocated
; /* allocated elements of d->dir */
87 size_t a_allocated
; /* allocated elements of a->arg */
88 size_t max_width_length
= 0;
89 size_t max_precision_length
= 0;
93 d
->dir
= (DIRECTIVE
*) malloc (d_allocated
* sizeof (DIRECTIVE
));
102 #define REGISTER_ARG(_index_,_type_) \
104 size_t n = (_index_); \
105 if (n >= a_allocated) \
107 size_t memory_size; \
110 a_allocated = xtimes (a_allocated, 2); \
111 if (a_allocated <= n) \
112 a_allocated = xsum (n, 1); \
113 memory_size = xtimes (a_allocated, sizeof (argument)); \
114 if (size_overflow_p (memory_size)) \
115 /* Overflow, would lead to out of memory. */ \
116 goto out_of_memory; \
117 memory = (argument *) (a->arg \
118 ? realloc (a->arg, memory_size) \
119 : malloc (memory_size)); \
120 if (memory == NULL) \
121 /* Out of memory. */ \
122 goto out_of_memory; \
125 while (a->count <= n) \
126 a->arg[a->count++].type = TYPE_NONE; \
127 if (a->arg[n].type == TYPE_NONE) \
128 a->arg[n].type = (_type_); \
129 else if (a->arg[n].type != (_type_)) \
130 /* Ambiguous type for positional argument. */ \
139 size_t arg_index
= ARG_NONE
;
140 DIRECTIVE
*dp
= &d
->dir
[d
->count
]; /* pointer to next directive */
142 /* Initialize the next directive. */
143 dp
->dir_start
= cp
- 1;
145 dp
->width_start
= NULL
;
146 dp
->width_end
= NULL
;
147 dp
->width_arg_index
= ARG_NONE
;
148 dp
->precision_start
= NULL
;
149 dp
->precision_end
= NULL
;
150 dp
->precision_arg_index
= ARG_NONE
;
151 dp
->arg_index
= ARG_NONE
;
153 /* Test for positional argument. */
154 if (*cp
>= '0' && *cp
<= '9')
158 for (np
= cp
; *np
>= '0' && *np
<= '9'; np
++)
164 for (np
= cp
; *np
>= '0' && *np
<= '9'; np
++)
165 n
= xsum (xtimes (n
, 10), *np
- '0');
167 /* Positional argument 0. */
169 if (size_overflow_p (n
))
170 /* n too large, would lead to out of memory later. */
177 /* Read the flags. */
182 dp
->flags
|= FLAG_GROUP
;
187 dp
->flags
|= FLAG_LEFT
;
192 dp
->flags
|= FLAG_SHOWSIGN
;
197 dp
->flags
|= FLAG_SPACE
;
202 dp
->flags
|= FLAG_ALT
;
207 dp
->flags
|= FLAG_ZERO
;
214 /* Parse the field width. */
217 dp
->width_start
= cp
;
220 if (max_width_length
< 1)
221 max_width_length
= 1;
223 /* Test for positional argument. */
224 if (*cp
>= '0' && *cp
<= '9')
228 for (np
= cp
; *np
>= '0' && *np
<= '9'; np
++)
234 for (np
= cp
; *np
>= '0' && *np
<= '9'; np
++)
235 n
= xsum (xtimes (n
, 10), *np
- '0');
237 /* Positional argument 0. */
239 if (size_overflow_p (n
))
240 /* n too large, would lead to out of memory later. */
242 dp
->width_arg_index
= n
- 1;
246 if (dp
->width_arg_index
== ARG_NONE
)
248 dp
->width_arg_index
= arg_posn
++;
249 if (dp
->width_arg_index
== ARG_NONE
)
250 /* arg_posn wrapped around. */
253 REGISTER_ARG (dp
->width_arg_index
, TYPE_INT
);
255 else if (*cp
>= '0' && *cp
<= '9')
259 dp
->width_start
= cp
;
260 for (; *cp
>= '0' && *cp
<= '9'; cp
++)
263 width_length
= dp
->width_end
- dp
->width_start
;
264 if (max_width_length
< width_length
)
265 max_width_length
= width_length
;
268 /* Parse the precision. */
274 dp
->precision_start
= cp
- 1;
276 dp
->precision_end
= cp
;
277 if (max_precision_length
< 2)
278 max_precision_length
= 2;
280 /* Test for positional argument. */
281 if (*cp
>= '0' && *cp
<= '9')
285 for (np
= cp
; *np
>= '0' && *np
<= '9'; np
++)
291 for (np
= cp
; *np
>= '0' && *np
<= '9'; np
++)
292 n
= xsum (xtimes (n
, 10), *np
- '0');
294 /* Positional argument 0. */
296 if (size_overflow_p (n
))
297 /* n too large, would lead to out of memory
300 dp
->precision_arg_index
= n
- 1;
304 if (dp
->precision_arg_index
== ARG_NONE
)
306 dp
->precision_arg_index
= arg_posn
++;
307 if (dp
->precision_arg_index
== ARG_NONE
)
308 /* arg_posn wrapped around. */
311 REGISTER_ARG (dp
->precision_arg_index
, TYPE_INT
);
315 size_t precision_length
;
317 dp
->precision_start
= cp
- 1;
318 for (; *cp
>= '0' && *cp
<= '9'; cp
++)
320 dp
->precision_end
= cp
;
321 precision_length
= dp
->precision_end
- dp
->precision_start
;
322 if (max_precision_length
< precision_length
)
323 max_precision_length
= precision_length
;
330 /* Parse argument type/size specifiers. */
338 flags
|= (1 << (flags
& 1));
353 if (sizeof (intmax_t) > sizeof (long))
355 /* intmax_t = long long */
358 else if (sizeof (intmax_t) > sizeof (int))
360 /* intmax_t = long */
365 else if (*cp
== 'z' || *cp
== 'Z')
367 /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
368 because the warning facility in gcc-2.95.2 understands
369 only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
370 if (sizeof (size_t) > sizeof (long))
372 /* size_t = long long */
375 else if (sizeof (size_t) > sizeof (int))
384 if (sizeof (ptrdiff_t) > sizeof (long))
386 /* ptrdiff_t = long long */
389 else if (sizeof (ptrdiff_t) > sizeof (int))
391 /* ptrdiff_t = long */
400 /* Read the conversion character. */
405 #if HAVE_LONG_LONG_INT
406 /* If 'long long' exists and is larger than 'long': */
407 if (flags
>= 16 || (flags
& 4))
408 type
= TYPE_LONGLONGINT
;
411 /* If 'long long' exists and is the same as 'long', we parse
412 "lld" into TYPE_LONGINT. */
422 case 'o': case 'u': case 'x': case 'X':
423 #if HAVE_LONG_LONG_INT
424 /* If 'long long' exists and is larger than 'long': */
425 if (flags
>= 16 || (flags
& 4))
426 type
= TYPE_ULONGLONGINT
;
429 /* If 'unsigned long long' exists and is the same as
430 'unsigned long', we parse "llu" into TYPE_ULONGINT. */
432 type
= TYPE_ULONGINT
;
440 case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
442 if (flags
>= 16 || (flags
& 4))
443 type
= TYPE_LONGDOUBLE
;
450 type
= TYPE_WIDE_CHAR
;
459 type
= TYPE_WIDE_CHAR
;
466 type
= TYPE_WIDE_STRING
;
475 type
= TYPE_WIDE_STRING
;
483 #if HAVE_LONG_LONG_INT
484 /* If 'long long' exists and is larger than 'long': */
485 if (flags
>= 16 || (flags
& 4))
486 type
= TYPE_COUNT_LONGLONGINT_POINTER
;
489 /* If 'long long' exists and is the same as 'long', we parse
490 "lln" into TYPE_COUNT_LONGINT_POINTER. */
492 type
= TYPE_COUNT_LONGINT_POINTER
;
494 type
= TYPE_COUNT_SCHAR_POINTER
;
496 type
= TYPE_COUNT_SHORT_POINTER
;
498 type
= TYPE_COUNT_INT_POINTER
;
501 /* The unistdio extensions. */
504 type
= TYPE_U32_STRING
;
506 type
= TYPE_U16_STRING
;
508 type
= TYPE_U8_STRING
;
515 /* Unknown conversion character. */
520 if (type
!= TYPE_NONE
)
522 dp
->arg_index
= arg_index
;
523 if (dp
->arg_index
== ARG_NONE
)
525 dp
->arg_index
= arg_posn
++;
526 if (dp
->arg_index
== ARG_NONE
)
527 /* arg_posn wrapped around. */
530 REGISTER_ARG (dp
->arg_index
, type
);
537 if (d
->count
>= d_allocated
)
542 d_allocated
= xtimes (d_allocated
, 2);
543 memory_size
= xtimes (d_allocated
, sizeof (DIRECTIVE
));
544 if (size_overflow_p (memory_size
))
545 /* Overflow, would lead to out of memory. */
547 memory
= (DIRECTIVE
*) realloc (d
->dir
, memory_size
);
554 #if CHAR_T_ONLY_ASCII
555 else if (!c_isascii (c
))
557 /* Non-ASCII character. Not supported. */
562 d
->dir
[d
->count
].dir_start
= cp
;
564 d
->max_width_length
= max_width_length
;
565 d
->max_precision_length
= max_precision_length
;
589 #undef CHAR_T_ONLY_ASCII