1
/* Formatted output to strings.
2
Copyright (C) 1999-2000, 2002-2003 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,
25
# include "wprintf-parse.h"
27
# include "printf-parse.h"
30
/* Get size_t, NULL. */
34
#if HAVE_STDINT_H_WITH_UINTMAX
37
#if HAVE_INTTYPES_H_WITH_UINTMAX
38
# include <inttypes.h>
41
/* malloc(), realloc(), free(). */
44
/* Checked size_t computations. */
48
# define PRINTF_PARSE wprintf_parse
49
# define CHAR_T wchar_t
50
# define DIRECTIVE wchar_t_directive
51
# define DIRECTIVES wchar_t_directives
53
# define PRINTF_PARSE printf_parse
55
# define DIRECTIVE char_directive
56
# define DIRECTIVES char_directives
63
PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
65
const CHAR_T *cp = format; /* pointer into format */
66
size_t arg_posn = 0; /* number of regular arguments consumed */
67
size_t d_allocated; /* allocated elements of d->dir */
68
size_t a_allocated; /* allocated elements of a->arg */
69
size_t max_width_length = 0;
70
size_t max_precision_length = 0;
74
d->dir = malloc (d_allocated * sizeof (DIRECTIVE));
83
#define REGISTER_ARG(_index_,_type_) \
85
size_t n = (_index_); \
86
if (n >= a_allocated) \
91
a_allocated = xtimes (a_allocated, 2); \
92
if (a_allocated <= n) \
93
a_allocated = xsum (n, 1); \
94
memory_size = xtimes (a_allocated, sizeof (argument)); \
95
if (size_overflow_p (memory_size)) \
96
/* Overflow, would lead to out of memory. */ \
99
? realloc (a->arg, memory_size) \
100
: malloc (memory_size)); \
101
if (memory == NULL) \
102
/* Out of memory. */ \
106
while (a->count <= n) \
107
a->arg[a->count++].type = TYPE_NONE; \
108
if (a->arg[n].type == TYPE_NONE) \
109
a->arg[n].type = (_type_); \
110
else if (a->arg[n].type != (_type_)) \
111
/* Ambiguous type for positional argument. */ \
120
size_t arg_index = ARG_NONE;
121
DIRECTIVE *dp = &d->dir[d->count];/* pointer to next directive */
123
/* Initialize the next directive. */
124
dp->dir_start = cp - 1;
126
dp->width_start = NULL;
127
dp->width_end = NULL;
128
dp->width_arg_index = ARG_NONE;
129
dp->precision_start = NULL;
130
dp->precision_end = NULL;
131
dp->precision_arg_index = ARG_NONE;
132
dp->arg_index = ARG_NONE;
134
/* Test for positional argument. */
135
if (*cp >= '0' && *cp <= '9')
139
for (np = cp; *np >= '0' && *np <= '9'; np++)
145
for (np = cp; *np >= '0' && *np <= '9'; np++)
146
n = xsum (xtimes (n, 10), *np - '0');
148
/* Positional argument 0. */
150
if (size_overflow_p (n))
151
/* n too large, would lead to out of memory later. */
158
/* Read the flags. */
163
dp->flags |= FLAG_GROUP;
168
dp->flags |= FLAG_LEFT;
173
dp->flags |= FLAG_SHOWSIGN;
178
dp->flags |= FLAG_SPACE;
183
dp->flags |= FLAG_ALT;
188
dp->flags |= FLAG_ZERO;
195
/* Parse the field width. */
198
dp->width_start = cp;
201
if (max_width_length < 1)
202
max_width_length = 1;
204
/* Test for positional argument. */
205
if (*cp >= '0' && *cp <= '9')
209
for (np = cp; *np >= '0' && *np <= '9'; np++)
215
for (np = cp; *np >= '0' && *np <= '9'; np++)
216
n = xsum (xtimes (n, 10), *np - '0');
218
/* Positional argument 0. */
220
if (size_overflow_p (n))
221
/* n too large, would lead to out of memory later. */
223
dp->width_arg_index = n - 1;
227
if (dp->width_arg_index == ARG_NONE)
229
dp->width_arg_index = arg_posn++;
230
if (dp->width_arg_index == ARG_NONE)
231
/* arg_posn wrapped around. */
234
REGISTER_ARG (dp->width_arg_index, TYPE_INT);
236
else if (*cp >= '0' && *cp <= '9')
240
dp->width_start = cp;
241
for (; *cp >= '0' && *cp <= '9'; cp++)
244
width_length = dp->width_end - dp->width_start;
245
if (max_width_length < width_length)
246
max_width_length = width_length;
249
/* Parse the precision. */
255
dp->precision_start = cp - 1;
257
dp->precision_end = cp;
258
if (max_precision_length < 2)
259
max_precision_length = 2;
261
/* Test for positional argument. */
262
if (*cp >= '0' && *cp <= '9')
266
for (np = cp; *np >= '0' && *np <= '9'; np++)
272
for (np = cp; *np >= '0' && *np <= '9'; np++)
273
n = xsum (xtimes (n, 10), *np - '0');
275
/* Positional argument 0. */
277
if (size_overflow_p (n))
278
/* n too large, would lead to out of memory
281
dp->precision_arg_index = n - 1;
285
if (dp->precision_arg_index == ARG_NONE)
287
dp->precision_arg_index = arg_posn++;
288
if (dp->precision_arg_index == ARG_NONE)
289
/* arg_posn wrapped around. */
292
REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
296
size_t precision_length;
298
dp->precision_start = cp - 1;
299
for (; *cp >= '0' && *cp <= '9'; cp++)
301
dp->precision_end = cp;
302
precision_length = dp->precision_end - dp->precision_start;
303
if (max_precision_length < precision_length)
304
max_precision_length = precision_length;
311
/* Parse argument type/size specifiers. */
319
flags |= (1 << (flags & 1));
335
if (sizeof (intmax_t) > sizeof (long))
337
/* intmax_t = long long */
340
else if (sizeof (intmax_t) > sizeof (int))
342
/* intmax_t = long */
348
else if (*cp == 'z' || *cp == 'Z')
350
/* 'z' is standardized in ISO C 99, but glibc uses 'Z'
351
because the warning facility in gcc-2.95.2 understands
352
only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
353
if (sizeof (size_t) > sizeof (long))
355
/* size_t = long long */
358
else if (sizeof (size_t) > sizeof (int))
367
if (sizeof (ptrdiff_t) > sizeof (long))
369
/* ptrdiff_t = long long */
372
else if (sizeof (ptrdiff_t) > sizeof (int))
374
/* ptrdiff_t = long */
383
/* Read the conversion character. */
388
#ifdef HAVE_LONG_LONG
389
if (flags >= 16 || (flags & 4))
390
type = TYPE_LONGLONGINT;
402
case 'o': case 'u': case 'x': case 'X':
403
#ifdef HAVE_LONG_LONG
404
if (flags >= 16 || (flags & 4))
405
type = TYPE_ULONGLONGINT;
409
type = TYPE_ULONGINT;
417
case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
419
#ifdef HAVE_LONG_DOUBLE
420
if (flags >= 16 || (flags & 4))
421
type = TYPE_LONGDOUBLE;
429
type = TYPE_WIDE_CHAR;
438
type = TYPE_WIDE_CHAR;
445
type = TYPE_WIDE_STRING;
454
type = TYPE_WIDE_STRING;
462
#ifdef HAVE_LONG_LONG
463
if (flags >= 16 || (flags & 4))
464
type = TYPE_COUNT_LONGLONGINT_POINTER;
468
type = TYPE_COUNT_LONGINT_POINTER;
470
type = TYPE_COUNT_SCHAR_POINTER;
472
type = TYPE_COUNT_SHORT_POINTER;
474
type = TYPE_COUNT_INT_POINTER;
480
/* Unknown conversion character. */
485
if (type != TYPE_NONE)
487
dp->arg_index = arg_index;
488
if (dp->arg_index == ARG_NONE)
490
dp->arg_index = arg_posn++;
491
if (dp->arg_index == ARG_NONE)
492
/* arg_posn wrapped around. */
495
REGISTER_ARG (dp->arg_index, type);
502
if (d->count >= d_allocated)
507
d_allocated = xtimes (d_allocated, 2);
508
memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
509
if (size_overflow_p (memory_size))
510
/* Overflow, would lead to out of memory. */
512
memory = realloc (d->dir, memory_size);
520
d->dir[d->count].dir_start = cp;
522
d->max_width_length = max_width_length;
523
d->max_precision_length = max_precision_length;