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 67struct 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 115enum { 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 140typedef int printf_arginfo_function(const struct printf_info *__info, 141 size_t __n, int *__argtypes); 142typedef 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 153struct _printf_domain; /* forward reference */ 154typedef struct _printf_domain *printf_domain_t; 155 156__BEGIN_DECLS 157 158printf_domain_t copy_printf_domain(printf_domain_t __domain) 159 __XPRINTF_ATTR((__nonnull__(1))) 160 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); 161void free_printf_domain(printf_domain_t __domain) 162 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); 163printf_domain_t new_printf_domain(void) 164 __XPRINTF_ATTR((__malloc__)) 165 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); 166int 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); 171int 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 ****/ 177int 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); 182int 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); 186int 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); 191int 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); 196int 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 201int 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); 206int 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); 211int 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); 216int 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); 221int 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 *********/ 230struct _printf_compiled; /* forward reference */ 231typedef struct _printf_compiled *printf_comp_t; 232 233__BEGIN_DECLS 234 235void free_printf_comp(printf_comp_t __pc) 236 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); 237printf_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 ****/ 243int 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); 247int dxprintf_exec(int __fd, printf_comp_t __restrict __pc, ...) 248 __XPRINTF_ATTR((__nonnull__(2))) 249 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); 250int 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); 254int 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); 258int xprintf_exec(printf_comp_t __restrict __pc, ...) 259 __XPRINTF_ATTR((__nonnull__(1))) 260 __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0); 261 262int 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); 266int 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); 270int 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); 274int 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); 278int 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 */ 285