/ include / printf.h
printf.h
  1  /*-
  2   * Copyright (c) 2005 Poul-Henning Kamp
  3   * All rights reserved.
  4   *
  5   * Redistribution and use in source and binary forms, with or without
  6   * modification, are permitted provided that the following conditions
  7   * are met:
  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.
 13   *
 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
 24   * SUCH DAMAGE.
 25   *
 26   * $FreeBSD: src/include/printf.h,v 1.5 2011/03/06 17:45:37 pjd Exp $
 27   */
 28  
 29  #ifndef _PRINTF_H_
 30  #define _PRINTF_H_
 31  
 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:
 36   *
 37   *   http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
 38   *
 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.
 44   *
 45   * See xprintf(5) for more details.
 46   ****************************************************************************/
 47  
 48  #include <stdio.h>
 49  #include <wchar.h>
 50  #include <xlocale.h>
 51  #include <Availability.h>
 52  
 53  #ifdef __GNUC__
 54  #define __XPRINTF_ATTR(x)	__attribute__(x)
 55  #else /* !__GNUC__ */
 56  #define __XPRINTF_ATTR(x)	/* nothing */
 57  #endif /* !__GNUC__ */
 58  
 59  /*
 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).
 64   */
 65  #define __PRINTFMAXARG		2
 66  
 67  struct printf_info {
 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 */
 73  
 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 */
 80  
 81  	/* FreeBSD extensions */
 82  	wchar_t		signchar;		/* Sign char */
 83  
 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) */
 96  
 97  	/* FreeBSD flags */
 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 */
102  
103  	/* Mac OS X flags */
104  	unsigned	is_vec		:1;	/* v flag */
105  
106  	/* private */
107  	int		sofar;
108  	unsigned	get_width;
109  	unsigned	get_prec;
110  	const char	*begin;
111  	const char	*end;
112  	void 		*arg[__PRINTFMAXARG];
113  };
114  
115  enum {
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 */
125  };
126  
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
137  
138  /************************ Basic Extensible Printf APIs ************************/
139  
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);
144  
145  /*
146   * We don't support the GLIBC register_printf_function() or FreeBSD
147   * register_printf_render_std(), because they affect printf globally
148   * and are unsafe.
149   */
150  
151  /*************** Extensible Printf Domains APIs ****************/
152  
153  struct _printf_domain; /* forward reference */
154  typedef struct _printf_domain *printf_domain_t;
155  
156  __BEGIN_DECLS
157  
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,
172  	 const char *__specs)
173  	 __XPRINTF_ATTR((__nonnull__(1)))
174  	 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
175  
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);
200  
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,
208  	 va_list __ap)
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,
223  	 va_list __ap)
224  	 __XPRINTF_ATTR((__nonnull__(1, 3)))
225  	 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
226  
227  __END_DECLS
228  
229  /******** Extensible Printf Compilation/Execution APIs *********/
230  struct _printf_compiled; /* forward reference */
231  typedef struct _printf_compiled *printf_comp_t;
232  
233  __BEGIN_DECLS
234  
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);
241  
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);
261  
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,
267  	 va_list __ap)
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);
281  
282  __END_DECLS
283  
284  #endif /* !_PRINTF_H */