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