2 * Copyright (c) 2005 Poul-Henning Kamp
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/include/printf.h,v 1.5 2011/03/06 17:45:37 pjd Exp $
32 /****************************************************************************
33 * This is the header file for extensible printf, a set of APIs that allow
34 * adding/modifying conversion specifier(s) for stdio formatted printing.
35 * It is based on the GLIBC API documented in:
37 * http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
39 * Because that API affects printf behavior process-wide and so is unsafe,
40 * we adapt a modified form, based on the concept of printf domains in which
41 * changes to conversion specifiers can be made independent of one another
42 * and which don't affect the normal printf behavior. In addition, there
43 * is now a set of printf variants that take a printf domain as an argument.
45 * See xprintf(5) for more details.
46 ****************************************************************************/
51 #include <Availability.h>
54 #define __XPRINTF_ATTR(x) __attribute__(x)
56 #define __XPRINTF_ATTR(x) /* nothing */
57 #endif /* !__GNUC__ */
60 * The API defined by GLIBC allows a renderer to take multiple arguments
61 * This is obviously usable for things like (ptr+len) pairs etc.
62 * The current limit is to deal with up to __PRINTFMAXARG arguments (any
63 * above this limit are ignored).
65 #define __PRINTFMAXARG 2
68 /* Mac OS X extensions */
69 void *context
; /* User context pointer */
70 locale_t loc
; /* Extended locale */
71 wchar_t vsep
; /* Vector separator char */
72 /* one of ,:;_ flag or X by default */
74 /* GLIBC compatible */
75 int prec
; /* precision */
76 int width
; /* Width */
77 wchar_t spec
; /* Format letter */
78 wchar_t pad
; /* Padding char */
79 /* 0 if 0 flag set, otherwise space */
81 /* FreeBSD extensions */
82 wchar_t signchar
; /* Sign char */
84 /* GLIBC compatible flags */
85 unsigned is_long_double
:1; /* L or ll flag */
86 unsigned is_char
:1; /* hh flag */
87 unsigned is_short
:1; /* h flag */
88 unsigned is_long
:1; /* l flag */
89 unsigned alt
:1; /* # flag */
90 unsigned space
:1; /* Space flag */
91 unsigned left
:1; /* - flag */
92 unsigned showsign
:1; /* + flag */
93 unsigned group
:1; /* ' flag */
94 unsigned extra
:1; /* For special use (currently unused) */
95 unsigned wide
:1; /* Nonzero for wide character streams (currently unused) */
98 unsigned is_quad
:1; /* q flag */
99 unsigned is_intmax
:1; /* j flag */
100 unsigned is_ptrdiff
:1; /* t flag */
101 unsigned is_size
:1; /* z flag */
104 unsigned is_vec
:1; /* v flag */
112 void *arg
[__PRINTFMAXARG
];
116 PA_INT
= (1 << 0), /* int */
117 PA_CHAR
= (1 << 1), /* int, cast to char */
118 PA_WCHAR
= (1 << 2), /* wide char */
119 PA_STRING
= (1 << 3), /* const char * (with '\0') */
120 PA_WSTRING
= (1 << 4), /* const wchar_t * */
121 PA_POINTER
= (1 << 5), /* void * */
122 PA_FLOAT
= (1 << 6), /* float (Defined but unused; best to avoid.) */
123 PA_DOUBLE
= (1 << 7), /* double */
124 PA_VECTOR
= (1 << 8), /* vector */
127 #define PA_FLAG_MASK 0xff0000
128 #define PA_FLAG_LONG_LONG (1 << 16)
129 #define PA_FLAG_LONG (1 << 17)
130 #define PA_FLAG_SHORT (1 << 18)
131 #define PA_FLAG_PTR (1 << 19)
132 #define PA_FLAG_QUAD (1 << 20)
133 #define PA_FLAG_INTMAX (1 << 21)
134 #define PA_FLAG_SIZE (1 << 22)
135 #define PA_FLAG_PTRDIFF (1 << 23)
136 #define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
138 /************************ Basic Extensible Printf APIs ************************/
140 typedef int printf_arginfo_function(const struct printf_info
*__info
,
141 size_t __n
, int *__argtypes
);
142 typedef int printf_function(FILE *__stream
,
143 const struct printf_info
*__info
, const void *const *__args
);
146 * We don't support the GLIBC register_printf_function() or FreeBSD
147 * register_printf_render_std(), because they affect printf globally
151 /*************** Extensible Printf Domains APIs ****************/
153 struct _printf_domain
; /* forward reference */
154 typedef struct _printf_domain
*printf_domain_t
;
158 printf_domain_t
copy_printf_domain(printf_domain_t __domain
)
159 __XPRINTF_ATTR((__nonnull__(1)))
160 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
161 void free_printf_domain(printf_domain_t __domain
)
162 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
163 printf_domain_t
new_printf_domain(void)
164 __XPRINTF_ATTR((__malloc__
))
165 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
166 int register_printf_domain_function(printf_domain_t __domain
,
167 int __spec
, printf_function
*__render
,
168 printf_arginfo_function
*__arginfo
, void *__context
)
169 __XPRINTF_ATTR((__nonnull__(1)))
170 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
171 int register_printf_domain_render_std(printf_domain_t __domain
,
173 __XPRINTF_ATTR((__nonnull__(1)))
174 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
176 /**** All-in-one extensible printf variants ****/
177 int asxprintf(char ** __restrict __ret
,
178 printf_domain_t __restrict __domain
, locale_t __restrict __loc
,
179 const char * __restrict __format
, ...)
180 __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
181 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
182 int dxprintf(int __fd
, printf_domain_t __restrict __domain
,
183 locale_t __restrict __loc
, const char * __restrict __format
, ...)
184 __XPRINTF_ATTR((__nonnull__(2, 4)))
185 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
186 int fxprintf(FILE * __restrict __stream
,
187 printf_domain_t __restrict __domain
, locale_t __restrict __loc
,
188 const char * __restrict __format
, ...)
189 __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
190 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
191 int sxprintf(char * __restrict __str
, size_t __size
,
192 printf_domain_t __restrict __domain
, locale_t __restrict __loc
,
193 const char * __restrict __format
, ...)
194 __XPRINTF_ATTR((__nonnull__(1, 3, 5)))
195 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
196 int xprintf(printf_domain_t __restrict __domain
,
197 locale_t __restrict __loc
, const char * __restrict __format
, ...)
198 __XPRINTF_ATTR((__nonnull__(1, 3)))
199 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
201 int vasxprintf(char ** __restrict __ret
,
202 printf_domain_t __restrict __domain
, locale_t __restrict __loc
,
203 const char * __restrict __format
, va_list __ap
)
204 __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
205 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
206 int vdxprintf(int __fd
, printf_domain_t __restrict __domain
,
207 locale_t __restrict __loc
, const char * __restrict __format
,
209 __XPRINTF_ATTR((__nonnull__(2, 4)))
210 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
211 int vfxprintf(FILE * __restrict __stream
,
212 printf_domain_t __restrict __domain
, locale_t __restrict __loc
,
213 const char * __restrict __format
, va_list __ap
)
214 __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
215 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
216 int vsxprintf(char * __restrict __str
, size_t __size
,
217 printf_domain_t __restrict __domain
, locale_t __restrict __loc
,
218 const char * __restrict __format
, va_list __ap
)
219 __XPRINTF_ATTR((__nonnull__(1, 3, 5)))
220 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
221 int vxprintf(printf_domain_t __restrict __domain
,
222 locale_t __restrict __loc
, const char * __restrict __format
,
224 __XPRINTF_ATTR((__nonnull__(1, 3)))
225 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
229 /******** Extensible Printf Compilation/Execution APIs *********/
230 struct _printf_compiled
; /* forward reference */
231 typedef struct _printf_compiled
*printf_comp_t
;
235 void free_printf_comp(printf_comp_t __pc
)
236 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
237 printf_comp_t
new_printf_comp(printf_domain_t __restrict __domain
,
238 locale_t __restrict __loc
, const char * __restrict __fmt
)
239 __XPRINTF_ATTR((__nonnull__(1, 3)))
240 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
242 /**** Extensible printf execution ****/
243 int asxprintf_exec(char ** __restrict __ret
,
244 printf_comp_t __restrict __pc
, ...)
245 __XPRINTF_ATTR((__nonnull__(1, 2)))
246 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
247 int dxprintf_exec(int __fd
, printf_comp_t __restrict __pc
, ...)
248 __XPRINTF_ATTR((__nonnull__(2)))
249 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
250 int fxprintf_exec(FILE * __restrict __stream
,
251 printf_comp_t __restrict __pc
, ...)
252 __XPRINTF_ATTR((__nonnull__(1, 2)))
253 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
254 int sxprintf_exec(char * __restrict __str
, size_t __size
,
255 printf_comp_t __restrict __pc
, ...)
256 __XPRINTF_ATTR((__nonnull__(1, 3)))
257 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
258 int xprintf_exec(printf_comp_t __restrict __pc
, ...)
259 __XPRINTF_ATTR((__nonnull__(1)))
260 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
262 int vasxprintf_exec(char ** __restrict __ret
,
263 printf_comp_t __restrict __pc
, va_list __ap
)
264 __XPRINTF_ATTR((__nonnull__(1, 2)))
265 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
266 int vdxprintf_exec(int __fd
, printf_comp_t __restrict __pc
,
268 __XPRINTF_ATTR((__nonnull__(2)))
269 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
270 int vfxprintf_exec(FILE * __restrict __stream
,
271 printf_comp_t __restrict __pc
, va_list __ap
)
272 __XPRINTF_ATTR((__nonnull__(1, 2)))
273 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
274 int vsxprintf_exec(char * __restrict __str
, size_t __size
,
275 printf_comp_t __restrict __pc
, va_list __ap
)
276 __XPRINTF_ATTR((__nonnull__(1, 3)))
277 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
278 int vxprintf_exec(printf_comp_t __restrict __pc
, va_list __ap
)
279 __XPRINTF_ATTR((__nonnull__(1)))
280 __OSX_AVAILABLE_STARTING(__MAC_10_9
,__IPHONE_7_0
);
284 #endif /* !_PRINTF_H */