1/* 2 * Copyright (c) 1999-2005, 2008, 2010 3 * Todd C. Miller <Todd.Miller@courtesan.com> 4 * Copyright (c) 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Chris Torek. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * From: @(#)vfprintf.c 8.1 (Berkeley) 6/4/93 35 */ 36 37/* 38 * v?snprintf/v?asprintf based on 4.4BSD stdio. 39 * NOTE: does not support floating point. 40 */ 41 42#include <config.h> 43 44#include <sys/types.h> 45#include <sys/param.h> 46 47#include <stdio.h> 48#ifdef STDC_HEADERS 49# include <stdlib.h> 50# include <stddef.h> 51#else 52# ifdef HAVE_STDLIB_H 53# include <stdlib.h> 54# endif 55#endif /* STDC_HEADERS */ 56#ifdef HAVE_STDINT_H 57# include <stdint.h> 58#endif 59#ifdef HAVE_STRING_H 60# if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS) 61# include <memory.h> 62# endif 63# include <string.h> 64#endif /* HAVE_STRING_H */ 65#ifdef HAVE_STRINGS_H 66# include <strings.h> 67#endif /* HAVE_STRINGS_H */ 68#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS) 69# include <malloc.h> 70#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ 71#include <limits.h> 72 73#ifdef __STDC__ 74# include <stdarg.h> 75#else 76# include <varargs.h> 77#endif 78 79#include "missing.h" 80 81static int xxxprintf __P((char **, size_t, int, const char *, va_list)); 82 83/* 84 * Some systems may not have these defined in <limits.h> 85 */ 86#ifndef ULONG_MAX 87# define ULONG_MAX ((unsigned long)-1) 88#endif 89#ifndef LONG_MAX 90# define LONG_MAX (ULONG_MAX / 2) 91#endif 92#ifdef HAVE_LONG_LONG_INT 93# ifndef ULLONG_MAX 94# ifdef UQUAD_MAX 95# define ULLONG_MAX UQUAD_MAX 96# else 97# define ULLONG_MAX ((unsigned long long)-1) 98# endif 99# endif 100# ifndef LLONG_MAX 101# ifdef QUAD_MAX 102# define LLONG_MAX QUAD_MAX 103# else 104# define LLONG_MAX (ULLONG_MAX / 2) 105# endif 106# endif 107#endif /* HAVE_LONG_LONG_INT */ 108 109/* 110 * Macros for converting digits to letters and vice versa 111 */ 112#define to_digit(c) ((c) - '0') 113#define is_digit(c) ((unsigned int)to_digit(c) <= 9) 114#define to_char(n) ((n) + '0') 115 116/* 117 * Flags used during conversion. 118 */ 119#define ALT 0x001 /* alternate form */ 120#define HEXPREFIX 0x002 /* add 0x or 0X prefix */ 121#define LADJUST 0x004 /* left adjustment */ 122#define LONGDBL 0x008 /* long double; unimplemented */ 123#define LONGINT 0x010 /* long integer */ 124#define QUADINT 0x020 /* quad integer */ 125#define SHORTINT 0x040 /* short integer */ 126#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ 127 128#define BUF 68 129 130#ifndef HAVE_MEMCHR 131void * 132memchr(s, c, n) 133 const void *s; 134 unsigned char c; 135 size_t n; 136{ 137 if (n != 0) { 138 const unsigned char *p = s; 139 140 do { 141 if (*p++ == c) 142 return (void *)(p - 1); 143 } while (--n != 0); 144 } 145 return NULL; 146} 147#endif /* !HAVE_MEMCHR */ 148 149/* 150 * Convert an unsigned long to ASCII for printf purposes, returning 151 * a pointer to the first character of the string representation. 152 * Octal numbers can be forced to have a leading zero; hex numbers 153 * use the given digits. 154 */ 155static char * 156__ultoa(val, endp, base, octzero, xdigs) 157 unsigned long val; 158 char *endp; 159 int base, octzero; 160 char *xdigs; 161{ 162 char *cp = endp; 163 long sval; 164 165 /* 166 * Handle the three cases separately, in the hope of getting 167 * better/faster code. 168 */ 169 switch (base) { 170 case 10: 171 if (val < 10) { /* many numbers are 1 digit */ 172 *--cp = to_char(val); 173 return cp; 174 } 175 /* 176 * On many machines, unsigned arithmetic is harder than 177 * signed arithmetic, so we do at most one unsigned mod and 178 * divide; this is sufficient to reduce the range of 179 * the incoming value to where signed arithmetic works. 180 */ 181 if (val > LONG_MAX) { 182 *--cp = to_char(val % 10); 183 sval = val / 10; 184 } else 185 sval = val; 186 do { 187 *--cp = to_char(sval % 10); 188 sval /= 10; 189 } while (sval != 0); 190 break; 191 192 case 8: 193 do { 194 *--cp = to_char(val & 7); 195 val >>= 3; 196 } while (val); 197 if (octzero && *cp != '0') 198 *--cp = '0'; 199 break; 200 201 case 16: 202 do { 203 *--cp = xdigs[val & 15]; 204 val >>= 4; 205 } while (val); 206 break; 207 208 default: /* oops */ 209 abort(); 210 } 211 return cp; 212} 213 214/* Identical to __ultoa, but for quads. */ 215#ifdef HAVE_LONG_LONG_INT 216# if SIZEOF_LONG_INT == 8 217# define __uqtoa(v, e, b, o, x) __ultoa((unsigned long)(v), (e), (b), (o), (x)) 218# else 219static char * 220__uqtoa(val, endp, base, octzero, xdigs) 221 unsigned long long val; 222 char *endp; 223 int base, octzero; 224 char *xdigs; 225{ 226 char *cp = endp; 227 long long sval; 228 229 /* quick test for small values; __ultoa is typically much faster */ 230 /* (perhaps instead we should run until small, then call __ultoa?) */ 231 if (val <= (unsigned long long)ULONG_MAX) 232 return __ultoa((unsigned long)val, endp, base, octzero, xdigs); 233 switch (base) { 234 case 10: 235 if (val < 10) { 236 *--cp = to_char(val % 10); 237 return cp; 238 } 239 if (val > LLONG_MAX) { 240 *--cp = to_char(val % 10); 241 sval = val / 10; 242 } else 243 sval = val; 244 do { 245 *--cp = to_char(sval % 10); 246 sval /= 10; 247 } while (sval != 0); 248 break; 249 250 case 8: 251 do { 252 *--cp = to_char(val & 7); 253 val >>= 3; 254 } while (val); 255 if (octzero && *cp != '0') 256 *--cp = '0'; 257 break; 258 259 case 16: 260 do { 261 *--cp = xdigs[val & 15]; 262 val >>= 4; 263 } while (val); 264 break; 265 266 default: /* oops */ 267 abort(); 268 } 269 return cp; 270} 271# endif /* !SIZEOF_LONG_INT */ 272#endif /* HAVE_LONG_LONG_INT */ 273 274/* 275 * Actual printf innards. 276 */ 277static int 278xxxprintf(strp, strsize, alloc, fmt0, ap) 279 char **strp; 280 size_t strsize; 281 int alloc; 282 const char *fmt0; 283 va_list ap; 284{ 285 char *fmt; /* format string */ 286 int ch; /* character from fmt */ 287 int n; /* handy integer (short term usage) */ 288 char *cp; /* handy char pointer (short term usage) */ 289 int flags; /* flags as above */ 290 int ret; /* return value accumulator */ 291 int width; /* width from format (%8d), or 0 */ 292 int prec; /* precision from format (%.3d), or -1 */ 293 char sign; /* sign prefix (' ', '+', '-', or \0) */ 294 unsigned long ulval = 0; /* integer arguments %[diouxX] */ 295#ifdef HAVE_LONG_LONG_INT 296 unsigned long long uqval = 0; /* %q (quad) integers */ 297#endif 298 int base; /* base for [diouxX] conversion */ 299 int dprec; /* a copy of prec if [diouxX], 0 otherwise */ 300 int fieldsz; /* field size expanded by sign, etc */ 301 int realsz; /* field size expanded by dprec */ 302 int size; /* size of converted field or string */ 303 char *xdigs = ""; /* digits for [xX] conversion */ 304 char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ 305 char ox[2]; /* space for 0x hex-prefix */ 306 char *str; /* pointer to string to fill */ 307 char *estr; /* pointer to last char in str */ 308 309 /* 310 * Choose PADSIZE to trade efficiency vs. size. If larger printf 311 * fields occur frequently, increase PADSIZE and make the initialisers 312 * below longer. 313 */ 314#define PADSIZE 16 /* pad chunk size */ 315 static char blanks[PADSIZE] = 316 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 317 static char zeroes[PADSIZE] = 318 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 319 320 /* Print chars to "str", (allocate as needed if alloc is set). */ 321#define PRINT(ptr, len) do { \ 322 const char *p = ptr; \ 323 const char *endp = ptr + len; \ 324 while (p < endp && (str < estr || alloc)) { \ 325 if (alloc && str >= estr) { \ 326 char *t; \ 327 strsize = (strsize << 1) + 1; \ 328 if (!(t = (char *)realloc(*strp, strsize))) { \ 329 free(str); \ 330 *strp = NULL; \ 331 ret = -1; \ 332 goto done; \ 333 } \ 334 str = t + (str - *strp); \ 335 estr = t + strsize - 1; \ 336 *strp = t; \ 337 } \ 338 *str++ = *p++; \ 339 } \ 340} while (0) 341 342 /* BEWARE, PAD uses `n'. */ 343#define PAD(plen, pstr) do { \ 344 if ((n = (plen)) > 0) { \ 345 while (n > PADSIZE) { \ 346 PRINT(pstr, PADSIZE); \ 347 n -= PADSIZE; \ 348 } \ 349 PRINT(pstr, n); \ 350 } \ 351} while (0) 352 353 /* 354 * To extend shorts properly, we need both signed and unsigned 355 * argument extraction methods. 356 */ 357#define SARG() \ 358 (flags&LONGINT ? va_arg(ap, long) : \ 359 flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ 360 (long)va_arg(ap, int)) 361#define UARG() \ 362 (flags&LONGINT ? va_arg(ap, unsigned long) : \ 363 flags&SHORTINT ? (unsigned long)(unsigned short)va_arg(ap, int) : \ 364 (unsigned long)va_arg(ap, unsigned int)) 365 366 fmt = (char *)fmt0; 367 ret = 0; 368 369 if (alloc) { 370 strsize = 128; 371 *strp = str = (char *)malloc(strsize); 372 if (str == NULL) { 373 ret = -1; 374 goto done; 375 } 376 estr = str + 127; 377 } else { 378 str = *strp; 379 if (strsize) 380 estr = str + strsize - 1; 381 else 382 estr = NULL; 383 } 384 385 /* 386 * Scan the format for conversions (`%' character). 387 */ 388 for (;;) { 389 for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) 390 /* void */; 391 if ((n = fmt - cp) != 0) { 392 PRINT(cp, n); 393 ret += n; 394 } 395 if (ch == '\0') 396 goto done; 397 fmt++; /* skip over '%' */ 398 399 flags = 0; 400 dprec = 0; 401 width = 0; 402 prec = -1; 403 sign = '\0'; 404 405rflag: ch = *fmt++; 406reswitch: switch (ch) { 407 case ' ': 408 /* 409 * ``If the space and + flags both appear, the space 410 * flag will be ignored.'' 411 * -- ANSI X3J11 412 */ 413 if (!sign) 414 sign = ' '; 415 goto rflag; 416 case '#': 417 flags |= ALT; 418 goto rflag; 419 case '*': 420 /* 421 * ``A negative field width argument is taken as a 422 * - flag followed by a positive field width.'' 423 * -- ANSI X3J11 424 * They don't exclude field widths read from args. 425 */ 426 if ((width = va_arg(ap, int)) >= 0) 427 goto rflag; 428 width = -width; 429 /* FALLTHROUGH */ 430 case '-': 431 flags |= LADJUST; 432 goto rflag; 433 case '+': 434 sign = '+'; 435 goto rflag; 436 case '.': 437 if ((ch = *fmt++) == '*') { 438 n = va_arg(ap, int); 439 prec = n < 0 ? -1 : n; 440 goto rflag; 441 } 442 n = 0; 443 while (is_digit(ch)) { 444 n = 10 * n + to_digit(ch); 445 ch = *fmt++; 446 } 447 prec = n < 0 ? -1 : n; 448 goto reswitch; 449 case '0': 450 /* 451 * ``Note that 0 is taken as a flag, not as the 452 * beginning of a field width.'' 453 * -- ANSI X3J11 454 */ 455 flags |= ZEROPAD; 456 goto rflag; 457 case '1': case '2': case '3': case '4': 458 case '5': case '6': case '7': case '8': case '9': 459 n = 0; 460 do { 461 n = 10 * n + to_digit(ch); 462 ch = *fmt++; 463 } while (is_digit(ch)); 464 width = n; 465 goto reswitch; 466 case 'h': 467 flags |= SHORTINT; 468 goto rflag; 469 case 'l': 470 flags |= LONGINT; 471 goto rflag; 472#ifdef HAVE_LONG_LONG_INT 473 case 'q': 474 flags |= QUADINT; 475 goto rflag; 476#endif /* HAVE_LONG_LONG_INT */ 477 case 'c': 478 *(cp = buf) = va_arg(ap, int); 479 size = 1; 480 sign = '\0'; 481 break; 482 case 'D': 483 flags |= LONGINT; 484 /*FALLTHROUGH*/ 485 case 'd': 486 case 'i': 487#ifdef HAVE_LONG_LONG_INT 488 if (flags & QUADINT) { 489 uqval = va_arg(ap, long long); 490 if ((long long)uqval < 0) { 491 uqval = -uqval; 492 sign = '-'; 493 } 494 } 495 else 496#endif /* HAVE_LONG_LONG_INT */ 497 { 498 ulval = SARG(); 499 if ((long)ulval < 0) { 500 ulval = -ulval; 501 sign = '-'; 502 } 503 } 504 base = 10; 505 goto number; 506 case 'n': 507#ifdef HAVE_LONG_LONG_INT 508 if (flags & QUADINT) 509 *va_arg(ap, long long *) = ret; 510 else 511#endif /* HAVE_LONG_LONG_INT */ 512 if (flags & LONGINT) 513 *va_arg(ap, long *) = ret; 514 else if (flags & SHORTINT) 515 *va_arg(ap, short *) = ret; 516 else 517 *va_arg(ap, int *) = ret; 518 continue; /* no output */ 519 case 'O': 520 flags |= LONGINT; 521 /*FALLTHROUGH*/ 522 case 'o': 523#ifdef HAVE_LONG_LONG_INT 524 if (flags & QUADINT) 525 uqval = va_arg(ap, unsigned long long); 526 else 527#endif /* HAVE_LONG_LONG_INT */ 528 ulval = UARG(); 529 base = 8; 530 goto nosign; 531 case 'p': 532 /* 533 * ``The argument shall be a pointer to void. The 534 * value of the pointer is converted to a sequence 535 * of printable characters, in an implementation- 536 * defined manner.'' 537 * -- ANSI X3J11 538 */ 539 ulval = (unsigned long)va_arg(ap, void *); 540 base = 16; 541 xdigs = "0123456789abcdef"; 542 flags = (flags & ~QUADINT) | HEXPREFIX; 543 ch = 'x'; 544 goto nosign; 545 case 's': 546 if ((cp = va_arg(ap, char *)) == NULL) 547 cp = "(null)"; 548 if (prec >= 0) { 549 /* 550 * can't use strlen; can only look for the 551 * NUL in the first `prec' characters, and 552 * strlen() will go further. 553 */ 554 char *p = memchr(cp, 0, prec); 555 556 if (p != NULL) { 557 size = p - cp; 558 if (size > prec) 559 size = prec; 560 } else 561 size = prec; 562 } else 563 size = strlen(cp); 564 sign = '\0'; 565 break; 566 case 'U': 567 flags |= LONGINT; 568 /*FALLTHROUGH*/ 569 case 'u': 570#ifdef HAVE_LONG_LONG_INT 571 if (flags & QUADINT) 572 uqval = va_arg(ap, unsigned long long); 573 else 574#endif /* HAVE_LONG_LONG_INT */ 575 ulval = UARG(); 576 base = 10; 577 goto nosign; 578 case 'X': 579 xdigs = "0123456789ABCDEF"; 580 goto hex; 581 case 'x': 582 xdigs = "0123456789abcdef"; 583hex: 584#ifdef HAVE_LONG_LONG_INT 585 if (flags & QUADINT) 586 uqval = va_arg(ap, unsigned long long); 587 else 588#endif /* HAVE_LONG_LONG_INT */ 589 ulval = UARG(); 590 base = 16; 591 /* leading 0x/X only if non-zero */ 592 if (flags & ALT && 593#ifdef HAVE_LONG_LONG_INT 594 (flags & QUADINT ? uqval != 0 : ulval != 0)) 595#else 596 ulval != 0) 597#endif /* HAVE_LONG_LONG_INT */ 598 flags |= HEXPREFIX; 599 600 /* unsigned conversions */ 601nosign: sign = '\0'; 602 /* 603 * ``... diouXx conversions ... if a precision is 604 * specified, the 0 flag will be ignored.'' 605 * -- ANSI X3J11 606 */ 607number: if ((dprec = prec) >= 0) 608 flags &= ~ZEROPAD; 609 610 /* 611 * ``The result of converting a zero value with an 612 * explicit precision of zero is no characters.'' 613 * -- ANSI X3J11 614 */ 615 cp = buf + BUF; 616#ifdef HAVE_LONG_LONG_INT 617 if (flags & QUADINT) { 618 if (uqval != 0 || prec != 0) 619 cp = __uqtoa(uqval, cp, base, 620 flags & ALT, xdigs); 621 } 622 else 623#endif /* HAVE_LONG_LONG_INT */ 624 { 625 if (ulval != 0 || prec != 0) 626 cp = __ultoa(ulval, cp, base, 627 flags & ALT, xdigs); 628 } 629 size = buf + BUF - cp; 630 break; 631 default: /* "%?" prints ?, unless ? is NUL */ 632 if (ch == '\0') 633 goto done; 634 /* pretend it was %c with argument ch */ 635 cp = buf; 636 *cp = ch; 637 size = 1; 638 sign = '\0'; 639 break; 640 } 641 642 /* 643 * All reasonable formats wind up here. At this point, `cp' 644 * points to a string which (if not flags&LADJUST) should be 645 * padded out to `width' places. If flags&ZEROPAD, it should 646 * first be prefixed by any sign or other prefix; otherwise, 647 * it should be blank padded before the prefix is emitted. 648 * After any left-hand padding and prefixing, emit zeroes 649 * required by a decimal [diouxX] precision, then print the 650 * string proper, then emit zeroes required by any leftover 651 * floating precision; finally, if LADJUST, pad with blanks. 652 * 653 * Compute actual size, so we know how much to pad. 654 * fieldsz excludes decimal prec; realsz includes it. 655 */ 656 fieldsz = size; 657 if (sign) 658 fieldsz++; 659 else if (flags & HEXPREFIX) 660 fieldsz += 2; 661 realsz = dprec > fieldsz ? dprec : fieldsz; 662 663 /* right-adjusting blank padding */ 664 if ((flags & (LADJUST|ZEROPAD)) == 0) 665 PAD(width - realsz, blanks); 666 667 /* prefix */ 668 if (sign) { 669 PRINT(&sign, 1); 670 } else if (flags & HEXPREFIX) { 671 ox[0] = '0'; 672 ox[1] = ch; 673 PRINT(ox, 2); 674 } 675 676 /* right-adjusting zero padding */ 677 if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) 678 PAD(width - realsz, zeroes); 679 680 /* leading zeroes from decimal precision */ 681 PAD(dprec - fieldsz, zeroes); 682 683 /* the string or number proper */ 684 PRINT(cp, size); 685 686 /* left-adjusting padding (always blank) */ 687 if (flags & LADJUST) 688 PAD(width - realsz, blanks); 689 690 /* finally, adjust ret */ 691 ret += width > realsz ? width : realsz; 692 } 693done: 694 if (strsize) 695 *str = '\0'; 696 return ret; 697 /* NOTREACHED */ 698} 699 700#ifndef HAVE_VSNPRINTF 701int 702vsnprintf(str, n, fmt, ap) 703 char *str; 704 size_t n; 705 const char *fmt; 706 va_list ap; 707{ 708 709 return xxxprintf(&str, n, 0, fmt, ap); 710} 711#endif /* HAVE_VSNPRINTF */ 712 713#ifndef HAVE_SNPRINTF 714int 715#ifdef __STDC__ 716snprintf(char *str, size_t n, char const *fmt, ...) 717#else 718snprintf(str, n, fmt, va_alist) 719 char *str; 720 size_t n; 721 char const *fmt; 722 va_dcl 723#endif 724{ 725 int ret; 726 va_list ap; 727 728#ifdef __STDC__ 729 va_start(ap, fmt); 730#else 731 va_start(ap); 732#endif 733 ret = xxxprintf(&str, n, 0, fmt, ap); 734 va_end(ap); 735 return ret; 736} 737#endif /* HAVE_SNPRINTF */ 738 739#ifndef HAVE_VASPRINTF 740int 741vasprintf(str, fmt, ap) 742 char **str; 743 const char *fmt; 744 va_list ap; 745{ 746 747 return xxxprintf(str, 0, 1, fmt, ap); 748} 749#endif /* HAVE_VASPRINTF */ 750 751#ifndef HAVE_ASPRINTF 752int 753#ifdef __STDC__ 754asprintf(char **str, char const *fmt, ...) 755#else 756asprintf(str, fmt, va_alist) 757 char **str; 758 char const *fmt; 759 va_dcl 760#endif 761{ 762 int ret; 763 va_list ap; 764 765#ifdef __STDC__ 766 va_start(ap, fmt); 767#else 768 va_start(ap); 769#endif 770 ret = xxxprintf(str, 0, 1, fmt, ap); 771 va_end(ap); 772 return ret; 773} 774#endif /* HAVE_ASPRINTF */ 775