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