1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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
29 #include "glib/galloca.h"
34 #include "vasnprintf.h"
36 #include <stdio.h> /* snprintf(), sprintf() */
37 #include <stdlib.h> /* abort(), malloc(), realloc(), free() */
38 #include <string.h> /* memcpy(), strlen() */
39 #include <errno.h> /* errno */
40 #include <limits.h> /* CHAR_BIT */
41 #include <float.h> /* DBL_MAX_EXP, LDBL_MAX_EXP */
42 #include "printf-parse.h"
46 # define local_wcslen wcslen
48 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
49 a dependency towards this library, here is a local substitute.
50 Define this substitute only once, even if this file is included
51 twice in the same compilation unit. */
52 # ifndef local_wcslen_defined
53 # define local_wcslen_defined 1
55 local_wcslen (const wchar_t *s)
59 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
67 /* For those losing systems which don't have 'alloca' we have to add
68 some additional code emulating it. */
70 # define freea(p) /* nothing */
72 # define alloca(n) malloc (n)
73 # define freea(p) free (p)
76 #ifndef HAVE_LONG_LONG_FORMAT
78 print_long_long (char *buf,
84 unsigned long long number)
91 static const char *upper = "0123456789ABCDEFX";
92 static const char *lower = "0123456789abcdefx";
99 if (p - buf == len - 1) \
129 negative = (long long)number < 0;
131 number = -((long long)number);
136 pointer = bufferend = &buffer[sizeof(buffer) - 1];
138 for (i = 1; i < (int)sizeof(buffer); i++)
140 *pointer-- = digits[number % base];
147 width -= (bufferend - pointer) - 1;
149 /* Adjust precision */
152 precision -= (bufferend - pointer) - 1;
158 /* Adjust width further */
159 if (negative || (flags & FLAG_SHOWSIGN) || (flags & FLAG_SPACE))
161 if (flags & FLAG_ALT)
176 /* Output prefixes spaces if needed */
177 if (! ((flags & FLAG_LEFT) ||
178 ((flags & FLAG_ZERO) && (precision == -1))))
180 count = (precision == -1) ? 0 : precision;
181 while (width-- > count)
185 /* width has been adjusted for signs and alternatives */
190 else if (flags & FLAG_SHOWSIGN)
194 else if (flags & FLAG_SPACE)
199 if (flags & FLAG_ALT)
215 /* Output prefixed zero padding if needed */
216 if (flags & FLAG_ZERO)
220 while (precision-- > 0)
227 /* Output the number itself */
233 /* Output trailing spaces if needed */
234 if (flags & FLAG_LEFT)
247 vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
252 if (printf_parse (format, &d, &a) < 0)
263 if (printf_fetchargs (args, &a) < 0)
272 (char *) alloca (7 + d.max_width_length + d.max_precision_length + 6);
276 /* Output string accumulator. */
281 if (resultbuf != NULL)
284 allocated = *lengthp;
293 result is either == resultbuf or == NULL or malloc-allocated.
294 If length > 0, then result != NULL. */
296 #define ENSURE_ALLOCATION(needed) \
297 if ((needed) > allocated) \
301 allocated = (allocated > 0 ? 2 * allocated : 12); \
302 if ((needed) > allocated) \
303 allocated = (needed); \
304 if (result == resultbuf || result == NULL) \
305 memory = (char *) malloc (allocated); \
307 memory = (char *) realloc (result, allocated); \
309 if (memory == NULL) \
311 if (!(result == resultbuf || result == NULL)) \
318 if (result == resultbuf && length > 0) \
319 memcpy (memory, result, length); \
323 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
325 if (cp != dp->dir_start)
327 size_t n = dp->dir_start - cp;
329 ENSURE_ALLOCATION (length + n);
330 memcpy (result + length, cp, n);
336 /* Execute a single directive. */
337 if (dp->conversion == '%')
339 if (!(dp->arg_index < 0))
341 ENSURE_ALLOCATION (length + 1);
342 result[length] = '%';
347 if (!(dp->arg_index >= 0))
350 if (dp->conversion == 'n')
352 switch (a.arg[dp->arg_index].type)
354 case TYPE_COUNT_SCHAR_POINTER:
355 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
357 case TYPE_COUNT_SHORT_POINTER:
358 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
360 case TYPE_COUNT_INT_POINTER:
361 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
363 case TYPE_COUNT_LONGINT_POINTER:
364 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
366 #ifdef HAVE_LONG_LONG
367 case TYPE_COUNT_LONGLONGINT_POINTER:
368 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
377 arg_type type = a.arg[dp->arg_index].type;
379 unsigned int prefix_count;
382 unsigned int tmp_length;
386 /* Allocate a temporary buffer of sufficient size for calling
390 unsigned int precision;
393 if (dp->width_start != dp->width_end)
395 if (dp->width_arg_index >= 0)
399 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
401 arg = a.arg[dp->width_arg_index].a.a_int;
402 width = (arg < 0 ? -arg : arg);
406 const char *digitp = dp->width_start;
409 width = width * 10 + (*digitp++ - '0');
410 while (digitp != dp->width_end);
415 if (dp->precision_start != dp->precision_end)
417 if (dp->precision_arg_index >= 0)
421 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
423 arg = a.arg[dp->precision_arg_index].a.a_int;
424 precision = (arg < 0 ? 0 : arg);
428 const char *digitp = dp->precision_start + 1;
431 while (digitp != dp->precision_end)
432 precision = precision * 10 + (*digitp++ - '0');
436 switch (dp->conversion)
438 case 'd': case 'i': case 'u':
439 # ifdef HAVE_LONG_LONG
440 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
442 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
443 * 0.30103 /* binary -> decimal */
444 * 2 /* estimate for FLAG_GROUP */
446 + 1 /* turn floor into ceil */
447 + 1; /* account for leading sign */
450 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
452 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
453 * 0.30103 /* binary -> decimal */
454 * 2 /* estimate for FLAG_GROUP */
456 + 1 /* turn floor into ceil */
457 + 1; /* account for leading sign */
460 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
461 * 0.30103 /* binary -> decimal */
462 * 2 /* estimate for FLAG_GROUP */
464 + 1 /* turn floor into ceil */
465 + 1; /* account for leading sign */
469 # ifdef HAVE_LONG_LONG
470 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
472 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
473 * 0.333334 /* binary -> octal */
475 + 1 /* turn floor into ceil */
476 + 1; /* account for leading sign */
479 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
481 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
482 * 0.333334 /* binary -> octal */
484 + 1 /* turn floor into ceil */
485 + 1; /* account for leading sign */
488 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
489 * 0.333334 /* binary -> octal */
491 + 1 /* turn floor into ceil */
492 + 1; /* account for leading sign */
496 # ifdef HAVE_LONG_LONG
497 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
499 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
500 * 0.25 /* binary -> hexadecimal */
502 + 1 /* turn floor into ceil */
503 + 2; /* account for leading sign or alternate form */
506 # ifdef HAVE_INT64_AND_I64
507 if (type == TYPE_INT64 || type == TYPE_UINT64)
509 (unsigned int) (sizeof (unsigned __int64) * CHAR_BIT
510 * 0.25 /* binary -> hexadecimal */
512 + 1 /* turn floor into ceil */
513 + 2; /* account for leading sign or alternate form */
516 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
518 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
519 * 0.25 /* binary -> hexadecimal */
521 + 1 /* turn floor into ceil */
522 + 2; /* account for leading sign or alternate form */
525 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
526 * 0.25 /* binary -> hexadecimal */
528 + 1 /* turn floor into ceil */
529 + 2; /* account for leading sign or alternate form */
533 # ifdef HAVE_LONG_DOUBLE
534 if (type == TYPE_LONGDOUBLE)
536 (unsigned int) (LDBL_MAX_EXP
537 * 0.30103 /* binary -> decimal */
538 * 2 /* estimate for FLAG_GROUP */
540 + 1 /* turn floor into ceil */
542 + 10; /* sign, decimal point etc. */
546 (unsigned int) (DBL_MAX_EXP
547 * 0.30103 /* binary -> decimal */
548 * 2 /* estimate for FLAG_GROUP */
550 + 1 /* turn floor into ceil */
552 + 10; /* sign, decimal point etc. */
555 case 'e': case 'E': case 'g': case 'G':
559 + 12; /* sign, decimal point, exponent etc. */
564 if (type == TYPE_WIDE_CHAR)
565 tmp_length = MB_CUR_MAX;
573 if (type == TYPE_WIDE_STRING)
575 local_wcslen (a.arg[dp->arg_index].a.a_wide_string)
579 tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
584 (unsigned int) (sizeof (void *) * CHAR_BIT
585 * 0.25 /* binary -> hexadecimal */
587 + 1 /* turn floor into ceil */
588 + 2; /* account for leading 0x */
595 if (tmp_length < width)
598 tmp_length++; /* account for trailing NUL */
601 if (tmp_length <= sizeof (tmpbuf))
605 tmp = (char *) malloc (tmp_length);
609 if (!(result == resultbuf || result == NULL))
619 /* Construct the format string for calling snprintf or
623 if (dp->flags & FLAG_GROUP)
625 if (dp->flags & FLAG_LEFT)
627 if (dp->flags & FLAG_SHOWSIGN)
629 if (dp->flags & FLAG_SPACE)
631 if (dp->flags & FLAG_ALT)
633 if (dp->flags & FLAG_ZERO)
635 if (dp->width_start != dp->width_end)
637 size_t n = dp->width_end - dp->width_start;
638 memcpy (p, dp->width_start, n);
641 if (dp->precision_start != dp->precision_end)
643 size_t n = dp->precision_end - dp->precision_start;
644 memcpy (p, dp->precision_start, n);
650 #ifdef HAVE_INT64_AND_I64
658 #ifdef HAVE_LONG_LONG
659 case TYPE_LONGLONGINT:
660 case TYPE_ULONGLONGINT:
661 #ifdef HAVE_INT64_AND_I64 /* The system (sn)printf uses %I64. Also assume
662 * that long long == __int64.
679 case TYPE_WIDE_STRING:
683 #ifdef HAVE_LONG_DOUBLE
684 case TYPE_LONGDOUBLE:
700 /* Construct the arguments for calling snprintf or sprintf. */
702 if (dp->width_arg_index >= 0)
704 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
706 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
708 if (dp->precision_arg_index >= 0)
710 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
712 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
716 /* Prepare checking whether snprintf returns the count
718 ENSURE_ALLOCATION (length + 1);
719 result[length] = '\0';
728 maxlen = allocated - length;
733 #define SNPRINTF_BUF(arg) \
734 switch (prefix_count) \
737 retcount = snprintf (result + length, maxlen, buf, \
741 retcount = snprintf (result + length, maxlen, buf, \
742 prefixes[0], arg, &count); \
745 retcount = snprintf (result + length, maxlen, buf, \
746 prefixes[0], prefixes[1], arg, \
753 #define SNPRINTF_BUF(arg) \
754 switch (prefix_count) \
757 count = sprintf (tmp, buf, arg); \
760 count = sprintf (tmp, buf, prefixes[0], arg); \
763 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
775 int arg = a.arg[dp->arg_index].a.a_schar;
781 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
787 int arg = a.arg[dp->arg_index].a.a_short;
793 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
799 int arg = a.arg[dp->arg_index].a.a_int;
805 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
811 long int arg = a.arg[dp->arg_index].a.a_longint;
817 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
821 #ifdef HAVE_INT64_AND_I64
824 __int64 arg = a.arg[dp->arg_index].a.a_int64;
830 unsigned __int64 arg = a.arg[dp->arg_index].a.a_uint64;
835 #ifdef HAVE_LONG_LONG
836 #ifndef HAVE_LONG_LONG_FORMAT
837 case TYPE_LONGLONGINT:
838 case TYPE_ULONGLONGINT:
840 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
845 if (dp->width_start != dp->width_end)
847 if (dp->width_arg_index >= 0)
851 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
853 arg = a.arg[dp->width_arg_index].a.a_int;
854 width = (arg < 0 ? -arg : arg);
858 const char *digitp = dp->width_start;
861 width = width * 10 + (*digitp++ - '0');
862 while (digitp != dp->width_end);
867 if (dp->precision_start != dp->precision_end)
869 if (dp->precision_arg_index >= 0)
873 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
875 arg = a.arg[dp->precision_arg_index].a.a_int;
876 precision = (arg < 0 ? 0 : arg);
880 const char *digitp = dp->precision_start + 1;
884 precision = precision * 10 + (*digitp++ - '0');
885 while (digitp != dp->precision_end);
890 count = print_long_long (result + length, maxlen,
896 count = print_long_long (tmp, tmp_length,
905 case TYPE_LONGLONGINT:
907 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
911 case TYPE_ULONGLONGINT:
913 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
921 double arg = a.arg[dp->arg_index].a.a_double;
925 #ifdef HAVE_LONG_DOUBLE
926 case TYPE_LONGDOUBLE:
928 long double arg = a.arg[dp->arg_index].a.a_longdouble;
935 int arg = a.arg[dp->arg_index].a.a_char;
942 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
949 const char *arg = a.arg[dp->arg_index].a.a_string;
954 case TYPE_WIDE_STRING:
956 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
963 void *arg = a.arg[dp->arg_index].a.a_pointer;
972 /* Portability: Not all implementations of snprintf()
973 are ISO C 99 compliant. Determine the number of
974 bytes that snprintf() has produced or would have
978 /* Verify that snprintf() has NUL-terminated its
980 if (count < maxlen && result[length + count] != '\0')
982 /* Portability hack. */
983 if (retcount > count)
988 /* snprintf() doesn't understand the '%n'
992 /* Don't use the '%n' directive; instead, look
993 at the snprintf() return value. */
1001 /* Attempt to handle failure. */
1004 if (!(result == resultbuf || result == NULL))
1013 if (count >= tmp_length)
1014 /* tmp_length was incorrectly calculated - fix the
1019 /* Make room for the result. */
1020 if (count >= maxlen)
1022 /* Need at least count bytes. But allocate
1023 proportionally, to avoid looping eternally if
1024 snprintf() reports a too small count. */
1025 size_t n = length + count;
1027 if (n < 2 * allocated)
1030 ENSURE_ALLOCATION (n);
1037 /* The snprintf() result did fit. */
1039 /* Append the sprintf() result. */
1040 memcpy (result + length, tmp, count);
1052 /* Add the final NUL. */
1053 ENSURE_ALLOCATION (length + 1);
1054 result[length] = '\0';
1056 if (result != resultbuf && length + 1 < allocated)
1058 /* Shrink the allocated memory if possible. */
1061 memory = (char *) realloc (result, length + 1);