1/* -*- Mode: C -*- */ 2 3/* printf.in --- printf clone for argv arrays 4 * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan 5 * Originally by Gary V. Vaughan, 1998 6 * This file is part of Snprintfv 7 * 8 * Snprintfv is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of the 11 * License, or (at your option) any later version. 12 * 13 * Snprintfv program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 * 22 * As a special exception to the GNU General Public License, if you 23 * distribute this file as part of a program that also links with and 24 * uses the libopts library from AutoGen, you may include it under 25 * the same distribution terms used by the libopts library. 26 */ 27 28/* Code: */ 29 30#ifndef SNPRINTFV_SNPRINTFV_H 31#define SNPRINTFV_SNPRINTFV_H 1 32 33#include <snprintfv/compat.h> 34#include <snprintfv/filament.h> 35#include <snprintfv/stream.h> 36#include <snprintfv/mem.h> 37 38#ifdef HAVE_WCHAR_H 39# include <wchar.h> 40#endif 41 42#ifdef __cplusplus 43extern "C" 44{ 45#endif 46 47/* The type of each element in the table of printf specifiers. */ 48struct spec_entry; 49 50typedef enum 51{ 52 SNV_ERROR = -1, 53 SNV_OK 54} 55snv_status; 56 57/* Basic states required by the parser. On initialisation the parser 58 will be in SNV_STATE_BEGIN, and tokens will be parsed by the registered 59 functions until the parser reached SNV_STATE_END. */ 60#define SNV_STATE_BEGIN 1 61#define SNV_STATE_END 0 62 63/* States needed to support: 64 %[<number>$]<flags>[<width>|\*][.<precision>|\*]<modifiers><specifier> */ 65#define SNV_STATE_FLAG (1 << 1) 66#define SNV_STATE_WIDTH (1 << 2) 67#define SNV_STATE_PRECISION (1 << 3) 68#define SNV_STATE_MODIFIER (1 << 4) 69#define SNV_STATE_SPECIFIER (1 << 5) 70 71/* First state available to the user */ 72#define SNV_STATE_USER_FIRST (1 << 8) 73 74/* Mask for states available to the user */ 75#define SNV_STATE_USER_MASK ~(SNV_STATE_USER_FIRST - 1) 76 77typedef struct printf_info 78{ 79 int count; /* accumulated count, or SNV_ERROR */ 80 int state; /* one of the defines above */ 81 Filament *error; /* accumulated error details */ 82 83 const char *format; /* pointer to format string */ 84 int argc; /* number of arguments used by format */ 85 int argindex; /* number of non-dollar arguments used so far */ 86 87 int dollar; /* standard parser state, as in glibc */ 88 int prec; /* from this field on, as in glibc */ 89 int width; 90 91 snv_pointer extra; 92 int type; 93 94 char spec; 95 char pad; 96 unsigned is_long_double:1; 97 unsigned is_char:1; 98 unsigned is_short:1; 99 unsigned is_long:1; 100 unsigned alt:1; 101 unsigned space:1; 102 unsigned left:1; 103 unsigned showsign:1; 104 unsigned group:1; 105 unsigned wide:1; 106 107 const union printf_arg *args; 108} printf_info; 109 110/** 111 * printf_arg: 112 * @pa_char: an unsigned %char 113 * @pa_wchar: a %wchar_t 114 * @pa_short_int: a %short integer 115 * @pa_int: an %int 116 * @pa_long_int: a %long integer 117 * @pa_long_long_int: the widest signed integer type in use on the host 118 * @pa_u_short_int: an unsigned %short integer 119 * @pa_u_int: an unsigned %int 120 * @pa_u_long_int: an unsigned %long integer 121 * @pa_u_long_long_int: the widest unsigned integer type in use on the host 122 * @pa_float: a %float 123 * @pa_double: a %double 124 * @pa_long_double: a long %double, or a simple %double if it is the widest floating-point type in use on the host 125 * @pa_string: a %const pointer to %char 126 * @pa_wstring: a %const pointer to %wchar_t 127 * @pa_pointer: a generic pointer 128 * 129 * The various kinds of arguments that can be passed to printf. 130 */ 131typedef union printf_arg 132{ 133 unsigned char pa_char; 134 snv_wchar_t pa_wchar; 135 short int pa_short_int; 136 int pa_int; 137 long int pa_long_int; 138 intmax_t pa_long_long_int; 139 unsigned short int pa_u_short_int; 140 unsigned int pa_u_int; 141 unsigned long int pa_u_long_int; 142 uintmax_t pa_u_long_long_int; 143 float pa_float; 144 double pa_double; 145 long double pa_long_double; 146 const char *pa_string; 147 const snv_wchar_t *pa_wstring; 148 snv_constpointer pa_pointer; 149} printf_arg; 150 151/** 152 * PRINTF_ERROR: 153 * @pi: A pointer to the current state for the parser 154 * @str: The error message 155 * 156 * Append an error that will be returned by printf_strerror. 157 */ 158#define PRINTF_ERROR(pi, str) \ 159 printf_error(pi, __FILE__, __LINE__, SNV_ASSERT_FMT, str); 160 161typedef int printf_function (STREAM *stream, struct printf_info *pparser, union printf_arg const * args); 162 163typedef int printf_arginfo_function (struct printf_info *pparser, size_t n, int *argtypes); 164 165/** 166 * spec_entry: 167 * @spec: the specifier character that was matched 168 * @type: when @arg is NULL, the type of the only argument to the specifier 169 * @fmt: the handler function to actually print the arguments to the specifier 170 * @arg: the handler function to tell %printf about the types of the arguments to the specifier 171 * @user: the user data for the specifier, accessible to the handler function 172 * 173 * This is returned by register_printf_function. 174 */ 175typedef struct spec_entry 176{ 177 int spec; 178 int unused; /* for binary compatibility */ 179 int type; 180 printf_function *fmt; 181 printf_arginfo_function *arg; 182 snv_pointer user; 183} 184spec_entry; 185 186/** 187 * register_callback_function: printf.h 188 * @spec: the character which will trigger the functions, cast to an unsigned int. 189 * @fmt: the handler function to actually print the arguments to the specifier 190 * @arg: the handler function to tell %printf about the types of the arguments to the specifier 191 * 192 * Register the pair made of @fmt and @arg, so that it is called 193 * when @spec is encountered in a format string. If you create 194 * a shared library with an entry point named 195 * %snv_register_printf_funcs, and put the library in the 196 * search path given by the environment library %LTDL_LIBRARY_PATH, 197 * that entry point will be called when %libsnprintfv is initialized, 198 * passing a pointer to this kind of function (actually, a pointer 199 * to %register_printf_function) to it. This functionality is only 200 * present when the library is installed, not when it is built as 201 * a convenience library. 202 * 203 * Return value: 204 * Returns %NULL if @func was not successfully registered, a 205 * %spec_entry with the information on the function if it was. 206 **/ 207typedef spec_entry *register_callback_function (unsigned spec, printf_function *func, printf_arginfo_function *arginfo); 208 209/* Codes to determine basic types. 210 211 These values cover all the standard format specifications. 212 Users can add new values after PA_LAST for their own types. */ 213 214enum 215{ 216 PA_INT, /* int */ 217 PA_CHAR, /* int, cast to char */ 218 PA_WCHAR, /* wide char */ 219 PA_STRING, /* const char *, a '\0'-terminated string */ 220 PA_WSTRING, /* const snv_wchar_t *, wide character string */ 221 PA_POINTER, /* void * */ 222 PA_FLOAT, /* float */ 223 PA_DOUBLE, /* double */ 224 PA_LAST, 225 PA_UNKNOWN = -1 226}; 227 228/* Flag bits that can be set in a type. */ 229#define PA_TYPE_MASK 0x00ff 230#define PA_FLAG_MASK ~SNV_TYPE_MASK 231 232#define PA_FLAG_LONG_LONG (1 << 8) 233#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG 234#define PA_FLAG_LONG (1 << 9) 235#define PA_FLAG_SHORT (1 << 10) 236#define PA_FLAG_UNSIGNED (1 << 11) 237#define PA_FLAG_CHAR (1 << 12) 238#define PA_FLAG_PTR (1 << 13) 239 240/** 241 * SNV_EMIT: 242 * @ch: the character to be printed 243 * @stream: the stream on which to print 244 * @count: a variable to be updated with the count of printed 245 * characters 246 * 247 * Maintain the count while putting @ch in @stream, also be careful about 248 * handling %NULL stream if the handler is being called purely to count 249 * output size. 250 **/ 251#define SNV_EMIT(ch, stream, count) \ 252 SNV_STMT_START { \ 253 if (stream) \ 254 { \ 255 if (count >= 0) \ 256 { \ 257 int m_status = stream_put((ch), stream); \ 258 count = m_status < 0 ? m_status : count + m_status; \ 259 } \ 260 } \ 261 else \ 262 { \ 263 (void)(ch); \ 264 count++; \ 265 } \ 266 } SNV_STMT_END 267 268@protos format.c 269@protos custom.c 270@protos printf.c 271 272/* If you don't want to use snprintfv functions for *all* of your string 273 formatting API, then define COMPILING_SNPRINTFV_C and use the snv_ 274 prefix for the entry points below. */ 275#ifndef COMPILING_PRINTF_C 276#undef printf 277#undef vprintf 278#undef dprintf 279#undef vdprintf 280#undef fprintf 281#undef vfprintf 282#undef sprintf 283#undef vsprintf 284#undef snprintf 285#undef vsnprintf 286#undef asprintf 287#undef vasprintf 288#undef asprintfv 289#undef dprintfv 290#undef fprintfv 291#undef sprintfv 292#undef printfv 293#undef snprintfv 294#define printf snv_printf 295#define vprintf snv_vprintf 296#define dprintf snv_dprintf 297#define vdprintf snv_vdprintf 298#define fprintf snv_fprintf 299#define vfprintf snv_vfprintf 300#define sprintf snv_sprintf 301#define vsprintf snv_vsprintf 302#define snprintf snv_snprintf 303#define vsnprintf snv_vsnprintf 304#define asprintf snv_asprintf 305#define vasprintf snv_vasprintf 306#define asprintfv snv_asprintfv 307#define dprintfv snv_dprintfv 308#define fprintfv snv_fprintfv 309#define sprintfv snv_sprintfv 310#define printfv snv_printfv 311#define snprintfv snv_snprintfv 312#endif /* !COMPILING_SNPRINTFV_C */ 313#ifdef __cplusplus 314} 315#endif 316 317#endif /* SNPRINTFV_SNPRINTFV_H */ 318 319/* snprintfv.h ends here */ 320