1 /*
2 * Copyright (c) 1995 Patrick Powell.
3 *
4 * This code is based on code written by Patrick Powell <papowell@astart.com>.
5 * It may be used for any purpose as long as this notice remains intact on all
6 * source code distributions.
7 */
8
9 /*
10 * Copyright (c) 2008 Holger Weiss.
11 *
12 * This version of the code is maintained by Holger Weiss <holger@jhweiss.de>.
13 * My changes to the code may freely be used, modified and/or redistributed for
14 * any purpose. It would be nice if additions and fixes to this file (including
15 * trivial code cleanups) would be sent back in order to let me include them in
16 * the version available at <http://www.jhweiss.de/software/snprintf.html>.
17 * However, this is not a requirement for using or redistributing (possibly
18 * modified) versions of this file, nor is leaving this notice intact mandatory.
19 */
20
21 #if HAVE_CONFIG_H
22 # include <config.h>
23 #endif /* HAVE_CONFIG_H */
24
25 #if !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || !HAVE_VASPRINTF
26 # include <stdio.h> /* For NULL, size_t, vsnprintf(3), and vasprintf(3). */
27 # ifdef VA_START
28 # undef VA_START
29 # endif /* defined(VA_START) */
30 # ifdef VA_SHIFT
31 # undef VA_SHIFT
32 # endif /* defined(VA_SHIFT) */
33 # if HAVE_STDARG_H
34 # include <stdarg.h>
35 # define VA_START(ap, last) va_start(ap, last)
36 # define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */
37 # else /* Assume <varargs.h> is available. */
38 # include <varargs.h>
39 # define VA_START(ap, last) va_start(ap) /* "last" is ignored. */
40 # define VA_SHIFT(ap, value, type) value = va_arg(ap, type)
41 # endif /* HAVE_STDARG_H */
42
43 # if !HAVE_VASPRINTF
44 # if HAVE_STDLIB_H
45 # include <stdlib.h> /* For malloc(3). */
46 # endif /* HAVE_STDLIB_H */
47 # ifdef VA_COPY
48 # undef VA_COPY
49 # endif /* defined(VA_COPY) */
50 # ifdef VA_END_COPY
51 # undef VA_END_COPY
52 # endif /* defined(VA_END_COPY) */
53 # if HAVE_VA_COPY
54 # define VA_COPY(dest, src) va_copy(dest, src)
55 # define VA_END_COPY(ap) va_end(ap)
56 # elif HAVE___VA_COPY
57 # define VA_COPY(dest, src) __va_copy(dest, src)
58 # define VA_END_COPY(ap) va_end(ap)
59 # else
60 # define VA_COPY(dest, src) (void)mymemcpy(&dest, &src, sizeof(va_list))
61 # define VA_END_COPY(ap) /* No-op. */
62 # define NEED_MYMEMCPY 1
63 static void *mymemcpy(void *, void *, size_t);
64 # endif /* HAVE_VA_COPY */
65 # endif /* !HAVE_VASPRINTF */
66
67 # if !HAVE_VSNPRINTF
68 # include <errno.h> /* For ERANGE and errno. */
69 # include <limits.h> /* For *_MAX. */
70 # if HAVE_INTTYPES_H
71 # include <inttypes.h> /* For intmax_t (if it's not in <stdint.h>). */
72 # endif /* HAVE_INTTYPES_H */
73 # if HAVE_LOCALE_H
74 # include <locale.h> /* For localeconv(3). */
75 # endif /* HAVE_LOCALE_H */
76 # if HAVE_STDDEF_H
77 # include <stddef.h> /* For ptrdiff_t. */
78 # endif /* HAVE_STDDEF_H */
79 # if HAVE_STDINT_H
80 # include <stdint.h> /* For intmax_t. */
81 # endif /* HAVE_STDINT_H */
82
83 # include "system.h"
84
85 /* Support for unsigned long long int. We may also need ULLONG_MAX. */
86 # ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */
87 # ifdef UINT_MAX
88 # define ULONG_MAX UINT_MAX
89 # else
90 # define ULONG_MAX INT_MAX
91 # endif /* defined(UINT_MAX) */
92 # endif /* !defined(ULONG_MAX) */
93 # ifdef ULLONG
94 # undef ULLONG
95 # endif /* defined(ULLONG) */
96 # if HAVE_UNSIGNED_LONG_LONG_INT
97 # define ULLONG unsigned long long int
98 # ifndef ULLONG_MAX
99 # define ULLONG_MAX ULONG_MAX
100 # endif /* !defined(ULLONG_MAX) */
101 # else
102 # define ULLONG unsigned long int
103 # ifdef ULLONG_MAX
104 # undef ULLONG_MAX
105 # endif /* defined(ULLONG_MAX) */
106 # define ULLONG_MAX ULONG_MAX
107 # endif /* HAVE_LONG_LONG_INT */
108
109 /* Support for uintmax_t. We also need UINTMAX_MAX. */
110 # ifdef UINTMAX_T
111 # undef UINTMAX_T
112 # endif /* defined(UINTMAX_T) */
113 # if HAVE_UINTMAX_T || defined(uintmax_t)
114 # define UINTMAX_T uintmax_t
115 # ifndef UINTMAX_MAX
116 # define UINTMAX_MAX ULLONG_MAX
117 # endif /* !defined(UINTMAX_MAX) */
118 # else
119 # define UINTMAX_T ULLONG
120 # ifdef UINTMAX_MAX
121 # undef UINTMAX_MAX
122 # endif /* defined(UINTMAX_MAX) */
123 # define UINTMAX_MAX ULLONG_MAX
124 # endif /* HAVE_UINTMAX_T || defined(uintmax_t) */
125
126 /* Support for long double. */
127 # ifndef LDOUBLE
128 # if HAVE_LONG_DOUBLE
129 # define LDOUBLE long double
130 # else
131 # define LDOUBLE double
132 # endif /* HAVE_LONG_DOUBLE */
133 # endif /* !defined(LDOUBLE) */
134
135 /* Support for long long int. */
136 # ifndef LLONG
137 # if HAVE_LONG_LONG_INT
138 # define LLONG long long int
139 # else
140 # define LLONG long int
141 # endif /* HAVE_LONG_LONG_INT */
142 # endif /* !defined(LLONG) */
143
144 /* Support for intmax_t. */
145 # ifndef INTMAX_T
146 # if HAVE_INTMAX_T || defined(intmax_t)
147 # define INTMAX_T intmax_t
148 # else
149 # define INTMAX_T LLONG
150 # endif /* HAVE_INTMAX_T || defined(intmax_t) */
151 # endif /* !defined(INTMAX_T) */
152
153 /* Support for uintptr_t. */
154 # ifndef UINTPTR_T
155 # if HAVE_UINTPTR_T || defined(uintptr_t)
156 # define UINTPTR_T uintptr_t
157 # else
158 # define UINTPTR_T unsigned long int
159 # endif /* HAVE_UINTPTR_T || defined(uintptr_t) */
160 # endif /* !defined(UINTPTR_T) */
161
162 /* Support for ptrdiff_t. */
163 # ifndef PTRDIFF_T
164 # if HAVE_PTRDIFF_T || defined(ptrdiff_t)
165 # define PTRDIFF_T ptrdiff_t
166 # else
167 # define PTRDIFF_T long int
168 # endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */
169 # endif /* !defined(PTRDIFF_T) */
170
171 /*
172 * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99:
173 * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an
174 * unsigned type if necessary. This should work just fine in practice.
175 */
176 # ifndef UPTRDIFF_T
177 # define UPTRDIFF_T PTRDIFF_T
178 # endif /* !defined(UPTRDIFF_T) */
179
180 /*
181 * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7).
182 * However, we'll simply use size_t and convert it to a signed type if
183 * necessary. This should work just fine in practice.
184 */
185 # ifndef SSIZE_T
186 # define SSIZE_T size_t
187 # endif /* !defined(SSIZE_T) */
188
189 /* Either ERANGE or E2BIG should be available everywhere. */
190 # ifndef ERANGE
191 # define ERANGE E2BIG
192 # endif /* !defined(ERANGE) */
193 # ifndef EOVERFLOW
194 # define EOVERFLOW ERANGE
195 # endif /* !defined(EOVERFLOW) */
196
197 /*
198 * Buffer size to hold the octal string representation of UINT128_MAX without
199 * nul-termination ("3777777777777777777777777777777777777777777").
200 */
201 # ifdef MAX_CONVERT_LENGTH
202 # undef MAX_CONVERT_LENGTH
203 # endif /* defined(MAX_CONVERT_LENGTH) */
204 # define MAX_CONVERT_LENGTH 43
205
206 /* Format read states. */
207 # define PRINT_S_DEFAULT 0
208 # define PRINT_S_FLAGS 1
209 # define PRINT_S_WIDTH 2
210 # define PRINT_S_DOT 3
211 # define PRINT_S_PRECISION 4
212 # define PRINT_S_MOD 5
213 # define PRINT_S_CONV 6
214
215 /* Format flags. */
216 # define PRINT_F_MINUS (1 << 0)
217 # define PRINT_F_PLUS (1 << 1)
218 # define PRINT_F_SPACE (1 << 2)
219 # define PRINT_F_NUM (1 << 3)
220 # define PRINT_F_ZERO (1 << 4)
221 # define PRINT_F_QUOTE (1 << 5)
222 # define PRINT_F_UP (1 << 6)
223 # define PRINT_F_UNSIGNED (1 << 7)
224 # define PRINT_F_TYPE_G (1 << 8)
225 # define PRINT_F_TYPE_E (1 << 9)
226
227 /* Conversion flags. */
228 # define PRINT_C_CHAR 1
229 # define PRINT_C_SHORT 2
230 # define PRINT_C_LONG 3
231 # define PRINT_C_LLONG 4
232 # define PRINT_C_LDOUBLE 5
233 # define PRINT_C_SIZE 6
234 # define PRINT_C_PTRDIFF 7
235 # define PRINT_C_INTMAX 8
236
237 # ifndef MAX
238 # define MAX(x, y) ((x >= y) ? x : y)
239 # endif /* !defined(MAX) */
240 # ifndef CHARTOINT
241 # define CHARTOINT(ch) (ch - '0')
242 # endif /* !defined(CHARTOINT) */
243 # ifndef ISDIGIT
244 # define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9')
245 # endif /* !defined(ISDIGIT) */
246 # ifndef ISNAN
247 # define ISNAN(x) (x != x)
248 # endif /* !defined(ISNAN) */
249 # ifndef ISINF
250 # define ISINF(x) (x != 0.0 && x + x == x)
251 # endif /* !defined(ISINF) */
252
253 # ifdef OUTCHAR
254 # undef OUTCHAR
255 # endif /* defined(OUTCHAR) */
256 # define OUTCHAR(str, len, size, ch) \
257 do { \
258 if (len + 1 < size) \
259 str[len] = ch; \
260 (len)++; \
261 } while (/* CONSTCOND */ 0)
262
263 static void fmtstr(char *, size_t *, size_t, const char *, int, int, int);
264 static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int);
265 static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *);
266 static void printsep(char *, size_t *, size_t);
267 static int getnumsep(int);
268 static int getexponent(LDOUBLE);
269 static int convert(UINTMAX_T, char *, size_t, int, int);
270 static UINTMAX_T cast(LDOUBLE);
271 static UINTMAX_T myround(LDOUBLE);
272 static LDOUBLE mypow10(int);
273
274 extern int errno;
275
276 int
rpl_vsnprintf(char * str,size_t size,const char * format,va_list args)277 rpl_vsnprintf(char *str, size_t size, const char *format, va_list args)
278 {
279 LDOUBLE fvalue;
280 INTMAX_T value;
281 unsigned char cvalue;
282 const char *strvalue;
283 INTMAX_T *intmaxptr;
284 PTRDIFF_T *ptrdiffptr;
285 SSIZE_T *sizeptr;
286 LLONG *llongptr;
287 long int *longptr;
288 int *intptr;
289 short int *shortptr;
290 signed char *charptr;
291 size_t len = 0;
292 int overflow = 0;
293 int base = 0;
294 int cflags = 0;
295 int flags = 0;
296 int width = 0;
297 int precision = -1;
298 int state = PRINT_S_DEFAULT;
299 char ch = *format++;
300
301 /*
302 * C99 says: "If `n' is zero, nothing is written, and `s' may be a null
303 * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer
304 * even if a size larger than zero was specified. At least NetBSD's
305 * snprintf(3) does the same, as well as other versions of this file.
306 * (Though some of these versions will write to a non-NULL buffer even
307 * if a size of zero was specified, which violates the standard.)
308 */
309 if (str == NULL && size != 0)
310 size = 0;
311
312 while (ch != '\0')
313 switch (state) {
314 case PRINT_S_DEFAULT:
315 if (ch == '%')
316 state = PRINT_S_FLAGS;
317 else
318 OUTCHAR(str, len, size, ch);
319 ch = *format++;
320 break;
321 case PRINT_S_FLAGS:
322 switch (ch) {
323 case '-':
324 flags |= PRINT_F_MINUS;
325 ch = *format++;
326 break;
327 case '+':
328 flags |= PRINT_F_PLUS;
329 ch = *format++;
330 break;
331 case ' ':
332 flags |= PRINT_F_SPACE;
333 ch = *format++;
334 break;
335 case '#':
336 flags |= PRINT_F_NUM;
337 ch = *format++;
338 break;
339 case '0':
340 flags |= PRINT_F_ZERO;
341 ch = *format++;
342 break;
343 case '\'': /* SUSv2 flag (not in C99). */
344 flags |= PRINT_F_QUOTE;
345 ch = *format++;
346 break;
347 default:
348 state = PRINT_S_WIDTH;
349 break;
350 }
351 break;
352 case PRINT_S_WIDTH:
353 if (ISDIGIT(ch)) {
354 ch = CHARTOINT(ch);
355 if (width > (INT_MAX - ch) / 10) {
356 overflow = 1;
357 goto out;
358 }
359 width = 10 * width + ch;
360 ch = *format++;
361 } else if (ch == '*') {
362 /*
363 * C99 says: "A negative field width argument is
364 * taken as a `-' flag followed by a positive
365 * field width." (7.19.6.1, 5)
366 */
367 if ((width = va_arg(args, int)) < 0) {
368 flags |= PRINT_F_MINUS;
369 width = -width;
370 }
371 ch = *format++;
372 state = PRINT_S_DOT;
373 } else
374 state = PRINT_S_DOT;
375 break;
376 case PRINT_S_DOT:
377 if (ch == '.') {
378 state = PRINT_S_PRECISION;
379 ch = *format++;
380 } else
381 state = PRINT_S_MOD;
382 break;
383 case PRINT_S_PRECISION:
384 if (precision == -1)
385 precision = 0;
386 if (ISDIGIT(ch)) {
387 ch = CHARTOINT(ch);
388 if (precision > (INT_MAX - ch) / 10) {
389 overflow = 1;
390 goto out;
391 }
392 precision = 10 * precision + ch;
393 ch = *format++;
394 } else if (ch == '*') {
395 /*
396 * C99 says: "A negative precision argument is
397 * taken as if the precision were omitted."
398 * (7.19.6.1, 5)
399 */
400 if ((precision = va_arg(args, int)) < 0)
401 precision = -1;
402 ch = *format++;
403 state = PRINT_S_MOD;
404 } else
405 state = PRINT_S_MOD;
406 break;
407 case PRINT_S_MOD:
408 switch (ch) {
409 case 'h':
410 ch = *format++;
411 if (ch == 'h') { /* It's a char. */
412 ch = *format++;
413 cflags = PRINT_C_CHAR;
414 } else
415 cflags = PRINT_C_SHORT;
416 break;
417 case 'l':
418 ch = *format++;
419 if (ch == 'l') { /* It's a long long. */
420 ch = *format++;
421 cflags = PRINT_C_LLONG;
422 } else
423 cflags = PRINT_C_LONG;
424 break;
425 case 'L':
426 cflags = PRINT_C_LDOUBLE;
427 ch = *format++;
428 break;
429 case 'j':
430 cflags = PRINT_C_INTMAX;
431 ch = *format++;
432 break;
433 case 't':
434 cflags = PRINT_C_PTRDIFF;
435 ch = *format++;
436 break;
437 case 'z':
438 cflags = PRINT_C_SIZE;
439 ch = *format++;
440 break;
441 }
442 state = PRINT_S_CONV;
443 break;
444 case PRINT_S_CONV:
445 switch (ch) {
446 case 'd':
447 /* FALLTHROUGH */
448 case 'i':
449 switch (cflags) {
450 case PRINT_C_CHAR:
451 value = (signed char)va_arg(args, int);
452 break;
453 case PRINT_C_SHORT:
454 value = (short int)va_arg(args, int);
455 break;
456 case PRINT_C_LONG:
457 value = va_arg(args, long int);
458 break;
459 case PRINT_C_LLONG:
460 value = va_arg(args, LLONG);
461 break;
462 case PRINT_C_SIZE:
463 value = va_arg(args, SSIZE_T);
464 break;
465 case PRINT_C_INTMAX:
466 value = va_arg(args, INTMAX_T);
467 break;
468 case PRINT_C_PTRDIFF:
469 value = va_arg(args, PTRDIFF_T);
470 break;
471 default:
472 value = va_arg(args, int);
473 break;
474 }
475 fmtint(str, &len, size, value, 10, width,
476 precision, flags);
477 break;
478 case 'X':
479 flags |= PRINT_F_UP;
480 /* FALLTHROUGH */
481 case 'x':
482 base = 16;
483 /* FALLTHROUGH */
484 case 'o':
485 if (base == 0)
486 base = 8;
487 /* FALLTHROUGH */
488 case 'u':
489 if (base == 0)
490 base = 10;
491 flags |= PRINT_F_UNSIGNED;
492 switch (cflags) {
493 case PRINT_C_CHAR:
494 value = (unsigned char)va_arg(args,
495 unsigned int);
496 break;
497 case PRINT_C_SHORT:
498 value = (unsigned short int)va_arg(args,
499 unsigned int);
500 break;
501 case PRINT_C_LONG:
502 value = va_arg(args, unsigned long int);
503 break;
504 case PRINT_C_LLONG:
505 value = va_arg(args, ULLONG);
506 break;
507 case PRINT_C_SIZE:
508 value = va_arg(args, size_t);
509 break;
510 case PRINT_C_INTMAX:
511 value = va_arg(args, UINTMAX_T);
512 break;
513 case PRINT_C_PTRDIFF:
514 value = va_arg(args, UPTRDIFF_T);
515 break;
516 default:
517 value = va_arg(args, unsigned int);
518 break;
519 }
520 fmtint(str, &len, size, value, base, width,
521 precision, flags);
522 break;
523 case 'A':
524 /* Not yet supported, we'll use "%F". */
525 /* FALLTHROUGH */
526 case 'F':
527 flags |= PRINT_F_UP;
528 case 'a':
529 /* Not yet supported, we'll use "%f". */
530 /* FALLTHROUGH */
531 case 'f':
532 if (cflags == PRINT_C_LDOUBLE)
533 fvalue = va_arg(args, LDOUBLE);
534 else
535 fvalue = va_arg(args, double);
536 fmtflt(str, &len, size, fvalue, width,
537 precision, flags, &overflow);
538 if (overflow)
539 goto out;
540 break;
541 case 'E':
542 flags |= PRINT_F_UP;
543 /* FALLTHROUGH */
544 case 'e':
545 flags |= PRINT_F_TYPE_E;
546 if (cflags == PRINT_C_LDOUBLE)
547 fvalue = va_arg(args, LDOUBLE);
548 else
549 fvalue = va_arg(args, double);
550 fmtflt(str, &len, size, fvalue, width,
551 precision, flags, &overflow);
552 if (overflow)
553 goto out;
554 break;
555 case 'G':
556 flags |= PRINT_F_UP;
557 /* FALLTHROUGH */
558 case 'g':
559 flags |= PRINT_F_TYPE_G;
560 if (cflags == PRINT_C_LDOUBLE)
561 fvalue = va_arg(args, LDOUBLE);
562 else
563 fvalue = va_arg(args, double);
564 /*
565 * If the precision is zero, it is treated as
566 * one (cf. C99: 7.19.6.1, 8).
567 */
568 if (precision == 0)
569 precision = 1;
570 fmtflt(str, &len, size, fvalue, width,
571 precision, flags, &overflow);
572 if (overflow)
573 goto out;
574 break;
575 case 'c':
576 cvalue = va_arg(args, int);
577 OUTCHAR(str, len, size, cvalue);
578 break;
579 case 's':
580 strvalue = va_arg(args, char *);
581 fmtstr(str, &len, size, strvalue, width,
582 precision, flags);
583 break;
584 case 'p':
585 /*
586 * C99 says: "The value of the pointer is
587 * converted to a sequence of printing
588 * characters, in an implementation-defined
589 * manner." (C99: 7.19.6.1, 8)
590 */
591 if ((strvalue = va_arg(args, void *)) == NULL)
592 /*
593 * We use the glibc format. BSD prints
594 * "0x0", SysV "0".
595 */
596 fmtstr(str, &len, size, "(nil)", width,
597 -1, flags);
598 else {
599 /*
600 * We use the BSD/glibc format. SysV
601 * omits the "0x" prefix (which we emit
602 * using the PRINT_F_NUM flag).
603 */
604 flags |= PRINT_F_NUM;
605 flags |= PRINT_F_UNSIGNED;
606 fmtint(str, &len, size,
607 (UINTPTR_T)strvalue, 16, width,
608 precision, flags);
609 }
610 break;
611 case 'n':
612 switch (cflags) {
613 case PRINT_C_CHAR:
614 charptr = va_arg(args, signed char *);
615 *charptr = len;
616 break;
617 case PRINT_C_SHORT:
618 shortptr = va_arg(args, short int *);
619 *shortptr = len;
620 break;
621 case PRINT_C_LONG:
622 longptr = va_arg(args, long int *);
623 *longptr = len;
624 break;
625 case PRINT_C_LLONG:
626 llongptr = va_arg(args, LLONG *);
627 *llongptr = len;
628 break;
629 case PRINT_C_SIZE:
630 /*
631 * C99 says that with the "z" length
632 * modifier, "a following `n' conversion
633 * specifier applies to a pointer to a
634 * signed integer type corresponding to
635 * size_t argument." (7.19.6.1, 7)
636 */
637 sizeptr = va_arg(args, SSIZE_T *);
638 *sizeptr = len;
639 break;
640 case PRINT_C_INTMAX:
641 intmaxptr = va_arg(args, INTMAX_T *);
642 *intmaxptr = len;
643 break;
644 case PRINT_C_PTRDIFF:
645 ptrdiffptr = va_arg(args, PTRDIFF_T *);
646 *ptrdiffptr = len;
647 break;
648 default:
649 intptr = va_arg(args, int *);
650 *intptr = len;
651 break;
652 }
653 break;
654 case '%': /* Print a "%" character verbatim. */
655 OUTCHAR(str, len, size, ch);
656 break;
657 default: /* Skip other characters. */
658 break;
659 }
660 ch = *format++;
661 state = PRINT_S_DEFAULT;
662 base = cflags = flags = width = 0;
663 precision = -1;
664 break;
665 }
666 out:
667 if (len < size)
668 str[len] = '\0';
669 else if (size > 0)
670 str[size - 1] = '\0';
671
672 if (overflow || len >= INT_MAX) {
673 errno = overflow ? EOVERFLOW : ERANGE;
674 return -1;
675 }
676 return (int)len;
677 }
678
679 static void
fmtstr(char * str,size_t * len,size_t size,const char * value,int width,int precision,int flags)680 fmtstr(char *str, size_t *len, size_t size, const char *value, int width,
681 int precision, int flags)
682 {
683 int padlen, strln; /* Amount to pad. */
684 int noprecision = (precision == -1);
685
686 if (value == NULL) /* We're forgiving. */
687 value = "(null)";
688
689 /* If a precision was specified, don't read the string past it. */
690 for (strln = 0; value[strln] != '\0' &&
691 (noprecision || strln < precision); strln++)
692 continue;
693
694 if ((padlen = width - strln) < 0)
695 padlen = 0;
696 if (flags & PRINT_F_MINUS) /* Left justify. */
697 padlen = -padlen;
698
699 while (padlen > 0) { /* Leading spaces. */
700 OUTCHAR(str, *len, size, ' ');
701 padlen--;
702 }
703 while (*value != '\0' && (noprecision || precision-- > 0)) {
704 OUTCHAR(str, *len, size, *value);
705 value++;
706 }
707 while (padlen < 0) { /* Trailing spaces. */
708 OUTCHAR(str, *len, size, ' ');
709 padlen++;
710 }
711 }
712
713 static void
fmtint(char * str,size_t * len,size_t size,INTMAX_T value,int base,int width,int precision,int flags)714 fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width,
715 int precision, int flags)
716 {
717 UINTMAX_T uvalue;
718 char iconvert[MAX_CONVERT_LENGTH];
719 char sign = 0;
720 char hexprefix = 0;
721 int spadlen = 0; /* Amount to space pad. */
722 int zpadlen = 0; /* Amount to zero pad. */
723 int pos;
724 int separators = (flags & PRINT_F_QUOTE);
725 int noprecision = (precision == -1);
726
727 if (flags & PRINT_F_UNSIGNED)
728 uvalue = value;
729 else {
730 uvalue = (value >= 0) ? value : -value;
731 if (value < 0)
732 sign = '-';
733 else if (flags & PRINT_F_PLUS) /* Do a sign. */
734 sign = '+';
735 else if (flags & PRINT_F_SPACE)
736 sign = ' ';
737 }
738
739 pos = convert(uvalue, iconvert, sizeof(iconvert), base,
740 flags & PRINT_F_UP);
741
742 if (flags & PRINT_F_NUM && uvalue != 0) {
743 /*
744 * C99 says: "The result is converted to an `alternative form'.
745 * For `o' conversion, it increases the precision, if and only
746 * if necessary, to force the first digit of the result to be a
747 * zero (if the value and precision are both 0, a single 0 is
748 * printed). For `x' (or `X') conversion, a nonzero result has
749 * `0x' (or `0X') prefixed to it." (7.19.6.1, 6)
750 */
751 switch (base) {
752 case 8:
753 if (precision <= pos)
754 precision = pos + 1;
755 break;
756 case 16:
757 hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x';
758 break;
759 }
760 }
761
762 if (separators) /* Get the number of group separators we'll print. */
763 separators = getnumsep(pos);
764
765 zpadlen = precision - pos - separators;
766 spadlen = width /* Minimum field width. */
767 - separators /* Number of separators. */
768 - MAX(precision, pos) /* Number of integer digits. */
769 - ((sign != 0) ? 1 : 0) /* Will we print a sign? */
770 - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */
771
772 if (zpadlen < 0)
773 zpadlen = 0;
774 if (spadlen < 0)
775 spadlen = 0;
776
777 /*
778 * C99 says: "If the `0' and `-' flags both appear, the `0' flag is
779 * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a
780 * precision is specified, the `0' flag is ignored." (7.19.6.1, 6)
781 */
782 if (flags & PRINT_F_MINUS) /* Left justify. */
783 spadlen = -spadlen;
784 else if (flags & PRINT_F_ZERO && noprecision) {
785 zpadlen += spadlen;
786 spadlen = 0;
787 }
788 while (spadlen > 0) { /* Leading spaces. */
789 OUTCHAR(str, *len, size, ' ');
790 spadlen--;
791 }
792 if (sign != 0) /* Sign. */
793 OUTCHAR(str, *len, size, sign);
794 if (hexprefix != 0) { /* A "0x" or "0X" prefix. */
795 OUTCHAR(str, *len, size, '0');
796 OUTCHAR(str, *len, size, hexprefix);
797 }
798 while (zpadlen > 0) { /* Leading zeros. */
799 OUTCHAR(str, *len, size, '0');
800 zpadlen--;
801 }
802 while (pos > 0) { /* The actual digits. */
803 pos--;
804 OUTCHAR(str, *len, size, iconvert[pos]);
805 if (separators > 0 && pos > 0 && pos % 3 == 0)
806 printsep(str, len, size);
807 }
808 while (spadlen < 0) { /* Trailing spaces. */
809 OUTCHAR(str, *len, size, ' ');
810 spadlen++;
811 }
812 }
813
814 static void
fmtflt(char * str,size_t * len,size_t size,LDOUBLE fvalue,int width,int precision,int flags,int * overflow)815 fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width,
816 int precision, int flags, int *overflow)
817 {
818 LDOUBLE ufvalue;
819 UINTMAX_T intpart;
820 UINTMAX_T fracpart;
821 UINTMAX_T mask;
822 const char *infnan = NULL;
823 char iconvert[MAX_CONVERT_LENGTH];
824 char fconvert[MAX_CONVERT_LENGTH];
825 char econvert[4]; /* "e-12" (without nul-termination). */
826 char esign = 0;
827 char sign = 0;
828 int leadfraczeros = 0;
829 int exponent = 0;
830 int emitpoint = 0;
831 int omitzeros = 0;
832 int omitcount = 0;
833 int padlen = 0;
834 int epos = 0;
835 int fpos = 0;
836 int ipos = 0;
837 int separators = (flags & PRINT_F_QUOTE);
838 int estyle = (flags & PRINT_F_TYPE_E);
839 # if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT
840 struct lconv *lc = localeconv();
841 # endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */
842
843 /*
844 * AIX' man page says the default is 0, but C99 and at least Solaris'
845 * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX
846 * defaults to 6.
847 */
848 if (precision == -1)
849 precision = 6;
850
851 if (fvalue < 0.0)
852 sign = '-';
853 else if (flags & PRINT_F_PLUS) /* Do a sign. */
854 sign = '+';
855 else if (flags & PRINT_F_SPACE)
856 sign = ' ';
857
858 if (ISNAN(fvalue))
859 infnan = (flags & PRINT_F_UP) ? "NAN" : "nan";
860 else if (ISINF(fvalue))
861 infnan = (flags & PRINT_F_UP) ? "INF" : "inf";
862
863 if (infnan != NULL) {
864 if (sign != 0)
865 iconvert[ipos++] = sign;
866 while (*infnan != '\0')
867 iconvert[ipos++] = *infnan++;
868 fmtstr(str, len, size, iconvert, width, ipos, flags);
869 return;
870 }
871
872 /* "%e" (or "%E") or "%g" (or "%G") conversion. */
873 if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) {
874 if (flags & PRINT_F_TYPE_G) {
875 /*
876 * For "%g" (and "%G") conversions, the precision
877 * specifies the number of significant digits, which
878 * includes the digits in the integer part. The
879 * conversion will or will not be using "e-style" (like
880 * "%e" or "%E" conversions) depending on the precision
881 * and on the exponent. However, the exponent can be
882 * affected by rounding the converted value, so we'll
883 * leave this decision for later. Until then, we'll
884 * assume that we're going to do an "e-style" conversion
885 * (in order to get the exponent calculated). For
886 * "e-style", the precision must be decremented by one.
887 */
888 precision--;
889 /*
890 * For "%g" (and "%G") conversions, trailing zeros are
891 * removed from the fractional portion of the result
892 * unless the "#" flag was specified.
893 */
894 if (!(flags & PRINT_F_NUM))
895 omitzeros = 1;
896 }
897 exponent = getexponent(fvalue);
898 estyle = 1;
899 }
900
901 again:
902 /*
903 * Sorry, we only support 9, 19, or 38 digits (that is, the number of
904 * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value
905 * minus one) past the decimal point due to our conversion method.
906 */
907 switch (sizeof(UINTMAX_T)) {
908 case 16:
909 if (precision > 38)
910 precision = 38;
911 break;
912 case 8:
913 if (precision > 19)
914 precision = 19;
915 break;
916 default:
917 if (precision > 9)
918 precision = 9;
919 break;
920 }
921
922 ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue;
923 if (estyle) /* We want exactly one integer digit. */
924 ufvalue /= mypow10(exponent);
925
926 if ((intpart = cast(ufvalue)) == UINTMAX_MAX) {
927 *overflow = 1;
928 return;
929 }
930
931 /*
932 * Factor of ten with the number of digits needed for the fractional
933 * part. For example, if the precision is 3, the mask will be 1000.
934 */
935 mask = mypow10(precision);
936 /*
937 * We "cheat" by converting the fractional part to integer by
938 * multiplying by a factor of ten.
939 */
940 if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) {
941 /*
942 * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000
943 * (because precision = 3). Now, myround(1000 * 0.99962) will
944 * return 1000. So, the integer part must be incremented by one
945 * and the fractional part must be set to zero.
946 */
947 intpart++;
948 fracpart = 0;
949 if (estyle && intpart == 10) {
950 /*
951 * The value was rounded up to ten, but we only want one
952 * integer digit if using "e-style". So, the integer
953 * part must be set to one and the exponent must be
954 * incremented by one.
955 */
956 intpart = 1;
957 exponent++;
958 }
959 }
960
961 /*
962 * Now that we know the real exponent, we can check whether or not to
963 * use "e-style" for "%g" (and "%G") conversions. If we don't need
964 * "e-style", the precision must be adjusted and the integer and
965 * fractional parts must be recalculated from the original value.
966 *
967 * C99 says: "Let P equal the precision if nonzero, 6 if the precision
968 * is omitted, or 1 if the precision is zero. Then, if a conversion
969 * with style `E' would have an exponent of X:
970 *
971 * - if P > X >= -4, the conversion is with style `f' (or `F') and
972 * precision P - (X + 1).
973 *
974 * - otherwise, the conversion is with style `e' (or `E') and precision
975 * P - 1." (7.19.6.1, 8)
976 *
977 * Note that we had decremented the precision by one.
978 */
979 if (flags & PRINT_F_TYPE_G && estyle &&
980 precision + 1 > exponent && exponent >= -4) {
981 precision -= exponent;
982 estyle = 0;
983 goto again;
984 }
985
986 if (estyle) {
987 if (exponent < 0) {
988 exponent = -exponent;
989 esign = '-';
990 } else
991 esign = '+';
992
993 /*
994 * Convert the exponent. The sizeof(econvert) is 4. So, the
995 * econvert buffer can hold e.g. "e+99" and "e-99". We don't
996 * support an exponent which contains more than two digits.
997 * Therefore, the following stores are safe.
998 */
999 epos = convert(exponent, econvert, 2, 10, 0);
1000 /*
1001 * C99 says: "The exponent always contains at least two digits,
1002 * and only as many more digits as necessary to represent the
1003 * exponent." (7.19.6.1, 8)
1004 */
1005 if (epos == 1)
1006 econvert[epos++] = '0';
1007 econvert[epos++] = esign;
1008 econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e';
1009 }
1010
1011 /* Convert the integer part and the fractional part. */
1012 ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0);
1013 if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */
1014 fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0);
1015
1016 leadfraczeros = precision - fpos;
1017
1018 if (omitzeros) {
1019 if (fpos > 0) /* Omit trailing fractional part zeros. */
1020 while (omitcount < fpos && fconvert[omitcount] == '0')
1021 omitcount++;
1022 else { /* The fractional part is zero, omit it completely. */
1023 omitcount = precision;
1024 leadfraczeros = 0;
1025 }
1026 precision -= omitcount;
1027 }
1028
1029 /*
1030 * Print a decimal point if either the fractional part is non-zero
1031 * and/or the "#" flag was specified.
1032 */
1033 if (precision > 0 || flags & PRINT_F_NUM)
1034 emitpoint = 1;
1035 if (separators) /* Get the number of group separators we'll print. */
1036 separators = getnumsep(ipos);
1037
1038 padlen = width /* Minimum field width. */
1039 - ipos /* Number of integer digits. */
1040 - epos /* Number of exponent characters. */
1041 - precision /* Number of fractional digits. */
1042 - separators /* Number of group separators. */
1043 - (emitpoint ? 1 : 0) /* Will we print a decimal point? */
1044 - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */
1045
1046 if (padlen < 0)
1047 padlen = 0;
1048
1049 /*
1050 * C99 says: "If the `0' and `-' flags both appear, the `0' flag is
1051 * ignored." (7.19.6.1, 6)
1052 */
1053 if (flags & PRINT_F_MINUS) /* Left justifty. */
1054 padlen = -padlen;
1055 else if (flags & PRINT_F_ZERO && padlen > 0) {
1056 if (sign != 0) { /* Sign. */
1057 OUTCHAR(str, *len, size, sign);
1058 sign = 0;
1059 }
1060 while (padlen > 0) { /* Leading zeros. */
1061 OUTCHAR(str, *len, size, '0');
1062 padlen--;
1063 }
1064 }
1065 while (padlen > 0) { /* Leading spaces. */
1066 OUTCHAR(str, *len, size, ' ');
1067 padlen--;
1068 }
1069 if (sign != 0) /* Sign. */
1070 OUTCHAR(str, *len, size, sign);
1071 while (ipos > 0) { /* Integer part. */
1072 ipos--;
1073 OUTCHAR(str, *len, size, iconvert[ipos]);
1074 if (separators > 0 && ipos > 0 && ipos % 3 == 0)
1075 printsep(str, len, size);
1076 }
1077 if (emitpoint) { /* Decimal point. */
1078 # if HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT
1079 if (lc->decimal_point != NULL && *lc->decimal_point != '\0')
1080 OUTCHAR(str, *len, size, *lc->decimal_point);
1081 else /* We'll always print some decimal point character. */
1082 # endif /* HAVE_LOCALECONV && HAVE_LCONV_DECIMAL_POINT */
1083 OUTCHAR(str, *len, size, '.');
1084 }
1085 while (leadfraczeros > 0) { /* Leading fractional part zeros. */
1086 OUTCHAR(str, *len, size, '0');
1087 leadfraczeros--;
1088 }
1089 while (fpos > omitcount) { /* The remaining fractional part. */
1090 fpos--;
1091 OUTCHAR(str, *len, size, fconvert[fpos]);
1092 }
1093 while (epos > 0) { /* Exponent. */
1094 epos--;
1095 OUTCHAR(str, *len, size, econvert[epos]);
1096 }
1097 while (padlen < 0) { /* Trailing spaces. */
1098 OUTCHAR(str, *len, size, ' ');
1099 padlen++;
1100 }
1101 }
1102
1103 static void
printsep(char * str,size_t * len,size_t size)1104 printsep(char *str, size_t *len, size_t size)
1105 {
1106 # if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP
1107 struct lconv *lc = localeconv();
1108 int i;
1109
1110 if (lc->thousands_sep != NULL)
1111 for (i = 0; lc->thousands_sep[i] != '\0'; i++)
1112 OUTCHAR(str, *len, size, lc->thousands_sep[i]);
1113 else
1114 # endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */
1115 OUTCHAR(str, *len, size, ',');
1116 }
1117
1118 static int
getnumsep(int digits)1119 getnumsep(int digits)
1120 {
1121 int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3;
1122 # if HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP
1123 int strln;
1124 struct lconv *lc = localeconv();
1125
1126 /* We support an arbitrary separator length (including zero). */
1127 if (lc->thousands_sep != NULL) {
1128 for (strln = 0; lc->thousands_sep[strln] != '\0'; strln++)
1129 continue;
1130 separators *= strln;
1131 }
1132 # endif /* HAVE_LOCALECONV && HAVE_LCONV_THOUSANDS_SEP */
1133 return separators;
1134 }
1135
1136 static int
getexponent(LDOUBLE value)1137 getexponent(LDOUBLE value)
1138 {
1139 LDOUBLE tmp = (value >= 0.0) ? value : -value;
1140 int exponent = 0;
1141
1142 /*
1143 * We check for 99 > exponent > -99 in order to work around possible
1144 * endless loops which could happen (at least) in the second loop (at
1145 * least) if we're called with an infinite value. However, we checked
1146 * for infinity before calling this function using our ISINF() macro, so
1147 * this might be somewhat paranoid.
1148 */
1149 while (tmp < 1.0 && tmp > 0.0 && --exponent > -99)
1150 tmp *= 10;
1151 while (tmp >= 10.0 && ++exponent < 99)
1152 tmp /= 10;
1153
1154 return exponent;
1155 }
1156
1157 static int
convert(UINTMAX_T value,char * buf,size_t size,int base,int caps)1158 convert(UINTMAX_T value, char *buf, size_t size, int base, int caps)
1159 {
1160 const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef";
1161 size_t pos = 0;
1162
1163 /* We return an unterminated buffer with the digits in reverse order. */
1164 do {
1165 buf[pos++] = digits[value % base];
1166 value /= base;
1167 } while (value != 0 && pos < size);
1168
1169 return (int)pos;
1170 }
1171
1172 static UINTMAX_T
cast(LDOUBLE value)1173 cast(LDOUBLE value)
1174 {
1175 UINTMAX_T result;
1176
1177 /*
1178 * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be
1179 * represented exactly as an LDOUBLE value (but is less than LDBL_MAX),
1180 * it may be increased to the nearest higher representable value for the
1181 * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE
1182 * value although converting the latter to UINTMAX_T would overflow.
1183 */
1184 if (value >= UINTMAX_MAX)
1185 return UINTMAX_MAX;
1186
1187 result = value;
1188 /*
1189 * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to
1190 * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates
1191 * the standard). Sigh.
1192 */
1193 return (result <= value) ? result : result - 1;
1194 }
1195
1196 static UINTMAX_T
myround(LDOUBLE value)1197 myround(LDOUBLE value)
1198 {
1199 UINTMAX_T intpart = cast(value);
1200
1201 return ((value -= intpart) < 0.5) ? intpart : intpart + 1;
1202 }
1203
1204 static LDOUBLE
mypow10(int exponent)1205 mypow10(int exponent)
1206 {
1207 LDOUBLE result = 1;
1208
1209 while (exponent > 0) {
1210 result *= 10;
1211 exponent--;
1212 }
1213 while (exponent < 0) {
1214 result /= 10;
1215 exponent++;
1216 }
1217 return result;
1218 }
1219 # endif /* !HAVE_VSNPRINTF */
1220
1221 # if !HAVE_VASPRINTF
1222 # if NEED_MYMEMCPY
1223 void *
mymemcpy(void * dst,void * src,size_t len)1224 mymemcpy(void *dst, void *src, size_t len)
1225 {
1226 const char *from = src;
1227 char *to = dst;
1228
1229 /* No need for optimization, we use this only to replace va_copy(3). */
1230 while (len-- > 0)
1231 *to++ = *from++;
1232 return dst;
1233 }
1234 # endif /* NEED_MYMEMCPY */
1235
1236 int
rpl_vasprintf(char ** ret,const char * format,va_list ap)1237 rpl_vasprintf(char **ret, const char *format, va_list ap)
1238 {
1239 size_t size;
1240 int len;
1241 va_list aq;
1242
1243 VA_COPY(aq, ap);
1244 len = vsnprintf(NULL, 0, format, aq);
1245 VA_END_COPY(aq);
1246 if (len < 0 || (*ret = malloc(size = len + 1)) == NULL)
1247 return -1;
1248 return vsnprintf(*ret, size, format, ap);
1249 }
1250 # endif /* !HAVE_VASPRINTF */
1251
1252 # if !HAVE_SNPRINTF
1253 # if HAVE_STDARG_H
1254 int
rpl_snprintf(char * str,size_t size,const char * format,...)1255 rpl_snprintf(char *str, size_t size, const char *format, ...)
1256 # else
1257 int
1258 rpl_snprintf(va_alist) va_dcl
1259 # endif /* HAVE_STDARG_H */
1260 {
1261 # if !HAVE_STDARG_H
1262 char *str;
1263 size_t size;
1264 char *format;
1265 # endif /* HAVE_STDARG_H */
1266 va_list ap;
1267 int len;
1268
1269 VA_START(ap, format);
1270 VA_SHIFT(ap, str, char *);
1271 VA_SHIFT(ap, size, size_t);
1272 VA_SHIFT(ap, format, const char *);
1273 len = vsnprintf(str, size, format, ap);
1274 va_end(ap);
1275 return len;
1276 }
1277 # endif /* !HAVE_SNPRINTF */
1278
1279 # if !HAVE_ASPRINTF
1280 # if HAVE_STDARG_H
1281 int
rpl_asprintf(char ** ret,const char * format,...)1282 rpl_asprintf(char **ret, const char *format, ...)
1283 # else
1284 int
1285 rpl_asprintf(va_alist) va_dcl
1286 # endif /* HAVE_STDARG_H */
1287 {
1288 # if !HAVE_STDARG_H
1289 char **ret;
1290 char *format;
1291 # endif /* HAVE_STDARG_H */
1292 va_list ap;
1293 int len;
1294
1295 VA_START(ap, format);
1296 VA_SHIFT(ap, ret, char **);
1297 VA_SHIFT(ap, format, const char *);
1298 len = vasprintf(ret, format, ap);
1299 va_end(ap);
1300 return len;
1301 }
1302 # endif /* !HAVE_ASPRINTF */
1303 #endif /* !HAVE_SNPRINTF || !HAVE_VSNPRINTF || !HAVE_ASPRINTF || [...] */
1304
1305 /* vim:set joinspaces textwidth=80: */
1306