1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
3 * Copyright (C) 2006 Brent Smith <gnome@nextreality.net>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include <glib/gi18n.h>
22 #include <glib/gprintf.h>
26 #include "yelp-debug.h"
29 * @file: you should pass the __FILE__ constant as this parameter
30 * @line: you should pass the __LINE__ constant as this parameter
31 * @function: you should pass the __FUNCTION__ constant as this parameter
32 * @flags: should be one of #YelpDebugEnums. Arguments can be bitwise OR'd together.
33 * @format: the printf style format
35 * This function is not meant to be called directly, instead you should use the
36 * debug_print() macro which will pass the __FILE__, __LINE__, and __FUNCTION__
38 * The flags passed to the function identify the type of debug statement. Some action
39 * (usually a print to the console) will take place depending on if the corresponding
40 * flag is set in the YELP_DEBUG environment variable. YELP_DEBUG is a colon separated
41 * list of zero or more the following values:
42 * "log" - debug_print calls with DB_LOG, DB_INFO, DB_DEBUG, DB_WARN, and
43 * DB_ERROR will be printed to stdout
44 * "info" - debug_print calls with DB_INFO, DB_DEBUG, DB_WARN and DB_ERROR
45 * will be printed to stdout
46 * "debug" - debug_print calls with DB_DEBUG, DB_WARN, and DB_ERROR will be
48 * "warn" - debug_print calls with DB_WARN and DB_ERROR will be printed to
50 * "error" - debug_print calls with DB_ERROR will be printed to stdout
51 * "function-calls" - debug_print (DB_FUNCTION, ...) calls will be printed to stdout
52 * along with the function name
53 * "function-args" - debug_print (DB_ARG, ...) calls will be printed to stdout
54 * "enable-profiling" - debug_print (DB_PROFILE, ...) calls will make an access() call
55 * with a "MARK:" at the beginning: this is for profiling with
56 * Federico's plot-timeline.py python script:
57 * see http://primates.ximian.com/~federico/docs/login-profile/plot-timeline.py
58 * "all" - Turns on all options.
61 void yelp_debug (const gchar
*file
, guint line
,
62 const gchar
*function
, guint flags
, const gchar
*format
, ...)
64 static gboolean first_call
= TRUE
;
65 static guint debug_flags
= 0;
66 static gchar
**debug_files
= NULL
;
68 const gchar
*debugenv
= NULL
;
69 gchar
*formatted
= NULL
;
73 const GDebugKey debug_keys
[] = {
74 { "function-calls", DB_FUNCTION
},
75 { "function-args", DB_ARG
},
76 { "enable-profiling", DB_PROFILE
},
79 { "debug", DB_DEBUG
},
81 { "error", DB_ERROR
},
85 /* figure out which debug flags were set in the environment on the first
86 * call to this function */
88 debugenv
= g_getenv ("YELP_DEBUG");
91 debug_flags
= g_parse_debug_string (debugenv
, debug_keys
,
92 G_N_ELEMENTS (debug_keys
));
96 /* turn on all flags if "all" option was specified */
97 if (debug_flags
& DB_ALL
)
98 debug_flags
|= (DB_LOG
| DB_INFO
| DB_DEBUG
| DB_WARN
| DB_ERROR
|
99 DB_FUNCTION
| DB_ARG
| DB_PROFILE
);
101 /* turn on all higher severity logging levels; for instance if DB_LOG is set
102 * in debug_flags, then we turn on INFO, DEBUG, WARN and ERROR */
103 else if (debug_flags
& DB_LOG
)
104 debug_flags
|= (DB_INFO
| DB_DEBUG
| DB_WARN
| DB_ERROR
);
105 else if (debug_flags
& DB_INFO
)
106 debug_flags
|= (DB_DEBUG
| DB_WARN
| DB_ERROR
);
107 else if (debug_flags
& DB_DEBUG
)
108 debug_flags
|= (DB_WARN
| DB_ERROR
);
109 else if (debug_flags
& DB_WARN
)
110 debug_flags
|= (DB_ERROR
);
112 debugenv
= g_getenv ("YELP_DEBUG_FILTER");
114 if (debugenv
!= NULL
&& *debugenv
!= '\0')
115 debug_files
= g_strsplit (debugenv
, ":", -1);
122 /* if none of the flags are set either by the calling function
123 * or in the YELP_DEBUG environment variable, then just return */
124 if ((flags
& debug_flags
) == 0)
127 /* if the YELP_DEBUG_FILTER environment variable was specified with
128 * a colon delimited list of source files, then debug_files will not be
129 * NULL and will contain a list of files for which we print out debug
130 * statements. Check if this function was called from one of the files
131 * in the list. If not, return. */
132 if (debug_files
!= NULL
) {
133 for (i
=0; debug_files
[i
] != NULL
; i
++) {
134 if (*(debug_files
[i
]) == '\0')
136 if (g_strrstr (file
, debug_files
[i
]) != NULL
)
140 /* if we are on the NULL element, then a match was not found so
141 * we should return now */
142 if (debug_files
[i
] == NULL
)
146 va_start (args
, format
);
148 if (flags
& DB_FUNCTION
) {
149 g_fprintf (stdout
, "%s:%u: %s: ", file
, line
, function
);
150 g_vfprintf (stdout
, format
, args
);
151 } else if ((flags
& DB_LOG
) ||
153 (flags
& DB_DEBUG
) ||
155 (flags
& DB_ERROR
) ||
157 g_fprintf (stdout
, "%s:%u: ", file
, line
);
158 g_vfprintf (stdout
, format
, args
);
161 if (flags
& DB_PROFILE
) {
169 strftime (timestamp
, 20, "%H:%M:%S", tmp
);
170 formatted
= g_strdup_vprintf (format
, args
);
172 g_fprintf (stdout
, "PROFILE [%s]: %s\n", timestamp
, formatted
);
173 str
= g_strdup_printf ("MARK: %s: %s", g_get_prgname(), formatted
);