1 /*
2  * gedit-debug.c
3  * This file is part of gedit
4  *
5  * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
6  * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
7  * Copyright (C) 2002 - 2005 Paolo Maggi
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (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 General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include "gedit-debug.h"
24 #include <stdio.h>
25 
26 #define ENABLE_PROFILING
27 
28 #ifdef ENABLE_PROFILING
29 static GTimer *timer = NULL;
30 static gdouble last_time = 0.0;
31 #endif
32 
33 static GeditDebugSection enabled_sections = GEDIT_NO_DEBUG;
34 
35 #define DEBUG_IS_ENABLED(section) (enabled_sections & (section))
36 
37 /**
38  * gedit_debug_init:
39  *
40  * Initializes the debugging subsystem of gedit.
41  *
42  * The function checks for the existence of certain environment variables to
43  * determine whether to enable output for a debug section. To enable output
44  * for a specific debug section, set an environment variable of the same name;
45  * e.g. to enable output for the %GEDIT_DEBUG_PLUGINS section, set a
46  * <code>GEDIT_DEBUG_PLUGINS</code> environment variable. To enable output
47  * for all debug sections, set the <code>GEDIT_DEBUG</code> environment
48  * variable.
49  *
50  * This function must be called before any of the other debug functions are
51  * called. It must only be called once.
52  */
53 void
gedit_debug_init(void)54 gedit_debug_init (void)
55 {
56 	if (g_getenv ("GEDIT_DEBUG") != NULL)
57 	{
58 		/* enable all debugging */
59 		enabled_sections = ~GEDIT_NO_DEBUG;
60 		goto out;
61 	}
62 
63 	if (g_getenv ("GEDIT_DEBUG_VIEW") != NULL)
64 	{
65 		enabled_sections |= GEDIT_DEBUG_VIEW;
66 	}
67 	if (g_getenv ("GEDIT_DEBUG_PREFS") != NULL)
68 	{
69 		enabled_sections |= GEDIT_DEBUG_PREFS;
70 	}
71 	if (g_getenv ("GEDIT_DEBUG_WINDOW") != NULL)
72 	{
73 		enabled_sections |= GEDIT_DEBUG_WINDOW;
74 	}
75 	if (g_getenv ("GEDIT_DEBUG_PANEL") != NULL)
76 	{
77 		enabled_sections |= GEDIT_DEBUG_PANEL;
78 	}
79 	if (g_getenv ("GEDIT_DEBUG_PLUGINS") != NULL)
80 	{
81 		enabled_sections |= GEDIT_DEBUG_PLUGINS;
82 	}
83 	if (g_getenv ("GEDIT_DEBUG_TAB") != NULL)
84 	{
85 		enabled_sections |= GEDIT_DEBUG_TAB;
86 	}
87 	if (g_getenv ("GEDIT_DEBUG_DOCUMENT") != NULL)
88 	{
89 		enabled_sections |= GEDIT_DEBUG_DOCUMENT;
90 	}
91 	if (g_getenv ("GEDIT_DEBUG_COMMANDS") != NULL)
92 	{
93 		enabled_sections |= GEDIT_DEBUG_COMMANDS;
94 	}
95 	if (g_getenv ("GEDIT_DEBUG_APP") != NULL)
96 	{
97 		enabled_sections |= GEDIT_DEBUG_APP;
98 	}
99 	if (g_getenv ("GEDIT_DEBUG_UTILS") != NULL)
100 	{
101 		enabled_sections |= GEDIT_DEBUG_UTILS;
102 	}
103 
104 out:
105 
106 #ifdef ENABLE_PROFILING
107 	if (enabled_sections != GEDIT_NO_DEBUG)
108 	{
109 		timer = g_timer_new ();
110 	}
111 #endif
112 }
113 
114 /**
115  * gedit_debug:
116  * @section: debug section.
117  * @file: file name.
118  * @line: line number.
119  * @function: name of the function that is calling gedit_debug().
120  *
121  * If @section is enabled, then logs the trace information @file, @line, and
122  * @function.
123  */
124 void
gedit_debug(GeditDebugSection section,const gchar * file,gint line,const gchar * function)125 gedit_debug (GeditDebugSection  section,
126 	     const gchar       *file,
127 	     gint               line,
128 	     const gchar       *function)
129 {
130 	gedit_debug_message (section, file, line, function, "%s", "");
131 }
132 
133 /**
134  * gedit_debug_message:
135  * @section: debug section.
136  * @file: file name.
137  * @line: line number.
138  * @function: name of the function that is calling gedit_debug_message().
139  * @format: A g_vprintf() format string.
140  * @...: The format string arguments.
141  *
142  * If @section is enabled, then logs the trace information @file, @line, and
143  * @function along with the message obtained by formatting @format with the
144  * given format string arguments.
145  */
146 void
gedit_debug_message(GeditDebugSection section,const gchar * file,gint line,const gchar * function,const gchar * format,...)147 gedit_debug_message (GeditDebugSection  section,
148 		     const gchar       *file,
149 		     gint               line,
150 		     const gchar       *function,
151 		     const gchar       *format,
152 		     ...)
153 {
154 	if (G_UNLIKELY (DEBUG_IS_ENABLED (section)))
155 	{
156 		va_list args;
157 		gchar *msg;
158 
159 #ifdef ENABLE_PROFILING
160 		gdouble seconds;
161 
162 		g_return_if_fail (timer != NULL);
163 
164 		seconds = g_timer_elapsed (timer, NULL);
165 #endif
166 
167 		g_return_if_fail (format != NULL);
168 
169 		va_start (args, format);
170 		msg = g_strdup_vprintf (format, args);
171 		va_end (args);
172 
173 #ifdef ENABLE_PROFILING
174 		g_print ("[%f (%f)] %s:%d (%s) %s\n",
175 			 seconds,
176 			 seconds - last_time,
177 			 file,
178 			 line,
179 			 function,
180 			 msg);
181 
182 		last_time = seconds;
183 #else
184 		g_print ("%s:%d (%s) %s\n", file, line, function, msg);
185 #endif
186 
187 		fflush (stdout);
188 
189 		g_free (msg);
190 	}
191 }
192 
193 /**
194  * gedit_debug_plugin_message:
195  * @file: file name.
196  * @line: line number.
197  * @function: name of the function that is calling gedit_debug_plugin_message().
198  * @message: a message.
199  *
200  * If the section %GEDIT_DEBUG_PLUGINS is enabled, then logs the trace
201  * information @file, @line, and @function along with @message.
202  *
203  * This function may be overridden by GObject Introspection language bindings
204  * to be more language-specific.
205  *
206  * <emphasis>Python</emphasis>
207  *
208  * A PyGObject override is provided that has the following signature:
209  * <informalexample>
210  *   <programlisting>
211  *     def debug_plugin_message(format_str, *format_args):
212  *         #...
213  *   </programlisting>
214  * </informalexample>
215  *
216  * It automatically supplies parameters @file, @line, and @function, and it
217  * formats <code>format_str</code> with the given format arguments. The syntax
218  * of the format string is the usual Python string formatting syntax described
219  * by <ulink url="http://docs.python.org/library/stdtypes.html#string-formatting">5.6.2. String Formatting Operations</ulink>.
220  *
221  * Since: 3.4
222  */
223 void
gedit_debug_plugin_message(const gchar * file,gint line,const gchar * function,const gchar * message)224 gedit_debug_plugin_message (const gchar       *file,
225 			    gint               line,
226 			    const gchar       *function,
227 			    const gchar       *message)
228 {
229 	gedit_debug_message (GEDIT_DEBUG_PLUGINS, file, line, function, "%s", message);
230 }
231 
232 /* ex:set ts=8 noet: */
233