44c5f38e2a712f5cd4868e537cbc2dc669cfb2b7
[platform/upstream/gstreamer.git] / gst / gstinfo.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstinfo.c: INFO, ERROR, and DEBUG systems
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include "gst_private.h"
24 #include "gst.h"
25
26 extern gchar *_gst_progname;
27
28
29 /***** DEBUG system *****/
30 GHashTable *__gst_function_pointers = NULL;
31
32
33
34 /***** INFO system *****/
35 GstInfoHandler _gst_info_handler = gst_default_info_handler;
36 #ifdef GST_INFO_ENABLED_VERBOSE
37 guint32 _gst_info_categories = 0xffffffff;
38 #else
39 guint32 _gst_info_categories = 0x00000001;
40 #endif
41
42 static gchar *_gst_info_category_strings[] = {
43   "GST_INIT",
44   "COTHREADS",
45   "COTHREAD_SWITCH",
46   "AUTOPLUG",
47   "AUTOPLUG_ATTEMPT",
48   "PARENTAGE",
49   "STATES",
50   "PLANING",
51   "SCHEDULING",
52   "OPERATION",
53   "BUFFER",
54   "CAPS",
55   "CLOCK",
56   "ELEMENT_PADS",
57   "ELEMENTFACTORY",
58   "PADS",
59   "PIPELINE",
60   "PLUGIN_LOADING",
61   "PLUGIN_ERRORS",
62   "PROPERTIES",
63   "THREAD",
64   "TYPES",
65   "XML",
66 };
67
68 /**
69  * gst_default_info_handler:
70  * @category: category of the INFO message
71  * @file: the file the INFO occurs in
72  * @function: the function the INFO occurs in
73  * @line: the line number in the file
74  * @debug_string: the current debug_string in the function, if any
75  * @element: pointer to the #GstElement in question
76  * @string: the actual INFO string
77  *
78  * Prints out the INFO mesage in a variant of the following form:
79  *
80  *   INFO:gst_function:542(args): [elementname] something neat happened
81  */
82 void
83 gst_default_info_handler (gint category, gchar *file, gchar *function,
84                            gint line, gchar *debug_string,
85                            void *element, gchar *string)
86 {
87   gchar *empty = "";
88   gchar *elementname = empty,*location = empty;
89
90   if (debug_string == NULL) debug_string = "";
91   if (category != GST_CAT_GST_INIT)
92     location = g_strdup_printf("%s:%d%s:",function,line,debug_string);
93   if (element && GST_IS_ELEMENT (element))
94     elementname = g_strdup_printf (" [%s]",gst_element_get_name (element));
95
96   fprintf(stderr,"INFO:%s%s %s\n",location,elementname,string);
97
98   if (location != empty) g_free(location);
99   if (elementname != empty) g_free(elementname);
100
101   g_free(string);
102 }
103
104 /**
105  * gst_info_set_categories:
106  * @categories: bitmask of INFO categories to enable
107  *
108  * Enable the output of INFO categories based on the given bitmask.
109  * The bit for any given category is (1 << GST_CAT_...).
110  */
111 void
112 gst_info_set_categories (guint32 categories) {
113   _gst_info_categories = categories;
114   if (categories)
115     GST_INFO (0, "setting INFO categories to 0x%08X",categories);
116 }
117
118 /**
119  * gst_info_get_categories:
120  *
121  * Returns: the current bitmask of enabled INFO categories
122  * The bit for any given category is (1 << GST_CAT_...).
123  */
124 guint32
125 gst_info_get_categories () {
126   return _gst_info_categories;
127 }
128
129 /**
130  * gst_info_enable_category:
131  * @category: the category to enable
132  *
133  * Enables the given GST_CAT_... INFO category.
134  */
135 void
136 gst_info_enable_category (gint category) {
137   _gst_info_categories |= (1 << category);
138   if (_gst_info_categories)
139     GST_INFO (0, "setting INFO categories to 0x%08X",_gst_info_categories);
140 }
141
142 /**
143  * gst_info_disable_category:
144  * @category: the category to disable
145  *
146  * Disables the given GST_CAT_... INFO category.
147  */
148 void
149 gst_info_disable_category (gint category) {
150   _gst_info_categories &= ~ (1 << category);
151   if (_gst_info_categories)
152     GST_INFO (0, "setting INFO categories to 0x%08X",_gst_info_categories);
153 }
154
155
156
157 /***** DEBUG system *****/
158 guint32 _gst_debug_categories = 0x00000000;
159
160
161 /**
162  * gst_debug_set_categories:
163  * @categories: bitmask of DEBUG categories to enable
164  *
165  * Enable the output of DEBUG categories based on the given bitmask.
166  * The bit for any given category is (1 << GST_CAT_...).
167  */
168 void
169 gst_debug_set_categories (guint32 categories) {
170   _gst_debug_categories = categories;
171   if (categories)
172     GST_INFO (0, "setting DEBUG categories to 0x%08X",categories);
173 }
174
175 /**
176  * gst_debug_get_categories:
177  *
178  * Returns: the current bitmask of enabled DEBUG categories
179  * The bit for any given category is (1 << GST_CAT_...).
180  */
181 guint32
182 gst_debug_get_categories () {
183   return _gst_debug_categories;
184 }
185
186 /**
187  * gst_debug_enable_category:
188  * @category: the category to enable
189  *
190  * Enables the given GST_CAT_... DEBUG category.
191  */
192 void
193 gst_debug_enable_category (gint category) {
194   _gst_debug_categories |= (1 << category);
195   if (_gst_debug_categories)
196     GST_INFO (0, "setting DEBUG categories to 0x%08X",_gst_debug_categories);
197 }
198
199 /**
200  * gst_debug_disable_category:
201  * @category: the category to disable
202  *
203  * Disables the given GST_CAT_... DEBUG category.
204  */
205 void
206 gst_debug_disable_category (gint category) {
207   _gst_debug_categories &= ~ (1 << category);
208   if (_gst_debug_categories)
209     GST_INFO (0, "setting DEBUG categories to 0x%08X",_gst_debug_categories);
210 }
211
212 /**
213  * gst_get_category_name:
214  * @category: the category to return the name of
215  *
216  * Returns: string containing the name of the category
217  */
218 const gchar *
219 gst_get_category_name (gint category) {
220   if ((category >= 0) && (category < GST_CAT_MAX_CATEGORY))
221     return _gst_info_category_strings[category];
222   else
223     return NULL;
224 }
225
226
227
228 /***** ERROR system *****/
229 GstErrorHandler _gst_error_handler = gst_default_error_handler;
230
231 /**
232  * gst_default_error_handler:
233  * @file: the file the ERROR occurs in
234  * @function: the function the INFO occurs in
235  * @line: the line number in the file
236  * @debug_string: the current debug_string in the function, if any
237  * @element: pointer to the #GstElement in question
238  * @object: pointer to a related object
239  * @string: the actual ERROR string
240  *
241  * Prints out the given ERROR string in a variant of the following format:
242  *
243  * ***** GStreamer ERROR ***** in file gstsomething.c at gst_function:399(arg)
244  * Element: /pipeline/thread/element.src
245  * Error: peer is null!
246  * ***** attempting to stack trace.... *****
247  *
248  * At the end, it attempts to print the stack trace via GDB.
249  */
250 void
251 gst_default_error_handler (gchar *file, gchar *function,
252                            gint line, gchar *debug_string,
253                            void *element, void *object, gchar *string)
254 {
255   int chars = 0;
256   gchar *path;
257   int i;
258
259   // if there are NULL pointers, point them to null strings to clean up output
260   if (!debug_string) debug_string = "";
261   if (!string) string = "";
262
263   // print out a preamble
264   fprintf(stderr,"***** GStreamer ERROR ***** in file %s at %s:%d%s\n",
265           file,function,line,debug_string);
266
267   // if there's an element, print out the pertinent information
268   if (element) {
269     if (GST_IS_OBJECT(element)) {
270       path = gst_object_get_path_string(element);
271       fprintf(stderr,"Element: %s",path);
272       chars = 9 + strlen(path);
273       g_free(path);
274     } else {
275       fprintf(stderr,"Element ptr: %p",element);
276       chars = 15 + sizeof(void*)*2;
277     }
278   }
279
280   // if there's an object, print it out as well
281   if (object) {
282     // attempt to pad the line, or create a new one
283     if (chars < 40)
284       for (i=0;i<(40-chars)/8+1;i++) fprintf(stderr,"\t");
285     else
286       fprintf(stderr,"\n");
287
288     if (GST_IS_OBJECT(object)) {
289       path = gst_object_get_path_string(object);
290       fprintf(stderr,"Object: %s",path);
291       g_free(path);
292     } else {
293       fprintf(stderr,"Object ptr: %p",object);
294     }
295   }
296
297   fprintf(stderr,"\n");
298   fprintf(stderr,"Error: %s\n",string);
299
300   g_free(string);
301
302   fprintf(stderr,"***** attempting to stack trace.... *****\n");
303
304   g_on_error_stack_trace (_gst_progname);
305
306   exit(1);
307 }