1*86d7f5d3SJohn Marino /*-
2*86d7f5d3SJohn Marino * Copyright (c) 2005 Poul-Henning Kamp
3*86d7f5d3SJohn Marino * Copyright (c) 1990, 1993
4*86d7f5d3SJohn Marino * The Regents of the University of California. All rights reserved.
5*86d7f5d3SJohn Marino *
6*86d7f5d3SJohn Marino * This code is derived from software contributed to Berkeley by
7*86d7f5d3SJohn Marino * Chris Torek.
8*86d7f5d3SJohn Marino *
9*86d7f5d3SJohn Marino * Redistribution and use in source and binary forms, with or without
10*86d7f5d3SJohn Marino * modification, are permitted provided that the following conditions
11*86d7f5d3SJohn Marino * are met:
12*86d7f5d3SJohn Marino * 1. Redistributions of source code must retain the above copyright
13*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer.
14*86d7f5d3SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
15*86d7f5d3SJohn Marino * notice, this list of conditions and the following disclaimer in the
16*86d7f5d3SJohn Marino * documentation and/or other materials provided with the distribution.
17*86d7f5d3SJohn Marino * 3. Neither the name of the University nor the names of its contributors
18*86d7f5d3SJohn Marino * may be used to endorse or promote products derived from this software
19*86d7f5d3SJohn Marino * without specific prior written permission.
20*86d7f5d3SJohn Marino *
21*86d7f5d3SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22*86d7f5d3SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23*86d7f5d3SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24*86d7f5d3SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25*86d7f5d3SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26*86d7f5d3SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27*86d7f5d3SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28*86d7f5d3SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29*86d7f5d3SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30*86d7f5d3SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*86d7f5d3SJohn Marino * SUCH DAMAGE.
32*86d7f5d3SJohn Marino *
33*86d7f5d3SJohn Marino * $FreeBSD: src/lib/libc/stdio/xprintf_int.c,v 1.2 2005/12/22 14:23:54 cognet Exp $
34*86d7f5d3SJohn Marino */
35*86d7f5d3SJohn Marino
36*86d7f5d3SJohn Marino #include "namespace.h"
37*86d7f5d3SJohn Marino #include <err.h>
38*86d7f5d3SJohn Marino #include <sys/types.h>
39*86d7f5d3SJohn Marino #include <stddef.h>
40*86d7f5d3SJohn Marino #include <stdlib.h>
41*86d7f5d3SJohn Marino #include <stdio.h>
42*86d7f5d3SJohn Marino #include <limits.h>
43*86d7f5d3SJohn Marino #include <locale.h>
44*86d7f5d3SJohn Marino #include <stdint.h>
45*86d7f5d3SJohn Marino #include <assert.h>
46*86d7f5d3SJohn Marino #include <string.h>
47*86d7f5d3SJohn Marino #include <wchar.h>
48*86d7f5d3SJohn Marino #include "un-namespace.h"
49*86d7f5d3SJohn Marino
50*86d7f5d3SJohn Marino #include "printf.h"
51*86d7f5d3SJohn Marino
52*86d7f5d3SJohn Marino /* private stuff -----------------------------------------------------*/
53*86d7f5d3SJohn Marino
54*86d7f5d3SJohn Marino union arg {
55*86d7f5d3SJohn Marino int intarg;
56*86d7f5d3SJohn Marino u_int uintarg;
57*86d7f5d3SJohn Marino long longarg;
58*86d7f5d3SJohn Marino u_long ulongarg;
59*86d7f5d3SJohn Marino intmax_t intmaxarg;
60*86d7f5d3SJohn Marino uintmax_t uintmaxarg;
61*86d7f5d3SJohn Marino };
62*86d7f5d3SJohn Marino
63*86d7f5d3SJohn Marino /*
64*86d7f5d3SJohn Marino * Macros for converting digits to letters and vice versa
65*86d7f5d3SJohn Marino */
66*86d7f5d3SJohn Marino #define to_char(n) ((n) + '0')
67*86d7f5d3SJohn Marino
68*86d7f5d3SJohn Marino /* various globals ---------------------------------------------------*/
69*86d7f5d3SJohn Marino
70*86d7f5d3SJohn Marino /*
71*86d7f5d3SJohn Marino * The size of the buffer we use for integer conversions.
72*86d7f5d3SJohn Marino * Technically, we would need the most space for base 10
73*86d7f5d3SJohn Marino * conversions with thousands' grouping characters between
74*86d7f5d3SJohn Marino * each pair of digits: 60 digits for 128 bit intmax_t.
75*86d7f5d3SJohn Marino * Use a bit more for better alignment of stuff.
76*86d7f5d3SJohn Marino */
77*86d7f5d3SJohn Marino #define BUF 64
78*86d7f5d3SJohn Marino
79*86d7f5d3SJohn Marino /* misc --------------------------------------------------------------*/
80*86d7f5d3SJohn Marino
81*86d7f5d3SJohn Marino /*
82*86d7f5d3SJohn Marino * Convert an unsigned long to ASCII for printf purposes, returning
83*86d7f5d3SJohn Marino * a pointer to the first character of the string representation.
84*86d7f5d3SJohn Marino * Octal numbers can be forced to have a leading zero; hex numbers
85*86d7f5d3SJohn Marino * use the given digits.
86*86d7f5d3SJohn Marino */
87*86d7f5d3SJohn Marino static char *
__ultoa(u_long val,char * endp,int base,const char * xdigs,int needgrp,char thousep,const char * grp)88*86d7f5d3SJohn Marino __ultoa(u_long val, char *endp, int base, const char *xdigs,
89*86d7f5d3SJohn Marino int needgrp, char thousep, const char *grp)
90*86d7f5d3SJohn Marino {
91*86d7f5d3SJohn Marino char *cp = endp;
92*86d7f5d3SJohn Marino long sval;
93*86d7f5d3SJohn Marino int ndig;
94*86d7f5d3SJohn Marino
95*86d7f5d3SJohn Marino /*
96*86d7f5d3SJohn Marino * Handle the three cases separately, in the hope of getting
97*86d7f5d3SJohn Marino * better/faster code.
98*86d7f5d3SJohn Marino */
99*86d7f5d3SJohn Marino switch (base) {
100*86d7f5d3SJohn Marino case 10:
101*86d7f5d3SJohn Marino if (val < 10) { /* many numbers are 1 digit */
102*86d7f5d3SJohn Marino *--cp = to_char(val);
103*86d7f5d3SJohn Marino return (cp);
104*86d7f5d3SJohn Marino }
105*86d7f5d3SJohn Marino ndig = 0;
106*86d7f5d3SJohn Marino /*
107*86d7f5d3SJohn Marino * On many machines, unsigned arithmetic is harder than
108*86d7f5d3SJohn Marino * signed arithmetic, so we do at most one unsigned mod and
109*86d7f5d3SJohn Marino * divide; this is sufficient to reduce the range of
110*86d7f5d3SJohn Marino * the incoming value to where signed arithmetic works.
111*86d7f5d3SJohn Marino */
112*86d7f5d3SJohn Marino if (val > LONG_MAX) {
113*86d7f5d3SJohn Marino *--cp = to_char(val % 10);
114*86d7f5d3SJohn Marino ndig++;
115*86d7f5d3SJohn Marino sval = val / 10;
116*86d7f5d3SJohn Marino } else {
117*86d7f5d3SJohn Marino sval = val;
118*86d7f5d3SJohn Marino }
119*86d7f5d3SJohn Marino do {
120*86d7f5d3SJohn Marino *--cp = to_char(sval % 10);
121*86d7f5d3SJohn Marino ndig++;
122*86d7f5d3SJohn Marino /*
123*86d7f5d3SJohn Marino * If (*grp == CHAR_MAX) then no more grouping
124*86d7f5d3SJohn Marino * should be performed.
125*86d7f5d3SJohn Marino */
126*86d7f5d3SJohn Marino if (needgrp && ndig == *grp && *grp != CHAR_MAX
127*86d7f5d3SJohn Marino && sval > 9) {
128*86d7f5d3SJohn Marino *--cp = thousep;
129*86d7f5d3SJohn Marino ndig = 0;
130*86d7f5d3SJohn Marino /*
131*86d7f5d3SJohn Marino * If (*(grp+1) == '\0') then we have to
132*86d7f5d3SJohn Marino * use *grp character (last grouping rule)
133*86d7f5d3SJohn Marino * for all next cases
134*86d7f5d3SJohn Marino */
135*86d7f5d3SJohn Marino if (*(grp+1) != '\0')
136*86d7f5d3SJohn Marino grp++;
137*86d7f5d3SJohn Marino }
138*86d7f5d3SJohn Marino sval /= 10;
139*86d7f5d3SJohn Marino } while (sval != 0);
140*86d7f5d3SJohn Marino break;
141*86d7f5d3SJohn Marino
142*86d7f5d3SJohn Marino case 8:
143*86d7f5d3SJohn Marino do {
144*86d7f5d3SJohn Marino *--cp = to_char(val & 7);
145*86d7f5d3SJohn Marino val >>= 3;
146*86d7f5d3SJohn Marino } while (val);
147*86d7f5d3SJohn Marino break;
148*86d7f5d3SJohn Marino
149*86d7f5d3SJohn Marino case 16:
150*86d7f5d3SJohn Marino do {
151*86d7f5d3SJohn Marino *--cp = xdigs[val & 15];
152*86d7f5d3SJohn Marino val >>= 4;
153*86d7f5d3SJohn Marino } while (val);
154*86d7f5d3SJohn Marino break;
155*86d7f5d3SJohn Marino
156*86d7f5d3SJohn Marino default: /* oops */
157*86d7f5d3SJohn Marino assert(base == 16);
158*86d7f5d3SJohn Marino }
159*86d7f5d3SJohn Marino return (cp);
160*86d7f5d3SJohn Marino }
161*86d7f5d3SJohn Marino
162*86d7f5d3SJohn Marino
163*86d7f5d3SJohn Marino /* Identical to __ultoa, but for intmax_t. */
164*86d7f5d3SJohn Marino static char *
__ujtoa(uintmax_t val,char * endp,int base,const char * xdigs,int needgrp,char thousep,const char * grp)165*86d7f5d3SJohn Marino __ujtoa(uintmax_t val, char *endp, int base, const char *xdigs,
166*86d7f5d3SJohn Marino int needgrp, char thousep, const char *grp)
167*86d7f5d3SJohn Marino {
168*86d7f5d3SJohn Marino char *cp = endp;
169*86d7f5d3SJohn Marino intmax_t sval;
170*86d7f5d3SJohn Marino int ndig;
171*86d7f5d3SJohn Marino
172*86d7f5d3SJohn Marino switch (base) {
173*86d7f5d3SJohn Marino case 10:
174*86d7f5d3SJohn Marino if (val < 10) {
175*86d7f5d3SJohn Marino *--cp = to_char(val % 10);
176*86d7f5d3SJohn Marino return (cp);
177*86d7f5d3SJohn Marino }
178*86d7f5d3SJohn Marino ndig = 0;
179*86d7f5d3SJohn Marino if (val > INTMAX_MAX) {
180*86d7f5d3SJohn Marino *--cp = to_char(val % 10);
181*86d7f5d3SJohn Marino ndig++;
182*86d7f5d3SJohn Marino sval = val / 10;
183*86d7f5d3SJohn Marino } else {
184*86d7f5d3SJohn Marino sval = val;
185*86d7f5d3SJohn Marino }
186*86d7f5d3SJohn Marino do {
187*86d7f5d3SJohn Marino *--cp = to_char(sval % 10);
188*86d7f5d3SJohn Marino ndig++;
189*86d7f5d3SJohn Marino /*
190*86d7f5d3SJohn Marino * If (*grp == CHAR_MAX) then no more grouping
191*86d7f5d3SJohn Marino * should be performed.
192*86d7f5d3SJohn Marino */
193*86d7f5d3SJohn Marino if (needgrp && *grp != CHAR_MAX && ndig == *grp
194*86d7f5d3SJohn Marino && sval > 9) {
195*86d7f5d3SJohn Marino *--cp = thousep;
196*86d7f5d3SJohn Marino ndig = 0;
197*86d7f5d3SJohn Marino /*
198*86d7f5d3SJohn Marino * If (*(grp+1) == '\0') then we have to
199*86d7f5d3SJohn Marino * use *grp character (last grouping rule)
200*86d7f5d3SJohn Marino * for all next cases
201*86d7f5d3SJohn Marino */
202*86d7f5d3SJohn Marino if (*(grp+1) != '\0')
203*86d7f5d3SJohn Marino grp++;
204*86d7f5d3SJohn Marino }
205*86d7f5d3SJohn Marino sval /= 10;
206*86d7f5d3SJohn Marino } while (sval != 0);
207*86d7f5d3SJohn Marino break;
208*86d7f5d3SJohn Marino
209*86d7f5d3SJohn Marino case 8:
210*86d7f5d3SJohn Marino do {
211*86d7f5d3SJohn Marino *--cp = to_char(val & 7);
212*86d7f5d3SJohn Marino val >>= 3;
213*86d7f5d3SJohn Marino } while (val);
214*86d7f5d3SJohn Marino break;
215*86d7f5d3SJohn Marino
216*86d7f5d3SJohn Marino case 16:
217*86d7f5d3SJohn Marino do {
218*86d7f5d3SJohn Marino *--cp = xdigs[val & 15];
219*86d7f5d3SJohn Marino val >>= 4;
220*86d7f5d3SJohn Marino } while (val);
221*86d7f5d3SJohn Marino break;
222*86d7f5d3SJohn Marino
223*86d7f5d3SJohn Marino default:
224*86d7f5d3SJohn Marino abort();
225*86d7f5d3SJohn Marino }
226*86d7f5d3SJohn Marino return (cp);
227*86d7f5d3SJohn Marino }
228*86d7f5d3SJohn Marino
229*86d7f5d3SJohn Marino
230*86d7f5d3SJohn Marino /* 'd' ---------------------------------------------------------------*/
231*86d7f5d3SJohn Marino
232*86d7f5d3SJohn Marino int
__printf_arginfo_int(const struct printf_info * pi,size_t n,int * argt)233*86d7f5d3SJohn Marino __printf_arginfo_int(const struct printf_info *pi, size_t n, int *argt)
234*86d7f5d3SJohn Marino {
235*86d7f5d3SJohn Marino assert (n > 0);
236*86d7f5d3SJohn Marino argt[0] = PA_INT;
237*86d7f5d3SJohn Marino if (pi->is_ptrdiff)
238*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_PTRDIFF;
239*86d7f5d3SJohn Marino else if (pi->is_size)
240*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_SIZE;
241*86d7f5d3SJohn Marino else if (pi->is_long)
242*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_LONG;
243*86d7f5d3SJohn Marino else if (pi->is_intmax)
244*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_INTMAX;
245*86d7f5d3SJohn Marino else if (pi->is_quad)
246*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_QUAD;
247*86d7f5d3SJohn Marino else if (pi->is_long_double)
248*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_LONG_LONG;
249*86d7f5d3SJohn Marino else if (pi->is_short)
250*86d7f5d3SJohn Marino argt[0] |= PA_FLAG_SHORT;
251*86d7f5d3SJohn Marino else if (pi->is_char)
252*86d7f5d3SJohn Marino argt[0] = PA_CHAR;
253*86d7f5d3SJohn Marino return (1);
254*86d7f5d3SJohn Marino }
255*86d7f5d3SJohn Marino
256*86d7f5d3SJohn Marino int
__printf_render_int(struct __printf_io * io,const struct printf_info * pi,const void * const * arg)257*86d7f5d3SJohn Marino __printf_render_int(struct __printf_io *io, const struct printf_info *pi,
258*86d7f5d3SJohn Marino const void *const *arg)
259*86d7f5d3SJohn Marino {
260*86d7f5d3SJohn Marino const union arg *argp;
261*86d7f5d3SJohn Marino char buf[BUF];
262*86d7f5d3SJohn Marino char *p, *pe;
263*86d7f5d3SJohn Marino char ns, l;
264*86d7f5d3SJohn Marino int rdx, sign, zext, ngrp;
265*86d7f5d3SJohn Marino const char *nalt, *digit;
266*86d7f5d3SJohn Marino char thousands_sep; /* locale specific thousands separator */
267*86d7f5d3SJohn Marino const char *grouping; /* locale specific numeric grouping rules */
268*86d7f5d3SJohn Marino uintmax_t uu;
269*86d7f5d3SJohn Marino int ret;
270*86d7f5d3SJohn Marino
271*86d7f5d3SJohn Marino ret = 0;
272*86d7f5d3SJohn Marino nalt = NULL;
273*86d7f5d3SJohn Marino digit = __lowercase_hex;
274*86d7f5d3SJohn Marino ns = '\0';
275*86d7f5d3SJohn Marino pe = buf + sizeof buf - 1;
276*86d7f5d3SJohn Marino
277*86d7f5d3SJohn Marino if (pi->group) {
278*86d7f5d3SJohn Marino thousands_sep = *(localeconv()->thousands_sep);
279*86d7f5d3SJohn Marino grouping = localeconv()->grouping;
280*86d7f5d3SJohn Marino ngrp = 1;
281*86d7f5d3SJohn Marino } else {
282*86d7f5d3SJohn Marino thousands_sep = 0;
283*86d7f5d3SJohn Marino grouping = NULL;
284*86d7f5d3SJohn Marino ngrp = 0;
285*86d7f5d3SJohn Marino }
286*86d7f5d3SJohn Marino
287*86d7f5d3SJohn Marino switch(pi->spec) {
288*86d7f5d3SJohn Marino case 'd':
289*86d7f5d3SJohn Marino case 'i':
290*86d7f5d3SJohn Marino rdx = 10;
291*86d7f5d3SJohn Marino sign = 1;
292*86d7f5d3SJohn Marino break;
293*86d7f5d3SJohn Marino case 'X':
294*86d7f5d3SJohn Marino digit = __uppercase_hex;
295*86d7f5d3SJohn Marino /*FALLTHOUGH*/
296*86d7f5d3SJohn Marino case 'x':
297*86d7f5d3SJohn Marino rdx = 16;
298*86d7f5d3SJohn Marino sign = 0;
299*86d7f5d3SJohn Marino break;
300*86d7f5d3SJohn Marino case 'u':
301*86d7f5d3SJohn Marino case 'U':
302*86d7f5d3SJohn Marino rdx = 10;
303*86d7f5d3SJohn Marino sign = 0;
304*86d7f5d3SJohn Marino break;
305*86d7f5d3SJohn Marino case 'o':
306*86d7f5d3SJohn Marino case 'O':
307*86d7f5d3SJohn Marino rdx = 8;
308*86d7f5d3SJohn Marino sign = 0;
309*86d7f5d3SJohn Marino break;
310*86d7f5d3SJohn Marino default:
311*86d7f5d3SJohn Marino fprintf(stderr, "pi->spec = '%c'\n", pi->spec);
312*86d7f5d3SJohn Marino assert(1 == 0);
313*86d7f5d3SJohn Marino }
314*86d7f5d3SJohn Marino argp = arg[0];
315*86d7f5d3SJohn Marino
316*86d7f5d3SJohn Marino if (sign)
317*86d7f5d3SJohn Marino ns = pi->showsign;
318*86d7f5d3SJohn Marino
319*86d7f5d3SJohn Marino if (pi->is_long_double || pi->is_quad || pi->is_intmax ||
320*86d7f5d3SJohn Marino pi->is_size || pi->is_ptrdiff) {
321*86d7f5d3SJohn Marino if (sign && argp->intmaxarg < 0) {
322*86d7f5d3SJohn Marino uu = -argp->intmaxarg;
323*86d7f5d3SJohn Marino ns = '-';
324*86d7f5d3SJohn Marino } else {
325*86d7f5d3SJohn Marino uu = argp->uintmaxarg;
326*86d7f5d3SJohn Marino }
327*86d7f5d3SJohn Marino } else if (pi->is_long) {
328*86d7f5d3SJohn Marino if (sign && argp->longarg < 0) {
329*86d7f5d3SJohn Marino uu = (u_long)-argp->longarg;
330*86d7f5d3SJohn Marino ns = '-';
331*86d7f5d3SJohn Marino } else {
332*86d7f5d3SJohn Marino uu = argp->ulongarg;
333*86d7f5d3SJohn Marino }
334*86d7f5d3SJohn Marino } else if (pi->is_short) {
335*86d7f5d3SJohn Marino if (sign && (short)argp->intarg < 0) {
336*86d7f5d3SJohn Marino uu = -(short)argp->intarg;
337*86d7f5d3SJohn Marino ns = '-';
338*86d7f5d3SJohn Marino } else {
339*86d7f5d3SJohn Marino uu = (unsigned short)argp->uintarg;
340*86d7f5d3SJohn Marino }
341*86d7f5d3SJohn Marino } else if (pi->is_char) {
342*86d7f5d3SJohn Marino if (sign && (signed char)argp->intarg < 0) {
343*86d7f5d3SJohn Marino uu = -(signed char)argp->intarg;
344*86d7f5d3SJohn Marino ns = '-';
345*86d7f5d3SJohn Marino } else {
346*86d7f5d3SJohn Marino uu = (unsigned char)argp->uintarg;
347*86d7f5d3SJohn Marino }
348*86d7f5d3SJohn Marino } else {
349*86d7f5d3SJohn Marino if (sign && argp->intarg < 0) {
350*86d7f5d3SJohn Marino uu = (unsigned)-argp->intarg;
351*86d7f5d3SJohn Marino ns = '-';
352*86d7f5d3SJohn Marino } else {
353*86d7f5d3SJohn Marino uu = argp->uintarg;
354*86d7f5d3SJohn Marino }
355*86d7f5d3SJohn Marino }
356*86d7f5d3SJohn Marino if (uu <= ULONG_MAX)
357*86d7f5d3SJohn Marino p = __ultoa(uu, pe, rdx, digit, ngrp, thousands_sep, grouping);
358*86d7f5d3SJohn Marino else
359*86d7f5d3SJohn Marino p = __ujtoa(uu, pe, rdx, digit, ngrp, thousands_sep, grouping);
360*86d7f5d3SJohn Marino
361*86d7f5d3SJohn Marino l = 0;
362*86d7f5d3SJohn Marino if (uu == 0) {
363*86d7f5d3SJohn Marino /*-
364*86d7f5d3SJohn Marino * ``The result of converting a zero value with an
365*86d7f5d3SJohn Marino * explicit precision of zero is no characters.''
366*86d7f5d3SJohn Marino * -- ANSI X3J11
367*86d7f5d3SJohn Marino *
368*86d7f5d3SJohn Marino * ``The C Standard is clear enough as is. The call
369*86d7f5d3SJohn Marino * printf("%#.0o", 0) should print 0.''
370*86d7f5d3SJohn Marino * -- Defect Report #151
371*86d7f5d3SJohn Marino */
372*86d7f5d3SJohn Marino if (pi->prec == 0 && !(pi->alt && rdx == 8))
373*86d7f5d3SJohn Marino p = pe;
374*86d7f5d3SJohn Marino } else if (pi->alt) {
375*86d7f5d3SJohn Marino if (rdx == 8)
376*86d7f5d3SJohn Marino *--p = '0';
377*86d7f5d3SJohn Marino if (rdx == 16) {
378*86d7f5d3SJohn Marino if (pi->spec == 'x')
379*86d7f5d3SJohn Marino nalt = "0x";
380*86d7f5d3SJohn Marino else
381*86d7f5d3SJohn Marino nalt = "0X";
382*86d7f5d3SJohn Marino l += 2;
383*86d7f5d3SJohn Marino }
384*86d7f5d3SJohn Marino }
385*86d7f5d3SJohn Marino l += pe - p;
386*86d7f5d3SJohn Marino if (ns)
387*86d7f5d3SJohn Marino l++;
388*86d7f5d3SJohn Marino
389*86d7f5d3SJohn Marino /*-
390*86d7f5d3SJohn Marino * ``... diouXx conversions ... if a precision is
391*86d7f5d3SJohn Marino * specified, the 0 flag will be ignored.''
392*86d7f5d3SJohn Marino * -- ANSI X3J11
393*86d7f5d3SJohn Marino */
394*86d7f5d3SJohn Marino if (pi->prec > (pe - p))
395*86d7f5d3SJohn Marino zext = pi->prec - (pe - p);
396*86d7f5d3SJohn Marino else if (pi->prec != -1)
397*86d7f5d3SJohn Marino zext = 0;
398*86d7f5d3SJohn Marino else if (pi->pad == '0' && pi->width > l && !pi->left)
399*86d7f5d3SJohn Marino zext = pi->width - l;
400*86d7f5d3SJohn Marino else
401*86d7f5d3SJohn Marino zext = 0;
402*86d7f5d3SJohn Marino
403*86d7f5d3SJohn Marino l += zext;
404*86d7f5d3SJohn Marino
405*86d7f5d3SJohn Marino while (zext > 0 && p > buf) {
406*86d7f5d3SJohn Marino *--p = '0';
407*86d7f5d3SJohn Marino zext--;
408*86d7f5d3SJohn Marino }
409*86d7f5d3SJohn Marino
410*86d7f5d3SJohn Marino if (l < BUF) {
411*86d7f5d3SJohn Marino if (ns) {
412*86d7f5d3SJohn Marino *--p = ns;
413*86d7f5d3SJohn Marino } else if (nalt != NULL) {
414*86d7f5d3SJohn Marino *--p = nalt[1];
415*86d7f5d3SJohn Marino *--p = nalt[0];
416*86d7f5d3SJohn Marino }
417*86d7f5d3SJohn Marino if (pi->width > (pe - p) && !pi->left) {
418*86d7f5d3SJohn Marino l = pi->width - (pe - p);
419*86d7f5d3SJohn Marino while (l > 0 && p > buf) {
420*86d7f5d3SJohn Marino *--p = ' ';
421*86d7f5d3SJohn Marino l--;
422*86d7f5d3SJohn Marino }
423*86d7f5d3SJohn Marino if (l)
424*86d7f5d3SJohn Marino ret += __printf_pad(io, l, 0);
425*86d7f5d3SJohn Marino }
426*86d7f5d3SJohn Marino } else {
427*86d7f5d3SJohn Marino if (!pi->left && pi->width > l)
428*86d7f5d3SJohn Marino ret += __printf_pad(io, pi->width - l, 0);
429*86d7f5d3SJohn Marino if (ns != '\0')
430*86d7f5d3SJohn Marino ret += __printf_puts(io, &ns, 1);
431*86d7f5d3SJohn Marino else if (nalt != NULL)
432*86d7f5d3SJohn Marino ret += __printf_puts(io, nalt, 2);
433*86d7f5d3SJohn Marino if (zext > 0)
434*86d7f5d3SJohn Marino ret += __printf_pad(io, zext, 1);
435*86d7f5d3SJohn Marino }
436*86d7f5d3SJohn Marino
437*86d7f5d3SJohn Marino ret += __printf_puts(io, p, pe - p);
438*86d7f5d3SJohn Marino if (pi->width > ret && pi->left)
439*86d7f5d3SJohn Marino ret += __printf_pad(io, pi->width - ret, 0);
440*86d7f5d3SJohn Marino __printf_flush(io);
441*86d7f5d3SJohn Marino return (ret);
442*86d7f5d3SJohn Marino }
443*86d7f5d3SJohn Marino
444*86d7f5d3SJohn Marino /* 'p' ---------------------------------------------------------------*/
445*86d7f5d3SJohn Marino
446*86d7f5d3SJohn Marino int
__printf_arginfo_ptr(const struct printf_info * pi __unused,size_t n,int * argt)447*86d7f5d3SJohn Marino __printf_arginfo_ptr(const struct printf_info *pi __unused, size_t n, int *argt)
448*86d7f5d3SJohn Marino {
449*86d7f5d3SJohn Marino
450*86d7f5d3SJohn Marino assert (n > 0);
451*86d7f5d3SJohn Marino argt[0] = PA_POINTER;
452*86d7f5d3SJohn Marino return (1);
453*86d7f5d3SJohn Marino }
454*86d7f5d3SJohn Marino
455*86d7f5d3SJohn Marino int
__printf_render_ptr(struct __printf_io * io,const struct printf_info * pi,const void * const * arg)456*86d7f5d3SJohn Marino __printf_render_ptr(struct __printf_io *io, const struct printf_info *pi,
457*86d7f5d3SJohn Marino const void *const *arg)
458*86d7f5d3SJohn Marino {
459*86d7f5d3SJohn Marino struct printf_info p2;
460*86d7f5d3SJohn Marino uintmax_t u;
461*86d7f5d3SJohn Marino const void *p;
462*86d7f5d3SJohn Marino
463*86d7f5d3SJohn Marino /*-
464*86d7f5d3SJohn Marino * ``The argument shall be a pointer to void. The
465*86d7f5d3SJohn Marino * value of the pointer is converted to a sequence
466*86d7f5d3SJohn Marino * of printable characters, in an implementation-
467*86d7f5d3SJohn Marino * defined manner.''
468*86d7f5d3SJohn Marino * -- ANSI X3J11
469*86d7f5d3SJohn Marino */
470*86d7f5d3SJohn Marino u = (uintmax_t)(uintptr_t) *((void **)arg[0]);
471*86d7f5d3SJohn Marino p2 = *pi;
472*86d7f5d3SJohn Marino
473*86d7f5d3SJohn Marino p2.spec = 'x';
474*86d7f5d3SJohn Marino p2.alt = 1;
475*86d7f5d3SJohn Marino p2.is_long_double = 1;
476*86d7f5d3SJohn Marino p = &u;
477*86d7f5d3SJohn Marino return (__printf_render_int(io, &p2, &p));
478*86d7f5d3SJohn Marino }
479