Default to register_printf_specifier() if no printf hooking #defined
[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 enum printf_hook_argtype_t printf_hook_argtype_t;
28
29 #if !defined(USE_VSTR) && \
30 !defined(HAVE_PRINTF_FUNCTION) && \
31 !defined(HAVE_PRINTF_SPECIFIER)
32 /* assume newer glibc register_printf_specifier if none given */
33 #define HAVE_PRINTF_SPECIFIER
34 #endif
35
36 #if !defined(USE_VSTR) && \
37 (defined(HAVE_PRINTF_FUNCTION) || defined(HAVE_PRINTF_SPECIFIER))
38
39 #include <stdio.h>
40 #include <printf.h>
41
42 enum printf_hook_argtype_t {
43 PRINTF_HOOK_ARGTYPE_END = -1,
44 PRINTF_HOOK_ARGTYPE_INT = PA_INT,
45 PRINTF_HOOK_ARGTYPE_POINTER = PA_POINTER,
46 };
47
48 #else
49
50 #include <vstr.h>
51
52 enum printf_hook_argtype_t {
53 PRINTF_HOOK_ARGTYPE_END = VSTR_TYPE_FMT_END,
54 PRINTF_HOOK_ARGTYPE_INT = VSTR_TYPE_FMT_INT,
55 PRINTF_HOOK_ARGTYPE_POINTER = VSTR_TYPE_FMT_PTR_VOID,
56 };
57
58 /**
59 * Redefining printf and alike
60 */
61 #include <stdio.h>
62 #include <stdarg.h>
63
64 int vstr_wrapper_printf(const char *format, ...);
65 int vstr_wrapper_fprintf(FILE *stream, const char *format, ...);
66 int vstr_wrapper_sprintf(char *str, const char *format, ...);
67 int vstr_wrapper_snprintf(char *str, size_t size, const char *format, ...);
68 int vstr_wrapper_asprintf(char **str, const char *format, ...);
69
70 int vstr_wrapper_vprintf(const char *format, va_list ap);
71 int vstr_wrapper_vfprintf(FILE *stream, const char *format, va_list ap);
72 int vstr_wrapper_vsprintf(char *str, const char *format, va_list ap);
73 int vstr_wrapper_vsnprintf(char *str, size_t size, const char *format, va_list ap);
74 int vstr_wrapper_vasprintf(char **str, const char *format, va_list ap);
75
76 #define printf vstr_wrapper_printf
77 #define fprintf vstr_wrapper_fprintf
78 #define sprintf vstr_wrapper_sprintf
79 #define snprintf vstr_wrapper_snprintf
80 #define asprintf vstr_wrapper_asprintf
81
82 #define vprintf vstr_wrapper_vprintf
83 #define vfprintf vstr_wrapper_vfprintf
84 #define vsprintf vstr_wrapper_vsprintf
85 #define vsnprintf vstr_wrapper_vsnprintf
86 #define vasprintf vstr_wrapper_vasprintf
87
88 #endif
89
90 /**
91 * Callback function type for printf hooks.
92 *
93 * @param dst destination buffer
94 * @param len length of the buffer
95 * @param spec format specifier
96 * @param args arguments array
97 * @return number of characters written
98 */
99 typedef int (*printf_hook_function_t)(char *dst, size_t len,
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(buf, buflen, fmt, ...) ({\
108 int _written = snprintf(buf, buflen, fmt, ##__VA_ARGS__);\
109 if (_written < 0 || _written >= buflen)\
110 {\
111 _written = buflen - 1;\
112 }\
113 buf += _written;\
114 buflen -= _written;\
115 _written;\
116 })
117
118 /**
119 * Properties of the format specifier
120 */
121 struct printf_hook_spec_t {
122 /**
123 * TRUE if a '#' was used in the format specifier
124 */
125 int hash;
126
127 /**
128 * TRUE if a '-' was used in the format specifier
129 */
130 int minus;
131
132 /**
133 * The width as given in the format specifier.
134 */
135 int width;
136 };
137
138 /**
139 * Printf handler management.
140 */
141 struct printf_hook_t {
142
143 /**
144 * Register a printf handler.
145 *
146 * @param spec printf hook format character
147 * @param hook hook function
148 * @param ... list of PRINTF_HOOK_ARGTYPE_*, MUST end with PRINTF_HOOK_ARGTYPE_END
149 */
150 void (*add_handler)(printf_hook_t *this, char spec,
151 printf_hook_function_t hook, ...);
152
153 /**
154 * Destroy a printf_hook instance.
155 */
156 void (*destroy)(printf_hook_t *this);
157 };
158
159 /**
160 * Create a printf_hook instance.
161 */
162 printf_hook_t *printf_hook_create();
163
164 #endif /** PRINTF_HOOK_H_ @}*/