1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * lt-messages.h
4 * Copyright (C) 2006-2012 Akira TAGOH
5 *
6 * Authors:
7 * Akira TAGOH <akira@tagoh.org>
8 *
9 * You may distribute under the terms of either the GNU
10 * Lesser General Public License or the Mozilla Public
11 * License, as specified in the README file.
12 *
13 * Borrowed from hieroglyph:
14 * http://cgit.freedesktop.org/hieroglyph/tree/hieroglyph/hgmessages.h
15 */
16 #ifndef __LT_MESSAGES_H__
17 #define __LT_MESSAGES_H__
18
19 #include <stdarg.h>
20 #include "lt-config.h"
21 #include "lt-macros.h"
22
23 LT_BEGIN_DECLS
24
25 typedef enum _lt_message_type_t lt_message_type_t;
26 typedef enum _lt_message_flags_t lt_message_flags_t;
27 typedef enum _lt_message_category_t lt_message_category_t;
28 typedef void (* lt_message_func_t) (lt_message_type_t type,
29 lt_message_flags_t flags,
30 lt_message_category_t category,
31 const char *message,
32 lt_pointer_t user_data);
33
34 enum _lt_message_type_t {
35 LT_MSG_0 = 0,
36 LT_MSG_FATAL,
37 LT_MSG_CRITICAL,
38 LT_MSG_WARNING,
39 LT_MSG_INFO,
40 LT_MSG_DEBUG,
41 LT_MSG_END
42 };
43 enum _lt_message_flags_t {
44 LT_MSG_FLAG_NONE = 0,
45 LT_MSG_FLAG_NO_LINEFEED = (1 << 0),
46 LT_MSG_FLAG_NO_PREFIX = (1 << 1),
47 LT_MSG_FLAG_END
48 };
49 enum _lt_message_category_t {
50 LT_MSGCAT_0 = 0,
51 LT_MSGCAT_DEBUG, /* 1 */
52 LT_MSGCAT_TRACE, /* 2 */
53 LT_MSGCAT_MODULE, /* 4 */
54 LT_MSGCAT_TAG, /* 8 */
55 LT_MSGCAT_END
56 };
57
58
59 lt_message_func_t lt_message_set_default_handler(lt_message_func_t func,
60 lt_pointer_t user_data);
61 lt_message_func_t lt_message_set_handler (lt_message_type_t type,
62 lt_message_func_t func,
63 lt_pointer_t user_data);
64 lt_bool_t lt_message_is_enabled (lt_message_category_t category);
65 void lt_message_printf (lt_message_type_t type,
66 lt_message_flags_t flags,
67 lt_message_category_t category,
68 const char *format,
69 ...) LT_GNUC_PRINTF(4, 5);
70 void lt_message_vprintf (lt_message_type_t type,
71 lt_message_flags_t flags,
72 lt_message_category_t category,
73 const char *format,
74 va_list args) LT_GNUC_PRINTF(4, 0);
75 void lt_return_if_fail_warning (const char *pretty_function,
76 const char *expression);
77
78
79 /* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi
80 * is passed ISO vararg support is turned off, and there is no work
81 * around to turn it on, so we unconditionally turn it off.
82 */
83 #if __GNUC__ == 2 && __GNUC_MINOR__ == 95
84 # undef LT_HAVE_ISO_VARARGS
85 #endif
86
87 #ifdef LT_HAVE_ISO_VARARGS
88 /* for(;;) ; so that GCC knows that control doesn't go past lt_fatal().
89 * Put space before ending semicolon to avoid C++ build warnings.
90 */
91 #define lt_fatal(...) \
92 LT_STMT_START { \
93 lt_message_printf(LT_MSG_FATAL, \
94 LT_MSG_FLAG_NONE, \
95 0, \
96 __VA_ARGS__); \
97 for (;;) ; \
98 } LT_STMT_END
99 #define lt_critical(...) \
100 lt_message_printf(LT_MSG_CRITICAL, \
101 LT_MSG_FLAG_NONE, \
102 0, \
103 __VA_ARGS__)
104 #define lt_warning(...) \
105 lt_message_printf(LT_MSG_WARNING, \
106 LT_MSG_FLAG_NONE, \
107 0, \
108 __VA_ARGS__)
109 #define lt_info(...) \
110 lt_message_printf(LT_MSG_INFO, \
111 LT_MSG_FLAG_NONE, \
112 0, \
113 __VA_ARGS__)
114 #define lt_debug(_c_,...) \
115 lt_message_printf(LT_MSG_DEBUG, \
116 LT_MSG_FLAG_NONE, \
117 (_c_), \
118 __VA_ARGS__)
119 #define lt_debug0(_c_,_f_,...) \
120 lt_message_printf(LT_MSG_DEBUG, \
121 (_f_), \
122 (_c_), \
123 __VA_ARGS__)
124
125 #elif defined(LT_HAVE_GNUC_VARARGS)
126
127 #define lt_fatal(format...) \
128 LT_STMT_START { \
129 lt_message_printf(LT_MSG_FATAL, \
130 LT_MSG_FLAG_NONE, \
131 0, \
132 format); \
133 for (;;) ; \
134 } LT_STMT_END
135 #define lt_critical(format...) \
136 lt_message_printf(LT_MSG_CRITICAL, \
137 LT_MSG_FLAG_NONE, \
138 0, \
139 format)
140 #define lt_warning(format...) \
141 lt_message_printf(LT_MSG_WARNING, \
142 LT_MSG_FLAG_NONE, \
143 0, \
144 format)
145 #define lt_info(format...) \
146 lt_message_printf(LT_MSG_INFO, \
147 LT_MSG_FLAG_NONE, \
148 0, \
149 format)
150 #define lt_debug(_c_,format...) \
151 lt_message_printf(LT_MSG_DEBUG, \
152 LT_MSG_FLAG_NONE, \
153 (_c_), \
154 format)
155 #define lt_debug0(_c_,_f_,format...) \
156 lt_message_printf(LT_MSG_DEBUG, \
157 (_f_), \
158 (_c_), \
159 format)
160 #else
161 static void
lt_fatal(const char * format,...)162 lt_fatal(const char *format,
163 ...)
164 {
165 va_list args;
166
167 va_start(args, format);
168 lt_message_vprintf(LT_MSG_FATAL, LT_MSG_FLAG_NONE, 0, format, args);
169 va_end(args);
170
171 for (;;) ;
172 }
173 static void
lt_critical(const char * format,...)174 lt_critical(const char *format,
175 ...)
176 {
177 va_list args;
178
179 va_start(args, format);
180 lt_message_vprintf(LT_MSG_CRITICAL, LT_MSG_FLAG_NONE, 0, format, args);
181 va_end(args);
182 }
183 static void
lt_warning(const char * format,...)184 lt_warning(const char *format,
185 ...)
186 {
187 va_list args;
188
189 va_start(args, format);
190 lt_message_vprintf(LT_MSG_WARNING, LT_MSG_FLAG_NONE, 0, format, args);
191 va_end(args);
192 }
193 static void
lt_info(const char * format,...)194 lt_info(const char *format,
195 ...)
196 {
197 va_list args;
198
199 va_start(args, format);
200 lt_message_vprintf(LT_MSG_INFO, LT_MSG_FLAG_NONE, 0, format, args);
201 va_end(args);
202 }
203 static void
lt_debug(lt_message_category_t category,const char * format,...)204 lt_debug(lt_message_category_t category,
205 const char *format,
206 ...)
207 {
208 va_list args;
209
210 va_start(args, format);
211 lt_message_vprintf(LT_MSG_DEBUG, LT_MSG_FLAG_NONE, category, format, args);
212 va_end(args);
213 }
214 static void
lt_debug0(lt_message_category_t category,lt_message_flags_t flags,const char * format,...)215 lt_debug0(lt_message_category_t category,
216 lt_message_flags_t flags,
217 const char *format,
218 ...)
219 {
220 va_list args;
221
222 va_start(args, format);
223 lt_message_vprintf(LT_MSG_DEBUG, flags, category, format, args);
224 va_end(args);
225 }
226 #endif
227
228 #ifdef __GNUC__
229 #define _lt_return_after_eval_if_fail(__expr__,__eval__) \
230 LT_STMT_START { \
231 if (LT_LIKELY (__expr__)) { \
232 } else { \
233 lt_return_if_fail_warning(__PRETTY_FUNCTION__, \
234 #__expr__); \
235 __eval__; \
236 return; \
237 } \
238 } LT_STMT_END
239 #define _lt_return_val_after_eval_if_fail(__expr__,__val__,__eval__) \
240 LT_STMT_START { \
241 if (LT_LIKELY (__expr__)) { \
242 } else { \
243 lt_return_if_fail_warning(__PRETTY_FUNCTION__, \
244 #__expr__); \
245 __eval__; \
246 return (__val__); \
247 } \
248 } LT_STMT_END
249 #define lt_assert(__expr__) \
250 LT_STMT_START { \
251 if (LT_LIKELY (__expr__)) { \
252 } else { \
253 lt_fatal("%s: assertion `%s' failed", __PRETTY_FUNCTION__, \
254 #__expr__); \
255 } \
256 } LT_STMT_END
257 #else /* !__GNUC__ */
258 #define _lt_return_after_eval_if_fail(__expr__,__eval__) \
259 LT_STMT_START { \
260 if (__expr__) { \
261 } else { \
262 lt_critical("file %s: line %d: assertion `%s' failed", \
263 __FILE__, \
264 __LINE__, \
265 #__expr__); \
266 __eval__; \
267 return; \
268 } \
269 } LT_STMT_END
270 #define _lt_return_val_after_eval_if_fail(__expr__,__val__,__eval__) \
271 LT_STMT_START { \
272 if (__expr__) { \
273 } else { \
274 lt_critical("file %s: line %d: assertion `%s' failed", \
275 __FILE__, \
276 __LINE__, \
277 #__expr__); \
278 __eval__; \
279 return (__val__); \
280 } \
281 } LT_STMT_END
282 #define lt_assert(__expr__) \
283 LT_STMT_START { \
284 if (__expr__) { \
285 } else { \
286 lt_fatal("file %s: line %d: assertion `%s' failed", \
287 __FILE__, \
288 __LINE__, \
289 #__expr__); \
290 } \
291 } LT_STMT_END
292 #endif /* __GNUC__ */
293
294 #define lt_return_if_fail(__expr__) \
295 _lt_return_after_eval_if_fail(__expr__,{})
296 #define lt_return_val_if_fail(__expr__,__val__) \
297 _lt_return_val_after_eval_if_fail(__expr__,__val__,{})
298 #define lt_return_after_eval_if_fail(__expr__,__eval__) \
299 _lt_return_after_eval_if_fail(__expr__,__eval__)
300 #define lt_return_val_after_eval_if_fail(__expr__,__val__,__eval__) \
301 _lt_return_val_after_eval_if_fail(__expr__,__val__,__eval__)
302 #ifdef __GNUC__
303 #define lt_warn_if_reached() \
304 lt_message_printf(LT_MSG_WARNING, LT_MSG_FLAG_NONE, 0, \
305 "(%s:%d): %s: code should not be reached", \
306 __FILE__, __LINE__, __PRETTY_FUNCTION__)
307 #else
308 #define lt_warn_if_reached() \
309 lt_message_printf(LT_MSG_WARNING, LT_MSG_FLAG_NONE, 0, \
310 "(%s:%d): code should not be reached", \
311 __FILE__, __LINE__)
312 #endif
313
314 LT_END_DECLS
315
316 #endif /* __LT_MESSAGES_H__ */
317