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