1
/* vsprintf with automatic memory allocation.
2
Copyright (C) 1999, 2002-2006 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
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
20
This must come before <config.h> because <config.h> may include
21
<features.h>, and once <features.h> has been included, it's too late. */
23
# define _GNU_SOURCE 1
33
# include "vasnwprintf.h"
35
# include "vasnprintf.h"
38
#include <stdio.h> /* snprintf(), sprintf() */
39
#include <stdlib.h> /* abort(), malloc(), realloc(), free() */
40
#include <string.h> /* memcpy(), strlen() */
41
#include <errno.h> /* errno */
42
#include <limits.h> /* CHAR_BIT */
43
#include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
45
# include "wprintf-parse.h"
47
# include "printf-parse.h"
50
/* Checked size_t computations. */
55
# define local_wcslen wcslen
57
/* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
58
a dependency towards this library, here is a local substitute.
59
Define this substitute only once, even if this file is included
60
twice in the same compilation unit. */
61
# ifndef local_wcslen_defined
62
# define local_wcslen_defined 1
64
local_wcslen (const wchar_t *s)
68
for (ptr = s; *ptr != (wchar_t) 0; ptr++)
77
# define VASNPRINTF vasnwprintf
78
# define CHAR_T wchar_t
79
# define DIRECTIVE wchar_t_directive
80
# define DIRECTIVES wchar_t_directives
81
# define PRINTF_PARSE wprintf_parse
82
# define USE_SNPRINTF 1
83
# if HAVE_DECL__SNWPRINTF
84
/* On Windows, the function swprintf() has a different signature than
85
on Unix; we use the _snwprintf() function instead. */
86
# define SNPRINTF _snwprintf
89
# define SNPRINTF swprintf
92
# define VASNPRINTF vasnprintf
94
# define DIRECTIVE char_directive
95
# define DIRECTIVES char_directives
96
# define PRINTF_PARSE printf_parse
97
# define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)
98
# if HAVE_DECL__SNPRINTF
100
# define SNPRINTF _snprintf
103
# define SNPRINTF snprintf
108
VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
113
if (PRINTF_PARSE (format, &d, &a) < 0)
124
if (printf_fetchargs (args, &a) < 0)
132
size_t buf_neededlength;
134
CHAR_T *buf_malloced;
138
/* Output string accumulator. */
143
/* Allocate a small buffer that will hold a directive passed to
144
sprintf or snprintf. */
146
xsum4 (7, d.max_width_length, d.max_precision_length, 6);
148
if (buf_neededlength < 4000 / sizeof (CHAR_T))
150
buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
156
size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
157
if (size_overflow_p (buf_memsize))
158
goto out_of_memory_1;
159
buf = (CHAR_T *) malloc (buf_memsize);
161
goto out_of_memory_1;
165
if (resultbuf != NULL)
168
allocated = *lengthp;
177
result is either == resultbuf or == NULL or malloc-allocated.
178
If length > 0, then result != NULL. */
180
/* Ensures that allocated >= needed. Aborts through a jump to
181
out_of_memory if needed is SIZE_MAX or otherwise too big. */
182
#define ENSURE_ALLOCATION(needed) \
183
if ((needed) > allocated) \
185
size_t memory_size; \
188
allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
189
if ((needed) > allocated) \
190
allocated = (needed); \
191
memory_size = xtimes (allocated, sizeof (CHAR_T)); \
192
if (size_overflow_p (memory_size)) \
193
goto out_of_memory; \
194
if (result == resultbuf || result == NULL) \
195
memory = (CHAR_T *) malloc (memory_size); \
197
memory = (CHAR_T *) realloc (result, memory_size); \
198
if (memory == NULL) \
199
goto out_of_memory; \
200
if (result == resultbuf && length > 0) \
201
memcpy (memory, result, length * sizeof (CHAR_T)); \
205
for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
207
if (cp != dp->dir_start)
209
size_t n = dp->dir_start - cp;
210
size_t augmented_length = xsum (length, n);
212
ENSURE_ALLOCATION (augmented_length);
213
memcpy (result + length, cp, n * sizeof (CHAR_T));
214
length = augmented_length;
219
/* Execute a single directive. */
220
if (dp->conversion == '%')
222
size_t augmented_length;
224
if (!(dp->arg_index == ARG_NONE))
226
augmented_length = xsum (length, 1);
227
ENSURE_ALLOCATION (augmented_length);
228
result[length] = '%';
229
length = augmented_length;
233
if (!(dp->arg_index != ARG_NONE))
236
if (dp->conversion == 'n')
238
switch (a.arg[dp->arg_index].type)
240
case TYPE_COUNT_SCHAR_POINTER:
241
*a.arg[dp->arg_index].a.a_count_schar_pointer = length;
243
case TYPE_COUNT_SHORT_POINTER:
244
*a.arg[dp->arg_index].a.a_count_short_pointer = length;
246
case TYPE_COUNT_INT_POINTER:
247
*a.arg[dp->arg_index].a.a_count_int_pointer = length;
249
case TYPE_COUNT_LONGINT_POINTER:
250
*a.arg[dp->arg_index].a.a_count_longint_pointer = length;
252
#ifdef HAVE_LONG_LONG_INT
253
case TYPE_COUNT_LONGLONGINT_POINTER:
254
*a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
263
arg_type type = a.arg[dp->arg_index].type;
265
unsigned int prefix_count;
272
/* Allocate a temporary buffer of sufficient size for calling
279
if (dp->width_start != dp->width_end)
281
if (dp->width_arg_index != ARG_NONE)
285
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
287
arg = a.arg[dp->width_arg_index].a.a_int;
288
width = (arg < 0 ? (unsigned int) (-arg) : arg);
292
const CHAR_T *digitp = dp->width_start;
295
width = xsum (xtimes (width, 10), *digitp++ - '0');
296
while (digitp != dp->width_end);
301
if (dp->precision_start != dp->precision_end)
303
if (dp->precision_arg_index != ARG_NONE)
307
if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
309
arg = a.arg[dp->precision_arg_index].a.a_int;
310
precision = (arg < 0 ? 0 : arg);
314
const CHAR_T *digitp = dp->precision_start + 1;
317
while (digitp != dp->precision_end)
318
precision = xsum (xtimes (precision, 10), *digitp++ - '0');
322
switch (dp->conversion)
325
case 'd': case 'i': case 'u':
326
# ifdef HAVE_LONG_LONG_INT
327
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
329
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
330
* 0.30103 /* binary -> decimal */
332
+ 1; /* turn floor into ceil */
335
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
337
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
338
* 0.30103 /* binary -> decimal */
340
+ 1; /* turn floor into ceil */
343
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
344
* 0.30103 /* binary -> decimal */
346
+ 1; /* turn floor into ceil */
347
if (tmp_length < precision)
348
tmp_length = precision;
349
/* Multiply by 2, as an estimate for FLAG_GROUP. */
350
tmp_length = xsum (tmp_length, tmp_length);
351
/* Add 1, to account for a leading sign. */
352
tmp_length = xsum (tmp_length, 1);
356
# ifdef HAVE_LONG_LONG_INT
357
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
359
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
360
* 0.333334 /* binary -> octal */
362
+ 1; /* turn floor into ceil */
365
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
367
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
368
* 0.333334 /* binary -> octal */
370
+ 1; /* turn floor into ceil */
373
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
374
* 0.333334 /* binary -> octal */
376
+ 1; /* turn floor into ceil */
377
if (tmp_length < precision)
378
tmp_length = precision;
379
/* Add 1, to account for a leading sign. */
380
tmp_length = xsum (tmp_length, 1);
384
# ifdef HAVE_LONG_LONG_INT
385
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
387
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
388
* 0.25 /* binary -> hexadecimal */
390
+ 1; /* turn floor into ceil */
393
if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
395
(unsigned int) (sizeof (unsigned long) * CHAR_BIT
396
* 0.25 /* binary -> hexadecimal */
398
+ 1; /* turn floor into ceil */
401
(unsigned int) (sizeof (unsigned int) * CHAR_BIT
402
* 0.25 /* binary -> hexadecimal */
404
+ 1; /* turn floor into ceil */
405
if (tmp_length < precision)
406
tmp_length = precision;
407
/* Add 2, to account for a leading sign or alternate form. */
408
tmp_length = xsum (tmp_length, 2);
412
# ifdef HAVE_LONG_DOUBLE
413
if (type == TYPE_LONGDOUBLE)
415
(unsigned int) (LDBL_MAX_EXP
416
* 0.30103 /* binary -> decimal */
417
* 2 /* estimate for FLAG_GROUP */
419
+ 1 /* turn floor into ceil */
420
+ 10; /* sign, decimal point etc. */
424
(unsigned int) (DBL_MAX_EXP
425
* 0.30103 /* binary -> decimal */
426
* 2 /* estimate for FLAG_GROUP */
428
+ 1 /* turn floor into ceil */
429
+ 10; /* sign, decimal point etc. */
430
tmp_length = xsum (tmp_length, precision);
433
case 'e': case 'E': case 'g': case 'G':
436
12; /* sign, decimal point, exponent etc. */
437
tmp_length = xsum (tmp_length, precision);
441
# if defined HAVE_WINT_T && !WIDE_CHAR_VERSION
442
if (type == TYPE_WIDE_CHAR)
443
tmp_length = MB_CUR_MAX;
451
if (type == TYPE_WIDE_STRING)
454
local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
456
# if !WIDE_CHAR_VERSION
457
tmp_length = xtimes (tmp_length, MB_CUR_MAX);
462
tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
467
(unsigned int) (sizeof (void *) * CHAR_BIT
468
* 0.25 /* binary -> hexadecimal */
470
+ 1 /* turn floor into ceil */
471
+ 2; /* account for leading 0x */
478
if (tmp_length < width)
481
tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
484
if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
488
size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
490
if (size_overflow_p (tmp_memsize))
491
/* Overflow, would lead to out of memory. */
493
tmp = (CHAR_T *) malloc (tmp_memsize);
500
/* Construct the format string for calling snprintf or
504
if (dp->flags & FLAG_GROUP)
506
if (dp->flags & FLAG_LEFT)
508
if (dp->flags & FLAG_SHOWSIGN)
510
if (dp->flags & FLAG_SPACE)
512
if (dp->flags & FLAG_ALT)
514
if (dp->flags & FLAG_ZERO)
516
if (dp->width_start != dp->width_end)
518
size_t n = dp->width_end - dp->width_start;
519
memcpy (p, dp->width_start, n * sizeof (CHAR_T));
522
if (dp->precision_start != dp->precision_end)
524
size_t n = dp->precision_end - dp->precision_start;
525
memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
531
#ifdef HAVE_LONG_LONG_INT
532
case TYPE_LONGLONGINT:
533
case TYPE_ULONGLONGINT:
543
case TYPE_WIDE_STRING:
547
#ifdef HAVE_LONG_DOUBLE
548
case TYPE_LONGDOUBLE:
564
/* Construct the arguments for calling snprintf or sprintf. */
566
if (dp->width_arg_index != ARG_NONE)
568
if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
570
prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
572
if (dp->precision_arg_index != ARG_NONE)
574
if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
576
prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
580
/* Prepare checking whether snprintf returns the count
582
ENSURE_ALLOCATION (xsum (length, 1));
583
result[length] = '\0';
592
maxlen = allocated - length;
597
# define SNPRINTF_BUF(arg) \
598
switch (prefix_count) \
601
retcount = SNPRINTF (result + length, maxlen, buf, \
605
retcount = SNPRINTF (result + length, maxlen, buf, \
606
prefixes[0], arg, &count); \
609
retcount = SNPRINTF (result + length, maxlen, buf, \
610
prefixes[0], prefixes[1], arg, \
617
# define SNPRINTF_BUF(arg) \
618
switch (prefix_count) \
621
count = sprintf (tmp, buf, arg); \
624
count = sprintf (tmp, buf, prefixes[0], arg); \
627
count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
639
int arg = a.arg[dp->arg_index].a.a_schar;
645
unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
651
int arg = a.arg[dp->arg_index].a.a_short;
657
unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
663
int arg = a.arg[dp->arg_index].a.a_int;
669
unsigned int arg = a.arg[dp->arg_index].a.a_uint;
675
long int arg = a.arg[dp->arg_index].a.a_longint;
681
unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
685
#ifdef HAVE_LONG_LONG_INT
686
case TYPE_LONGLONGINT:
688
long long int arg = a.arg[dp->arg_index].a.a_longlongint;
692
case TYPE_ULONGLONGINT:
694
unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
701
double arg = a.arg[dp->arg_index].a.a_double;
705
#ifdef HAVE_LONG_DOUBLE
706
case TYPE_LONGDOUBLE:
708
long double arg = a.arg[dp->arg_index].a.a_longdouble;
715
int arg = a.arg[dp->arg_index].a.a_char;
722
wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
729
const char *arg = a.arg[dp->arg_index].a.a_string;
734
case TYPE_WIDE_STRING:
736
const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
743
void *arg = a.arg[dp->arg_index].a.a_pointer;
752
/* Portability: Not all implementations of snprintf()
753
are ISO C 99 compliant. Determine the number of
754
bytes that snprintf() has produced or would have
758
/* Verify that snprintf() has NUL-terminated its
760
if (count < maxlen && result[length + count] != '\0')
762
/* Portability hack. */
763
if (retcount > count)
768
/* snprintf() doesn't understand the '%n'
772
/* Don't use the '%n' directive; instead, look
773
at the snprintf() return value. */
779
/* Look at the snprintf() return value. */
782
/* HP-UX 10.20 snprintf() is doubly deficient:
783
It doesn't understand the '%n' directive,
784
*and* it returns -1 (rather than the length
785
that would have been required) when the
786
buffer is too small. */
788
xsum (xtimes (allocated, 2), 12);
789
ENSURE_ALLOCATION (bigger_need);
798
/* Attempt to handle failure. */
801
if (!(result == resultbuf || result == NULL))
803
if (buf_malloced != NULL)
811
if (count >= tmp_length)
812
/* tmp_length was incorrectly calculated - fix the
817
/* Make room for the result. */
820
/* Need at least count bytes. But allocate
821
proportionally, to avoid looping eternally if
822
snprintf() reports a too small count. */
824
xmax (xsum (length, count), xtimes (allocated, 2));
826
ENSURE_ALLOCATION (n);
833
/* The snprintf() result did fit. */
835
/* Append the sprintf() result. */
836
memcpy (result + length, tmp, count * sizeof (CHAR_T));
848
/* Add the final NUL. */
849
ENSURE_ALLOCATION (xsum (length, 1));
850
result[length] = '\0';
852
if (result != resultbuf && length + 1 < allocated)
854
/* Shrink the allocated memory if possible. */
857
memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
862
if (buf_malloced != NULL)
866
/* Note that we can produce a big string of a length > INT_MAX. POSIX
867
says that snprintf() fails with errno = EOVERFLOW in this case, but
868
that's only because snprintf() returns an 'int'. This function does
869
not have this limitation. */
873
if (!(result == resultbuf || result == NULL))
875
if (buf_malloced != NULL)