2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
29 #include <glib/gmacros.h>
35 /* This is needed in printf's if a char* might be NULL. Solaris crashes then */
36 #define GST_STR_NULL(str) ((str) ? (str) : "(NULL)")
38 /* FIXME: convert to using G_STRLOC all the way if we can ! */
41 #ifdef G_GNUC_PRETTY_FUNCTION
42 #define FUNCTION G_GNUC_PRETTY_FUNCTION
44 #define FUNCTION __func__
45 #elif HAVE_PRETTY_FUNCTION
46 #define FUNCTION __PRETTY_FUNCTION__
48 #define FUNCTION __FUNCTION__
52 #endif /* ifndef FUNCTION */
54 /***** are we in the core or not? *****/
55 #ifdef __GST_PRIVATE_H__
56 #define _GST_DEBUG_INCORE TRUE
58 #define _GST_DEBUG_INCORE FALSE
62 /* colorization stuff */
63 #ifdef GST_DEBUG_COLOR
64 #ifdef __GST_PRIVATE_H__ /* FIXME this should be some libgst.la -specific thing */
65 #define GST_DEBUG_CHAR_MODE "00"
67 #define GST_DEBUG_CHAR_MODE "01"
71 gint _gst_debug_stringhash_color(gchar *file);
75 /**********************************************************************
77 **********************************************************************/
79 const gchar * gst_get_category_name (gint category);
82 GST_CAT_GST_INIT = 0, /* Library initialization */
83 GST_CAT_COTHREADS, /* Cothread creation, etc. */
84 GST_CAT_COTHREAD_SWITCH, /* Cothread switching */
85 GST_CAT_AUTOPLUG, /* Successful autoplug results */
86 GST_CAT_AUTOPLUG_ATTEMPT, /* Attempted autoplug operations */
87 GST_CAT_PARENTAGE, /* GstBin parentage issues */
88 GST_CAT_STATES, /* State changes and such */
89 GST_CAT_PLANNING, /* Plan generation */
90 GST_CAT_SCHEDULING, /* Schedule construction */
91 GST_CAT_DATAFLOW, /* Events during actual data movement */
92 GST_CAT_BUFFER, /* Buffer creation/destruction */
93 GST_CAT_CAPS, /* Capabilities matching */
94 GST_CAT_CLOCK, /* Clocking */
95 GST_CAT_ELEMENT_PADS, /* Element pad management */
96 GST_CAT_ELEMENT_FACTORY, /* Elementfactory stuff */
97 GST_CAT_PADS, /* Pad creation/linking */
98 GST_CAT_PIPELINE, /* Pipeline stuff */
99 GST_CAT_PLUGIN_LOADING, /* Plugin loading */
100 GST_CAT_PLUGIN_ERRORS, /* Errors during plugin loading */
101 GST_CAT_PLUGIN_INFO, /* Plugin state information */
102 GST_CAT_PROPERTIES, /* Properties */
103 GST_CAT_THREAD, /* Thread creation/management */
104 GST_CAT_TYPES, /* Typing */
105 GST_CAT_XML, /* XML load/save of everything */
106 GST_CAT_NEGOTIATION, /* Caps Negotiation stuff */
107 GST_CAT_REFCOUNTING, /* Ref Counting stuff */
108 GST_CAT_EVENT, /* Event system */
109 GST_CAT_PARAMS, /* Dynamic parameters */
110 GST_CAT_APPLICATION, /* Application-defined debugging */
112 GST_CAT_CALL_TRACE = 30, /* Call tracing */
114 GST_CAT_MAX_CATEGORY = 31
117 extern const gchar *_gst_category_colors[32];
119 extern GStaticPrivate _gst_debug_cothread_index;
122 /**********************************************************************
124 **********************************************************************/
126 /* for include files that make too much noise normally */
127 #ifdef GST_DEBUG_FORCE_DISABLE
128 #undef GST_DEBUG_ENABLED
130 /* for applications that really really want all the noise */
131 #ifdef GST_DEBUG_FORCE_ENABLE
132 #define GST_DEBUG_ENABLED
135 /*#ifdef GST_DEBUG_ENABLED */
136 #define GST_DEBUG_ENABLE_CATEGORIES 0xffffffff
138 /*#define GST_DEBUG_ENABLE_CATEGORIES 0x00000000 */
142 typedef void (*GstDebugHandler) (gint category,gboolean core,
143 const gchar *file,const gchar *function,
144 gint line,const gchar *debug_string,
145 void *element,gchar *string);
147 void gst_default_debug_handler (gint category,gboolean incore,
148 const gchar *file, const gchar *function,
149 gint line,const gchar *debug_string,
150 void *element,gchar *string);
152 extern guint32 _gst_debug_categories;
153 extern GstDebugHandler _gst_debug_handler;
155 /* fallback, this should probably be a 'weak' symbol or something */
156 G_GNUC_UNUSED static gchar *_debug_string = NULL;
160 #ifdef G_HAVE_ISO_VARARGS
162 #ifdef GST_DEBUG_ENABLED
163 #define GST_DEBUG(cat, ...) G_STMT_START{ \
164 if ((1<<cat) & _gst_debug_categories) \
165 _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
166 NULL,g_strdup_printf( __VA_ARGS__ )); \
169 #define GST_DEBUG_ELEMENT(cat, element, ...) G_STMT_START{ \
170 if ((1<<cat) & _gst_debug_categories) \
171 _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
172 element,g_strdup_printf( __VA_ARGS__ )); \
176 #define GST_DEBUG(cat, ...)
177 #define GST_DEBUG_ELEMENT(cat,element, ...)
180 #elif defined(G_HAVE_GNUC_VARARGS)
182 #ifdef GST_DEBUG_ENABLED
183 #define GST_DEBUG(cat,format,args...) G_STMT_START{ \
184 if ((1<<cat) & _gst_debug_categories) \
185 _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
186 NULL,g_strdup_printf( format , ## args )); \
189 #define GST_DEBUG_ELEMENT(cat,element,format,args...) G_STMT_START{ \
190 if ((1<<cat) & _gst_debug_categories) \
191 _gst_debug_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
192 element,g_strdup_printf( format , ## args )); \
196 #define GST_DEBUG(cat,format,args...)
197 #define GST_DEBUG_ELEMENT(cat,element,format,args...)
205 /********** some convenience macros for debugging **********/
206 #define GST_DEBUG_PAD_NAME(pad) \
207 (GST_OBJECT_PARENT(pad) != NULL) ? \
208 GST_STR_NULL (GST_OBJECT_NAME (GST_OBJECT_PARENT(pad))) : \
209 "''", GST_OBJECT_NAME (pad)
211 #ifdef G_HAVE_ISO_VARARGS
213 #ifdef GST_DEBUG_COLOR
214 #define GST_DEBUG_ENTER(...) GST_DEBUG( 31 , "\033[00;37mentering\033[00m: " __VA_ARGS__ )
215 #define GST_DEBUG_LEAVE(...) GST_DEBUG( 31 , "\033[00;37mleaving\033[00m: " __VA_ARGS__ )
217 #define GST_DEBUG_ENTER(...) GST_DEBUG( 31 , "entering: " __VA_ARGS__ )
218 #define GST_DEBUG_LEAVE(...) GST_DEBUG( 31 , "leaving: " __VA_ARGS__ )
221 #elif defined(G_HAVE_GNUC_VARARGS)
223 #ifdef GST_DEBUG_COLOR
224 #define GST_DEBUG_ENTER(format, args...) GST_DEBUG( 31 , format ": \033[00;37mentering\033[00m" , ##args )
225 #define GST_DEBUG_LEAVE(format, args...) GST_DEBUG( 31 , format ": \033[00;37mleaving\033[00m" , ##args )
227 #define GST_DEBUG_ENTER(format, args...) GST_DEBUG( 31 , format ": entering" , ##args )
228 #define GST_DEBUG_LEAVE(format, args...) GST_DEBUG( 31 , format ": leaving" , ##args )
234 /***** Colorized debug for thread ids *****/
235 #ifdef GST_DEBUG_COLOR
236 #define GST_DEBUG_THREAD_FORMAT "\033[00;%dm%d\033[00m"
237 #define GST_DEBUG_THREAD_ARGS(id) ( ((id) < 0) ? 37 : ((id) % 6 + 31) ), (id)
239 #define GST_DEBUG_THREAD_FORMAT "%d"
240 #define GST_DEBUG_THREAD_ARGS(id) (id)
245 /**********************************************************************
246 * The following is a DEBUG_ENTER implementation that will wrap the
247 * function it sits at the head of. It removes the need for a
248 * DEBUG_LEAVE call. However, it segfaults whenever it gets anywhere
249 * near cothreads. We will not use it for the moment.
251 typedef void (*_debug_function_f)();
252 G_GNUC_UNUSED static gchar *_debug_string_pointer = NULL;
253 G_GNUC_UNUSED static GModule *_debug_self_module = NULL;
255 #ifdef G_HAVE_ISO_VARARGS
257 #define _DEBUG_ENTER_BUILTIN(...) \
258 static int _debug_in_wrapper = 0; \
259 gchar *_debug_string = ({ \
260 if (!_debug_in_wrapper) { \
261 void *_return_value; \
262 gchar *_debug_string; \
263 _debug_function_f function; \
264 void *_function_args = __builtin_apply_args(); \
265 _debug_in_wrapper = 1; \
266 _debug_string = g_strdup_printf(GST_DEBUG_PREFIX("")); \
267 _debug_string_pointer = _debug_string; \
268 fprintf(stderr,"%s: entered " FUNCTION, _debug_string); \
269 fprintf(stderr, __VA_ARGS__ ); \
270 fprintf(stderr,"\n"); \
271 if (_debug_self_module == NULL) _debug_self_module = g_module_open(NULL,0); \
272 g_module_symbol(_debug_self_module,FUNCTION,(gpointer *)&function); \
273 _return_value = __builtin_apply(function,_function_args,64); \
274 fprintf(stderr,"%s: left " FUNCTION, _debug_string); \
275 fprintf(stderr, __VA_ARGS__); \
276 fprintf(stderr,"\n"); \
277 g_free(_debug_string); \
278 __builtin_return(_return_value); \
280 _debug_in_wrapper = 0; \
282 _debug_string_pointer; \
285 #elif defined(G_HAVE_GNUC_VARARGS)
287 #define _DEBUG_ENTER_BUILTIN(format,args...) \
288 static int _debug_in_wrapper = 0; \
289 gchar *_debug_string = ({ \
290 if (!_debug_in_wrapper) { \
291 void *_return_value; \
292 gchar *_debug_string; \
293 _debug_function_f function; \
294 void *_function_args = __builtin_apply_args(); \
295 _debug_in_wrapper = 1; \
296 _debug_string = g_strdup_printf(GST_DEBUG_PREFIX("")); \
297 _debug_string_pointer = _debug_string; \
298 fprintf(stderr,"%s: entered " FUNCTION format "\n" , _debug_string , ## args ); \
299 if (_debug_self_module == NULL) _debug_self_module = g_module_open(NULL,0); \
300 g_module_symbol(_debug_self_module,FUNCTION,(gpointer *)&function); \
301 _return_value = __builtin_apply(function,_function_args,64); \
302 fprintf(stderr,"%s: left " FUNCTION format "\n" , _debug_string , ## args ); \
303 g_free(_debug_string); \
304 __builtin_return(_return_value); \
306 _debug_in_wrapper = 0; \
308 _debug_string_pointer; \
313 * WARNING: there's a gcc CPP bug lurking in here. The extra space before the ##args *
314 * somehow make the preprocessor leave the _debug_string. If it's removed, the *
315 * _debug_string somehow gets stripped along with the ##args, and that's all she wrote. *
317 #ifdef G_HAVE_ISO_VARARGS
319 #define _DEBUG_BUILTIN(...) \
320 if (_debug_string != (void *)-1) { \
321 if (_debug_string) { \
322 fprintf(stderr, "%s: " _debug_string); \
323 fprintf(stderr, __VA_ARGS__); \
325 fprintf(stderr,GST_DEBUG_PREFIX(": " __VA_ARGS__)); \
329 #elif defined(G_HAVE_GNUC_VARARGS)
331 #define _DEBUG_BUILTIN(format,args...) \
332 if (_debug_string != (void *)-1) { \
334 fprintf(stderr,"%s: " format , _debug_string , ## args); \
336 fprintf(stderr,GST_DEBUG_PREFIX(": " format , ## args)); \
345 /**********************************************************************
347 **********************************************************************/
349 typedef void (*GstInfoHandler) (gint category,gboolean incore,
350 const gchar *file,const gchar *function,
351 gint line,const gchar *debug_string,
352 void *element,gchar *string);
354 void gst_default_info_handler (gint category,gboolean incore,
355 const gchar *file,const gchar *function,
356 gint line,const gchar *debug_string,
357 void *element,gchar *string);
359 extern GstInfoHandler _gst_info_handler;
360 extern guint32 _gst_info_categories;
362 /* for include files that make too much noise normally */
363 #ifdef GST_INFO_FORCE_DISABLE
364 #undef GST_INFO_ENABLED
366 /* for applications that really really want all the noise */
367 #ifdef GST_INFO_FORCE_ENABLE
368 #define GST_INFO_ENABLED
371 #ifdef G_HAVE_ISO_VARARGS
373 #ifdef GST_INFO_ENABLED
374 #define GST_INFO(cat,...) G_STMT_START{ \
375 if ((1<<cat) & _gst_info_categories) \
376 _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
377 NULL,g_strdup_printf( __VA_ARGS__ )); \
380 #define GST_INFO_ELEMENT(cat,element,...) G_STMT_START{ \
381 if ((1<<cat) & _gst_info_categories) \
382 _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
383 element,g_strdup_printf( __VA_ARGS__ )); \
387 #define GST_INFO(cat,...)
388 #define GST_INFO_ELEMENT(cat,element,...)
391 #elif defined(G_HAVE_GNUC_VARARGS)
393 #ifdef GST_INFO_ENABLED
394 #define GST_INFO(cat,format,args...) G_STMT_START{ \
395 if ((1<<cat) & _gst_info_categories) \
396 _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
397 NULL,g_strdup_printf( format , ## args )); \
400 #define GST_INFO_ELEMENT(cat,element,format,args...) G_STMT_START{ \
401 if ((1<<cat) & _gst_info_categories) \
402 _gst_info_handler(cat,_GST_DEBUG_INCORE,__FILE__,FUNCTION,__LINE__,_debug_string, \
403 element,g_strdup_printf( format , ## args )); \
407 #define GST_INFO(cat,format,args...)
408 #define GST_INFO_ELEMENT(cat,element,format,args...)
414 void gst_info_set_categories (guint32 categories);
415 guint32 gst_info_get_categories (void);
416 void gst_info_enable_category (gint category);
417 void gst_info_disable_category (gint category);
419 void gst_debug_set_categories (guint32 categories);
420 guint32 gst_debug_get_categories (void);
421 void gst_debug_enable_category (gint category);
422 void gst_debug_disable_category (gint category);
427 /**********************************************************************
429 **********************************************************************/
431 typedef void (*GstErrorHandler) (gchar *file,gchar *function,
432 gint line,gchar *debug_string,
433 void *element,void *object,gchar *string);
435 void gst_default_error_handler (gchar *file,gchar *function,
436 gint line,gchar *debug_string,
437 void *element,void *object,gchar *string);
439 extern GstErrorHandler _gst_error_handler;
441 #ifdef G_HAVE_ISO_VARARGS
443 #define GST_ERROR(element,...) \
444 _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
445 element,NULL,g_strdup_printf( __VA_ARGS__ ))
447 #define GST_ERROR_OBJECT(element,object,...) \
448 _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
449 element,object,g_strdup_printf( __VA_ARGS__ ))
451 #elif defined(G_HAVE_GNUC_VARARGS)
453 #define GST_ERROR(element,format,args...) \
454 _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
455 element,NULL,g_strdup_printf( format , ## args ))
457 #define GST_ERROR_OBJECT(element,object,format,args...) \
458 _gst_error_handler(__FILE__,FUNCTION,__LINE__,_debug_string, \
459 element,object,g_strdup_printf( format , ## args ))
463 /********** function pointer stuff **********/
464 #if GST_DEBUG_ENABLED
465 void* _gst_debug_register_funcptr (void *ptr, gchar *ptrname);
466 gchar* _gst_debug_nameof_funcptr (void *ptr);
468 #define GST_DEBUG_FUNCPTR(ptr) (_gst_debug_register_funcptr((void *)(ptr), #ptr) , ptr)
469 #define GST_DEBUG_FUNCPTR_NAME(ptr) _gst_debug_nameof_funcptr((void *)ptr)
471 #define GST_DEBUG_FUNCPTR(ptr) (ptr)
472 #define GST_DEBUG_FUNCPTR_NAME(ptr) ""
473 #endif /* GST_DEBUG_ENABLED */
475 void gst_debug_print_stack_trace (void);
477 #endif /* __GSTINFO_H__ */