Add a wrapper around vstr_add_fmt() to avoid having to link libcharon against libvstr
[strongswan.git] / src / libstrongswan / printf_hook.h
1 /*
2 * Copyright (C) 2009 Tobias Brunner
3 * Copyright (C) 2006-2008 Martin Willi
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 /**
18 * @defgroup printf_hook printf_hook
19 * @{ @ingroup libstrongswan
20 */
21
22 #ifndef PRINTF_HOOK_H_
23 #define PRINTF_HOOK_H_
24
25 typedef struct printf_hook_t printf_hook_t;
26 typedef struct printf_hook_spec_t printf_hook_spec_t;
27 typedef struct printf_hook_data_t printf_hook_data_t;
28 typedef enum printf_hook_argtype_t printf_hook_argtype_t;
29
30 #if !defined(USE_VSTR) && \
31 !defined(HAVE_PRINTF_FUNCTION) && \
32 !defined(HAVE_PRINTF_SPECIFIER)
33 /* assume newer glibc register_printf_specifier if none given */
34 #define HAVE_PRINTF_SPECIFIER
35 #endif
36
37 #if !defined(USE_VSTR) && \
38 (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER))
39
40 #include <stdio.h>
41 #include <printf.h>
42
43 enum printf_hook_argtype_t {
44 PRINTF_HOOK_ARGTYPE_END = -1,
45 PRINTF_HOOK_ARGTYPE_INT = PA_INT,
46 PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
47 };
48
49 /**
50 * Data to pass to a printf hook.
51 */
52 struct printf_hook_data_t {
53
54 /**
55 * Output FILE stream
56 */
57 FILE *stream;;
58 };
59
60 /**
61 * Helper macro to be used in printf hook callbacks.
62 */
63 #define print_in_hook(data, fmt, ...) ({\
64 ssize_t _written = fprintf(data->stream, fmt, ##__VA_ARGS__);\
65 if (_written < 0)\
66 {\
67 _written = 0;\
68 }\
69 _written;\
70 })
71
72 #else
73
74 #include <vstr.h>
75
76 enum printf_hook_argtype_t {
77 PRINTF_HOOK_ARGTYPE_END = VSTR_TYPE_FMT_END,
78 PRINTF_HOOK_ARGTYPE_INT = VSTR_TYPE_FMT_INT,
79 PRINTF_HOOK_ARGTYPE_POINTER = VSTR_TYPE_FMT_PTR_VOID,
80 };
81
82 /**
83 * Redefining printf and alike
84 */
85 #include <stdio.h>
86 #include <stdarg.h>
87
88 int vstr_wrapper_printf(const char *format, ...);
89 int vstr_wrapper_fprintf(FILE *stream, const char *format, ...);
90 int vstr_wrapper_sprintf(char *str, const char *format, ...);
91 int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...);
92 int vstr_wrapper_asprintf(char **str, const char *format, ...);
93
94 int vstr_wrapper_vprintf(const char *format, va_list ap);
95 int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list ap);
96 int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
97 int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
98 int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
99
100 #ifdef printf
101 #undef printf
102 #endif
103 #ifdef fprintf
104 #undef fprintf
105 #endif
106 #ifdef sprintf
107 #undef sprintf
108 #endif
109 #ifdef snprintf
110 #undef snprintf
111 #endif
112 #ifdef asprintf
113 #undef asprintf
114 #endif
115 #ifdef vprintf
116 #undef vprintf
117 #endif
118 #ifdef vfprintf
119 #undef vfprintf
120 #endif
121 #ifdef vsprintf
122 #undef vsprintf
123 #endif
124 #ifdef vsnprintf
125 #undef vsnprintf
126 #endif
127 #ifdef vasprintf
128 #undef vasprintf
129 #endif
130
131 #define printf vstr_wrapper_printf
132 #define fprintf vstr_wrapper_fprintf
133 #define sprintf vstr_wrapper_sprintf
134 #define snprintf vstr_wrapper_snprintf
135 #define asprintf vstr_wrapper_asprintf
136
137 #define vprintf vstr_wrapper_vprintf
138 #define vfprintf vstr_wrapper_vfprintf
139 #define vsprintf vstr_wrapper_vsprintf
140 #define vsnprintf vstr_wrapper_vsnprintf
141 #define vasprintf vstr_wrapper_vasprintf
142
143 /**
144 * Data to pass to a printf hook.
145 */
146 struct printf_hook_data_t {
147
148 /**
149 * Base to append printf to
150 */
151 Vstr_base *base;
152
153 /**
154 * Position in base to write to
155 */
156 size_t pos;
157 };
158
159 /**
160 * Wrapper around vstr_add_vfmt(), avoids having to link all users of
161 * print_in_hook() against libvstr.
162 *
163 * @param base Vstr_string to add string to
164 * @param pos position to write to
165 * @param fmt format string
166 * @param ... arguments
167 * @return number of characters written
168 */
169 size_t vstr_print_in_hook(struct Vstr_base *base, size_t pos, const char *fmt,
170 ...);
171
172 /**
173 * Helper macro to be used in printf hook callbacks.
174 */
175 #define print_in_hook(data, fmt, ...) ({\
176 size_t _written; \
177 _written = vstr_print_in_hook(data->base, data->pos, fmt, ##__VA_ARGS__);\
178 data->pos += _written;\
179 _written;\
180 })
181
182 #endif
183
184 /**
185 * Callback function type for printf hooks.
186 *
187 * @param data hook data, to pass to print_in_hook()
188 * @param spec format specifier
189 * @param args arguments array
190 * @return number of characters written
191 */
192 typedef int (*printf_hook_function_t)(printf_hook_data_t *data,
193 printf_hook_spec_t *spec,
194 const void *const *args);
195
196 /**
197 * Properties of the format specifier
198 */
199 struct printf_hook_spec_t {
200 /**
201 * TRUE if a '#' was used in the format specifier
202 */
203 int hash;
204
205 /**
206 * TRUE if a '-' was used in the format specifier
207 */
208 int minus;
209
210 /**
211 * TRUE if a '+' was used in the format specifier
212 */
213 int plus;
214
215 /**
216 * The width as given in the format specifier.
217 */
218 int width;
219 };
220
221 /**
222 * Printf handler management.
223 */
224 struct printf_hook_t {
225
226 /**
227 * Register a printf handler.
228 *
229 * @param spec printf hook format character
230 * @param hook hook function
231 * @param ... list of PRINTF_HOOK_ARGTYPE_*, MUST end with PRINTF_HOOK_ARGTYPE_END
232 */
233 void (*add_handler)(printf_hook_t *this, char spec,
234 printf_hook_function_t hook, ...);
235
236 /**
237 * Destroy a printf_hook instance.
238 */
239 void (*destroy)(printf_hook_t *this);
240 };
241
242 /**
243 * Create a printf_hook instance.
244 */
245 printf_hook_t *printf_hook_create();
246
247 #endif /** PRINTF_HOOK_H_ @}*/