1 /* Libvisual - The audio visualisation framework.
2  *
3  * Copyright (C) 2004, 2005 Dennis Smit <ds@nerds-incorporated.org>
4  *
5  * Authors: Dennis Smit <ds@nerds-incorporated.org>
6  *
7  * $Id:
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU Lesser General Public License as
11  * published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 
24 #ifndef _LV_LOG_H
25 #define _LV_LOG_H
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdarg.h>
30 #include <assert.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif /* __cplusplus */
35 
36 /* This is read-only */
37 extern char *__lv_progname;
38 
39 /**
40  * Used to determine the severity of the log message using the visual_log
41  * define.
42  *
43  * @see visual_log
44  */
45 typedef enum {
46 	VISUAL_LOG_DEBUG,	/**< Debug message, to use for debug messages. */
47 	VISUAL_LOG_INFO,	/**< Informative message, can be used for general info. */
48 	VISUAL_LOG_WARNING,	/**< Warning message, use to warn the user. */
49 	VISUAL_LOG_CRITICAL,	/**< Critical message, when a critical situation happens.
50 				 * Like a NULL pointer passed to a method. */
51 	VISUAL_LOG_ERROR	/**< Error message, use to notify the user of fatals.
52 				 * After the message has been showed, the program is aborted. */
53 } VisLogSeverity;
54 
55 /**
56  * Used to determine how much verbose the log system should be.
57  *
58  * @see visual_log_set_verboseness
59  */
60 typedef enum {
61 	VISUAL_LOG_VERBOSENESS_NONE,	/**< Don't show any message at all. */
62 	VISUAL_LOG_VERBOSENESS_LOW,	/**< Show only VISUAL_LOG_ERROR and
63 					  VISUAL_LOG_CRITICAL messages. */
64 	VISUAL_LOG_VERBOSENESS_MEDIUM,	/**< Show all log messages except VISUAL_LOG_DEBUG ones. */
65 	VISUAL_LOG_VERBOSENESS_HIGH	/**< Show all log messages. */
66 } VisLogVerboseness;
67 
68 /**
69  * Functions that want to handle messages must match this signature.
70  *
71  * @arg message The message that will be shown, exactly the same as that was passed
72  * to visual_log(), but after formatting.
73  *
74  * @arg funcname The name of the function that invokes visual_log(). On non-GNU systems
75  * this will probably be NULL.
76  *
77  * @arg priv Private field to be used by the client. The library will never touch this.
78  */
79 typedef void (*VisLogMessageHandlerFunc) (const char *message,
80 							const char *funcname, void *priv);
81 
82 void visual_log_set_verboseness (VisLogVerboseness verboseness);
83 VisLogVerboseness visual_log_get_verboseness (void);
84 
85 void visual_log_set_info_handler (VisLogMessageHandlerFunc handler, void *priv);
86 void visual_log_set_warning_handler (VisLogMessageHandlerFunc handler, void *priv);
87 void visual_log_set_critical_handler (VisLogMessageHandlerFunc handler, void *priv);
88 void visual_log_set_error_handler (VisLogMessageHandlerFunc handler, void *priv);
89 
90 void visual_log_set_all_messages_handler (VisLogMessageHandlerFunc handler, void *priv);
91 
92 /**
93  * Used for log messages, this is brought under a define so
94  * that the __FILE__ and __LINE__ macros (and probably __PRETTY_FUNC__) work,
95  * and thus provide better information.
96  *
97  * @see VisLogSeverity
98  *
99  * @param severity Determines the severity of the message using VisLogSeverity.
100  * @param format The format string of the log message.
101  */
102 #ifdef __GNUC__
103 
104 #ifdef LV_HAVE_ISO_VARARGS
105 #define visual_log(severity,...)		\
106 		_lv_log (severity,		\
107 			__FILE__,		\
108 			__LINE__,		\
109 			__PRETTY_FUNCTION__,	\
110 			__VA_ARGS__)
111 #elif defined(LV_HAVE_GNUC_VARARGS)
112 #define visual_log(severity,format...)		\
113 		_lv_log (severity,		\
114 			__FILE__,		\
115 			__LINE__,		\
116 			__PRETTY_FUNCTION__,	\
117 			format)
118 #else
119 
120 #include <signal.h>
121 
visual_log(VisLogSeverity severity,const char * fmt,...)122 static void visual_log (VisLogSeverity severity, const char *fmt, ...)
123 {
124 	char str[1024];
125 	va_list va;
126 	char sever_msg[10];
127 	VisLogVerboseness v;
128 
129 	assert (fmt != NULL);
130 
131 	va_start (va, fmt);
132 	vsnprintf (str, 1023, fmt, va);
133 	va_end (va);
134 
135 	switch (severity) {
136 		case VISUAL_LOG_DEBUG:
137 			strncpy (sever_msg, "DEBUG", 9);
138 			break;
139 		case VISUAL_LOG_INFO:
140 			strncpy (sever_msg, "INFO", 9);
141 			break;
142 		case VISUAL_LOG_WARNING:
143 			strncpy (sever_msg, "WARNING", 9);
144 			break;
145 		case VISUAL_LOG_CRITICAL:
146 			strncpy (sever_msg, "CRITICAL", 9);
147 			break;
148 		case VISUAL_LOG_ERROR:
149 			strncpy (sever_msg, "ERROR", 9);
150 			break;
151 		default:
152 			assert (0);
153 	}
154 	/*
155 	 * Sorry, we doesn't have (file,line) information
156 	 */
157 	v = visual_log_get_verboseness ();
158 	switch (severity) {
159 		case VISUAL_LOG_DEBUG:
160 			if (v == VISUAL_LOG_VERBOSENESS_HIGH)
161 				fprintf (stderr, "libvisual %s: %s: %s\n",
162 					sever_msg, __lv_progname, str);
163 			break;
164 		case VISUAL_LOG_INFO:
165 			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
166 				printf ("libvisual %s: %s: %s\n",
167 					sever_msg, __lv_progname, str);
168 			break;
169 		case VISUAL_LOG_WARNING:
170 			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
171 				fprintf (stderr, "libvisual %s: %s: %s\n",
172 					sever_msg, __lv_progname, str);
173 			break;
174 		case VISUAL_LOG_CRITICAL:
175 			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
176 				fprintf (stderr, "libvisual %s: %s: %s\n",
177 					sever_msg, __lv_progname, str);
178 			break;
179 		case VISUAL_LOG_ERROR:
180 			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
181 				printf ("libvisual %s: %s: %s\n",
182 					sever_msg, __lv_progname, str);
183 			visual_error_raise ();
184 			break;
185 	}
186 }
187 #endif /* !(ISO_VARARGS || GNUC_VARARGS) */
188 
189 #endif /* __GNUC__ */
190 
191 
192 #ifndef __GNUC__
193 
194 #ifdef LV_HAVE_ISO_VARARGS
195 #define visual_log(severity,...)		\
196 		_lv_log (severity,		\
197 			__FILE__,		\
198 			__LINE__,		\
199 			(NULL),			\
200 			__VA_ARGS__)
201 #else
202 
203 #include <signal.h>
204 
visual_log(VisLogSeverity severity,const char * fmt,...)205 static void visual_log (VisLogSeverity severity, const char *fmt, ...)
206 {
207 	char str[1024];
208 	va_list va;
209 	char sever_msg[10];
210 	VisLogVerboseness v;
211 
212 	assert (fmt != NULL);
213 
214 	va_start (va, fmt);
215 	vsnprintf (str, 1023, fmt, va);
216 	va_end (va);
217 
218 	switch (severity) {
219 		case VISUAL_LOG_DEBUG:
220 			strncpy (sever_msg, "DEBUG", 9);
221 			break;
222 		case VISUAL_LOG_INFO:
223 			strncpy (sever_msg, "INFO", 9);
224 			break;
225 		case VISUAL_LOG_WARNING:
226 			strncpy (sever_msg, "WARNING", 9);
227 			break;
228 		case VISUAL_LOG_CRITICAL:
229 			strncpy (sever_msg, "CRITICAL", 9);
230 			break;
231 		case VISUAL_LOG_ERROR:
232 			strncpy (sever_msg, "ERROR", 9);
233 			break;
234 		default:
235 			assert (0);
236 	}
237 	/*
238 	 * Sorry, we don't have (file,line) information
239 	 */
240 	v = visual_log_get_verboseness ();
241 	switch (severity) {
242 		case VISUAL_LOG_DEBUG:
243 			if (v == VISUAL_LOG_VERBOSENESS_HIGH)
244 				fprintf (stderr, "libvisual %s: %s: %s\n",
245 					sever_msg, __lv_progname, str);
246 			break;
247 		case VISUAL_LOG_INFO:
248 			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
249 				printf ("libvisual %s: %s: %s\n",
250 					sever_msg, __lv_progname, str);
251 			break;
252 		case VISUAL_LOG_WARNING:
253 			if (v >= VISUAL_LOG_VERBOSENESS_MEDIUM)
254 				fprintf (stderr, "libvisual %s: %s: %s\n",
255 					sever_msg, __lv_progname, str);
256 			break;
257 		case VISUAL_LOG_CRITICAL:
258 			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
259 				fprintf (stderr, "libvisual %s: %s: %s\n",
260 					sever_msg, __lv_progname, str);
261 			break;
262 		case VISUAL_LOG_ERROR:
263 			if (v >= VISUAL_LOG_VERBOSENESS_LOW)
264 				printf ("libvisual %s: %s: %s\n",
265 					sever_msg, __lv_progname, str);
266 			visual_error_raise ();
267 			break;
268 	}
269 }
270 #endif /* ISO_VARARGS */
271 
272 #endif /* !__GNUC__ */
273 
274 /**
275  * Return if @a expr is FALSE, showing a critical message with
276  * useful information.
277  */
278 #define visual_log_return_if_fail(expr)				\
279 	if (expr) { } else					\
280 	{							\
281 	visual_log (VISUAL_LOG_CRITICAL,			\
282 		 "assertion `%s' failed",			\
283 		#expr);						\
284 	return;							\
285 	}
286 
287 /**
288  * Return if @a val if @a expr is FALSE, showing a critical message
289  * with useful information.
290  */
291 #define visual_log_return_val_if_fail(expr, val)		\
292 	if (expr) { } else					\
293 	{							\
294 	visual_log (VISUAL_LOG_CRITICAL,			\
295 		 "assertion `%s' failed",			\
296 		#expr);						\
297 	return (val);						\
298 	}
299 
300 #if defined __GNUC__
301 void _lv_log (VisLogSeverity severity, const char *file,
302 		int line, const char *funcname, const char *fmt, ...)
303 			__attribute__ ((__format__ (__printf__, 5, 6)));
304 #else
305 void _lv_log (VisLogSeverity severity, const char *file,
306 		int line, const char *funcname, const char *fmt, ...);
307 #endif
308 
309 #ifdef __cplusplus
310 }
311 #endif /* __cplusplus */
312 
313 #endif /* _LV_LOG_H */
314