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