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$ 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 53 static int exponent(CHAR *, int, CHAR); 54 55 #endif /* !NO_FLOATING_POINT */ 56 57 static CHAR *__ujtoa(uintmax_t, CHAR *, int, int, const char *, int, char, 58 const char *); 59 static CHAR *__ultoa(u_long, CHAR *, int, int, const char *, int, char, 60 const char *); 61 62 #define NIOV 8 63 struct io_state { 64 FILE *fp; 65 struct __suio uio; /* output information: summary */ 66 struct __siov iov[NIOV];/* ... and individual io vectors */ 67 struct __siov *iovp; /* pointer to next free slot in iov */ 68 }; 69 70 static inline void 71 io_init(struct io_state *iop, FILE *fp) 72 { 73 74 iop->uio.uio_iov = iop->iovp = iop->iov; 75 iop->uio.uio_resid = 0; 76 iop->uio.uio_iovcnt = 0; 77 iop->fp = fp; 78 } 79 80 /* 81 * WARNING: The buffer passed to io_print() is not copied immediately; it must 82 * remain valid until io_flush() is called. 83 */ 84 static inline int 85 io_print(struct io_state *iop, const CHAR * __restrict ptr, int len) 86 { 87 88 iop->iovp->iov_base = (char *)ptr; 89 iop->iovp->iov_len = len; 90 iop->uio.uio_resid += len; 91 iop->iovp++; 92 if (++iop->uio.uio_iovcnt >= NIOV) { 93 iop->iovp = iop->iov; 94 return (__sprint(iop->fp, &iop->uio)); 95 } 96 return (0); 97 } 98 99 /* 100 * Choose PADSIZE to trade efficiency vs. size. If larger printf 101 * fields occur frequently, increase PADSIZE and make the initialisers 102 * below longer. 103 */ 104 #define PADSIZE 16 /* pad chunk size */ 105 static const CHAR blanks[PADSIZE] = 106 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; 107 static const CHAR zeroes[PADSIZE] = 108 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; 109 110 /* 111 * Pad with blanks or zeroes. 'with' should point to either the blanks array 112 * or the zeroes array. 113 */ 114 static inline int 115 io_pad(struct io_state *iop, int howmany, const CHAR * __restrict with) 116 { 117 118 while (howmany > PADSIZE) { 119 if (io_print(iop, with, PADSIZE)) 120 return (-1); 121 howmany -= PADSIZE; 122 } 123 if (howmany > 0 && io_print(iop, with, howmany)) 124 return (-1); 125 return (0); 126 } 127 128 /* 129 * Print exactly len characters of the string spanning p to ep, truncating 130 * or padding with 'with' as necessary. 131 */ 132 static inline int 133 io_printandpad(struct io_state *iop, const CHAR *p, const CHAR *ep, 134 int len, const CHAR * __restrict with) 135 { 136 int p_len; 137 138 p_len = ep - p; 139 if (p_len > len) 140 p_len = len; 141 if (p_len > 0 && io_print(iop, p, p_len)) 142 return (-1); 143 return (io_pad(iop, len - (p_len > 0 ? p_len : 0), with)); 144 } 145 146 static inline int 147 io_flush(struct io_state *iop) 148 { 149 150 iop->iovp = iop->iov; 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 */ 160 static 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. */ 237 static 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 310 static int 311 exponent(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