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