1 /* vi: set et sw=4 ts=8 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 8 -*- */
3 /*
4 * This file is part of mission-control
5 *
6 * Copyright (C) 2007-2009 Nokia Corporation.
7 * Copyright (C) 2008 Collabora Ltd.
8 *
9 * Contact: Naba Kumar <naba.kumar@nokia.com>
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * version 2.1 as published by the Free Software Foundation.
14 *
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 *
25 */
26
27 /**
28 * SECTION:mcd-debug
29 * @title: Debugging
30 * @short_description: Debugging utilities
31 * @see_also:
32 * @stability: Unstable
33 * @include: mcd-debug.h
34 *
35 * FIXME
36 */
37
38 #include <config.h>
39
40 #include <stdlib.h>
41
42 #include <telepathy-glib/telepathy-glib.h>
43 #include <telepathy-glib/telepathy-glib-dbus.h>
44
45 #include <mission-control-plugins/mission-control-plugins.h>
46
47 #include "mcd-debug.h"
48 #include "mcd-operation.h"
49
50 gint mcd_debug_level = 0;
51
52 static void
mcd_debug_print_tree_real(gpointer object,gint level)53 mcd_debug_print_tree_real (gpointer object, gint level)
54 {
55 GString *indent_str;
56 gchar *indent = " ";
57 gint i;
58
59 indent_str = g_string_new ("");
60
61 for (i = 0; i < level; i++)
62 {
63 g_string_append (indent_str, indent);
64 }
65
66 g_debug ("%s%s (%p): %d", indent_str->str,
67 G_OBJECT_TYPE_NAME(object), object, G_OBJECT (object)->ref_count);
68
69 if (MCD_IS_OPERATION (object))
70 {
71 const GList *missions = mcd_operation_get_missions (MCD_OPERATION (object));
72 const GList *node = missions;
73 while (node)
74 {
75 mcd_debug_print_tree_real (node->data, level + 1);
76 node = g_list_next (node);
77 }
78 }
79 g_string_free (indent_str, TRUE);
80 }
81
82 /* We don't really have debug categories yet */
83
84 typedef enum {
85 MCD_DEBUG_MISC = 1 << 0,
86 MCD_DEBUG_TREES = 1 << 1
87 } McdDebugCategory;
88
89 static GDebugKey const keys[] = {
90 { "misc", MCD_DEBUG_MISC },
91 { "trees", MCD_DEBUG_TREES },
92 { NULL, 0 }
93 };
94
95 static McdDebugCategory categories = 0;
96
97 void
mcd_debug_print_tree(gpointer object)98 mcd_debug_print_tree (gpointer object)
99 {
100 g_return_if_fail (MCD_IS_MISSION (object));
101
102 if (categories & MCD_DEBUG_TREES)
103 {
104 g_debug ("Object Hierarchy of object %p", object);
105 g_debug ("[");
106 mcd_debug_print_tree_real (object, 1);
107 g_debug ("]");
108 }
109 }
110
mcd_debug_init()111 void mcd_debug_init ()
112 {
113 gchar *mc_debug_str;
114 guint level;
115
116 mc_debug_str = getenv ("MC_DEBUG");
117
118 if (mc_debug_str)
119 {
120 /* historically, MC_DEBUG was an integer; try that first */
121 level = atoi (mc_debug_str);
122
123 /* if it wasn't an integer; try interpreting it as a
124 * telepathy-glib-style flags-word */
125 if (level == 0)
126 {
127 categories = g_parse_debug_string (mc_debug_str, keys,
128 G_N_ELEMENTS (keys) - 1);
129 tp_debug_set_flags (mc_debug_str);
130
131 /* mcd-debug.h uses the value of mcd_debug_level directly, so
132 * we need to set it nonzero to get uncategorized messages */
133 if ((categories & MCD_DEBUG_MISC) != 0 && mcd_debug_level == 0)
134 {
135 mcd_debug_level = 1;
136 }
137 }
138 else
139 {
140 /* this is API, and will also try to set up categories from the
141 * level */
142 mcd_debug_set_level (level);
143 }
144 }
145
146 mcp_set_debug ((mcd_debug_level >= 1));
147 mcp_debug_init ();
148
149 tp_debug_divert_messages (g_getenv ("MC_LOGFILE"));
150
151 if (mcd_debug_level >= 1)
152 g_debug ("%s version %s", PACKAGE, VERSION);
153 }
154
155 void
mcd_debug_set_level(gint level)156 mcd_debug_set_level (gint level)
157 {
158 mcd_debug_level = level;
159
160 mcp_set_debug ((mcd_debug_level >= 1));
161
162 if (level >= 1)
163 {
164 categories |= MCD_DEBUG_MISC;
165 }
166 else
167 {
168 categories = 0;
169 }
170
171 if (level >= 2)
172 {
173 categories |= MCD_DEBUG_TREES;
174 }
175 }
176
177 void
mcd_debug(const gchar * format,...)178 mcd_debug (const gchar *format, ...)
179 {
180 gchar *message = NULL;
181 gchar **formatted = NULL;
182 TpDebugSender *dbg = tp_debug_sender_dup ();
183 va_list args;
184
185 if (_mcd_debug_get_level () > 0)
186 formatted = &message;
187
188 va_start (args, format);
189 tp_debug_sender_add_message_vprintf (dbg, NULL, formatted,
190 G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args);
191 va_end (args);
192
193 if (!tp_str_empty (message))
194 {
195 g_debug ("%s", message);
196 g_free (message);
197 }
198
199 /* NOTE: the sender must be cached elsewhere, or this gets EXPENSIVE: */
200 g_object_unref (dbg);
201 }
202