Pass opaque data to printf hooks and print_in_hook()
[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 #else
50
51 #include <vstr.h>
52
53 enum printf_hook_argtype_t {
54 PRINTF_HOOK_ARGTYPE_END = VSTR_TYPE_FMT_END,
55 PRINTF_HOOK_ARGTYPE_INT = VSTR_TYPE_FMT_INT,
56 PRINTF_HOOK_ARGTYPE_POINTER = VSTR_TYPE_FMT_PTR_VOID,
57 };
58
59 /**
60 * Redefining printf and alike
61 */
62 #include <stdio.h>
63 #include <stdarg.h>
64
65 int vstr_wrapper_printf(const char *format, ...);
66 int vstr_wrapper_fprintf(FILE *stream, const char *format, ...);
67 int vstr_wrapper_sprintf(char *str, const char *format, ...);
68 int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...);
69 int vstr_wrapper_asprintf(char **str, const char *format, ...);
70
71 int vstr_wrapper_vprintf(const char *format, va_list ap);
72 int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list ap);
73 int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
74 int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
75 int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
76
77 #define printf vstr_wrapper_printf
78 #define fprintf vstr_wrapper_fprintf
79 #define sprintf vstr_wrapper_sprintf
80 #define snprintf vstr_wrapper_snprintf
81 #define asprintf vstr_wrapper_asprintf
82
83 #define vprintf vstr_wrapper_vprintf
84 #define vfprintf vstr_wrapper_vfprintf
85 #define vsprintf vstr_wrapper_vsprintf
86 #define vsnprintf vstr_wrapper_vsnprintf
87 #define vasprintf vstr_wrapper_vasprintf
88
89 #endif
90
91 /**
92 * Callback function type for printf hooks.
93 *
94 * @param data hook data, to pass to print_in_hook()
95 * @param spec format specifier
96 * @param args arguments array
97 * @return number of characters written
98 */
99 typedef int (*printf_hook_function_t)(printf_hook_data_t *data,
100 printf_hook_spec_t *spec,
101 const void *const *args);
102
103 /**
104 * Helper macro to be used in printf hook callbacks.
105 * buf and buflen get modified.
106 */
107 #define print_in_hook(data, fmt, ...) ({\
108 int _written = snprintf(data->buf, data->buflen, fmt, ##__VA_ARGS__);\
109 if (_written < 0 || _written >= data->buflen)\
110 {\
111 _written = data->buflen - 1;\
112 }\
113 data->buf += _written;\
114 data->buflen -= _written;\
115 _written;\
116 })
117
118 /**
119 * Data to pass to a printf hook.
120 */
121 struct printf_hook_data_t {
122
123 /**
124 * Buffer to write to
125 */
126 char *buf;
127
128 /**
129 * Size of the buffer
130 */
131 size_t buflen;
132 };
133
134 /**
135 * Properties of the format specifier
136 */
137 struct printf_hook_spec_t {
138 /**
139 * TRUE if a '#' was used in the format specifier
140 */
141 int hash;
142
143 /**
144 * TRUE if a '-' was used in the format specifier
145 */
146 int minus;
147
148 /**
149 * The width as given in the format specifier.
150 */
151 int width;
152 };
153
154 /**
155 * Printf handler management.
156 */
157 struct printf_hook_t {
158
159 /**
160 * Register a printf handler.
161 *
162 * @param spec printf hook format character
163 * @param hook hook function
164 * @param ... list of PRINTF_HOOK_ARGTYPE_*, MUST end with PRINTF_HOOK_ARGTYPE_END
165 */
166 void (*add_handler)(printf_hook_t *this, char spec,
167 printf_hook_function_t hook, ...);
168
169 /**
170 * Destroy a printf_hook instance.
171 */
172 void (*destroy)(printf_hook_t *this);
173 };
174
175 /**
176 * Create a printf_hook instance.
177 */
178 printf_hook_t *printf_hook_create();
179
180 #endif /** PRINTF_HOOK_H_ @}*/