1 /* vsprintf with automatic memory allocation.
2 Copyright (C) 1999, 2002-2007 Free Software Foundation, Inc.
3
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
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
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
12 GNU General Public License for more details.
13
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,
16 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
17
18 /* Tell glibc's <stdio.h> to provide a prototype for snprintf().
19 This must come before <config.h> because <config.h> may include
20 <features.h>, and once <features.h> has been included, it's too late. */
21 #ifndef _GNU_SOURCE
22 # define _GNU_SOURCE 1
23 #endif
24
25 #include <config.h>
26 #ifndef IN_LIBINTL
27 # include <alloca.h>
28 #endif
29
30 /* Specification. */
31 #if WIDE_CHAR_VERSION
32 # include "vasnwprintf.h"
33 #else
34 # include "vasnprintf.h"
35 #endif
36
37 #include <locale.h> /* localeconv() */
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 */
44 #if WIDE_CHAR_VERSION
45 # include "wprintf-parse.h"
46 #else
47 # include "printf-parse.h"
48 #endif
49
50 /* Checked size_t computations. */
51 #include "xsize.h"
52
53 #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
54 # include "isnan.h"
55 # include "isnanl-nolibm.h"
56 # if HAVE_LONG_DOUBLE
57 # include "printf-frexp.h"
58 # include "printf-frexpl.h"
59 # endif
60 #endif
61
62 /* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW. */
63 #ifndef EOVERFLOW
64 # define EOVERFLOW E2BIG
65 #endif
66
67 #if HAVE_WCHAR_T
68 # if HAVE_WCSLEN
69 # define local_wcslen wcslen
70 # else
71 /* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
72 a dependency towards this library, here is a local substitute.
73 Define this substitute only once, even if this file is included
74 twice in the same compilation unit. */
75 # ifndef local_wcslen_defined
76 # define local_wcslen_defined 1
77 static size_t
local_wcslen(const wchar_t * s)78 local_wcslen (const wchar_t *s)
79 {
80 const wchar_t *ptr;
81
82 for (ptr = s; *ptr != (wchar_t) 0; ptr++)
83 ;
84 return ptr - s;
85 }
86 # endif
87 # endif
88 #endif
89
90 #if WIDE_CHAR_VERSION
91 # define VASNPRINTF vasnwprintf
92 # define CHAR_T wchar_t
93 # define DIRECTIVE wchar_t_directive
94 # define DIRECTIVES wchar_t_directives
95 # define PRINTF_PARSE wprintf_parse
96 # define USE_SNPRINTF 1
97 # if HAVE_DECL__SNWPRINTF
98 /* On Windows, the function swprintf() has a different signature than
99 on Unix; we use the _snwprintf() function instead. */
100 # define SNPRINTF _snwprintf
101 # else
102 /* Unix. */
103 # define SNPRINTF swprintf
104 # endif
105 #else
106 # define VASNPRINTF vasnprintf
107 # define CHAR_T char
108 # define DIRECTIVE char_directive
109 # define DIRECTIVES char_directives
110 # define PRINTF_PARSE printf_parse
111 # define USE_SNPRINTF (HAVE_DECL__SNPRINTF || HAVE_SNPRINTF)
112 # if HAVE_DECL__SNPRINTF
113 /* Windows. */
114 # define SNPRINTF _snprintf
115 # else
116 /* Unix. */
117 # define SNPRINTF snprintf
118 /* Here we need to call the native snprintf, not rpl_snprintf. */
119 # undef snprintf
120 # endif
121 #endif
122 /* Here we need to call the native sprintf, not rpl_sprintf. */
123 #undef sprintf
124
125 CHAR_T *
VASNPRINTF(CHAR_T * resultbuf,size_t * lengthp,const CHAR_T * format,va_list args)126 VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list args)
127 {
128 DIRECTIVES d;
129 arguments a;
130
131 if (PRINTF_PARSE (format, &d, &a) < 0)
132 {
133 errno = EINVAL;
134 return NULL;
135 }
136
137 #define CLEANUP() \
138 free (d.dir); \
139 if (a.arg) \
140 free (a.arg);
141
142 if (printf_fetchargs (args, &a) < 0)
143 {
144 CLEANUP ();
145 errno = EINVAL;
146 return NULL;
147 }
148
149 {
150 size_t buf_neededlength;
151 CHAR_T *buf;
152 CHAR_T *buf_malloced;
153 const CHAR_T *cp;
154 size_t i;
155 DIRECTIVE *dp;
156 /* Output string accumulator. */
157 CHAR_T *result;
158 size_t allocated;
159 size_t length;
160
161 /* Allocate a small buffer that will hold a directive passed to
162 sprintf or snprintf. */
163 buf_neededlength =
164 xsum4 (7, d.max_width_length, d.max_precision_length, 6);
165 #if HAVE_ALLOCA
166 if (buf_neededlength < 4000 / sizeof (CHAR_T))
167 {
168 buf = (CHAR_T *) alloca (buf_neededlength * sizeof (CHAR_T));
169 buf_malloced = NULL;
170 }
171 else
172 #endif
173 {
174 size_t buf_memsize = xtimes (buf_neededlength, sizeof (CHAR_T));
175 if (size_overflow_p (buf_memsize))
176 goto out_of_memory_1;
177 buf = (CHAR_T *) malloc (buf_memsize);
178 if (buf == NULL)
179 goto out_of_memory_1;
180 buf_malloced = buf;
181 }
182
183 if (resultbuf != NULL)
184 {
185 result = resultbuf;
186 allocated = *lengthp;
187 }
188 else
189 {
190 result = NULL;
191 allocated = 0;
192 }
193 length = 0;
194 /* Invariants:
195 result is either == resultbuf or == NULL or malloc-allocated.
196 If length > 0, then result != NULL. */
197
198 /* Ensures that allocated >= needed. Aborts through a jump to
199 out_of_memory if needed is SIZE_MAX or otherwise too big. */
200 #define ENSURE_ALLOCATION(needed) \
201 if ((needed) > allocated) \
202 { \
203 size_t memory_size; \
204 CHAR_T *memory; \
205 \
206 allocated = (allocated > 0 ? xtimes (allocated, 2) : 12); \
207 if ((needed) > allocated) \
208 allocated = (needed); \
209 memory_size = xtimes (allocated, sizeof (CHAR_T)); \
210 if (size_overflow_p (memory_size)) \
211 goto out_of_memory; \
212 if (result == resultbuf || result == NULL) \
213 memory = (CHAR_T *) malloc (memory_size); \
214 else \
215 memory = (CHAR_T *) realloc (result, memory_size); \
216 if (memory == NULL) \
217 goto out_of_memory; \
218 if (result == resultbuf && length > 0) \
219 memcpy (memory, result, length * sizeof (CHAR_T)); \
220 result = memory; \
221 }
222
223 for (cp = format, i = 0, dp = &d.dir[0]; ; cp = dp->dir_end, i++, dp++)
224 {
225 if (cp != dp->dir_start)
226 {
227 size_t n = dp->dir_start - cp;
228 size_t augmented_length = xsum (length, n);
229
230 ENSURE_ALLOCATION (augmented_length);
231 memcpy (result + length, cp, n * sizeof (CHAR_T));
232 length = augmented_length;
233 }
234 if (i == d.count)
235 break;
236
237 /* Execute a single directive. */
238 if (dp->conversion == '%')
239 {
240 size_t augmented_length;
241
242 if (!(dp->arg_index == ARG_NONE))
243 abort ();
244 augmented_length = xsum (length, 1);
245 ENSURE_ALLOCATION (augmented_length);
246 result[length] = '%';
247 length = augmented_length;
248 }
249 else
250 {
251 if (!(dp->arg_index != ARG_NONE))
252 abort ();
253
254 if (dp->conversion == 'n')
255 {
256 switch (a.arg[dp->arg_index].type)
257 {
258 case TYPE_COUNT_SCHAR_POINTER:
259 *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
260 break;
261 case TYPE_COUNT_SHORT_POINTER:
262 *a.arg[dp->arg_index].a.a_count_short_pointer = length;
263 break;
264 case TYPE_COUNT_INT_POINTER:
265 *a.arg[dp->arg_index].a.a_count_int_pointer = length;
266 break;
267 case TYPE_COUNT_LONGINT_POINTER:
268 *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
269 break;
270 #if HAVE_LONG_LONG_INT
271 case TYPE_COUNT_LONGLONGINT_POINTER:
272 *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
273 break;
274 #endif
275 default:
276 abort ();
277 }
278 }
279 #if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
280 else if (dp->conversion == 'a' || dp->conversion == 'A')
281 {
282 arg_type type = a.arg[dp->arg_index].type;
283 int flags = dp->flags;
284 int has_width;
285 size_t width;
286 int has_precision;
287 size_t precision;
288 size_t tmp_length;
289 CHAR_T tmpbuf[700];
290 CHAR_T *tmp;
291 CHAR_T *pad_ptr;
292 CHAR_T *p;
293
294 has_width = 0;
295 width = 0;
296 if (dp->width_start != dp->width_end)
297 {
298 if (dp->width_arg_index != ARG_NONE)
299 {
300 int arg;
301
302 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
303 abort ();
304 arg = a.arg[dp->width_arg_index].a.a_int;
305 if (arg < 0)
306 {
307 /* "A negative field width is taken as a '-' flag
308 followed by a positive field width." */
309 flags |= FLAG_LEFT;
310 width = (unsigned int) (-arg);
311 }
312 else
313 width = arg;
314 }
315 else
316 {
317 const CHAR_T *digitp = dp->width_start;
318
319 do
320 width = xsum (xtimes (width, 10), *digitp++ - '0');
321 while (digitp != dp->width_end);
322 }
323 has_width = 1;
324 }
325
326 has_precision = 0;
327 precision = 0;
328 if (dp->precision_start != dp->precision_end)
329 {
330 if (dp->precision_arg_index != ARG_NONE)
331 {
332 int arg;
333
334 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
335 abort ();
336 arg = a.arg[dp->precision_arg_index].a.a_int;
337 /* "A negative precision is taken as if the precision
338 were omitted." */
339 if (arg >= 0)
340 {
341 precision = arg;
342 has_precision = 1;
343 }
344 }
345 else
346 {
347 const CHAR_T *digitp = dp->precision_start + 1;
348
349 precision = 0;
350 while (digitp != dp->precision_end)
351 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
352 has_precision = 1;
353 }
354 }
355
356 /* Allocate a temporary buffer of sufficient size. */
357 # if HAVE_LONG_DOUBLE
358 if (type == TYPE_LONGDOUBLE)
359 tmp_length =
360 (unsigned int) ((LDBL_DIG + 1)
361 * 0.831 /* decimal -> hexadecimal */
362 )
363 + 1; /* turn floor into ceil */
364 else
365 # endif
366 tmp_length =
367 (unsigned int) ((DBL_DIG + 1)
368 * 0.831 /* decimal -> hexadecimal */
369 )
370 + 1; /* turn floor into ceil */
371 if (tmp_length < precision)
372 tmp_length = precision;
373 /* Account for sign, decimal point etc. */
374 tmp_length = xsum (tmp_length, 12);
375
376 if (tmp_length < width)
377 tmp_length = width;
378
379 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
380
381 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
382 tmp = tmpbuf;
383 else
384 {
385 size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
386
387 if (size_overflow_p (tmp_memsize))
388 /* Overflow, would lead to out of memory. */
389 goto out_of_memory;
390 tmp = (CHAR_T *) malloc (tmp_memsize);
391 if (tmp == NULL)
392 /* Out of memory. */
393 goto out_of_memory;
394 }
395
396 pad_ptr = NULL;
397 p = tmp;
398 # if HAVE_LONG_DOUBLE
399 if (type == TYPE_LONGDOUBLE)
400 {
401 long double arg = a.arg[dp->arg_index].a.a_longdouble;
402
403 if (isnanl (arg))
404 {
405 if (dp->conversion == 'A')
406 {
407 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
408 }
409 else
410 {
411 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
412 }
413 }
414 else
415 {
416 int sign = 0;
417
418 if (arg < 0.0L)
419 {
420 sign = -1;
421 arg = -arg;
422 }
423 else if (arg == 0.0L)
424 {
425 /* Distinguish 0.0L and -0.0L. */
426 static long double plus_zero = 0.0L;
427 long double arg_mem;
428 memset (&arg_mem, 0, sizeof (long double));
429 arg_mem = arg;
430 if (memcmp (&plus_zero, &arg_mem, sizeof (long double)) != 0)
431 {
432 sign = -1;
433 arg = -arg;
434 }
435 }
436
437 if (sign < 0)
438 *p++ = '-';
439 else if (flags & FLAG_SHOWSIGN)
440 *p++ = '+';
441 else if (flags & FLAG_SPACE)
442 *p++ = ' ';
443
444 if (arg > 0.0L && arg + arg == arg)
445 {
446 if (dp->conversion == 'A')
447 {
448 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
449 }
450 else
451 {
452 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
453 }
454 }
455 else
456 {
457 int exponent;
458 long double mantissa;
459
460 if (arg > 0.0L)
461 mantissa = printf_frexpl (arg, &exponent);
462 else
463 {
464 exponent = 0;
465 mantissa = 0.0L;
466 }
467
468 if (has_precision
469 && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
470 {
471 /* Round the mantissa. */
472 long double tail = mantissa;
473 size_t q;
474
475 for (q = precision; ; q--)
476 {
477 int digit = (int) tail;
478 tail -= digit;
479 if (q == 0)
480 {
481 if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
482 tail = 1 - tail;
483 else
484 tail = - tail;
485 break;
486 }
487 tail *= 16.0L;
488 }
489 if (tail != 0.0L)
490 for (q = precision; q > 0; q--)
491 tail *= 0.0625L;
492 mantissa += tail;
493 }
494
495 *p++ = '0';
496 *p++ = dp->conversion - 'A' + 'X';
497 pad_ptr = p;
498 {
499 int digit;
500
501 digit = (int) mantissa;
502 mantissa -= digit;
503 *p++ = '0' + digit;
504 if ((flags & FLAG_ALT)
505 || mantissa > 0.0L || precision > 0)
506 {
507 const char *point =
508 localeconv () -> decimal_point;
509 /* The decimal point is always a single byte:
510 either '.' or ','. */
511 *p++ = (point[0] != '\0' ? point[0] : '.');
512 /* This loop terminates because we assume
513 that FLT_RADIX is a power of 2. */
514 while (mantissa > 0.0L)
515 {
516 mantissa *= 16.0L;
517 digit = (int) mantissa;
518 mantissa -= digit;
519 *p++ = digit
520 + (digit < 10
521 ? '0'
522 : dp->conversion - 10);
523 if (precision > 0)
524 precision--;
525 }
526 while (precision > 0)
527 {
528 *p++ = '0';
529 precision--;
530 }
531 }
532 }
533 *p++ = dp->conversion - 'A' + 'P';
534 # if WIDE_CHAR_VERSION
535 {
536 static const wchar_t decimal_format[] =
537 { '%', '+', 'd', '\0' };
538 SNPRINTF (p, 6 + 1, decimal_format, exponent);
539 }
540 # else
541 sprintf (p, "%+d", exponent);
542 # endif
543 while (*p != '\0')
544 p++;
545 }
546 }
547 }
548 else
549 # endif
550 {
551 double arg = a.arg[dp->arg_index].a.a_double;
552
553 if (isnan (arg))
554 {
555 if (dp->conversion == 'A')
556 {
557 *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
558 }
559 else
560 {
561 *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
562 }
563 }
564 else
565 {
566 int sign = 0;
567
568 if (arg < 0.0)
569 {
570 sign = -1;
571 arg = -arg;
572 }
573 else if (arg == 0.0)
574 {
575 /* Distinguish 0.0 and -0.0. */
576 static double plus_zero = 0.0;
577 double arg_mem;
578 memset (&arg_mem, 0, sizeof (double));
579 arg_mem = arg;
580 if (memcmp (&plus_zero, &arg_mem, sizeof (double)) != 0)
581 {
582 sign = -1;
583 arg = -arg;
584 }
585 }
586
587 if (sign < 0)
588 *p++ = '-';
589 else if (flags & FLAG_SHOWSIGN)
590 *p++ = '+';
591 else if (flags & FLAG_SPACE)
592 *p++ = ' ';
593
594 if (arg > 0.0 && arg + arg == arg)
595 {
596 if (dp->conversion == 'A')
597 {
598 *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
599 }
600 else
601 {
602 *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
603 }
604 }
605 else
606 {
607 int exponent;
608 double mantissa;
609
610 if (arg > 0.0)
611 mantissa = printf_frexp (arg, &exponent);
612 else
613 {
614 exponent = 0;
615 mantissa = 0.0;
616 }
617
618 if (has_precision
619 && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
620 {
621 /* Round the mantissa. */
622 double tail = mantissa;
623 size_t q;
624
625 for (q = precision; ; q--)
626 {
627 int digit = (int) tail;
628 tail -= digit;
629 if (q == 0)
630 {
631 if (digit & 1 ? tail >= 0.5 : tail > 0.5)
632 tail = 1 - tail;
633 else
634 tail = - tail;
635 break;
636 }
637 tail *= 16.0;
638 }
639 if (tail != 0.0)
640 for (q = precision; q > 0; q--)
641 tail *= 0.0625;
642 mantissa += tail;
643 }
644
645 *p++ = '0';
646 *p++ = dp->conversion - 'A' + 'X';
647 pad_ptr = p;
648 {
649 int digit;
650
651 digit = (int) mantissa;
652 mantissa -= digit;
653 *p++ = '0' + digit;
654 if ((flags & FLAG_ALT)
655 || mantissa > 0.0 || precision > 0)
656 {
657 const char *point =
658 localeconv () -> decimal_point;
659 /* The decimal point is always a single byte:
660 either '.' or ','. */
661 *p++ = (point[0] != '\0' ? point[0] : '.');
662 /* This loop terminates because we assume
663 that FLT_RADIX is a power of 2. */
664 while (mantissa > 0.0)
665 {
666 mantissa *= 16.0;
667 digit = (int) mantissa;
668 mantissa -= digit;
669 *p++ = digit
670 + (digit < 10
671 ? '0'
672 : dp->conversion - 10);
673 if (precision > 0)
674 precision--;
675 }
676 while (precision > 0)
677 {
678 *p++ = '0';
679 precision--;
680 }
681 }
682 }
683 *p++ = dp->conversion - 'A' + 'P';
684 # if WIDE_CHAR_VERSION
685 {
686 static const wchar_t decimal_format[] =
687 { '%', '+', 'd', '\0' };
688 SNPRINTF (p, 6 + 1, decimal_format, exponent);
689 }
690 # else
691 sprintf (p, "%+d", exponent);
692 # endif
693 while (*p != '\0')
694 p++;
695 }
696 }
697 }
698 /* The generated string now extends from tmp to p, with the
699 zero padding insertion point being at pad_ptr. */
700 if (has_width && p - tmp < width)
701 {
702 size_t pad = width - (p - tmp);
703 CHAR_T *end = p + pad;
704
705 if (flags & FLAG_LEFT)
706 {
707 /* Pad with spaces on the right. */
708 for (; pad > 0; pad--)
709 *p++ = ' ';
710 }
711 else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
712 {
713 /* Pad with zeroes. */
714 CHAR_T *q = end;
715
716 while (p > pad_ptr)
717 *--q = *--p;
718 for (; pad > 0; pad--)
719 *p++ = '0';
720 }
721 else
722 {
723 /* Pad with spaces on the left. */
724 CHAR_T *q = end;
725
726 while (p > tmp)
727 *--q = *--p;
728 for (; pad > 0; pad--)
729 *p++ = ' ';
730 }
731
732 p = end;
733 }
734
735 {
736 size_t count = p - tmp;
737
738 if (count >= tmp_length)
739 /* tmp_length was incorrectly calculated - fix the
740 code above! */
741 abort ();
742
743 /* Make room for the result. */
744 if (count >= allocated - length)
745 {
746 size_t n = xsum (length, count);
747
748 ENSURE_ALLOCATION (n);
749 }
750
751 /* Append the result. */
752 memcpy (result + length, tmp, count * sizeof (CHAR_T));
753 if (tmp != tmpbuf)
754 free (tmp);
755 length += count;
756 }
757 }
758 #endif
759 else
760 {
761 arg_type type = a.arg[dp->arg_index].type;
762 CHAR_T *p;
763 unsigned int prefix_count;
764 int prefixes[2];
765 #if !USE_SNPRINTF
766 size_t tmp_length;
767 CHAR_T tmpbuf[700];
768 CHAR_T *tmp;
769
770 /* Allocate a temporary buffer of sufficient size for calling
771 sprintf. */
772 {
773 size_t width;
774 size_t precision;
775
776 width = 0;
777 if (dp->width_start != dp->width_end)
778 {
779 if (dp->width_arg_index != ARG_NONE)
780 {
781 int arg;
782
783 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
784 abort ();
785 arg = a.arg[dp->width_arg_index].a.a_int;
786 width = (arg < 0 ? (unsigned int) (-arg) : arg);
787 }
788 else
789 {
790 const CHAR_T *digitp = dp->width_start;
791
792 do
793 width = xsum (xtimes (width, 10), *digitp++ - '0');
794 while (digitp != dp->width_end);
795 }
796 }
797
798 precision = 6;
799 if (dp->precision_start != dp->precision_end)
800 {
801 if (dp->precision_arg_index != ARG_NONE)
802 {
803 int arg;
804
805 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
806 abort ();
807 arg = a.arg[dp->precision_arg_index].a.a_int;
808 precision = (arg < 0 ? 0 : arg);
809 }
810 else
811 {
812 const CHAR_T *digitp = dp->precision_start + 1;
813
814 precision = 0;
815 while (digitp != dp->precision_end)
816 precision = xsum (xtimes (precision, 10), *digitp++ - '0');
817 }
818 }
819
820 switch (dp->conversion)
821 {
822
823 case 'd': case 'i': case 'u':
824 # if HAVE_LONG_LONG_INT
825 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
826 tmp_length =
827 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
828 * 0.30103 /* binary -> decimal */
829 )
830 + 1; /* turn floor into ceil */
831 else
832 # endif
833 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
834 tmp_length =
835 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
836 * 0.30103 /* binary -> decimal */
837 )
838 + 1; /* turn floor into ceil */
839 else
840 tmp_length =
841 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
842 * 0.30103 /* binary -> decimal */
843 )
844 + 1; /* turn floor into ceil */
845 if (tmp_length < precision)
846 tmp_length = precision;
847 /* Multiply by 2, as an estimate for FLAG_GROUP. */
848 tmp_length = xsum (tmp_length, tmp_length);
849 /* Add 1, to account for a leading sign. */
850 tmp_length = xsum (tmp_length, 1);
851 break;
852
853 case 'o':
854 # if HAVE_LONG_LONG_INT
855 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
856 tmp_length =
857 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
858 * 0.333334 /* binary -> octal */
859 )
860 + 1; /* turn floor into ceil */
861 else
862 # endif
863 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
864 tmp_length =
865 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
866 * 0.333334 /* binary -> octal */
867 )
868 + 1; /* turn floor into ceil */
869 else
870 tmp_length =
871 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
872 * 0.333334 /* binary -> octal */
873 )
874 + 1; /* turn floor into ceil */
875 if (tmp_length < precision)
876 tmp_length = precision;
877 /* Add 1, to account for a leading sign. */
878 tmp_length = xsum (tmp_length, 1);
879 break;
880
881 case 'x': case 'X':
882 # if HAVE_LONG_LONG_INT
883 if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
884 tmp_length =
885 (unsigned int) (sizeof (unsigned long long) * CHAR_BIT
886 * 0.25 /* binary -> hexadecimal */
887 )
888 + 1; /* turn floor into ceil */
889 else
890 # endif
891 if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
892 tmp_length =
893 (unsigned int) (sizeof (unsigned long) * CHAR_BIT
894 * 0.25 /* binary -> hexadecimal */
895 )
896 + 1; /* turn floor into ceil */
897 else
898 tmp_length =
899 (unsigned int) (sizeof (unsigned int) * CHAR_BIT
900 * 0.25 /* binary -> hexadecimal */
901 )
902 + 1; /* turn floor into ceil */
903 if (tmp_length < precision)
904 tmp_length = precision;
905 /* Add 2, to account for a leading sign or alternate form. */
906 tmp_length = xsum (tmp_length, 2);
907 break;
908
909 case 'f': case 'F':
910 # if HAVE_LONG_DOUBLE
911 if (type == TYPE_LONGDOUBLE)
912 tmp_length =
913 (unsigned int) (LDBL_MAX_EXP
914 * 0.30103 /* binary -> decimal */
915 * 2 /* estimate for FLAG_GROUP */
916 )
917 + 1 /* turn floor into ceil */
918 + 10; /* sign, decimal point etc. */
919 else
920 # endif
921 tmp_length =
922 (unsigned int) (DBL_MAX_EXP
923 * 0.30103 /* binary -> decimal */
924 * 2 /* estimate for FLAG_GROUP */
925 )
926 + 1 /* turn floor into ceil */
927 + 10; /* sign, decimal point etc. */
928 tmp_length = xsum (tmp_length, precision);
929 break;
930
931 case 'e': case 'E': case 'g': case 'G':
932 tmp_length =
933 12; /* sign, decimal point, exponent etc. */
934 tmp_length = xsum (tmp_length, precision);
935 break;
936
937 case 'a': case 'A':
938 # if HAVE_LONG_DOUBLE
939 if (type == TYPE_LONGDOUBLE)
940 tmp_length =
941 (unsigned int) (LDBL_DIG
942 * 0.831 /* decimal -> hexadecimal */
943 )
944 + 1; /* turn floor into ceil */
945 else
946 # endif
947 tmp_length =
948 (unsigned int) (DBL_DIG
949 * 0.831 /* decimal -> hexadecimal */
950 )
951 + 1; /* turn floor into ceil */
952 if (tmp_length < precision)
953 tmp_length = precision;
954 /* Account for sign, decimal point etc. */
955 tmp_length = xsum (tmp_length, 12);
956 break;
957
958 case 'c':
959 # if HAVE_WINT_T && !WIDE_CHAR_VERSION
960 if (type == TYPE_WIDE_CHAR)
961 tmp_length = MB_CUR_MAX;
962 else
963 # endif
964 tmp_length = 1;
965 break;
966
967 case 's':
968 # if HAVE_WCHAR_T
969 if (type == TYPE_WIDE_STRING)
970 {
971 tmp_length =
972 local_wcslen (a.arg[dp->arg_index].a.a_wide_string);
973
974 # if !WIDE_CHAR_VERSION
975 tmp_length = xtimes (tmp_length, MB_CUR_MAX);
976 # endif
977 }
978 else
979 # endif
980 tmp_length = strlen (a.arg[dp->arg_index].a.a_string);
981 break;
982
983 case 'p':
984 tmp_length =
985 (unsigned int) (sizeof (void *) * CHAR_BIT
986 * 0.25 /* binary -> hexadecimal */
987 )
988 + 1 /* turn floor into ceil */
989 + 2; /* account for leading 0x */
990 break;
991
992 default:
993 abort ();
994 }
995
996 if (tmp_length < width)
997 tmp_length = width;
998
999 tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
1000 }
1001
1002 if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
1003 tmp = tmpbuf;
1004 else
1005 {
1006 size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
1007
1008 if (size_overflow_p (tmp_memsize))
1009 /* Overflow, would lead to out of memory. */
1010 goto out_of_memory;
1011 tmp = (CHAR_T *) malloc (tmp_memsize);
1012 if (tmp == NULL)
1013 /* Out of memory. */
1014 goto out_of_memory;
1015 }
1016 #endif
1017
1018 /* Construct the format string for calling snprintf or
1019 sprintf. */
1020 p = buf;
1021 *p++ = '%';
1022 if (dp->flags & FLAG_GROUP)
1023 *p++ = '\'';
1024 if (dp->flags & FLAG_LEFT)
1025 *p++ = '-';
1026 if (dp->flags & FLAG_SHOWSIGN)
1027 *p++ = '+';
1028 if (dp->flags & FLAG_SPACE)
1029 *p++ = ' ';
1030 if (dp->flags & FLAG_ALT)
1031 *p++ = '#';
1032 if (dp->flags & FLAG_ZERO)
1033 *p++ = '0';
1034 if (dp->width_start != dp->width_end)
1035 {
1036 size_t n = dp->width_end - dp->width_start;
1037 memcpy (p, dp->width_start, n * sizeof (CHAR_T));
1038 p += n;
1039 }
1040 if (dp->precision_start != dp->precision_end)
1041 {
1042 size_t n = dp->precision_end - dp->precision_start;
1043 memcpy (p, dp->precision_start, n * sizeof (CHAR_T));
1044 p += n;
1045 }
1046
1047 switch (type)
1048 {
1049 #if HAVE_LONG_LONG_INT
1050 case TYPE_LONGLONGINT:
1051 case TYPE_ULONGLONGINT:
1052 *p++ = 'l';
1053 /*FALLTHROUGH*/
1054 #endif
1055 case TYPE_LONGINT:
1056 case TYPE_ULONGINT:
1057 #if HAVE_WINT_T
1058 case TYPE_WIDE_CHAR:
1059 #endif
1060 #if HAVE_WCHAR_T
1061 case TYPE_WIDE_STRING:
1062 #endif
1063 *p++ = 'l';
1064 break;
1065 #if HAVE_LONG_DOUBLE
1066 case TYPE_LONGDOUBLE:
1067 *p++ = 'L';
1068 break;
1069 #endif
1070 default:
1071 break;
1072 }
1073 *p = dp->conversion;
1074 #if USE_SNPRINTF
1075 p[1] = '%';
1076 p[2] = 'n';
1077 p[3] = '\0';
1078 #else
1079 p[1] = '\0';
1080 #endif
1081
1082 /* Construct the arguments for calling snprintf or sprintf. */
1083 prefix_count = 0;
1084 if (dp->width_arg_index != ARG_NONE)
1085 {
1086 if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
1087 abort ();
1088 prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
1089 }
1090 if (dp->precision_arg_index != ARG_NONE)
1091 {
1092 if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
1093 abort ();
1094 prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
1095 }
1096
1097 #if USE_SNPRINTF
1098 /* Prepare checking whether snprintf returns the count
1099 via %n. */
1100 ENSURE_ALLOCATION (xsum (length, 1));
1101 result[length] = '\0';
1102 #endif
1103
1104 for (;;)
1105 {
1106 size_t maxlen;
1107 int count;
1108 int retcount;
1109
1110 maxlen = allocated - length;
1111 count = -1;
1112 retcount = 0;
1113
1114 #if USE_SNPRINTF
1115 /* SNPRINTF can fail if maxlen > INT_MAX. */
1116 if (maxlen > INT_MAX)
1117 goto overflow;
1118 # define SNPRINTF_BUF(arg) \
1119 switch (prefix_count) \
1120 { \
1121 case 0: \
1122 retcount = SNPRINTF (result + length, maxlen, buf, \
1123 arg, &count); \
1124 break; \
1125 case 1: \
1126 retcount = SNPRINTF (result + length, maxlen, buf, \
1127 prefixes[0], arg, &count); \
1128 break; \
1129 case 2: \
1130 retcount = SNPRINTF (result + length, maxlen, buf, \
1131 prefixes[0], prefixes[1], arg, \
1132 &count); \
1133 break; \
1134 default: \
1135 abort (); \
1136 }
1137 #else
1138 # define SNPRINTF_BUF(arg) \
1139 switch (prefix_count) \
1140 { \
1141 case 0: \
1142 count = sprintf (tmp, buf, arg); \
1143 break; \
1144 case 1: \
1145 count = sprintf (tmp, buf, prefixes[0], arg); \
1146 break; \
1147 case 2: \
1148 count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
1149 arg); \
1150 break; \
1151 default: \
1152 abort (); \
1153 }
1154 #endif
1155
1156 switch (type)
1157 {
1158 case TYPE_SCHAR:
1159 {
1160 int arg = a.arg[dp->arg_index].a.a_schar;
1161 SNPRINTF_BUF (arg);
1162 }
1163 break;
1164 case TYPE_UCHAR:
1165 {
1166 unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
1167 SNPRINTF_BUF (arg);
1168 }
1169 break;
1170 case TYPE_SHORT:
1171 {
1172 int arg = a.arg[dp->arg_index].a.a_short;
1173 SNPRINTF_BUF (arg);
1174 }
1175 break;
1176 case TYPE_USHORT:
1177 {
1178 unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
1179 SNPRINTF_BUF (arg);
1180 }
1181 break;
1182 case TYPE_INT:
1183 {
1184 int arg = a.arg[dp->arg_index].a.a_int;
1185 SNPRINTF_BUF (arg);
1186 }
1187 break;
1188 case TYPE_UINT:
1189 {
1190 unsigned int arg = a.arg[dp->arg_index].a.a_uint;
1191 SNPRINTF_BUF (arg);
1192 }
1193 break;
1194 case TYPE_LONGINT:
1195 {
1196 long int arg = a.arg[dp->arg_index].a.a_longint;
1197 SNPRINTF_BUF (arg);
1198 }
1199 break;
1200 case TYPE_ULONGINT:
1201 {
1202 unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
1203 SNPRINTF_BUF (arg);
1204 }
1205 break;
1206 #if HAVE_LONG_LONG_INT
1207 case TYPE_LONGLONGINT:
1208 {
1209 long long int arg = a.arg[dp->arg_index].a.a_longlongint;
1210 SNPRINTF_BUF (arg);
1211 }
1212 break;
1213 case TYPE_ULONGLONGINT:
1214 {
1215 unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
1216 SNPRINTF_BUF (arg);
1217 }
1218 break;
1219 #endif
1220 case TYPE_DOUBLE:
1221 {
1222 double arg = a.arg[dp->arg_index].a.a_double;
1223 SNPRINTF_BUF (arg);
1224 }
1225 break;
1226 #if HAVE_LONG_DOUBLE
1227 case TYPE_LONGDOUBLE:
1228 {
1229 long double arg = a.arg[dp->arg_index].a.a_longdouble;
1230 SNPRINTF_BUF (arg);
1231 }
1232 break;
1233 #endif
1234 case TYPE_CHAR:
1235 {
1236 int arg = a.arg[dp->arg_index].a.a_char;
1237 SNPRINTF_BUF (arg);
1238 }
1239 break;
1240 #if HAVE_WINT_T
1241 case TYPE_WIDE_CHAR:
1242 {
1243 wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
1244 SNPRINTF_BUF (arg);
1245 }
1246 break;
1247 #endif
1248 case TYPE_STRING:
1249 {
1250 const char *arg = a.arg[dp->arg_index].a.a_string;
1251 SNPRINTF_BUF (arg);
1252 }
1253 break;
1254 #if HAVE_WCHAR_T
1255 case TYPE_WIDE_STRING:
1256 {
1257 const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string;
1258 SNPRINTF_BUF (arg);
1259 }
1260 break;
1261 #endif
1262 case TYPE_POINTER:
1263 {
1264 void *arg = a.arg[dp->arg_index].a.a_pointer;
1265 SNPRINTF_BUF (arg);
1266 }
1267 break;
1268 default:
1269 abort ();
1270 }
1271
1272 #if USE_SNPRINTF
1273 /* Portability: Not all implementations of snprintf()
1274 are ISO C 99 compliant. Determine the number of
1275 bytes that snprintf() has produced or would have
1276 produced. */
1277 if (count >= 0)
1278 {
1279 /* Verify that snprintf() has NUL-terminated its
1280 result. */
1281 if (count < maxlen && result[length + count] != '\0')
1282 abort ();
1283 /* Portability hack. */
1284 if (retcount > count)
1285 count = retcount;
1286 }
1287 else
1288 {
1289 /* snprintf() doesn't understand the '%n'
1290 directive. */
1291 if (p[1] != '\0')
1292 {
1293 /* Don't use the '%n' directive; instead, look
1294 at the snprintf() return value. */
1295 p[1] = '\0';
1296 continue;
1297 }
1298 else
1299 {
1300 /* Look at the snprintf() return value. */
1301 if (retcount < 0)
1302 {
1303 /* HP-UX 10.20 snprintf() is doubly deficient:
1304 It doesn't understand the '%n' directive,
1305 *and* it returns -1 (rather than the length
1306 that would have been required) when the
1307 buffer is too small. */
1308 size_t bigger_need =
1309 xsum (xtimes (allocated, 2), 12);
1310 ENSURE_ALLOCATION (bigger_need);
1311 continue;
1312 }
1313 else
1314 count = retcount;
1315 }
1316 }
1317 #endif
1318
1319 /* Attempt to handle failure. */
1320 if (count < 0)
1321 {
1322 if (!(result == resultbuf || result == NULL))
1323 free (result);
1324 if (buf_malloced != NULL)
1325 free (buf_malloced);
1326 CLEANUP ();
1327 errno = EINVAL;
1328 return NULL;
1329 }
1330
1331 #if !USE_SNPRINTF
1332 if (count >= tmp_length)
1333 /* tmp_length was incorrectly calculated - fix the
1334 code above! */
1335 abort ();
1336 #endif
1337
1338 /* Make room for the result. */
1339 if (count >= maxlen)
1340 {
1341 /* Need at least count bytes. But allocate
1342 proportionally, to avoid looping eternally if
1343 snprintf() reports a too small count. */
1344 size_t n =
1345 xmax (xsum (length, count), xtimes (allocated, 2));
1346
1347 ENSURE_ALLOCATION (n);
1348 #if USE_SNPRINTF
1349 continue;
1350 #endif
1351 }
1352
1353 #if USE_SNPRINTF
1354 /* The snprintf() result did fit. */
1355 #else
1356 /* Append the sprintf() result. */
1357 memcpy (result + length, tmp, count * sizeof (CHAR_T));
1358 if (tmp != tmpbuf)
1359 free (tmp);
1360 #endif
1361
1362 length += count;
1363 break;
1364 }
1365 }
1366 }
1367 }
1368
1369 /* Add the final NUL. */
1370 ENSURE_ALLOCATION (xsum (length, 1));
1371 result[length] = '\0';
1372
1373 if (result != resultbuf && length + 1 < allocated)
1374 {
1375 /* Shrink the allocated memory if possible. */
1376 CHAR_T *memory;
1377
1378 memory = (CHAR_T *) realloc (result, (length + 1) * sizeof (CHAR_T));
1379 if (memory != NULL)
1380 result = memory;
1381 }
1382
1383 if (buf_malloced != NULL)
1384 free (buf_malloced);
1385 CLEANUP ();
1386 *lengthp = length;
1387 /* Note that we can produce a big string of a length > INT_MAX. POSIX
1388 says that snprintf() fails with errno = EOVERFLOW in this case, but
1389 that's only because snprintf() returns an 'int'. This function does
1390 not have this limitation. */
1391 return result;
1392
1393 overflow:
1394 if (!(result == resultbuf || result == NULL))
1395 free (result);
1396 if (buf_malloced != NULL)
1397 free (buf_malloced);
1398 CLEANUP ();
1399 errno = EOVERFLOW;
1400 return NULL;
1401
1402 out_of_memory:
1403 if (!(result == resultbuf || result == NULL))
1404 free (result);
1405 if (buf_malloced != NULL)
1406 free (buf_malloced);
1407 out_of_memory_1:
1408 CLEANUP ();
1409 errno = ENOMEM;
1410 return NULL;
1411 }
1412 }
1413
1414 #undef SNPRINTF
1415 #undef USE_SNPRINTF
1416 #undef PRINTF_PARSE
1417 #undef DIRECTIVES
1418 #undef DIRECTIVE
1419 #undef CHAR_T
1420 #undef VASNPRINTF
1421