]>
git.saurik.com Git - apple/libc.git/blob - stdio/FreeBSD/xprintf_int.c
2 * Copyright (c) 2005 Poul-Henning Kamp
3 * Copyright (c) 1990, 1993
4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * $FreeBSD: src/lib/libc/stdio/xprintf_int.c,v 1.2 2005/12/22 14:23:54 cognet Exp $
36 #include <namespace.h>
38 #include <sys/types.h>
46 #include <namespace.h>
49 #include <un-namespace.h>
52 #include "xprintf_private.h"
54 /* private stuff -----------------------------------------------------*/
66 * Macros for converting digits to letters and vice versa
68 #define to_char(n) ((n) + '0')
70 /* various globals ---------------------------------------------------*/
73 * The size of the buffer we use for integer conversions.
74 * Technically, we would need the most space for base 10
75 * conversions with thousands' grouping characters between
76 * each pair of digits: 39 digits for 128 bit intmax_t plus
77 * 20 grouping characters (which may be multibyte).
78 * Use a bit more for better alignment of stuff.
82 /* misc --------------------------------------------------------------*/
84 extern const char *__fix_nogrouping(const char *str
);
87 * Convert an unsigned long to ASCII for printf purposes, returning
88 * a pointer to the first character of the string representation.
89 * Octal numbers can be forced to have a leading zero; hex numbers
90 * use the given digits.
93 __ultoa(u_long val
, char *endp
, int base
, const char *xdigs
,
94 int needgrp
, const char *thousep
, int thousep_len
, const char *grp
)
101 * Handle the three cases separately, in the hope of getting
102 * better/faster code.
106 if (val
< 10) { /* many numbers are 1 digit */
107 *--cp
= to_char(val
);
112 * On many machines, unsigned arithmetic is harder than
113 * signed arithmetic, so we do at most one unsigned mod and
114 * divide; this is sufficient to reduce the range of
115 * the incoming value to where signed arithmetic works.
117 if (val
> LONG_MAX
) {
118 *--cp
= to_char(val
% 10);
124 *--cp
= to_char(sval
% 10);
127 * If (*grp == CHAR_MAX) then no more grouping
128 * should be performed.
130 if (needgrp
&& ndig
== *grp
&& *grp
!= CHAR_MAX
133 memcpy(cp
, thousep
, thousep_len
);
136 * If (*(grp+1) == '\0') then we have to
137 * use *grp character (last grouping rule)
140 if (*(grp
+1) != '\0')
149 *--cp
= to_char(val
& 7);
156 *--cp
= xdigs
[val
& 15];
168 /* Identical to __ultoa, but for intmax_t. */
170 __ujtoa(uintmax_t val
, char *endp
, int base
, const char *xdigs
,
171 int needgrp
, const char *thousep
, int thousep_len
, const char *grp
)
180 *--cp
= to_char(val
% 10);
184 if (val
> INTMAX_MAX
) {
185 *--cp
= to_char(val
% 10);
191 *--cp
= to_char(sval
% 10);
194 * If (*grp == CHAR_MAX) then no more grouping
195 * should be performed.
197 if (needgrp
&& *grp
!= CHAR_MAX
&& ndig
== *grp
200 memcpy(cp
, thousep
, thousep_len
);
203 * If (*(grp+1) == '\0') then we have to
204 * use *grp character (last grouping rule)
207 if (*(grp
+1) != '\0')
216 *--cp
= to_char(val
& 7);
223 *--cp
= xdigs
[val
& 15];
235 /* 'd' ---------------------------------------------------------------*/
237 __private_extern__
int
238 __printf_arginfo_int(const struct printf_info
*pi
, size_t n
, int *argt
)
248 argt
[0] |= PA_FLAG_PTRDIFF
;
249 else if (pi
->is_size
)
250 argt
[0] |= PA_FLAG_SIZE
;
251 else if (pi
->is_long
)
252 argt
[0] |= PA_FLAG_LONG
;
253 else if (pi
->is_intmax
)
254 argt
[0] |= PA_FLAG_INTMAX
;
255 else if (pi
->is_quad
)
256 argt
[0] |= PA_FLAG_QUAD
;
257 else if (pi
->is_long_double
)
258 argt
[0] |= PA_FLAG_LONG_LONG
;
259 else if (pi
->is_short
)
260 argt
[0] |= PA_FLAG_SHORT
;
261 else if (pi
->is_char
)
266 __private_extern__
int
267 __printf_render_int(struct __printf_io
*io
, const struct printf_info
*pi
, const void *const *arg
)
269 const union arg
*argp
;
273 int rdx
, sign
, zext
, ngrp
;
274 const char *nalt
, *digit
;
275 const char *thousands_sep
; /* locale specific thousands separator */
276 int thousands_sep_len
; /* locale specific thousands separator length */
277 const char *grouping
; /* locale specific numeric grouping rules */
282 if (pi
->is_vec
) return __xprintf_vector(io
, pi
, arg
);
287 digit
= __lowercase_hex
;
289 pe
= buf
+ sizeof buf
- 1;
292 thousands_sep
= localeconv_l(pi
->loc
)->thousands_sep
;
293 thousands_sep_len
= strlen(thousands_sep
);
294 grouping
= __fix_nogrouping(localeconv_l(pi
->loc
)->grouping
);
297 thousands_sep
= NULL
;
298 thousands_sep_len
= 0;
310 digit
= __uppercase_hex
;
327 fprintf(stderr
, "pi->spec = '%c'\n", pi
->spec
);
335 if (pi
->is_long_double
|| pi
->is_quad
|| pi
->is_intmax
||
336 pi
->is_size
|| pi
->is_ptrdiff
) {
337 if (sign
&& argp
->intmaxarg
< 0) {
338 uu
= -argp
->intmaxarg
;
341 uu
= argp
->uintmaxarg
;
342 } else if (pi
->is_long
) {
343 if (sign
&& argp
->longarg
< 0) {
344 uu
= (u_long
)-argp
->longarg
;
348 } else if (pi
->is_short
) {
349 if (sign
&& (short)argp
->intarg
< 0) {
350 uu
= -(short)argp
->intarg
;
353 uu
= (unsigned short)argp
->uintarg
;
354 } else if (pi
->is_char
) {
355 if (sign
&& (signed char)argp
->intarg
< 0) {
356 uu
= -(signed char)argp
->intarg
;
359 uu
= (unsigned char)argp
->uintarg
;
361 if (sign
&& argp
->intarg
< 0) {
362 uu
= (unsigned)-argp
->intarg
;
368 p
= __ultoa(uu
, pe
, rdx
, digit
, ngrp
, thousands_sep
, thousands_sep_len
, grouping
);
370 p
= __ujtoa(uu
, pe
, rdx
, digit
, ngrp
, thousands_sep
, thousands_sep_len
, grouping
);
375 * ``The result of converting a zero value with an
376 * explicit precision of zero is no characters.''
379 * ``The C Standard is clear enough as is. The call
380 * printf("%#.0o", 0) should print 0.''
381 * -- Defect Report #151
384 if (pi
->prec
== 0 && !(pi
->alt
&& rdx
== 8))
386 } else if (pi
->alt
) {
402 * ``... diouXx conversions ... if a precision is
403 * specified, the 0 flag will be ignored.''
406 if (pi
->prec
> (pe
- p
))
407 zext
= pi
->prec
- (pe
- p
);
408 else if (pi
->prec
!= -1)
410 else if (pi
->pad
== '0' && pi
->width
> l
&& !pi
->left
)
411 zext
= pi
->width
- l
;
417 while (zext
> 0 && p
> buf
) {
425 } else if (nalt
!= NULL
) {
429 if (pi
->width
> (pe
- p
) && !pi
->left
) {
430 l
= pi
->width
- (pe
- p
);
431 while (l
> 0 && p
> buf
) {
436 ret
+= __printf_pad(io
, l
, 0);
439 if (!pi
->left
&& pi
->width
> l
)
440 ret
+= __printf_pad(io
, pi
->width
- l
, 0);
442 ret
+= __printf_puts(io
, &ns
, 1);
443 else if (nalt
!= NULL
)
444 ret
+= __printf_puts(io
, nalt
, 2);
446 ret
+= __printf_pad(io
, zext
, 1);
449 ret
+= __printf_puts(io
, p
, pe
- p
);
450 if (pi
->width
> ret
&& pi
->left
)
451 ret
+= __printf_pad(io
, pi
->width
- ret
, 0);
456 /* 'p' ---------------------------------------------------------------*/
458 __private_extern__
int
459 __printf_arginfo_ptr(const struct printf_info
*pi __unused
, size_t n
, int *argt
)
468 argt
[0] = PA_POINTER
;
472 __private_extern__
int
473 __printf_render_ptr(struct __printf_io
*io
, const struct printf_info
*pi
, const void *const *arg
)
475 struct printf_info p2
;
480 if (pi
->is_vec
) return __xprintf_vector(io
, pi
, arg
);
484 * ``The argument shall be a pointer to void. The
485 * value of the pointer is converted to a sequence
486 * of printable characters, in an implementation-
490 u
= (uintmax_t)(uintptr_t) *((void **)arg
[0]);
495 p2
.is_long_double
= 1;
497 return (__printf_render_int(io
, &p2
, &p
));