175067f4fSPoul-Henning Kamp /*- 275067f4fSPoul-Henning Kamp * Copyright (c) 2005 Poul-Henning Kamp 375067f4fSPoul-Henning Kamp * Copyright (c) 1990, 1993 475067f4fSPoul-Henning Kamp * The Regents of the University of California. All rights reserved. 575067f4fSPoul-Henning Kamp * 675067f4fSPoul-Henning Kamp * This code is derived from software contributed to Berkeley by 775067f4fSPoul-Henning Kamp * Chris Torek. 875067f4fSPoul-Henning Kamp * 975067f4fSPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 1075067f4fSPoul-Henning Kamp * modification, are permitted provided that the following conditions 1175067f4fSPoul-Henning Kamp * are met: 1275067f4fSPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 1375067f4fSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 1475067f4fSPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 1575067f4fSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 1675067f4fSPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 1775067f4fSPoul-Henning Kamp * 3. Neither the name of the University nor the names of its contributors 1875067f4fSPoul-Henning Kamp * may be used to endorse or promote products derived from this software 1975067f4fSPoul-Henning Kamp * without specific prior written permission. 2075067f4fSPoul-Henning Kamp * 2175067f4fSPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2275067f4fSPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2375067f4fSPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2475067f4fSPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2575067f4fSPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2675067f4fSPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2775067f4fSPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2875067f4fSPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2975067f4fSPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3075067f4fSPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3175067f4fSPoul-Henning Kamp * SUCH DAMAGE. 3275067f4fSPoul-Henning Kamp * 3375067f4fSPoul-Henning Kamp * $FreeBSD$ 3475067f4fSPoul-Henning Kamp */ 3575067f4fSPoul-Henning Kamp 3675067f4fSPoul-Henning Kamp #include <namespace.h> 3775067f4fSPoul-Henning Kamp #include <err.h> 3875067f4fSPoul-Henning Kamp #include <sys/types.h> 3975067f4fSPoul-Henning Kamp #include <stddef.h> 4075067f4fSPoul-Henning Kamp #include <stdlib.h> 4175067f4fSPoul-Henning Kamp #include <stdio.h> 4275067f4fSPoul-Henning Kamp #include <limits.h> 4375067f4fSPoul-Henning Kamp #include <locale.h> 4475067f4fSPoul-Henning Kamp #include <stdint.h> 4575067f4fSPoul-Henning Kamp #include <assert.h> 4675067f4fSPoul-Henning Kamp #include <namespace.h> 4775067f4fSPoul-Henning Kamp #include <string.h> 4875067f4fSPoul-Henning Kamp #include <wchar.h> 4975067f4fSPoul-Henning Kamp #include <un-namespace.h> 5075067f4fSPoul-Henning Kamp 5175067f4fSPoul-Henning Kamp #include "printf.h" 5275067f4fSPoul-Henning Kamp 5375067f4fSPoul-Henning Kamp /* private stuff -----------------------------------------------------*/ 5475067f4fSPoul-Henning Kamp 5575067f4fSPoul-Henning Kamp union arg { 5675067f4fSPoul-Henning Kamp int intarg; 5775067f4fSPoul-Henning Kamp u_int uintarg; 5875067f4fSPoul-Henning Kamp long longarg; 5975067f4fSPoul-Henning Kamp u_long ulongarg; 6075067f4fSPoul-Henning Kamp intmax_t intmaxarg; 6175067f4fSPoul-Henning Kamp uintmax_t uintmaxarg; 6275067f4fSPoul-Henning Kamp }; 6375067f4fSPoul-Henning Kamp 6475067f4fSPoul-Henning Kamp /* 6575067f4fSPoul-Henning Kamp * Macros for converting digits to letters and vice versa 6675067f4fSPoul-Henning Kamp */ 6775067f4fSPoul-Henning Kamp #define to_char(n) ((n) + '0') 6875067f4fSPoul-Henning Kamp 6975067f4fSPoul-Henning Kamp /* various globals ---------------------------------------------------*/ 7075067f4fSPoul-Henning Kamp 7175067f4fSPoul-Henning Kamp /* 7275067f4fSPoul-Henning Kamp * The size of the buffer we use for integer conversions. 7375067f4fSPoul-Henning Kamp * Technically, we would need the most space for base 10 7475067f4fSPoul-Henning Kamp * conversions with thousands' grouping characters between 7575067f4fSPoul-Henning Kamp * each pair of digits: 60 digits for 128 bit intmax_t. 7675067f4fSPoul-Henning Kamp * Use a bit more for better alignment of stuff. 7775067f4fSPoul-Henning Kamp */ 7875067f4fSPoul-Henning Kamp #define BUF 64 7975067f4fSPoul-Henning Kamp 8075067f4fSPoul-Henning Kamp /* misc --------------------------------------------------------------*/ 8175067f4fSPoul-Henning Kamp 8275067f4fSPoul-Henning Kamp /* 8375067f4fSPoul-Henning Kamp * Convert an unsigned long to ASCII for printf purposes, returning 8475067f4fSPoul-Henning Kamp * a pointer to the first character of the string representation. 8575067f4fSPoul-Henning Kamp * Octal numbers can be forced to have a leading zero; hex numbers 8675067f4fSPoul-Henning Kamp * use the given digits. 8775067f4fSPoul-Henning Kamp */ 8875067f4fSPoul-Henning Kamp static char * 8975067f4fSPoul-Henning Kamp __ultoa(u_long val, char *endp, int base, const char *xdigs, 9075067f4fSPoul-Henning Kamp int needgrp, char thousep, const char *grp) 9175067f4fSPoul-Henning Kamp { 9275067f4fSPoul-Henning Kamp char *cp = endp; 9375067f4fSPoul-Henning Kamp long sval; 9475067f4fSPoul-Henning Kamp int ndig; 9575067f4fSPoul-Henning Kamp 9675067f4fSPoul-Henning Kamp /* 9775067f4fSPoul-Henning Kamp * Handle the three cases separately, in the hope of getting 9875067f4fSPoul-Henning Kamp * better/faster code. 9975067f4fSPoul-Henning Kamp */ 10075067f4fSPoul-Henning Kamp switch (base) { 10175067f4fSPoul-Henning Kamp case 10: 10275067f4fSPoul-Henning Kamp if (val < 10) { /* many numbers are 1 digit */ 10375067f4fSPoul-Henning Kamp *--cp = to_char(val); 10475067f4fSPoul-Henning Kamp return (cp); 10575067f4fSPoul-Henning Kamp } 10675067f4fSPoul-Henning Kamp ndig = 0; 10775067f4fSPoul-Henning Kamp /* 10875067f4fSPoul-Henning Kamp * On many machines, unsigned arithmetic is harder than 10975067f4fSPoul-Henning Kamp * signed arithmetic, so we do at most one unsigned mod and 11075067f4fSPoul-Henning Kamp * divide; this is sufficient to reduce the range of 11175067f4fSPoul-Henning Kamp * the incoming value to where signed arithmetic works. 11275067f4fSPoul-Henning Kamp */ 11375067f4fSPoul-Henning Kamp if (val > LONG_MAX) { 11475067f4fSPoul-Henning Kamp *--cp = to_char(val % 10); 11575067f4fSPoul-Henning Kamp ndig++; 11675067f4fSPoul-Henning Kamp sval = val / 10; 11775067f4fSPoul-Henning Kamp } else 11875067f4fSPoul-Henning Kamp sval = val; 11975067f4fSPoul-Henning Kamp do { 12075067f4fSPoul-Henning Kamp *--cp = to_char(sval % 10); 12175067f4fSPoul-Henning Kamp ndig++; 12275067f4fSPoul-Henning Kamp /* 12375067f4fSPoul-Henning Kamp * If (*grp == CHAR_MAX) then no more grouping 12475067f4fSPoul-Henning Kamp * should be performed. 12575067f4fSPoul-Henning Kamp */ 12675067f4fSPoul-Henning Kamp if (needgrp && ndig == *grp && *grp != CHAR_MAX 12775067f4fSPoul-Henning Kamp && sval > 9) { 12875067f4fSPoul-Henning Kamp *--cp = thousep; 12975067f4fSPoul-Henning Kamp ndig = 0; 13075067f4fSPoul-Henning Kamp /* 13175067f4fSPoul-Henning Kamp * If (*(grp+1) == '\0') then we have to 13275067f4fSPoul-Henning Kamp * use *grp character (last grouping rule) 13375067f4fSPoul-Henning Kamp * for all next cases 13475067f4fSPoul-Henning Kamp */ 13575067f4fSPoul-Henning Kamp if (*(grp+1) != '\0') 13675067f4fSPoul-Henning Kamp grp++; 13775067f4fSPoul-Henning Kamp } 13875067f4fSPoul-Henning Kamp sval /= 10; 13975067f4fSPoul-Henning Kamp } while (sval != 0); 14075067f4fSPoul-Henning Kamp break; 14175067f4fSPoul-Henning Kamp 14275067f4fSPoul-Henning Kamp case 8: 14375067f4fSPoul-Henning Kamp do { 14475067f4fSPoul-Henning Kamp *--cp = to_char(val & 7); 14575067f4fSPoul-Henning Kamp val >>= 3; 14675067f4fSPoul-Henning Kamp } while (val); 14775067f4fSPoul-Henning Kamp break; 14875067f4fSPoul-Henning Kamp 14975067f4fSPoul-Henning Kamp case 16: 15075067f4fSPoul-Henning Kamp do { 15175067f4fSPoul-Henning Kamp *--cp = xdigs[val & 15]; 15275067f4fSPoul-Henning Kamp val >>= 4; 15375067f4fSPoul-Henning Kamp } while (val); 15475067f4fSPoul-Henning Kamp break; 15575067f4fSPoul-Henning Kamp 15675067f4fSPoul-Henning Kamp default: /* oops */ 15775067f4fSPoul-Henning Kamp assert(base == 16); 15875067f4fSPoul-Henning Kamp } 15975067f4fSPoul-Henning Kamp return (cp); 16075067f4fSPoul-Henning Kamp } 16175067f4fSPoul-Henning Kamp 16275067f4fSPoul-Henning Kamp 16375067f4fSPoul-Henning Kamp /* Identical to __ultoa, but for intmax_t. */ 16475067f4fSPoul-Henning Kamp static char * 16575067f4fSPoul-Henning Kamp __ujtoa(uintmax_t val, char *endp, int base, const char *xdigs, 16675067f4fSPoul-Henning Kamp int needgrp, char thousep, const char *grp) 16775067f4fSPoul-Henning Kamp { 16875067f4fSPoul-Henning Kamp char *cp = endp; 16975067f4fSPoul-Henning Kamp intmax_t sval; 17075067f4fSPoul-Henning Kamp int ndig; 17175067f4fSPoul-Henning Kamp 17275067f4fSPoul-Henning Kamp switch (base) { 17375067f4fSPoul-Henning Kamp case 10: 17475067f4fSPoul-Henning Kamp if (val < 10) { 17575067f4fSPoul-Henning Kamp *--cp = to_char(val % 10); 17675067f4fSPoul-Henning Kamp return (cp); 17775067f4fSPoul-Henning Kamp } 17875067f4fSPoul-Henning Kamp ndig = 0; 17975067f4fSPoul-Henning Kamp if (val > INTMAX_MAX) { 18075067f4fSPoul-Henning Kamp *--cp = to_char(val % 10); 18175067f4fSPoul-Henning Kamp ndig++; 18275067f4fSPoul-Henning Kamp sval = val / 10; 18375067f4fSPoul-Henning Kamp } else 18475067f4fSPoul-Henning Kamp sval = val; 18575067f4fSPoul-Henning Kamp do { 18675067f4fSPoul-Henning Kamp *--cp = to_char(sval % 10); 18775067f4fSPoul-Henning Kamp ndig++; 18875067f4fSPoul-Henning Kamp /* 18975067f4fSPoul-Henning Kamp * If (*grp == CHAR_MAX) then no more grouping 19075067f4fSPoul-Henning Kamp * should be performed. 19175067f4fSPoul-Henning Kamp */ 19275067f4fSPoul-Henning Kamp if (needgrp && *grp != CHAR_MAX && ndig == *grp 19375067f4fSPoul-Henning Kamp && sval > 9) { 19475067f4fSPoul-Henning Kamp *--cp = thousep; 19575067f4fSPoul-Henning Kamp ndig = 0; 19675067f4fSPoul-Henning Kamp /* 19775067f4fSPoul-Henning Kamp * If (*(grp+1) == '\0') then we have to 19875067f4fSPoul-Henning Kamp * use *grp character (last grouping rule) 19975067f4fSPoul-Henning Kamp * for all next cases 20075067f4fSPoul-Henning Kamp */ 20175067f4fSPoul-Henning Kamp if (*(grp+1) != '\0') 20275067f4fSPoul-Henning Kamp grp++; 20375067f4fSPoul-Henning Kamp } 20475067f4fSPoul-Henning Kamp sval /= 10; 20575067f4fSPoul-Henning Kamp } while (sval != 0); 20675067f4fSPoul-Henning Kamp break; 20775067f4fSPoul-Henning Kamp 20875067f4fSPoul-Henning Kamp case 8: 20975067f4fSPoul-Henning Kamp do { 21075067f4fSPoul-Henning Kamp *--cp = to_char(val & 7); 21175067f4fSPoul-Henning Kamp val >>= 3; 21275067f4fSPoul-Henning Kamp } while (val); 21375067f4fSPoul-Henning Kamp break; 21475067f4fSPoul-Henning Kamp 21575067f4fSPoul-Henning Kamp case 16: 21675067f4fSPoul-Henning Kamp do { 21775067f4fSPoul-Henning Kamp *--cp = xdigs[val & 15]; 21875067f4fSPoul-Henning Kamp val >>= 4; 21975067f4fSPoul-Henning Kamp } while (val); 22075067f4fSPoul-Henning Kamp break; 22175067f4fSPoul-Henning Kamp 22275067f4fSPoul-Henning Kamp default: 22375067f4fSPoul-Henning Kamp abort(); 22475067f4fSPoul-Henning Kamp } 22575067f4fSPoul-Henning Kamp return (cp); 22675067f4fSPoul-Henning Kamp } 22775067f4fSPoul-Henning Kamp 22875067f4fSPoul-Henning Kamp 22975067f4fSPoul-Henning Kamp /* 'd' ---------------------------------------------------------------*/ 23075067f4fSPoul-Henning Kamp 23175067f4fSPoul-Henning Kamp int 23275067f4fSPoul-Henning Kamp __printf_arginfo_int(const struct printf_info *pi, size_t n, int *argt) 23375067f4fSPoul-Henning Kamp { 23475067f4fSPoul-Henning Kamp assert (n > 0); 23575067f4fSPoul-Henning Kamp argt[0] = PA_INT; 23675067f4fSPoul-Henning Kamp if (pi->is_ptrdiff) 23775067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_PTRDIFF; 23875067f4fSPoul-Henning Kamp else if (pi->is_size) 23975067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_SIZE; 24075067f4fSPoul-Henning Kamp else if (pi->is_long) 24175067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_LONG; 24275067f4fSPoul-Henning Kamp else if (pi->is_intmax) 24375067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_INTMAX; 24475067f4fSPoul-Henning Kamp else if (pi->is_quad) 24575067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_QUAD; 24675067f4fSPoul-Henning Kamp else if (pi->is_long_double) 24775067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_LONG_LONG; 24875067f4fSPoul-Henning Kamp else if (pi->is_short) 24975067f4fSPoul-Henning Kamp argt[0] |= PA_FLAG_SHORT; 25075067f4fSPoul-Henning Kamp else if (pi->is_char) 25175067f4fSPoul-Henning Kamp argt[0] = PA_CHAR; 25275067f4fSPoul-Henning Kamp return (1); 25375067f4fSPoul-Henning Kamp } 25475067f4fSPoul-Henning Kamp 25575067f4fSPoul-Henning Kamp int 25675067f4fSPoul-Henning Kamp __printf_render_int(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) 25775067f4fSPoul-Henning Kamp { 25875067f4fSPoul-Henning Kamp const union arg *argp; 25975067f4fSPoul-Henning Kamp char buf[BUF]; 26075067f4fSPoul-Henning Kamp char *p, *pe; 26175067f4fSPoul-Henning Kamp char ns, l; 26275067f4fSPoul-Henning Kamp int rdx, sign, zext, ngrp; 26375067f4fSPoul-Henning Kamp const char *nalt, *digit; 26475067f4fSPoul-Henning Kamp char thousands_sep; /* locale specific thousands separator */ 26575067f4fSPoul-Henning Kamp const char *grouping; /* locale specific numeric grouping rules */ 26675067f4fSPoul-Henning Kamp uintmax_t uu; 26775067f4fSPoul-Henning Kamp int ret; 26875067f4fSPoul-Henning Kamp 26975067f4fSPoul-Henning Kamp ret = 0; 27075067f4fSPoul-Henning Kamp nalt = NULL; 27175067f4fSPoul-Henning Kamp digit = __lowercase_hex; 27275067f4fSPoul-Henning Kamp ns = '\0'; 27375067f4fSPoul-Henning Kamp pe = buf + sizeof buf - 1; 27475067f4fSPoul-Henning Kamp 27575067f4fSPoul-Henning Kamp if (pi->group) { 27675067f4fSPoul-Henning Kamp thousands_sep = *(localeconv()->thousands_sep); 27775067f4fSPoul-Henning Kamp grouping = localeconv()->grouping; 27875067f4fSPoul-Henning Kamp ngrp = 1; 27975067f4fSPoul-Henning Kamp } else { 28075067f4fSPoul-Henning Kamp thousands_sep = 0; 28175067f4fSPoul-Henning Kamp grouping = NULL; 28275067f4fSPoul-Henning Kamp ngrp = 0; 28375067f4fSPoul-Henning Kamp } 28475067f4fSPoul-Henning Kamp 28575067f4fSPoul-Henning Kamp switch(pi->spec) { 28675067f4fSPoul-Henning Kamp case 'd': 28775067f4fSPoul-Henning Kamp case 'i': 28875067f4fSPoul-Henning Kamp rdx = 10; 28975067f4fSPoul-Henning Kamp sign = 1; 29075067f4fSPoul-Henning Kamp break; 29175067f4fSPoul-Henning Kamp case 'X': 29275067f4fSPoul-Henning Kamp digit = __uppercase_hex; 29375067f4fSPoul-Henning Kamp /*FALLTHOUGH*/ 29475067f4fSPoul-Henning Kamp case 'x': 29575067f4fSPoul-Henning Kamp rdx = 16; 29675067f4fSPoul-Henning Kamp sign = 0; 29775067f4fSPoul-Henning Kamp break; 29875067f4fSPoul-Henning Kamp case 'u': 29975067f4fSPoul-Henning Kamp case 'U': 30075067f4fSPoul-Henning Kamp rdx = 10; 30175067f4fSPoul-Henning Kamp sign = 0; 30275067f4fSPoul-Henning Kamp break; 30375067f4fSPoul-Henning Kamp case 'o': 30475067f4fSPoul-Henning Kamp case 'O': 30575067f4fSPoul-Henning Kamp rdx = 8; 30675067f4fSPoul-Henning Kamp sign = 0; 30775067f4fSPoul-Henning Kamp break; 30875067f4fSPoul-Henning Kamp default: 30975067f4fSPoul-Henning Kamp fprintf(stderr, "pi->spec = '%c'\n", pi->spec); 31075067f4fSPoul-Henning Kamp assert(1 == 0); 31175067f4fSPoul-Henning Kamp } 31275067f4fSPoul-Henning Kamp argp = arg[0]; 31375067f4fSPoul-Henning Kamp 31475067f4fSPoul-Henning Kamp if (sign) 31575067f4fSPoul-Henning Kamp ns = pi->showsign; 31675067f4fSPoul-Henning Kamp 31775067f4fSPoul-Henning Kamp if (pi->is_long_double || pi->is_quad || pi->is_intmax || 31875067f4fSPoul-Henning Kamp pi->is_size || pi->is_ptrdiff) { 31975067f4fSPoul-Henning Kamp if (sign && argp->intmaxarg < 0) { 32075067f4fSPoul-Henning Kamp uu = -argp->intmaxarg; 32175067f4fSPoul-Henning Kamp ns = '-'; 32275067f4fSPoul-Henning Kamp } else 32375067f4fSPoul-Henning Kamp uu = argp->uintmaxarg; 32475067f4fSPoul-Henning Kamp } else if (pi->is_long) { 32575067f4fSPoul-Henning Kamp if (sign && argp->longarg < 0) { 32675067f4fSPoul-Henning Kamp uu = (u_long)-argp->longarg; 32775067f4fSPoul-Henning Kamp ns = '-'; 32875067f4fSPoul-Henning Kamp } else 32975067f4fSPoul-Henning Kamp uu = argp->ulongarg; 33075067f4fSPoul-Henning Kamp } else if (pi->is_short) { 33175067f4fSPoul-Henning Kamp if (sign && (short)argp->intarg < 0) { 33275067f4fSPoul-Henning Kamp uu = -(short)argp->intarg; 33375067f4fSPoul-Henning Kamp ns = '-'; 33475067f4fSPoul-Henning Kamp } else 33575067f4fSPoul-Henning Kamp uu = (unsigned short)argp->uintarg; 33675067f4fSPoul-Henning Kamp } else if (pi->is_char) { 33775067f4fSPoul-Henning Kamp if (sign && (char)argp->intarg < 0) { 33875067f4fSPoul-Henning Kamp uu = -(char)argp->intarg; 33975067f4fSPoul-Henning Kamp ns = '-'; 34075067f4fSPoul-Henning Kamp } else 34175067f4fSPoul-Henning Kamp uu = (unsigned char)argp->uintarg; 34275067f4fSPoul-Henning Kamp } else { 34375067f4fSPoul-Henning Kamp if (sign && argp->intarg < 0) { 34475067f4fSPoul-Henning Kamp uu = (unsigned)-argp->intarg; 34575067f4fSPoul-Henning Kamp ns = '-'; 34675067f4fSPoul-Henning Kamp } else 34775067f4fSPoul-Henning Kamp uu = argp->uintarg; 34875067f4fSPoul-Henning Kamp } 34975067f4fSPoul-Henning Kamp if (uu <= ULONG_MAX) 35075067f4fSPoul-Henning Kamp p = __ultoa(uu, pe, rdx, digit, ngrp, thousands_sep, grouping); 35175067f4fSPoul-Henning Kamp else 35275067f4fSPoul-Henning Kamp p = __ujtoa(uu, pe, rdx, digit, ngrp, thousands_sep, grouping); 35375067f4fSPoul-Henning Kamp 35475067f4fSPoul-Henning Kamp l = 0; 35575067f4fSPoul-Henning Kamp if (uu == 0) { 35675067f4fSPoul-Henning Kamp /*- 35775067f4fSPoul-Henning Kamp * ``The result of converting a zero value with an 35875067f4fSPoul-Henning Kamp * explicit precision of zero is no characters.'' 35975067f4fSPoul-Henning Kamp * -- ANSI X3J11 36075067f4fSPoul-Henning Kamp * 36175067f4fSPoul-Henning Kamp * ``The C Standard is clear enough as is. The call 36275067f4fSPoul-Henning Kamp * printf("%#.0o", 0) should print 0.'' 36375067f4fSPoul-Henning Kamp * -- Defect Report #151 36475067f4fSPoul-Henning Kamp */ 36575067f4fSPoul-Henning Kamp ; 36675067f4fSPoul-Henning Kamp if (pi->prec == 0 && !(pi->alt && rdx == 8)) 36775067f4fSPoul-Henning Kamp p = pe; 36875067f4fSPoul-Henning Kamp } else if (pi->alt) { 36975067f4fSPoul-Henning Kamp if (rdx == 8) 37075067f4fSPoul-Henning Kamp *--p = '0'; 37175067f4fSPoul-Henning Kamp if (rdx == 16) { 37275067f4fSPoul-Henning Kamp if (pi->spec == 'x') 37375067f4fSPoul-Henning Kamp nalt = "0x"; 37475067f4fSPoul-Henning Kamp else 37575067f4fSPoul-Henning Kamp nalt = "0X"; 37675067f4fSPoul-Henning Kamp l += 2; 37775067f4fSPoul-Henning Kamp } 37875067f4fSPoul-Henning Kamp } 37975067f4fSPoul-Henning Kamp l += pe - p; 38075067f4fSPoul-Henning Kamp if (ns) 38175067f4fSPoul-Henning Kamp l++; 38275067f4fSPoul-Henning Kamp 38375067f4fSPoul-Henning Kamp /*- 38475067f4fSPoul-Henning Kamp * ``... diouXx conversions ... if a precision is 38575067f4fSPoul-Henning Kamp * specified, the 0 flag will be ignored.'' 38675067f4fSPoul-Henning Kamp * -- ANSI X3J11 38775067f4fSPoul-Henning Kamp */ 38875067f4fSPoul-Henning Kamp if (pi->prec > (pe - p)) 38975067f4fSPoul-Henning Kamp zext = pi->prec - (pe - p); 39075067f4fSPoul-Henning Kamp else if (pi->prec != -1) 39175067f4fSPoul-Henning Kamp zext = 0; 39275067f4fSPoul-Henning Kamp else if (pi->pad == '0' && pi->width > l && !pi->left) 39375067f4fSPoul-Henning Kamp zext = pi->width - l; 39475067f4fSPoul-Henning Kamp else 39575067f4fSPoul-Henning Kamp zext = 0; 39675067f4fSPoul-Henning Kamp 39775067f4fSPoul-Henning Kamp l += zext; 39875067f4fSPoul-Henning Kamp 39975067f4fSPoul-Henning Kamp while (zext > 0 && p > buf) { 40075067f4fSPoul-Henning Kamp *--p = '0'; 40175067f4fSPoul-Henning Kamp zext--; 40275067f4fSPoul-Henning Kamp } 40375067f4fSPoul-Henning Kamp 40475067f4fSPoul-Henning Kamp if (l < BUF) { 40575067f4fSPoul-Henning Kamp if (ns) { 40675067f4fSPoul-Henning Kamp *--p = ns; 40775067f4fSPoul-Henning Kamp } else if (nalt != NULL) { 40875067f4fSPoul-Henning Kamp *--p = nalt[1]; 40975067f4fSPoul-Henning Kamp *--p = nalt[0]; 41075067f4fSPoul-Henning Kamp } 41175067f4fSPoul-Henning Kamp if (pi->width > (pe - p) && !pi->left) { 41275067f4fSPoul-Henning Kamp l = pi->width - (pe - p); 41375067f4fSPoul-Henning Kamp while (l > 0 && p > buf) { 41475067f4fSPoul-Henning Kamp *--p = ' '; 41575067f4fSPoul-Henning Kamp l--; 41675067f4fSPoul-Henning Kamp } 41775067f4fSPoul-Henning Kamp if (l) 41875067f4fSPoul-Henning Kamp ret += __printf_pad(io, l, 0); 41975067f4fSPoul-Henning Kamp } 42075067f4fSPoul-Henning Kamp } else { 42175067f4fSPoul-Henning Kamp if (!pi->left && pi->width > l) 42275067f4fSPoul-Henning Kamp ret += __printf_pad(io, pi->width - l, 0); 42375067f4fSPoul-Henning Kamp if (ns != '\0') 42475067f4fSPoul-Henning Kamp ret += __printf_puts(io, &ns, 1); 42575067f4fSPoul-Henning Kamp else if (nalt != NULL) 42675067f4fSPoul-Henning Kamp ret += __printf_puts(io, nalt, 2); 42775067f4fSPoul-Henning Kamp if (zext > 0) 42875067f4fSPoul-Henning Kamp ret += __printf_pad(io, zext, 1); 42975067f4fSPoul-Henning Kamp } 43075067f4fSPoul-Henning Kamp 43175067f4fSPoul-Henning Kamp ret += __printf_puts(io, p, pe - p); 43275067f4fSPoul-Henning Kamp if (pi->width > ret && pi->left) 43375067f4fSPoul-Henning Kamp ret += __printf_pad(io, pi->width - ret, 0); 43475067f4fSPoul-Henning Kamp __printf_flush(io); 43575067f4fSPoul-Henning Kamp return (ret); 43675067f4fSPoul-Henning Kamp } 43775067f4fSPoul-Henning Kamp 43875067f4fSPoul-Henning Kamp /* 'p' ---------------------------------------------------------------*/ 43975067f4fSPoul-Henning Kamp 44075067f4fSPoul-Henning Kamp int 44175067f4fSPoul-Henning Kamp __printf_arginfo_ptr(const struct printf_info *pi __unused, size_t n, int *argt) 44275067f4fSPoul-Henning Kamp { 44375067f4fSPoul-Henning Kamp 44475067f4fSPoul-Henning Kamp assert (n > 0); 44575067f4fSPoul-Henning Kamp argt[0] = PA_POINTER; 44675067f4fSPoul-Henning Kamp return (1); 44775067f4fSPoul-Henning Kamp } 44875067f4fSPoul-Henning Kamp 44975067f4fSPoul-Henning Kamp int 45075067f4fSPoul-Henning Kamp __printf_render_ptr(struct __printf_io *io, const struct printf_info *pi, const void *const *arg) 45175067f4fSPoul-Henning Kamp { 45275067f4fSPoul-Henning Kamp struct printf_info p2; 45375067f4fSPoul-Henning Kamp uintmax_t u; 45475067f4fSPoul-Henning Kamp const void *p; 45575067f4fSPoul-Henning Kamp 45675067f4fSPoul-Henning Kamp /*- 45775067f4fSPoul-Henning Kamp * ``The argument shall be a pointer to void. The 45875067f4fSPoul-Henning Kamp * value of the pointer is converted to a sequence 45975067f4fSPoul-Henning Kamp * of printable characters, in an implementation- 46075067f4fSPoul-Henning Kamp * defined manner.'' 46175067f4fSPoul-Henning Kamp * -- ANSI X3J11 46275067f4fSPoul-Henning Kamp */ 46375067f4fSPoul-Henning Kamp u = (uintmax_t)(uintptr_t) *((void **)arg[0]); 46475067f4fSPoul-Henning Kamp p2 = *pi; 46575067f4fSPoul-Henning Kamp 46675067f4fSPoul-Henning Kamp p2.spec = 'x'; 46775067f4fSPoul-Henning Kamp p2.alt = 1; 46875067f4fSPoul-Henning Kamp p2.is_long_double = 1; 46975067f4fSPoul-Henning Kamp p = &u; 47075067f4fSPoul-Henning Kamp return (__printf_render_int(io, &p2, &p)); 47175067f4fSPoul-Henning Kamp } 472