printfcommon.h revision 187354
1/*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $FreeBSD: head/lib/libc/stdio/printfcommon.h 187354 2009-01-17 05:38:14Z das $ 33 */ 34 35/* 36 * This file defines common routines used by both printf and wprintf. 37 * You must define CHAR to either char or wchar_t prior to including this. 38 */ 39 40 41#ifndef NO_FLOATING_POINT 42 43#define dtoa __dtoa 44#define freedtoa __freedtoa 45 46#include <float.h> 47#include <math.h> 48#include "floatio.h" 49#include "gdtoa.h" 50 51#define DEFPREC 6 52 53static int exponent(CHAR *, int, CHAR); 54 55#endif /* !NO_FLOATING_POINT */ 56 57static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *, int, char, 58 const char *); 59static CHAR *__ultoa(u_long, CHAR *, int, int, const char *, int, char, 60 const char *); 61 62#define NIOV 8 63struct io_state { 64 FILE *fp; 65 struct __suio uio; /* output information: summary */ 66 struct __siov iov[NIOV];/* ... and individual io vectors */ 67}; 68 69static inline void 70io_init(struct io_state *iop, FILE *fp) 71{ 72 73 iop->uio.uio_iov = iop->iov; 74 iop->uio.uio_resid = 0; 75 iop->uio.uio_iovcnt = 0; 76 iop->fp = fp; 77} 78 79/* 80 * WARNING: The buffer passed to io_print() is not copied immediately; it must 81 * remain valid until io_flush() is called. 82 */ 83static inline int 84io_print(struct io_state *iop, const CHAR * __restrict ptr, int len) 85{ 86 87 iop->iov[iop->uio.uio_iovcnt].iov_base = (char *)ptr; 88 iop->iov[iop->uio.uio_iovcnt].iov_len = len; 89 iop->uio.uio_resid += len; 90 if (++iop->uio.uio_iovcnt >= NIOV) 91 return (__sprint(iop->fp, &iop->uio)); 92 else 93 return (0); 94} 95 96/* 97 * Choose PADSIZE to trade efficiency vs. size. If larger printf 98 * fields occur frequently, increase PADSIZE and make the initialisers 99 * below longer. 100 */ 101#define PADSIZE 16 /* pad chunk size */ 102static const CHAR blanks[PADSIZE] = 103{' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 104static const CHAR zeroes[PADSIZE] = 105{'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 106 107/* 108 * Pad with blanks or zeroes. 'with' should point to either the blanks array 109 * or the zeroes array. 110 */ 111static inline int 112io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with) 113{ 114 int n; 115 116 while (howmany > 0) { 117 n = (howmany >= PADSIZE) ? PADSIZE : howmany; 118 if (io_print(iop, with, n)) 119 return (-1); 120 howmany -= n; 121 } 122 return (0); 123} 124 125/* 126 * Print exactly len characters of the string spanning p to ep, truncating 127 * or padding with 'with' as necessary. 128 */ 129static inline int 130io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, 131 int len, const CHAR * __restrict with) 132{ 133 int p_len; 134 135 p_len = ep - p; 136 if (p_len > len) 137 p_len = len; 138 if (p_len > 0) { 139 if (io_print(iop, p, p_len)) 140 return (-1); 141 } else { 142 p_len = 0; 143 } 144 return (io_pad(iop, len - p_len, with)); 145} 146 147static inline int 148io_flush(struct io_state *iop) 149{ 150 151 return (__sprint(iop->fp, &iop->uio)); 152} 153 154/* 155 * Convert an unsigned long to ASCII for printf purposes, returning 156 * a pointer to the first character of the string representation. 157 * Octal numbers can be forced to have a leading zero; hex numbers 158 * use the given digits. 159 */ 160static CHAR * 161__ultoa(u_long val, CHAR *endp, int base, int octzero, const char *xdigs, 162 int needgrp, char thousep, const char *grp) 163{ 164 CHAR *cp = endp; 165 long sval; 166 int ndig; 167 168 /* 169 * Handle the three cases separately, in the hope of getting 170 * better/faster code. 171 */ 172 switch (base) { 173 case 10: 174 if (val < 10) { /* many numbers are 1 digit */ 175 *--cp = to_char(val); 176 return (cp); 177 } 178 ndig = 0; 179 /* 180 * On many machines, unsigned arithmetic is harder than 181 * signed arithmetic, so we do at most one unsigned mod and 182 * divide; this is sufficient to reduce the range of 183 * the incoming value to where signed arithmetic works. 184 */ 185 if (val > LONG_MAX) { 186 *--cp = to_char(val % 10); 187 ndig++; 188 sval = val / 10; 189 } else 190 sval = val; 191 do { 192 *--cp = to_char(sval % 10); 193 ndig++; 194 /* 195 * If (*grp == CHAR_MAX) then no more grouping 196 * should be performed. 197 */ 198 if (needgrp && ndig == *grp && *grp != CHAR_MAX 199 && sval > 9) { 200 *--cp = thousep; 201 ndig = 0; 202 /* 203 * If (*(grp+1) == '\0') then we have to 204 * use *grp character (last grouping rule) 205 * for all next cases 206 */ 207 if (*(grp+1) != '\0') 208 grp++; 209 } 210 sval /= 10; 211 } while (sval != 0); 212 break; 213 214 case 8: 215 do { 216 *--cp = to_char(val & 7); 217 val >>= 3; 218 } while (val); 219 if (octzero && *cp != '0') 220 *--cp = '0'; 221 break; 222 223 case 16: 224 do { 225 *--cp = xdigs[val & 15]; 226 val >>= 4; 227 } while (val); 228 break; 229 230 default: /* oops */ 231 abort(); 232 } 233 return (cp); 234} 235 236/* Identical to __ultoa, but for intmax_t. */ 237static CHAR * 238__ujtoa(uintmax_t val, CHAR *endp, int base, int octzero, const char *xdigs, 239 int needgrp, char thousep, const char *grp) 240{ 241 CHAR *cp = endp; 242 intmax_t sval; 243 int ndig; 244 245 /* quick test for small values; __ultoa is typically much faster */ 246 /* (perhaps instead we should run until small, then call __ultoa?) */ 247 if (val <= ULONG_MAX) 248 return (__ultoa((u_long)val, endp, base, octzero, xdigs, 249 needgrp, thousep, grp)); 250 switch (base) { 251 case 10: 252 if (val < 10) { 253 *--cp = to_char(val % 10); 254 return (cp); 255 } 256 ndig = 0; 257 if (val > INTMAX_MAX) { 258 *--cp = to_char(val % 10); 259 ndig++; 260 sval = val / 10; 261 } else 262 sval = val; 263 do { 264 *--cp = to_char(sval % 10); 265 ndig++; 266 /* 267 * If (*grp == CHAR_MAX) then no more grouping 268 * should be performed. 269 */ 270 if (needgrp && *grp != CHAR_MAX && ndig == *grp 271 && sval > 9) { 272 *--cp = thousep; 273 ndig = 0; 274 /* 275 * If (*(grp+1) == '\0') then we have to 276 * use *grp character (last grouping rule) 277 * for all next cases 278 */ 279 if (*(grp+1) != '\0') 280 grp++; 281 } 282 sval /= 10; 283 } while (sval != 0); 284 break; 285 286 case 8: 287 do { 288 *--cp = to_char(val & 7); 289 val >>= 3; 290 } while (val); 291 if (octzero && *cp != '0') 292 *--cp = '0'; 293 break; 294 295 case 16: 296 do { 297 *--cp = xdigs[val & 15]; 298 val >>= 4; 299 } while (val); 300 break; 301 302 default: 303 abort(); 304 } 305 return (cp); 306} 307 308#ifndef NO_FLOATING_POINT 309 310static int 311exponent(CHAR *p0, int exp, CHAR fmtch) 312{ 313 CHAR *p, *t; 314 CHAR expbuf[MAXEXPDIG]; 315 316 p = p0; 317 *p++ = fmtch; 318 if (exp < 0) { 319 exp = -exp; 320 *p++ = '-'; 321 } 322 else 323 *p++ = '+'; 324 t = expbuf + MAXEXPDIG; 325 if (exp > 9) { 326 do { 327 *--t = to_char(exp % 10); 328 } while ((exp /= 10) > 9); 329 *--t = to_char(exp); 330 for (; t < expbuf + MAXEXPDIG; *p++ = *t++); 331 } 332 else { 333 /* 334 * Exponents for decimal floating point conversions 335 * (%[eEgG]) must be at least two characters long, 336 * whereas exponents for hexadecimal conversions can 337 * be only one character long. 338 */ 339 if (fmtch == 'e' || fmtch == 'E') 340 *p++ = '0'; 341 *p++ = to_char(exp); 342 } 343 return (p - p0); 344} 345 346#endif /* !NO_FLOATING_POINT */ 347