1 /* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * 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 * 3. 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 33 /* 34 * Copyright (c) 2012-2014 ARM Ltd 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 1. Redistributions of source code must retain the above copyright 41 * notice, this list of conditions and the following disclaimer. 42 * 2. Redistributions in binary form must reproduce the above copyright 43 * notice, this list of conditions and the following disclaimer in the 44 * documentation and/or other materials provided with the distribution. 45 * 3. The name of the company may not be used to endorse or promote 46 * products derived from this software without specific prior written 47 * permission. 48 * 49 * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED 50 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 51 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52 * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 53 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 54 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 55 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 56 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 57 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 58 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61 #ifndef VFPRINTF_LOCAL 62 #define VFPRINTF_LOCAL 63 64 #ifndef NO_FLOATING_POINT 65 # define FLOATING_POINT 66 #endif 67 68 #define _NO_POS_ARGS 69 #undef _WANT_IO_C99_FORMATS 70 71 /* Currently a test is made to see if long double processing is warranted. 72 This could be changed in the future should the __ldtoa code be 73 preferred over __dtoa. */ 74 #define _NO_LONGDBL 75 76 #define _NO_LONGLONG 77 78 #define _PRINTF_FLOAT_TYPE double 79 80 #if defined (FLOATING_POINT) 81 # include <locale.h> 82 #endif 83 #ifdef FLOATING_POINT 84 # include <math.h> 85 86 /* For %La, an exponent of 15 bits occupies the exponent character, 87 a sign, and up to 5 digits. */ 88 # define MAXEXPLEN 7 89 # define DEFPREC 6 90 91 # define _DTOA __dtoa 92 # define FREXP frexp 93 94 #endif /* FLOATING_POINT. */ 95 96 /* BUF must be big enough for the maximum %#llo (assuming long long is 97 at most 64 bits, this would be 23 characters), the maximum 98 multibyte character %C, and the maximum default precision of %La 99 (assuming long double is at most 128 bits with 113 bits of 100 mantissa, this would be 29 characters). %e, %f, and %g use 101 reentrant storage shared with mprec. All other formats that use 102 buf get by with fewer characters. Making BUF slightly bigger 103 reduces the need for malloc in %.*a and %S, when large precision or 104 long strings are processed. 105 The bigger size of 100 bytes is used on systems which allow number 106 strings using the locale's grouping character. Since that's a multibyte 107 value, we should use a conservative value. */ 108 #define BUF 40 109 110 #define quad_t long 111 #define u_quad_t unsigned long 112 113 typedef quad_t * quad_ptr_t; 114 typedef void *void_ptr_t; 115 typedef char * char_ptr_t; 116 typedef long * long_ptr_t; 117 typedef int * int_ptr_t; 118 typedef short * short_ptr_t; 119 120 /* Macros for converting digits to letters and vice versa. */ 121 #define to_digit(c) ((c) - '0') 122 #define is_digit(c) ((unsigned)to_digit (c) <= 9) 123 #define to_char(n) ((n) + '0') 124 125 /* Flags used during conversion. */ 126 #define ALT 0x001 /* Alternate form. */ 127 #define LADJUST 0x002 /* Left adjustment. */ 128 #define ZEROPAD 0x004 /* Zero (as opposed to blank) pad. */ 129 #define PLUSSGN 0x008 /* Plus sign flag. */ 130 #define SPACESGN 0x010 /* Space flag. */ 131 #define HEXPREFIX 0x020 /* Add 0x or 0X prefix. */ 132 #define SHORTINT 0x040 /* Short integer. */ 133 #define LONGINT 0x080 /* Long integer. */ 134 #define LONGDBL 0x100 /* Long double. */ 135 /* ifdef _NO_LONGLONG, make QUADINT equivalent to LONGINT, so 136 that %lld behaves the same as %ld, not as %d, as expected if: 137 sizeof (long long) = sizeof long > sizeof int. */ 138 #define QUADINT LONGINT 139 #define FPT 0x400 /* Floating point number. */ 140 /* Define as 0, to make SARG and UARG occupy fewer instructions. */ 141 # define CHARINT 0 142 143 /* Macros to support positional arguments. */ 144 #define GET_ARG(n, ap, type) (va_arg ((ap), type)) 145 146 /* To extend shorts properly, we need both signed and unsigned 147 argument extraction methods. Also they should be used in nano-vfprintf_i.c 148 and nano-vfprintf_float.c only, since ap is a pointer to va_list. */ 149 #define SARG(flags) \ 150 (flags&LONGINT ? GET_ARG (N, (*ap), long) : \ 151 flags&SHORTINT ? (long)(short)GET_ARG (N, (*ap), int) : \ 152 flags&CHARINT ? (long)(signed char)GET_ARG (N, (*ap), int) : \ 153 (long)GET_ARG (N, (*ap), int)) 154 #define UARG(flags) \ 155 (flags&LONGINT ? GET_ARG (N, (*ap), u_long) : \ 156 flags&SHORTINT ? (u_long)(u_short)GET_ARG (N, (*ap), int) : \ 157 flags&CHARINT ? (u_long)(unsigned char)GET_ARG (N, (*ap), int) : \ 158 (u_long)GET_ARG (N, (*ap), u_int)) 159 160 /* BEWARE, these `goto error' on error. And they are used 161 in more than one functions. 162 163 Following macros are each referred about twice in printf for integer, 164 so it is not worth to rewrite them into functions. This situation may 165 change in the future. */ 166 #define PRINT(ptr, len) { \ 167 if (pfunc (fp, (ptr), (len)) == EOF) \ 168 goto error; \ 169 } 170 #define PAD(howmany, ch) { \ 171 int temp_i = 0; \ 172 while (temp_i < (howmany)) \ 173 { \ 174 if (pfunc (fp, &(ch), 1) == EOF) \ 175 goto error; \ 176 temp_i++; \ 177 } \ 178 } 179 #define PRINTANDPAD(p, ep, len, ch) { \ 180 int temp_n = (ep) - (p); \ 181 if (temp_n > (len)) \ 182 temp_n = (len); \ 183 if (temp_n > 0) \ 184 PRINT((p), temp_n); \ 185 PAD((len) - (temp_n > 0 ? temp_n : 0), (ch)); \ 186 } 187 188 /* All data needed to decode format string are kept in below struct. */ 189 struct _prt_data_t 190 { 191 int flags; /* Flags. */ 192 int prec; /* Precision. */ 193 int dprec; /* Decimal precision. */ 194 int width; /* Width. */ 195 int size; /* Size of converted field or string. */ 196 int ret; /* Return value accumulator. */ 197 char code; /* Current conversion specifier. */ 198 char blank; /* Blank character. */ 199 char zero; /* Zero character. */ 200 char buf[BUF]; /* Output buffer for non-floating point number. */ 201 char l_buf[3]; /* Sign&hex_prefix, "+/-" and "0x/X". */ 202 #ifdef FLOATING_POINT 203 _PRINTF_FLOAT_TYPE _double_; /* Double value. */ 204 char expstr[MAXEXPLEN]; /* Buffer for exponent string. */ 205 int lead; /* The sig figs before decimal or group sep. */ 206 #endif 207 }; 208 209 extern int 210 _printf_common ( 211 struct _prt_data_t *pdata, 212 int *realsz, 213 FILE *fp, 214 int (*pfunc)(FILE *, 215 const char *, size_t len)); 216 217 extern int 218 _printf_i (struct _prt_data_t *pdata, FILE *fp, 219 int (*pfunc)(FILE *, const char *, size_t len), 220 va_list *ap); 221 222 /* Make _printf_float weak symbol, so it won't be linked in if target program 223 does not need it. */ 224 extern int 225 _printf_float ( 226 struct _prt_data_t *pdata, 227 FILE *fp, 228 int (*pfunc)(FILE *, 229 const char *, size_t len), 230 va_list *ap) _ATTRIBUTE((__weak__)); 231 #endif 232