]>
git.ipfire.org Git - thirdparty/bash.git/blob - lib/sh/snprintf.c
1 /* snprintf - formatted output to strings, with bounds checking and allocation */
4 build a test version with
5 gcc -g -DDRIVER -I../.. -I../../include -o test-snprintf snprintf.c fmtu*long.o
9 Unix snprintf implementation.
10 derived from inetutils/libinetutils/snprintf.c Version 1.1
12 Copyright (C) 2001,2006 Free Software Foundation, Inc.
14 This file is part of GNU Bash, the Bourne Again SHell.
16 Bash is free software: you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
21 Bash is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with Bash. If not, see <http://www.gnu.org/licenses/>.
32 * added changes from Miles Bader
33 * corrected a bug with %f
34 * added support for %#g
35 * added more comments :-)
37 * supporting must ANSI syntaxic_sugars
41 THANKS(for the patches and ideas):
50 * Currently doesn't handle (and bash/readline doesn't use):
51 * * *M$ width, precision specifications
52 * * %N$ numbered argument conversions
53 * * inf, nan floating values imperfect (if isinf(), isnan() not in libc)
54 * * support for `F' is imperfect with ldfallback(), since underlying
55 * printf may not handle it -- should ideally have another autoconf test
58 #define FLOATING_POINT
69 #if defined(DRIVER) && !defined(HAVE_CONFIG_H)
70 #define HAVE_LONG_LONG
71 #define HAVE_LONG_DOUBLE
73 #define HAVE_PRINTF_A_FORMAT
75 #define HAVE_ISINF_IN_LIBC
76 #define HAVE_ISNAN_IN_LIBC
78 #define HAVE_STRINGIZE
85 #if !defined (HAVE_SNPRINTF) || !defined (HAVE_ASPRINTF)
87 #include <bashtypes.h>
89 #if defined(PREFER_STDARG)
102 #include <chartypes.h>
108 #ifdef FLOATING_POINT
109 # include <float.h> /* for manifest constants */
110 # include <stdio.h> /* for sprintf */
120 #include <shmbutil.h>
125 # define FL_PREFIX 0x01 /* add 0x, 0X, or 0 prefix as appropriate */
126 # define FL_ADDBASE 0x02 /* add base# prefix to converted value */
127 # define FL_HEXUPPER 0x04 /* use uppercase when converting to hex */
128 # define FL_UNSIGNED 0x08 /* don't add any sign */
129 extern char *fmtulong
__P((unsigned long int, int, char *, size_t, int));
130 extern char *fmtullong
__P((unsigned long long int, int, char *, size_t, int));
134 # define FREE(x) if (x) free (x)
137 /* Bound on length of the string representing an integer value of type T.
138 Subtract one for the sign bit if T is signed;
139 302 / 1000 is log10 (2) rounded up;
140 add one for integer division truncation;
141 add one more for a minus sign if t is signed. */
142 #define INT_STRLEN_BOUND(t) \
143 ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
144 + 1 + TYPE_SIGNED (t))
146 /* conversion flags */
147 #define PF_ALTFORM 0x00001 /* # */
148 #define PF_HEXPREFIX 0x00002 /* 0[Xx] */
149 #define PF_LADJUST 0x00004 /* - */
150 #define PF_ZEROPAD 0x00008 /* 0 */
151 #define PF_PLUS 0x00010 /* + */
152 #define PF_SPACE 0x00020 /* ' ' */
153 #define PF_THOUSANDS 0x00040 /* ' */
155 #define PF_DOT 0x00080 /* `.precision' */
156 #define PF_STAR_P 0x00100 /* `*' after precision */
157 #define PF_STAR_W 0x00200 /* `*' before or without precision */
159 /* length modifiers */
160 #define PF_SIGNEDCHAR 0x00400 /* hh */
161 #define PF_SHORTINT 0x00800 /* h */
162 #define PF_LONGINT 0x01000 /* l */
163 #define PF_LONGLONG 0x02000 /* ll */
164 #define PF_LONGDBL 0x04000 /* L */
165 #define PF_INTMAX_T 0x08000 /* j */
166 #define PF_SIZE_T 0x10000 /* z */
167 #define PF_PTRDIFF_T 0x20000 /* t */
169 #define PF_ALLOCBUF 0x40000 /* for asprintf, vasprintf */
171 #define PFM_SN 0x01 /* snprintf, vsnprintf */
172 #define PFM_AS 0x02 /* asprintf, vasprintf */
174 #define ASBUFSIZE 128
176 #define x_digs "0123456789abcdef"
177 #define X_digs "0123456789ABCDEF"
179 static char intbuf
[INT_STRLEN_BOUND(unsigned long) + 1];
183 static char *grouping
;
186 * For the FLOATING POINT FORMAT :
187 * the challenge was finding a way to
188 * manipulate the Real numbers without having
189 * to resort to mathematical function(it
190 * would require to link with -lm) and not
191 * going down to the bit pattern(not portable)
193 * so a number, a real is:
195 real = integral + fraction
197 integral = ... + a(2)*10^2 + a(1)*10^1 + a(0)*10^0
198 fraction = b(1)*10^-1 + b(2)*10^-2 + ...
204 from then it was simple math
208 * size of the buffer for the integral part
209 * and the fraction part
211 #define MAX_INT 99 + 1 /* 1 for the null */
212 #define MAX_FRACT 307 + 1
215 * These functions use static buffers to store the results,
216 * and so are not reentrant
218 #define itoa(n) fmtulong(n, 10, intbuf, sizeof(intbuf), 0);
219 #define dtoa(n, p, f) numtoa(n, 10, p, f)
221 #define SWAP_INT(a,b) {int t; t = (a); (a) = (b); (b) = t;}
223 #define GETARG(type) (va_arg(args, type))
225 /* Macros that do proper sign extension and handle length modifiers. Used
226 for the integer conversion specifiers. */
227 #define GETSIGNED(p) \
228 (((p)->flags & PF_LONGINT) \
230 : (((p)->flags & PF_SHORTINT) ? (long)(short)GETARG (int) \
231 : (long)GETARG (int)))
233 #define GETUNSIGNED(p) \
234 (((p)->flags & PF_LONGINT) \
235 ? GETARG (unsigned long) \
236 : (((p)->flags & PF_SHORTINT) ? (unsigned long)(unsigned short)GETARG (int) \
237 : (unsigned long)GETARG (unsigned int)))
240 #ifdef HAVE_LONG_DOUBLE
241 #define GETLDOUBLE(p) GETARG (long double)
243 #define GETDOUBLE(p) GETARG (double)
245 #define SET_SIZE_FLAGS(p, type) \
246 if (sizeof (type) > sizeof (int)) \
247 (p)->flags |= PF_LONGINT; \
248 if (sizeof (type) > sizeof (long)) \
249 (p)->flags |= PF_LONGLONG;
251 /* this struct holds everything we need */
255 char *base
; /* needed for [v]asprintf */
263 int width
, precision
;
267 /* the floating point stuff */
268 #ifdef FLOATING_POINT
269 static double pow_10
__P((int));
270 static int log_10
__P((double));
271 static double integral
__P((double, double *));
272 static char *numtoa
__P((double, int, int, char **));
275 static void init_data
__P((struct DATA
*, char *, size_t, const char *, int));
276 static void init_conv_flag
__P((struct DATA
*));
279 #ifdef FLOATING_POINT
280 static void floating
__P((struct DATA
*, double));
281 static void exponent
__P((struct DATA
*, double));
283 static void number
__P((struct DATA
*, unsigned long, int));
284 #ifdef HAVE_LONG_LONG
285 static void lnumber
__P((struct DATA
*, unsigned long long, int));
287 static void pointer
__P((struct DATA
*, unsigned long));
288 static void strings
__P((struct DATA
*, char *));
290 #ifdef FLOATING_POINT
291 # define FALLBACK_FMTSIZE 32
292 # define FALLBACK_BASE 4096
293 # define LFALLBACK_BASE 5120
294 # ifdef HAVE_LONG_DOUBLE
295 static void ldfallback
__P((struct DATA
*, const char *, const char *, long double));
297 static void dfallback
__P((struct DATA
*, const char *, const char *, double));
300 static char *groupnum
__P((char *));
303 static void memory_error_and_abort ();
304 static void *xmalloc
__P((size_t));
305 static void *xrealloc
__P((void *, size_t));
306 static void xfree
__P((void *));
308 # include <xmalloc.h>
311 /* those are defines specific to snprintf to hopefully
312 * make the code clearer :-)
320 /* round off to the precision */
321 #define ROUND(d, p) \
323 d - pow_10(-(p)->precision) * 0.5 : \
324 d + pow_10(-(p)->precision) * 0.5
326 /* set default precision */
327 #define DEF_PREC(p) \
328 if ((p)->precision == NOT_FOUND) \
331 /* put a char. increment the number of chars written even if we've exceeded
332 the vsnprintf/snprintf buffer size (for the return value) */
333 #define PUT_CHAR(c, p) \
336 if (((p)->flags & PF_ALLOCBUF) && ((p)->counter >= (p)->length - 1)) \
338 (p)->length += ASBUFSIZE; \
339 (p)->base = (char *)xrealloc((p)->base, (p)->length); \
340 (p)->holder = (p)->base + (p)->counter; /* in case reallocated */ \
342 if ((p)->counter < (p)->length) \
343 *(p)->holder++ = (c); \
348 /* Output a string. P->WIDTH has already been adjusted for padding. */
349 #define PUT_STRING(string, len, p) \
353 while ((len)-- > 0) \
355 PUT_CHAR (*(string), (p)); \
362 #define PUT_PLUS(d, p, zero) \
363 if ((d) > zero && (p)->justify == RIGHT) \
366 #define PUT_SPACE(d, p, zero) \
367 if (((p)->flags & PF_SPACE) && (d) > zero) \
371 #define PAD_RIGHT(p) \
372 if ((p)->width > 0 && (p)->justify != LEFT) \
373 for (; (p)->width > 0; (p)->width--) \
374 PUT_CHAR((p)->pad, p)
377 #define PAD_LEFT(p) \
378 if ((p)->width > 0 && (p)->justify == LEFT) \
379 for (; (p)->width > 0; (p)->width--) \
380 PUT_CHAR((p)->pad, p)
382 /* pad with zeros from decimal precision */
383 #define PAD_ZERO(p) \
384 if ((p)->precision > 0) \
385 for (; (p)->precision > 0; (p)->precision--) \
388 /* if width and prec. in the args */
389 #define STAR_ARGS(p) \
391 if ((p)->flags & PF_STAR_W) \
393 (p)->width = GETARG (int); \
394 if ((p)->width < 0) \
396 (p)->flags |= PF_LADJUST; \
397 (p)->justify = LEFT; \
398 (p)->width = -(p)->width; \
401 if ((p)->flags & PF_STAR_P) \
403 (p)->precision = GETARG (int); \
404 if ((p)->precision < 0) \
406 (p)->flags &= ~PF_STAR_P; \
407 (p)->precision = NOT_FOUND; \
412 #if defined (HAVE_LOCALE_H) && defined (HAVE_LOCALECONV)
413 # define GETLOCALEDATA(d, t, g) \
418 (d) = '.'; (t) = -1; (g) = 0; /* defaults */ \
422 if (lv->decimal_point && lv->decimal_point[0]) \
423 (d) = lv->decimal_point[0]; \
424 if (lv->thousands_sep && lv->thousands_sep[0]) \
425 (t) = lv->thousands_sep[0]; \
426 (g) = lv->grouping ? lv->grouping : ""; \
427 if (*(g) == '\0' || *(g) == CHAR_MAX || (t) == -1) (g) = 0; \
433 # define GETLOCALEDATA(d, t, g) \
434 ( (d) = '.', (t) = ',', g = "\003" )
437 #ifdef FLOATING_POINT
439 * Find the nth power of 10
447 /* handle common cases with fast switch statement. */
450 case -3: return .001;
456 case 3: return 1000.;
462 for (n
+= 4; n
< 0; n
++)
468 for (n
-= 4; n
> 0; n
--)
476 * Find the integral part of the log in base 10
477 * Note: this not a real log10()
478 I just need and approximation(integerpart) of x in:
483 * NOTE: do not call this with r == 0 -- an infinite loop results.
516 * This function return the fraction part of a double
517 * and set in ip the integral part.
518 * In many ways it resemble the modf() found on most Un*x
527 double real_integral
= 0.;
529 /* take care of the obvious */
530 /* equal to zero ? */
537 /* negative number ? */
548 /* the real work :-) */
549 for (j
= log_10(real
); j
>= 0; j
--)
552 s
= (real
- real_integral
)/p
;
556 real_integral
+= i
*p
;
559 return (real
- real_integral
);
562 #define PRECISION 1.e-6
564 * return an ascii representation of the integral part of the number
565 * and set fract to be an ascii representation of the fraction part
566 * the container for the fraction and the integral part or staticly
567 * declare with fix size
570 numtoa(number
, base
, precision
, fract
)
576 double ip
, fp
; /* integer and fraction part */
578 int digits
= MAX_INT
- 1;
579 static char integral_part
[MAX_INT
];
580 static char fraction_part
[MAX_FRACT
];
584 /* taking care of the obvious case: 0.0 */
587 integral_part
[0] = '0';
588 integral_part
[1] = '\0';
589 /* The fractional part has to take the precision into account */
590 for (ch
= 0; ch
< precision
-1; ch
++)
591 fraction_part
[ch
] = '0';
592 fraction_part
[ch
] = '0';
593 fraction_part
[ch
+1] = '\0';
595 *fract
= fraction_part
;
596 return integral_part
;
599 /* for negative numbers */
600 if ((sign
= number
) < 0.)
603 digits
--; /* sign consume one digit */
606 fraction
= integral(number
, &ip
);
609 /* do the integral part */
612 integral_part
[0] = '0';
617 for ( i
= 0; i
< digits
&& number
!= 0.; ++i
)
620 fp
= integral(number
, &ip
);
621 ch
= (int)((fp
+ PRECISION
)*base
); /* force to round */
622 integral_part
[i
] = (ch
<= 9) ? ch
+ '0' : ch
+ 'a' - 10;
623 if (! ISXDIGIT((unsigned char)integral_part
[i
]))
624 break; /* bail out overflow !! */
629 /* Oh No !! out of bound, ho well fill it up ! */
631 for (i
= 0; i
< digits
; ++i
)
632 integral_part
[i
] = '9';
636 integral_part
[i
++] = '-';
638 integral_part
[i
] = '\0';
640 /* reverse every thing */
641 for ( i
--, j
= 0; j
< i
; j
++, i
--)
642 SWAP_INT(integral_part
[i
], integral_part
[j
]);
644 /* the fractional part */
645 for (i
=0, fp
=fraction
; precision
> 0 && i
< MAX_FRACT
; i
++, precision
--)
647 fraction_part
[i
] = (int)((fp
+ PRECISION
)*10. + '0');
648 if (! DIGIT(fraction_part
[i
])) /* underflow ? */
650 fp
= (fp
*10.0) - (double)(long)((fp
+ PRECISION
)*10.);
652 fraction_part
[i
] = '\0';
654 if (fract
!= (char **)0)
655 *fract
= fraction_part
;
657 return integral_part
;
661 /* for %d and friends, it puts in holder
662 * the representation with the right padding
674 /* An explicit precision turns off the zero-padding flag. */
675 if ((p
->flags
& PF_ZEROPAD
) && p
->precision
>= 0 && (p
->flags
& PF_DOT
))
676 p
->flags
&= ~PF_ZEROPAD
;
678 sd
= d
; /* signed for ' ' padding in base 10 */
680 flags
= (*p
->pf
== 'x' || *p
->pf
== 'X' || *p
->pf
== 'o' || *p
->pf
== 'u' || *p
->pf
== 'U') ? FL_UNSIGNED
: 0;
682 flags
|= FL_HEXUPPER
;
684 tmp
= fmtulong (d
, base
, intbuf
, sizeof(intbuf
), flags
);
686 if ((p
->flags
& PF_THOUSANDS
))
688 GETLOCALEDATA(decpoint
, thoussep
, grouping
);
689 if (grouping
&& (t
= groupnum (tmp
)))
693 p
->width
-= strlen(tmp
);
696 if ((p
->flags
& PF_DOT
) && p
->precision
> 0)
698 p
->precision
-= strlen(tmp
);
709 if (p
->flags
& PF_ALTFORM
)
713 if (p
->flags
& PF_ALTFORM
)
731 #ifdef HAVE_LONG_LONG
733 * identical to number() but works for `long long'
738 unsigned long long d
;
745 /* An explicit precision turns off the zero-padding flag. */
746 if ((p
->flags
& PF_ZEROPAD
) && p
->precision
>= 0 && (p
->flags
& PF_DOT
))
747 p
->flags
&= ~PF_ZEROPAD
;
749 sd
= d
; /* signed for ' ' padding in base 10 */
750 flags
= (*p
->pf
== 'x' || *p
->pf
== 'X' || *p
->pf
== 'o' || *p
->pf
== 'u' || *p
->pf
== 'U') ? FL_UNSIGNED
: 0;
752 flags
|= FL_HEXUPPER
;
754 tmp
= fmtullong (d
, base
, intbuf
, sizeof(intbuf
), flags
);
756 if ((p
->flags
& PF_THOUSANDS
))
758 GETLOCALEDATA(decpoint
, thoussep
, grouping
);
759 if (grouping
&& (t
= groupnum (tmp
)))
763 p
->width
-= strlen(tmp
);
766 if ((p
->flags
& PF_DOT
) && p
->precision
> 0)
768 p
->precision
-= strlen(tmp
);
779 if (p
->flags
& PF_ALTFORM
)
783 if (p
->flags
& PF_ALTFORM
)
809 tmp
= fmtulong(d
, 16, intbuf
, sizeof(intbuf
), 0);
810 p
->width
-= strlen(tmp
);
813 /* prefix '0x' for pointers */
835 if (p
->precision
!= NOT_FOUND
) /* the smallest number */
836 len
= (len
< p
->precision
? len
: p
->precision
);
839 PUT_STRING (tmp
, len
, p
);
843 /* %ls wide-character strings */
854 memset (&mbs
, '\0', sizeof (mbstate_t));
855 ws
= (const wchar_t *)tmp
;
858 if (p
->precision
!= NOT_FOUND
)
860 os
= (char *)xmalloc (p
->precision
+ 1);
861 len
= wcsrtombs (os
, &ws
, p
->precision
, &mbs
);
865 len
= wcsrtombs (NULL
, &ws
, 0, &mbs
);
866 if (len
!= (size_t)-1)
868 memset (&mbs
, '\0', sizeof (mbstate_t));
869 os
= (char *)xmalloc (len
+ 1);
870 (void)wcsrtombs (os
, &ws
, len
+ 1, &mbs
);
873 if (len
== (size_t)-1)
875 /* invalid multibyte sequence; bail now. */
881 PUT_STRING (os
, len
, p
);
894 lbuf
= (char *)malloc (MB_CUR_MAX
+1);
897 memset (&mbs
, '\0', sizeof (mbstate_t));
898 len
= wcrtomb (lbuf
, wc
, &mbs
);
899 if (len
== (size_t)-1)
900 /* conversion failed; bail now. */
904 PUT_STRING (l
, len
, p
);
907 #endif /* HANDLE_MULTIBYTE */
909 #ifdef FLOATING_POINT
911 #ifndef HAVE_ISINF_IN_LIBC
912 /* Half-assed versions, since we don't want to link with libm. */
920 else if (d
> DBL_MAX
)
928 #ifndef HAVE_ISNAN_IN_LIBC
937 /* Check for [+-]infinity and NaN. If MODE == 1, we check for Infinity, else
938 (mode == 2) we check for NaN. This does the necessary printing. Returns
939 1 if Inf or Nan, 0 if not. */
941 chkinfnan(p
, d
, mode
)
944 int mode
; /* == 1 for inf, == 2 for nan */
950 i
= (mode
== 1) ? isinf(d
) : isnan(d
);
953 big
= (mode
== 1) ? "INF" : "NAN";
954 small
= (mode
== 1) ? "inf" : "nan";
956 tmp
= (*p
->pf
== 'F' || *p
->pf
== 'G' || *p
->pf
== 'E') ? big
: small
;
970 /* %f %F %g %G floating point representation */
976 char *tmp
, *tmp2
, *t
;
979 if (d
!= 0 && (chkinfnan(p
, d
, 1) || chkinfnan(p
, d
, 2)))
980 return; /* already printed nan or inf */
982 GETLOCALEDATA(decpoint
, thoussep
, grouping
);
985 tmp
= dtoa(d
, p
->precision
, &tmp2
);
987 if ((p
->flags
& PF_THOUSANDS
) && grouping
&& (t
= groupnum (tmp
)))
990 if ((*p
->pf
== 'g' || *p
->pf
== 'G') && (p
->flags
& PF_ALTFORM
) == 0)
992 /* smash the trailing zeros unless altform */
993 for (i
= strlen(tmp2
) - 1; i
>= 0 && tmp2
[i
] == '0'; i
--)
999 /* calculate the padding. 1 for the dot */
1000 p
->width
= p
->width
-
1001 ((d
> 0. && p
->justify
== RIGHT
) ? 1:0) -
1002 ((p
->flags
& PF_SPACE
) ? 1:0) -
1003 strlen(tmp
) - p
->precision
-
1004 ((p
->precision
!= 0 || (p
->flags
& PF_ALTFORM
)) ? 1 : 0); /* radix char */
1007 PUT_SPACE(d
, p
, 0.);
1011 PUT_CHAR(*tmp
, p
); /* the integral */
1016 if (p
->precision
!= 0 || (p
->flags
& PF_ALTFORM
))
1017 PUT_CHAR(decpoint
, p
); /* put the '.' */
1019 for (; *tmp2
; tmp2
++)
1020 PUT_CHAR(*tmp2
, p
); /* the fraction */
1025 /* %e %E %g %G exponent representation */
1034 if (d
!= 0 && (chkinfnan(p
, d
, 1) || chkinfnan(p
, d
, 2)))
1035 return; /* already printed nan or inf */
1037 GETLOCALEDATA(decpoint
, thoussep
, grouping
);
1044 d
= d
/ pow_10(j
); /* get the Mantissa */
1047 tmp
= dtoa(d
, p
->precision
, &tmp2
);
1049 /* 1 for unit, 1 for the '.', 1 for 'e|E',
1050 * 1 for '+|-', 2 for 'exp' */
1051 /* calculate how much padding need */
1052 p
->width
= p
->width
-
1053 ((d
> 0. && p
->justify
== RIGHT
) ? 1:0) -
1054 ((p
->flags
& PF_SPACE
) ? 1:0) - p
->precision
- 6;
1058 PUT_SPACE(d
, p
, 0.);
1066 if (p
->precision
!= 0 || (p
->flags
& PF_ALTFORM
))
1067 PUT_CHAR(decpoint
, p
); /* the '.' */
1069 if ((*p
->pf
== 'g' || *p
->pf
== 'G') && (p
->flags
& PF_ALTFORM
) == 0)
1070 /* smash the trailing zeros unless altform */
1071 for (i
= strlen(tmp2
) - 1; i
>= 0 && tmp2
[i
] == '0'; i
--)
1074 for (; *tmp2
; tmp2
++)
1075 PUT_CHAR(*tmp2
, p
); /* the fraction */
1077 /* the exponent put the 'e|E' */
1078 if (*p
->pf
== 'g' || *p
->pf
== 'e')
1083 /* the sign of the exp */
1093 /* pad out to at least two spaces. pad with `0' if the exponent is a
1109 /* Return a new string with the digits in S grouped according to the locale's
1110 grouping info and thousands separator. If no grouping should be performed,
1111 this returns NULL; the caller needs to check for it. */
1116 char *se
, *ret
, *re
, *g
;
1119 if (grouping
== 0 || *grouping
<= 0 || *grouping
== CHAR_MAX
)
1120 return ((char *)NULL
);
1122 /* find min grouping to size returned string */
1123 for (len
= *grouping
, g
= grouping
; *g
; g
++)
1124 if (*g
> 0 && *g
< len
)
1128 len
= slen
/ len
+ 1;
1129 ret
= (char *)xmalloc (slen
+ len
+ 1);
1130 re
= ret
+ slen
+ len
;
1141 /* handle `-' inserted by numtoa() and the fmtu* family here. */
1142 if (se
> s
&& se
[-1] == '-')
1145 /* begin new group. */
1146 if (--len
== 0 && se
> s
)
1149 len
= *++g
; /* was g++, but that uses first char twice (glibc bug, too) */
1151 len
= *--g
; /* use previous grouping */
1152 else if (*g
== CHAR_MAX
)
1164 memmove (ret
, re
, strlen (re
) + 1);
1172 /* initialize the conversion specifiers */
1177 p
->flags
&= PF_ALLOCBUF
; /* preserve PF_ALLOCBUF flag */
1178 p
->precision
= p
->width
= NOT_FOUND
;
1179 p
->justify
= NOT_FOUND
;
1184 init_data (p
, string
, length
, format
, mode
)
1191 p
->length
= length
- 1; /* leave room for '\0' */
1192 p
->holder
= p
->base
= string
;
1195 p
->flags
= (mode
== PFM_AS
) ? PF_ALLOCBUF
: 0;
1199 #if defined (__STDC__)
1200 vsnprintf_internal(struct DATA
*data
, char *string
, size_t length
, const char *format
, va_list args
)
1202 vsnprintf_internal(data
, string
, length
, format
, args
)
1210 double d
; /* temporary holder */
1211 #ifdef HAVE_LONG_DOUBLE
1212 long double ld
; /* for later */
1215 #ifdef HAVE_LONG_LONG
1216 unsigned long long ull
;
1220 #if HANDLE_MULTIBYTE
1224 const char *convstart
;
1227 /* Sanity check, the string length must be >= 0. C99 actually says that
1228 LENGTH can be zero here, in the case of snprintf/vsnprintf (it's never
1229 0 in the case of asprintf/vasprintf), and the return value is the number
1230 of characters that would have been written. */
1237 /* Reset these for each call because the locale might have changed. */
1238 decpoint
= thoussep
= 0;
1242 for (; c
= *(data
->pf
); data
->pf
++)
1250 convstart
= data
->pf
;
1251 init_conv_flag (data
); /* initialise format flags */
1254 for (state
= 1; state
&& *data
->pf
; )
1257 /* fmtend = data->pf */
1258 #if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
1259 if (data
->flags
& PF_LONGDBL
)
1266 # ifdef HAVE_PRINTF_A_FORMAT
1270 ld
= GETLDOUBLE (data
);
1271 ldfallback (data
, convstart
, data
->pf
, ld
);
1275 #endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
1279 /* Parse format flags */
1280 case '\0': /* a NULL here ? ? bail out */
1281 *data
->holder
= '\0';
1282 return data
->counter
;
1285 data
->flags
|= PF_ALTFORM
;
1288 data
->flags
|= PF_ZEROPAD
;
1292 if (data
->flags
& PF_DOT
)
1293 data
->flags
|= PF_STAR_P
;
1295 data
->flags
|= PF_STAR_W
;
1298 if ((data
->flags
& PF_DOT
) == 0)
1300 data
->flags
|= PF_LADJUST
;
1301 data
->justify
= LEFT
;
1307 if ((data
->flags
& PF_PLUS
) == 0)
1308 data
->flags
|= PF_SPACE
;
1311 if ((data
->flags
& PF_DOT
) == 0)
1313 data
->flags
|= PF_PLUS
;
1314 data
->justify
= RIGHT
;
1318 data
->flags
|= PF_THOUSANDS
;
1321 case '1': case '2': case '3':
1322 case '4': case '5': case '6':
1323 case '7': case '8': case '9':
1327 n
= n
* 10 + TODIGIT(c
);
1331 data
->pf
--; /* went too far */
1334 if (data
->flags
& PF_DOT
)
1335 data
->precision
= negprec
? NOT_FOUND
: n
;
1340 /* optional precision */
1342 data
->flags
|= PF_DOT
;
1343 data
->precision
= 0;
1346 /* length modifiers */
1348 data
->flags
|= (data
->flags
& PF_SHORTINT
) ? PF_SIGNEDCHAR
: PF_SHORTINT
;
1351 data
->flags
|= (data
->flags
& PF_LONGINT
) ? PF_LONGLONG
: PF_LONGINT
;
1354 data
->flags
|= PF_LONGDBL
;
1357 data
->flags
|= PF_LONGLONG
;
1360 data
->flags
|= PF_INTMAX_T
;
1361 SET_SIZE_FLAGS(data
, intmax_t);
1364 data
->flags
|= PF_SIZE_T
;
1365 SET_SIZE_FLAGS(data
, size_t);
1368 data
->flags
|= PF_PTRDIFF_T
;
1369 SET_SIZE_FLAGS(data
, ptrdiff_t);
1372 /* Conversion specifiers */
1373 #ifdef FLOATING_POINT
1374 case 'f': /* float, double */
1377 d
= GETDOUBLE(data
);
1386 d
= GETDOUBLE(data
);
1387 i
= (d
!= 0.) ? log_10(d
) : -1;
1389 * for '%g|%G' ANSI: use f if exponent
1390 * is in the range or [-4,p] exclusively
1393 if (-4 < i
&& i
< data
->precision
)
1395 /* reset precision */
1396 data
->precision
-= i
+ 1;
1401 /* reduce precision by 1 because of leading digit before
1402 decimal point in e format. */
1409 case 'E': /* Exponent double */
1411 d
= GETDOUBLE(data
);
1415 # ifdef HAVE_PRINTF_A_FORMAT
1419 d
= GETDOUBLE(data
);
1420 dfallback(data
, convstart
, data
->pf
, d
);
1423 # endif /* HAVE_PRINTF_A_FORMAT */
1424 #endif /* FLOATING_POINT */
1426 data
->flags
|= PF_LONGINT
;
1430 #ifdef HAVE_LONG_LONG
1431 if (data
->flags
& PF_LONGLONG
)
1433 ull
= GETARG (unsigned long long);
1434 lnumber(data
, ull
, 10);
1439 ul
= GETUNSIGNED(data
);
1440 number(data
, ul
, 10);
1445 data
->flags
|= PF_LONGINT
;
1447 case 'd': /* decimal */
1450 #ifdef HAVE_LONG_LONG
1451 if (data
->flags
& PF_LONGLONG
)
1453 ull
= GETARG (long long);
1454 lnumber(data
, ull
, 10);
1459 ul
= GETSIGNED(data
);
1460 number(data
, ul
, 10);
1464 case 'o': /* octal */
1466 #ifdef HAVE_LONG_LONG
1467 if (data
->flags
& PF_LONGLONG
)
1469 ull
= GETARG (unsigned long long);
1470 lnumber(data
, ull
, 8);
1475 ul
= GETUNSIGNED(data
);
1476 number(data
, ul
, 8);
1481 case 'X': /* hexadecimal */
1483 #ifdef HAVE_LONG_LONG
1484 if (data
->flags
& PF_LONGLONG
)
1486 ull
= GETARG (unsigned long long);
1487 lnumber(data
, ull
, 16);
1492 ul
= GETUNSIGNED(data
);
1493 number(data
, ul
, 16);
1499 ul
= (unsigned long)GETARG (void *);
1503 #if HANDLE_MULTIBYTE
1505 data
->flags
|= PF_LONGINT
;
1508 case 'c': /* character */
1510 #if HANDLE_MULTIBYTE
1511 if (data
->flags
& PF_LONGINT
)
1513 wc
= GETARG (wint_t);
1524 #if HANDLE_MULTIBYTE
1526 data
->flags
|= PF_LONGINT
;
1529 case 's': /* string */
1531 #if HANDLE_MULTIBYTE
1532 if (data
->flags
& PF_LONGINT
)
1534 ws
= GETARG (wchar_t *);
1535 wstrings (data
, ws
);
1540 s
= GETARG (char *);
1546 #ifdef HAVE_LONG_LONG
1547 if (data
->flags
& PF_LONGLONG
)
1548 *(GETARG (long long *)) = data
->counter
;
1551 if (data
->flags
& PF_LONGINT
)
1552 *(GETARG (long *)) = data
->counter
;
1553 else if (data
->flags
& PF_SHORTINT
)
1554 *(GETARG (short *)) = data
->counter
;
1556 *(GETARG (int *)) = data
->counter
;
1559 case '%': /* nothing just % */
1560 PUT_CHAR('%', data
);
1564 /* is this an error ? maybe bail out */
1568 } /* end of `%' for loop */
1569 } /* end of format string for loop */
1571 if (data
->length
>= 0)
1572 *data
->holder
= '\0'; /* the end ye ! */
1574 return data
->counter
;
1577 #if defined (FLOATING_POINT) && defined (HAVE_LONG_DOUBLE)
1579 * Printing floating point numbers accurately is an art. I'm not good
1580 * at it. Fall back to sprintf for long double formats.
1583 ldfallback (data
, fs
, fe
, ld
)
1585 const char *fs
, *fe
;
1589 char fmtbuf
[FALLBACK_FMTSIZE
], *obuf
;
1592 fl
= LFALLBACK_BASE
+ (data
->precision
< 6 ? 6 : data
->precision
) + 2;
1593 obuf
= (char *)xmalloc (fl
);
1595 strncpy (fmtbuf
, fs
, fl
);
1598 if ((data
->flags
& PF_STAR_W
) && (data
->flags
& PF_STAR_P
))
1599 sprintf (obuf
, fmtbuf
, data
->width
, data
->precision
, ld
);
1600 else if (data
->flags
& PF_STAR_W
)
1601 sprintf (obuf
, fmtbuf
, data
->width
, ld
);
1602 else if (data
->flags
& PF_STAR_P
)
1603 sprintf (obuf
, fmtbuf
, data
->precision
, ld
);
1605 sprintf (obuf
, fmtbuf
, ld
);
1607 for (x
= obuf
; *x
; x
++)
1608 PUT_CHAR (*x
, data
);
1611 #endif /* FLOATING_POINT && HAVE_LONG_DOUBLE */
1613 #ifdef FLOATING_POINT
1614 /* Used for %a, %A if the libc printf supports them. */
1616 dfallback (data
, fs
, fe
, d
)
1618 const char *fs
, *fe
;
1622 char fmtbuf
[FALLBACK_FMTSIZE
], obuf
[FALLBACK_BASE
];
1626 strncpy (fmtbuf
, fs
, fl
);
1629 if ((data
->flags
& PF_STAR_W
) && (data
->flags
& PF_STAR_P
))
1630 sprintf (obuf
, fmtbuf
, data
->width
, data
->precision
, d
);
1631 else if (data
->flags
& PF_STAR_W
)
1632 sprintf (obuf
, fmtbuf
, data
->width
, d
);
1633 else if (data
->flags
& PF_STAR_P
)
1634 sprintf (obuf
, fmtbuf
, data
->precision
, d
);
1636 sprintf (obuf
, fmtbuf
, d
);
1638 for (x
= obuf
; *x
; x
++)
1639 PUT_CHAR (*x
, data
);
1641 #endif /* FLOATING_POINT */
1643 #ifndef HAVE_SNPRINTF
1646 #if defined (__STDC__)
1647 vsnprintf(char *string
, size_t length
, const char *format
, va_list args
)
1649 vsnprintf(string
, length
, format
, args
)
1658 if (string
== 0 && length
!= 0)
1660 init_data (&data
, string
, length
, format
, PFM_SN
);
1661 return (vsnprintf_internal(&data
, string
, length
, format
, args
));
1665 #if defined(PREFER_STDARG)
1666 snprintf(char *string
, size_t length
, const char * format
, ...)
1668 snprintf(string
, length
, format
, va_alist
)
1679 SH_VA_START(args
, format
);
1681 if (string
== 0 && length
!= 0)
1683 init_data (&data
, string
, length
, format
, PFM_SN
);
1684 rval
= vsnprintf_internal (&data
, string
, length
, format
, args
);
1691 #endif /* HAVE_SNPRINTF */
1693 #ifndef HAVE_ASPRINTF
1696 #if defined (__STDC__)
1697 vasprintf(char **stringp
, const char *format
, va_list args
)
1699 vasprintf(stringp
, format
, args
)
1709 string
= (char *)xmalloc(ASBUFSIZE
);
1710 init_data (&data
, string
, ASBUFSIZE
, format
, PFM_AS
);
1711 r
= vsnprintf_internal(&data
, string
, ASBUFSIZE
, format
, args
);
1712 *stringp
= data
.base
; /* not string in case reallocated */
1717 #if defined(PREFER_STDARG)
1718 asprintf(char **stringp
, const char * format
, ...)
1720 asprintf(stringp
, format
, va_alist
)
1729 SH_VA_START(args
, format
);
1731 rval
= vasprintf (stringp
, format
, args
);
1745 memory_error_and_abort ()
1747 write (2, "out of virtual memory\n", 22);
1757 ret
= malloc(bytes
);
1759 memory_error_and_abort ();
1764 xrealloc (pointer
, bytes
)
1770 ret
= pointer
? realloc(pointer
, bytes
) : malloc(bytes
);
1772 memory_error_and_abort ();
1784 /* set of small tests for snprintf() */
1791 #ifdef HAVE_LOCALE_H
1792 setlocale(LC_ALL
, "");
1796 si
= snprintf((char *)NULL
, 0, "abcde\n");
1797 printf("snprintf returns %d with NULL first argument and size of 0\n", si
);
1798 si
= snprintf(holder
, 0, "abcde\n");
1799 printf("snprintf returns %d with non-NULL first argument and size of 0\n", si
);
1800 si
= snprintf((char *)NULL
, 16, "abcde\n");
1801 printf("snprintf returns %d with NULL first argument and non-zero size\n", si
);
1804 printf("Suite of test for snprintf:\n");
1805 printf("a_format\n");
1806 printf("printf() format\n");
1807 printf("snprintf() format\n\n");
1809 /* Checking the field widths */
1811 printf("/%%ld %%ld/, 336, 336\n");
1812 snprintf(holder
, sizeof holder
, "/%ld %ld/\n", 336, 336);
1813 asprintf(&h
, "/%ld %ld/\n", 336, 336);
1814 printf("/%ld %ld/\n", 336, 336);
1815 printf("%s", holder
);
1818 printf("/%%d/, 336\n");
1819 snprintf(holder
, sizeof holder
, "/%d/\n", 336);
1820 asprintf(&h
, "/%d/\n", 336);
1821 printf("/%d/\n", 336);
1822 printf("%s", holder
);
1825 printf("/%%2d/, 336\n");
1826 snprintf(holder
, sizeof holder
, "/%2d/\n", 336);
1827 asprintf(&h
, "/%2d/\n", 336);
1828 printf("/%2d/\n", 336);
1829 printf("%s", holder
);
1832 printf("/%%10d/, 336\n");
1833 snprintf(holder
, sizeof holder
, "/%10d/\n", 336);
1834 asprintf(&h
, "/%10d/\n", 336);
1835 printf("/%10d/\n", 336);
1836 printf("%s", holder
);
1839 printf("/%%-10d/, 336\n");
1840 snprintf(holder
, sizeof holder
, "/%-10d/\n", 336);
1841 asprintf(&h
, "/%-10d/\n", 336);
1842 printf("/%-10d/\n", 336);
1843 printf("%s", holder
);
1847 /* floating points */
1849 printf("/%%f/, 1234.56\n");
1850 snprintf(holder
, sizeof holder
, "/%f/\n", 1234.56);
1851 asprintf(&h
, "/%f/\n", 1234.56);
1852 printf("/%f/\n", 1234.56);
1853 printf("%s", holder
);
1856 printf("/%%e/, 1234.56\n");
1857 snprintf(holder
, sizeof holder
, "/%e/\n", 1234.56);
1858 asprintf(&h
, "/%e/\n", 1234.56);
1859 printf("/%e/\n", 1234.56);
1860 printf("%s", holder
);
1863 printf("/%%4.2f/, 1234.56\n");
1864 snprintf(holder
, sizeof holder
, "/%4.2f/\n", 1234.56);
1865 asprintf(&h
, "/%4.2f/\n", 1234.56);
1866 printf("/%4.2f/\n", 1234.56);
1867 printf("%s", holder
);
1870 printf("/%%3.1f/, 1234.56\n");
1871 snprintf(holder
, sizeof holder
, "/%3.1f/\n", 1234.56);
1872 asprintf(&h
, "/%3.1f/\n", 1234.56);
1873 printf("/%3.1f/\n", 1234.56);
1874 printf("%s", holder
);
1877 printf("/%%10.3f/, 1234.56\n");
1878 snprintf(holder
, sizeof holder
, "/%10.3f/\n", 1234.56);
1879 asprintf(&h
, "/%10.3f/\n", 1234.56);
1880 printf("/%10.3f/\n", 1234.56);
1881 printf("%s", holder
);
1884 printf("/%%10.3e/, 1234.56\n");
1885 snprintf(holder
, sizeof holder
, "/%10.3e/\n", 1234.56);
1886 asprintf(&h
, "/%10.3e/\n", 1234.56);
1887 printf("/%10.3e/\n", 1234.56);
1888 printf("%s", holder
);
1891 printf("/%%+4.2f/, 1234.56\n");
1892 snprintf(holder
, sizeof holder
, "/%+4.2f/\n", 1234.56);
1893 asprintf(&h
, "/%+4.2f/\n", 1234.56);
1894 printf("/%+4.2f/\n", 1234.56);
1895 printf("%s", holder
);
1898 printf("/%%010.2f/, 1234.56\n");
1899 snprintf(holder
, sizeof holder
, "/%010.2f/\n", 1234.56);
1900 asprintf(&h
, "/%010.2f/\n", 1234.56);
1901 printf("/%010.2f/\n", 1234.56);
1902 printf("%s", holder
);
1905 #define BLURB "Outstanding acting !"
1906 /* strings precisions */
1908 printf("/%%2s/, \"%s\"\n", BLURB
);
1909 snprintf(holder
, sizeof holder
, "/%2s/\n", BLURB
);
1910 asprintf(&h
, "/%2s/\n", BLURB
);
1911 printf("/%2s/\n", BLURB
);
1912 printf("%s", holder
);
1915 printf("/%%22s/ %s\n", BLURB
);
1916 snprintf(holder
, sizeof holder
, "/%22s/\n", BLURB
);
1917 asprintf(&h
, "/%22s/\n", BLURB
);
1918 printf("/%22s/\n", BLURB
);
1919 printf("%s", holder
);
1922 printf("/%%22.5s/ %s\n", BLURB
);
1923 snprintf(holder
, sizeof holder
, "/%22.5s/\n", BLURB
);
1924 asprintf(&h
, "/%22.5s/\n", BLURB
);
1925 printf("/%22.5s/\n", BLURB
);
1926 printf("%s", holder
);
1929 printf("/%%-22.5s/ %s\n", BLURB
);
1930 snprintf(holder
, sizeof holder
, "/%-22.5s/\n", BLURB
);
1931 asprintf(&h
, "/%-22.5s/\n", BLURB
);
1932 printf("/%-22.5s/\n", BLURB
);
1933 printf("%s", holder
);
1936 /* see some flags */
1938 printf("%%x %%X %%#x, 31, 31, 31\n");
1939 snprintf(holder
, sizeof holder
, "%x %X %#x\n", 31, 31, 31);
1940 asprintf(&h
, "%x %X %#x\n", 31, 31, 31);
1941 printf("%x %X %#x\n", 31, 31, 31);
1942 printf("%s", holder
);
1945 printf("**%%d**%% d**%% d**, 42, 42, -42\n");
1946 snprintf(holder
, sizeof holder
, "**%d**% d**% d**\n", 42, 42, -42);
1947 asprintf(&h
, "**%d**% d**% d**\n", 42, 42, -42);
1948 printf("**%d**% d**% d**\n", 42, 42, -42);
1949 printf("%s", holder
);
1954 printf("/%%g/, 31.4\n");
1955 snprintf(holder
, sizeof holder
, "/%g/\n", 31.4);
1956 asprintf(&h
, "/%g/\n", 31.4);
1957 printf("/%g/\n", 31.4);
1958 printf("%s", holder
);
1961 printf("/%%.6g/, 31.4\n");
1962 snprintf(holder
, sizeof holder
, "/%.6g/\n", 31.4);
1963 asprintf(&h
, "/%.6g/\n", 31.4);
1964 printf("/%.6g/\n", 31.4);
1965 printf("%s", holder
);
1968 printf("/%%.1G/, 31.4\n");
1969 snprintf(holder
, sizeof holder
, "/%.1G/\n", 31.4);
1970 asprintf(&h
, "/%.1G/\n", 31.4);
1971 printf("/%.1G/\n", 31.4);
1972 printf("%s", holder
);
1975 printf("/%%.1G/, 3100000000.4\n");
1976 snprintf(holder
, sizeof holder
, "/%.1G/\n", 3100000000.4);
1977 asprintf(&h
, "/%.1G/\n", 3100000000.4);
1978 printf("/%.1G/\n", 3100000000.4);
1979 printf("%s", holder
);
1983 printf("abc%n", &i
); printf("%d\n", i
);
1984 snprintf(holder
, sizeof holder
, "abc%n", &i
);
1985 printf("%s", holder
); printf("%d\n\n", i
);
1986 asprintf(&h
, "abc%n", &i
);
1987 printf("%s", h
); printf("%d\n\n", i
);
1989 printf("%%*.*s --> 10.10\n");
1990 snprintf(holder
, sizeof holder
, "%*.*s\n", 10, 10, BLURB
);
1991 asprintf(&h
, "%*.*s\n", 10, 10, BLURB
);
1992 printf("%*.*s\n", 10, 10, BLURB
);
1993 printf("%s", holder
);
1996 printf("%%%%%%%%\n");
1997 snprintf(holder
, sizeof holder
, "%%%%\n");
1998 asprintf(&h
, "%%%%\n");
2000 printf("%s", holder
);
2003 #define BIG "Hello this is a too big string for the buffer"
2004 /* printf("A buffer to small of 10, trying to put this:\n");*/
2005 printf("<%%>, %s\n", BIG
);
2006 i
= snprintf(holder
, 10, "%s\n", BIG
);
2007 i
= asprintf(&h
, "%s", BIG
);
2008 printf("<%s>\n", BIG
);
2009 printf("<%s>\n", holder
);
2010 printf("<%s>\n\n", h
);
2012 printf ("<%%p> vsnprintf\n");
2013 i
= snprintf(holder
, 100, "%p", vsnprintf
);
2014 i
= asprintf(&h
, "%p", vsnprintf
);
2015 printf("<%p>\n", vsnprintf
);
2016 printf("<%s>\n", holder
);
2017 printf("<%s>\n\n", h
);
2019 printf ("<%%lu> LONG_MAX+1\n");
2020 i
= snprintf(holder
, 100, "%lu", (unsigned long)(LONG_MAX
)+1);
2021 i
= asprintf(&h
, "%lu", (unsigned long)(LONG_MAX
)+1);
2022 printf("<%lu>\n", (unsigned long)(LONG_MAX
)+1);
2023 printf("<%s>\n", holder
);
2024 printf("<%s>\n\n", h
);
2026 #ifdef HAVE_LONG_LONG
2027 printf ("<%%llu> LLONG_MAX+1\n");
2028 i
= snprintf(holder
, 100, "%llu", (unsigned long long)(LLONG_MAX
)+1);
2029 i
= asprintf(&h
, "%llu", (unsigned long long)(LLONG_MAX
)+1);
2030 printf("<%llu>\n", (unsigned long long)(LLONG_MAX
)+1);
2031 printf("<%s>\n", holder
);
2032 printf("<%s>\n\n", h
);
2035 #ifdef HAVE_LONG_DOUBLE
2036 printf ("<%%6.2LE> 42.42\n");
2037 i
= snprintf(holder
, 100, "%6.2LE", (long double)42.42);
2038 i
= asprintf(&h
, "%6.2LE", (long double)42.42);
2039 printf ("<%6.2LE>\n", (long double)42.42);
2040 printf ("<%s>\n", holder
);
2041 printf ("<%s>\n\n", h
);
2044 #ifdef HAVE_PRINTF_A_FORMAT
2045 printf ("<%%6.2A> 42.42\n");
2046 i
= snprintf(holder
, 100, "%6.2A", 42.42);
2047 i
= asprintf(&h
, "%6.2A", 42.42);
2048 printf ("<%6.2A>\n", 42.42);
2049 printf ("<%s>\n", holder
);
2050 printf ("<%s>\n\n", h
);
2052 printf ("<%%6.2LA> 42.42\n");
2053 i
= snprintf(holder
, 100, "%6.2LA", (long double)42.42);
2054 i
= asprintf(&h
, "%6.2LA", (long double)42.42);
2055 printf ("<%6.2LA>\n", (long double)42.42);
2056 printf ("<%s>\n", holder
);
2057 printf ("<%s>\n\n", h
);
2060 printf ("<%%.10240f> DBL_MAX\n");
2061 si
= snprintf(holder
, 100, "%.10240f", DBL_MAX
);
2062 ai
= asprintf(&h
, "%.10240f", DBL_MAX
);
2063 printf ("<%.10240f>\n", DBL_MAX
);
2064 printf ("<%d> <%s>\n", si
, holder
);
2065 printf ("<%d> <%s>\n\n", ai
, h
);
2067 printf ("<%%.10240Lf> LDBL_MAX\n");
2068 si
= snprintf(holder
, 100, "%.10240Lf", (long double)LDBL_MAX
);
2069 ai
= asprintf(&h
, "%.10240Lf", (long double)LDBL_MAX
);
2070 printf ("<%.10240Lf>\n", (long double)LDBL_MAX
);
2071 printf ("<%d> <%s>\n", si
, holder
);
2072 printf ("<%d> <%s>\n\n", ai
, h
);
2075 printf("/%%g/, 421.2345\n");
2076 snprintf(holder
, sizeof holder
, "/%g/\n", 421.2345);
2077 asprintf(&h
, "/%g/\n", 421.2345);
2078 printf("/%g/\n", 421.2345);
2079 printf("%s", holder
);
2082 printf("/%%g/, 4214.2345\n");
2083 snprintf(holder
, sizeof holder
, "/%g/\n", 4214.2345);
2084 asprintf(&h
, "/%g/\n", 4214.2345);
2085 printf("/%g/\n", 4214.2345);
2086 printf("%s", holder
);
2089 printf("/%%.5g/, 4214.2345\n");
2090 snprintf(holder
, sizeof holder
, "/%.5g/\n", 4214.2345);
2091 asprintf(&h
, "/%.5g/\n", 4214.2345);
2092 printf("/%.5g/\n", 4214.2345);
2093 printf("%s", holder
);
2096 printf("/%%.4g/, 4214.2345\n");
2097 snprintf(holder
, sizeof holder
, "/%.4g/\n", 4214.2345);
2098 asprintf(&h
, "/%.4g/\n", 4214.2345);
2099 printf("/%.4g/\n", 4214.2345);
2100 printf("%s", holder
);
2103 printf("/%%'ld %%'ld/, 12345, 1234567\n");
2104 snprintf(holder
, sizeof holder
, "/%'ld %'ld/\n", 12345, 1234567);
2105 asprintf(&h
, "/%'ld %'ld/\n", 12345, 1234567);
2106 printf("/%'ld %'ld/\n", 12345, 1234567);
2107 printf("%s", holder
);
2110 printf("/%%'ld %%'ld/, 336, 3336\n");
2111 snprintf(holder
, sizeof holder
, "/%'ld %'ld/\n", 336, 3336);
2112 asprintf(&h
, "/%'ld %'ld/\n", 336, 3336);
2113 printf("/%'ld %'ld/\n", 336, 3336);
2114 printf("%s", holder
);
2117 printf("/%%'ld %%'ld/, -42786, -142786\n");
2118 snprintf(holder
, sizeof holder
, "/%'ld %'ld/\n", -42786, -142786);
2119 asprintf(&h
, "/%'ld %'ld/\n", -42786, -142786);
2120 printf("/%'ld %'ld/\n", -42786, -142786);
2121 printf("%s", holder
);
2124 printf("/%%'f %%'f/, 421.2345, 421234.56789\n");
2125 snprintf(holder
, sizeof holder
, "/%'f %'f/\n", 421.2345, 421234.56789);
2126 asprintf(&h
, "/%'f %'f/\n", 421.2345, 421234.56789);
2127 printf("/%'f %'f/\n", 421.2345, 421234.56789);
2128 printf("%s", holder
);
2131 printf("/%%'f %%'f/, -421.2345, -421234.56789\n");
2132 snprintf(holder
, sizeof holder
, "/%'f %'f/\n", -421.2345, -421234.56789);
2133 asprintf(&h
, "/%'f %'f/\n", -421.2345, -421234.56789);
2134 printf("/%'f %'f/\n", -421.2345, -421234.56789);
2135 printf("%s", holder
);
2138 printf("/%%'g %%'g/, 421.2345, 421234.56789\n");
2139 snprintf(holder
, sizeof holder
, "/%'g %'g/\n", 421.2345, 421234.56789);
2140 asprintf(&h
, "/%'g %'g/\n", 421.2345, 421234.56789);
2141 printf("/%'g %'g/\n", 421.2345, 421234.56789);
2142 printf("%s", holder
);
2145 printf("/%%'g %%'g/, -421.2345, -421234.56789\n");
2146 snprintf(holder
, sizeof holder
, "/%'g %'g/\n", -421.2345, -421234.56789);
2147 asprintf(&h
, "/%'g %'g/\n", -421.2345, -421234.56789);
2148 printf("/%'g %'g/\n", -421.2345, -421234.56789);
2149 printf("%s", holder
);
2153 printf("/%%'g/, 4213455.8392\n");
2154 snprintf(holder
, sizeof holder
, "/%'g/\n", 4213455.8392);
2155 asprintf(&h
, "/%'g/\n", 4213455.8392);
2156 printf("/%'g/\n", 4213455.8392);
2157 printf("%s", holder
);