From 23c4294bb9b64025f67141a104f116eaa28c9207 Mon Sep 17 00:00:00 2001 From: Brent Smith Date: Mon, 12 Jun 2006 02:17:56 +0000 Subject: add yelp-debug.[ch] * src/Makefile.am: add yelp-debug.[ch] * src/yelp-debug.c: (yelp_debug): * src/yelp-debug.h: New debug functions that enable printing of debug statements at runtime when compiled with --enable-debug * src/yelp-man-pager.c: (man_pager_parse): * src/yelp-toc-pager.c: (yelp_toc_pager_pause), (yelp_toc_pager_unpause), (toc_pager_error), (toc_pager_cancel), (toc_pager_finish), (toc_pager_process), (create_toc_from_index), (process_mandir_pending): * src/yelp-utils.c: (yelp_doc_info_new), (yelp_doc_info_get), (yelp_doc_info_free), (yelp_doc_info_add_uri): Modified to use new debug infrastructure --- ChangeLog | 17 +++++ src/Makefile.am | 1 + src/yelp-debug.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/yelp-debug.h | 68 ++++++++++++++++++++ src/yelp-man-pager.c | 3 +- src/yelp-toc-pager.c | 42 +++++++------ src/yelp-utils.c | 33 +++++----- 7 files changed, 297 insertions(+), 40 deletions(-) create mode 100644 src/yelp-debug.c create mode 100644 src/yelp-debug.h diff --git a/ChangeLog b/ChangeLog index fb9bd113..726fe47f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2006-06-11 Brent Smith + + * src/Makefile.am: + add yelp-debug.[ch] + * src/yelp-debug.c: (yelp_debug): + * src/yelp-debug.h: + New debug functions that enable printing of debug statements + at runtime when compiled with --enable-debug + * src/yelp-man-pager.c: (man_pager_parse): + * src/yelp-toc-pager.c: (yelp_toc_pager_pause), + (yelp_toc_pager_unpause), (toc_pager_error), (toc_pager_cancel), + (toc_pager_finish), (toc_pager_process), (create_toc_from_index), + (process_mandir_pending): + * src/yelp-utils.c: (yelp_doc_info_new), (yelp_doc_info_get), + (yelp_doc_info_free), (yelp_doc_info_add_uri): + Modified to use new debug infrastructure + 2006-06-11 Brent Smith * src/yelp-man-pager.c: (man_pager_parse): diff --git a/src/Makefile.am b/src/Makefile.am index eea724d3..bf1718b9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -6,6 +6,7 @@ yelp_SOURCES = \ yelp-bookmarks.c yelp-bookmarks.h \ yelp-db-pager.c yelp-db-pager.h \ yelp-db-print-pager.c yelp-db-print-pager.h \ + yelp-debug.c yelp-debug.h \ yelp-error.c yelp-error.h \ yelp-gecko-utils.cpp yelp-gecko-utils.h \ yelp-html.cpp yelp-html.h \ diff --git a/src/yelp-debug.c b/src/yelp-debug.c new file mode 100644 index 00000000..d5796a50 --- /dev/null +++ b/src/yelp-debug.c @@ -0,0 +1,173 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Copyright (C) 2006 Brent Smith + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include + +#include "yelp-debug.h" + +GDebugKey debug_keys[] = { + { "function-calls", DB_FUNCTION }, + { "function-args", DB_ARG }, + { "enable-profiling", DB_PROFILE }, + { "log", DB_LOG }, + { "info", DB_INFO }, + { "debug", DB_DEBUG }, + { "warn", DB_WARN }, + { "error", DB_ERROR }, + { "all", DB_ALL } +}; + +/** + * @file: you should pass the __FILE__ constant as this parameter + * @line: you should pass the __LINE__ constant as this parameter + * @function: you should pass the __FUNCTION__ constant as this parameter + * @flags: should be one of #YelpDebugEnums. Arguments can be bitwise OR'd together. + * @format: the printf style format + * + * This function is not meant to be called directly, instead you should use the + * debug_print() macro which will pass the __FILE__, __LINE__, and __FUNCTION__ + * constants for you. + * The flags passed to the function identify the type of debug statement. Some action + * (usually a print to the console) will take place depending on if the corresponding + * flag is set in the YELP_DEBUG environment variable. YELP_DEBUG is a colon separated + * list of zero or more the following values: + * "log" - debug_print calls with DB_LOG, DB_INFO, DB_DEBUG, DB_WARN, and + * DB_ERROR will be printed to stdout + * "info" - debug_print calls with DB_INFO, DB_DEBUG, DB_WARN and DB_ERROR + * will be printed to stdout + * "debug" - debug_print calls with DB_DEBUG, DB_WARN, and DB_ERROR will be + * printed to stdout + * "warn" - debug_print calls with DB_WARN and DB_ERROR will be printed to + * stdout + * "error" - debug_print calls with DB_ERROR will be printed to stdout + * "function-calls" - debug_print (DB_FUNCTION, ...) calls will be printed to stdout + * along with the function name + * "function-args" - debug_print (DB_ARG, ...) calls will be printed to stdout + * "enable-profiling" - debug_print (DB_PROFILE, ...) calls will make an access() call + * with a "MARK:" at the beginning: this is for profiling with + * Federico's plot-timeline.py python script: + * see http://primates.ximian.com/~federico/docs/login-profile/plot-timeline.py + * "all" - Turns on all options. + * + */ +void yelp_debug (const gchar *file, guint line, + const gchar *function, guint flags, const gchar *format, ...) +{ + static gboolean first_call = TRUE; + static guint debug_flags = 0; + static gchar **debug_files = NULL; + va_list args; + const gchar *debugenv = NULL; + gchar *formatted = NULL; + gchar *str = NULL; + gint i; + + /* figure out which debug flags were set in the environment on the first + * call to this function */ + if (first_call) { + debugenv = g_getenv ("YELP_DEBUG"); + + if (debugenv != NULL) + debug_flags = g_parse_debug_string (debugenv, debug_keys, + G_N_ELEMENTS (debug_keys)); + else + debug_flags = 0; + + /* turn on all flags if "all" option was specified */ + if (debug_flags & DB_ALL) + debug_flags |= (DB_LOG | DB_INFO | DB_DEBUG | DB_WARN | DB_ERROR | + DB_FUNCTION | DB_ARG | DB_PROFILE); + + /* turn on all higher severity logging levels; for instance if DB_LOG is set + * in debug_flags, then we turn on INFO, DEBUG, WARN and ERROR */ + else if (debug_flags & DB_LOG) + debug_flags |= (DB_INFO | DB_DEBUG | DB_WARN | DB_ERROR); + else if (debug_flags & DB_INFO) + debug_flags |= (DB_DEBUG | DB_WARN | DB_ERROR); + else if (debug_flags & DB_DEBUG) + debug_flags |= (DB_WARN | DB_ERROR); + else if (debug_flags & DB_WARN) + debug_flags |= (DB_ERROR); + + g_print ("debug_flags = %x\n", debug_flags); + + debugenv = g_getenv ("YELP_DEBUG_FILTER"); + + if (debugenv != NULL && *debugenv != '\0') + debug_files = g_strsplit (debugenv, ":", -1); + else + debug_files = NULL; + + first_call = FALSE; + } + + /* if none of the flags are set either by the calling function + * or in the YELP_DEBUG environment variable, then just return */ + if ((flags & debug_flags) == 0) + return; + + /* if the YELP_DEBUG_FILTER environment variable was specified with + * a colon delimited list of source files, then debug_files will not be + * NULL and will contain a list of files for which we print out debug + * statements. Check if this function was called from one of the files + * in the list. If not, return. */ + if (debug_files != NULL) { + for (i=0; debug_files[i] != NULL; i++) { + if (*(debug_files[i]) == '\0') + continue; + if (g_strrstr (file, debug_files[i]) != NULL) + break; + } + + /* if we are on the NULL element, then a match was not found so + * we should return now */ + if (debug_files[i] == NULL) + return; + } + + va_start (args, format); + + if (flags & DB_FUNCTION) { + g_fprintf (stdout, "%s:%u: %s: ", file, line, function); + g_vfprintf (stdout, format, args); + } else if ((flags & DB_LOG) || + (flags & DB_INFO) || + (flags & DB_DEBUG) || + (flags & DB_WARN) || + (flags & DB_ERROR) || + (flags & DB_ARG)) { + g_fprintf (stdout, "%s:%u: ", file, line); + g_vfprintf (stdout, format, args); + } + + if (flags & DB_PROFILE) { + formatted = g_strdup_vprintf (format, args); + str = g_strdup_printf ("MARK: %s: %s", g_get_prgname(), formatted); + access (str, F_OK); + g_free (formatted); + g_free (str); + } + + va_end (args); +} diff --git a/src/yelp-debug.h b/src/yelp-debug.h new file mode 100644 index 00000000..50d6ba13 --- /dev/null +++ b/src/yelp-debug.h @@ -0,0 +1,68 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2006 Brent Smith + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __YELP_DEBUG_H__ +#define __YELP_DEBUG_H__ + +#include +#include + +typedef enum { + DB_FUNCTION = 1 << 0, + DB_ARG = 1 << 1, + DB_PROFILE = 1 << 2, + DB_LOG = 1 << 3, + DB_INFO = 1 << 4, + DB_DEBUG = 1 << 5, + DB_WARN = 1 << 6, + DB_ERROR = 1 << 7, + DB_ALL = 1 << 8 +} YelpDebugEnums; + +#if __STDC_VERSION__ < 199901L +# if __GNUC__ >= 2 +# define __func__ __FUNCTION__ +# else +# define __func__ "" +# endif +#endif + +/* __VA_ARGS__ is C99 compliant but may not work on older versions of cpp, + * so we provide a fallback */ +#ifdef YELP_DEBUG +# if __STDC_VERSION__ < 199901L +# define debug_print(format, args...) yelp_debug (__FILE__, __LINE__, __func__, format, args) +# else +# define debug_print(format, ...) yelp_debug (__FILE__, __LINE__, __func__, format, __VA_ARGS__) +# endif +#else +# define debug_print(format, ...) +#endif + +#ifdef YELP_DEBUG +# define d(x) x +#else +# define d(x) +#endif + +void yelp_debug (const gchar *file, guint line, + const gchar *function, guint flags, const gchar *format, ...); + +#endif /* __YELP_DEBUG_H__ */ diff --git a/src/yelp-man-pager.c b/src/yelp-man-pager.c index c1d7da5b..a7d7ba71 100644 --- a/src/yelp-man-pager.c +++ b/src/yelp-man-pager.c @@ -40,6 +40,7 @@ #include "yelp-man-pager.h" #include "yelp-man-parser.h" #include "yelp-settings.h" +#include "yelp-debug.h" #define STYLESHEET_PATH DATADIR"/yelp/xslt/" #define MAN_STYLESHEET STYLESHEET_PATH"man2html.xsl" @@ -237,7 +238,7 @@ man_pager_parse (YelpPager *pager) /* We use the language to determine which encoding the manual * page is in */ language = yelp_doc_info_get_language (doc_info); - g_print ("The language of the man page is %s\n", language); + debug_print (DB_INFO, "The language of the man page is %s\n", language); /* default encoding if the language doesn't match below */ encoding = g_getenv("MAN_ENCODING"); diff --git a/src/yelp-toc-pager.c b/src/yelp-toc-pager.c index 60faf670..38753362 100644 --- a/src/yelp-toc-pager.c +++ b/src/yelp-toc-pager.c @@ -46,18 +46,13 @@ #include #include +#include "yelp-debug.h" #include "yelp-error.h" #include "yelp-settings.h" #include "yelp-toc-pager.h" #include "yelp-utils.h" #include "yelp-io-channel.h" -#ifdef YELP_DEBUG -#define d(x) x -#else -#define d(x) -#endif - #define YELP_NAMESPACE "http://www.gnome.org/yelp/ns" #define STYLESHEET_PATH DATADIR"/yelp/xslt/" @@ -246,10 +241,12 @@ yelp_toc_pager_pause (YelpTocPager *pager) { g_return_if_fail (pager != NULL); - d (g_print ("yelp_toc_pager_pause\n")); - d (g_print (" pause_caunt = %i\n", pager->priv->pause_count + 1)); + debug_print (DB_FUNCTION, "entering\n"); + debug_print (DB_ARG, " pause_count = %i\n", pager->priv->pause_count + 1); pager->priv->pause_count = pager->priv->pause_count + 1; + + debug_print (DB_FUNCTION, "exiting\n"); } void @@ -257,8 +254,8 @@ yelp_toc_pager_unpause (YelpTocPager *pager) { g_return_if_fail (pager != NULL); - d (g_print ("yelp_toc_pager_unpause\n")); - d (g_print (" pause_caunt = %i\n", pager->priv->pause_count - 1)); + debug_print (DB_FUNCTION, "entering\n"); + debug_print (DB_ARG, " pause_count = %i\n", pager->priv->pause_count - 1); pager->priv->pause_count = pager->priv->pause_count - 1; if (pager->priv->pause_count < 0) { @@ -271,6 +268,8 @@ yelp_toc_pager_unpause (YelpTocPager *pager) (GtkFunction) toc_process_pending, pager); } + + debug_print (DB_FUNCTION, "exiting\n"); } /******************************************************************************/ @@ -278,7 +277,7 @@ yelp_toc_pager_unpause (YelpTocPager *pager) static void toc_pager_error (YelpPager *pager) { - d (g_print ("toc_pager_error\n")); + debug_print (DB_FUNCTION, "entering\n"); yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR); } @@ -287,7 +286,7 @@ toc_pager_cancel (YelpPager *pager) { YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - d (g_print ("toc_pager_cancel\n")); + debug_print (DB_FUNCTION, "entering\n"); yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID); priv->cancel = TRUE; @@ -296,7 +295,7 @@ toc_pager_cancel (YelpPager *pager) static void toc_pager_finish (YelpPager *pager) { - d (g_print ("toc_pager_finish\n")); + debug_print (DB_FUNCTION, "entering\n"); yelp_pager_set_state (pager, YELP_PAGER_STATE_FINISHED); } @@ -305,7 +304,7 @@ toc_pager_process (YelpPager *pager) { YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv; - d (g_print ("toc_pager_process\n")); + debug_print (DB_FUNCTION, "entering\n"); yelp_pager_set_state (pager, YELP_PAGER_STATE_PARSING); g_signal_emit_by_name (pager, "parse"); @@ -1074,8 +1073,9 @@ create_toc_from_index (YelpTocPager *pager, gchar *index_file) * by the LANGUAGE environment variable) then return so that the index * is recreated */ if (language == NULL || !g_str_equal (BAD_CAST language, langs[0])) { - g_print (_("Current language and index file language do not match.\n" - "The index file will be recreated.\n")); + debug_print (DB_INFO, + "LANGUAGE and index file language do not match, " + "index file will be recreated.\n"); xmlFreeDoc (manindex_xml); return 0; } @@ -1356,18 +1356,20 @@ process_mandir_pending (YelpTocPager *pager) } priv->mandir_list = g_slist_reverse (priv->mandir_list); +#ifdef YELP_DEBUG /* debugging: print out lists in order */ - /*GSList *list1 = priv->mandir_list; + GSList *list1 = priv->mandir_list; GSList *list2 = NULL; while (list1 != NULL) { list2 = list1->data; while (list2 && list2->data) { - g_print ("Dir=%s\n", (gchar *)list2->data); + debug_print (DB_INFO, "Dir=%s\n", (gchar *)list2->data); list2 = g_slist_next (list2); } list1 = g_slist_next (list1); - }*/ + } +#endif g_strfreev (manpaths); @@ -1391,7 +1393,7 @@ process_mandir_pending (YelpTocPager *pager) gchar *lang = NULL; if (g_stat (dirname, &buf) < 0) - g_warning ("Unable to stat dir: \"%s\"\n", dirname); + debug_print (DB_WARN, "Unable to stat dir: \"%s\"\n", dirname); /* check to see if we need create a new hash table */ if (!priv->man_manhash) { diff --git a/src/yelp-utils.c b/src/yelp-utils.c index 089cbb99..48cce7fe 100644 --- a/src/yelp-utils.c +++ b/src/yelp-utils.c @@ -33,15 +33,10 @@ #include #include "yelp-utils.h" +#include "yelp-debug.h" #include -#ifdef YELP_DEBUG -#define d(x) x -#else -#define d(x) -#endif - static GHashTable *doc_info_table; typedef struct { @@ -132,8 +127,8 @@ yelp_doc_info_new (const gchar *uri, gboolean trust_uri) g_return_val_if_fail (uri != NULL, NULL); - d (g_print ("yelp_doc_info_new\n")); - d (g_print (" uri = \"%s\"\n", uri)); + debug_print (DB_FUNCTION, "entering\n"); + debug_print (DB_ARG, " uri = \"%s\"\n", uri); if (trust_uri) full_uri = gnome_vfs_make_uri_from_input (uri); @@ -192,9 +187,9 @@ yelp_doc_info_new (const gchar *uri, gboolean trust_uri) doc_type = YELP_DOC_TYPE_EXTERNAL; uri_type = YELP_URI_TYPE_EXTERNAL; } - - d (g_print (" full_uri = \"%s\"\n", full_uri)); - d (g_print (" doc_uri = \"%s\"\n", doc_uri)); + + debug_print (DB_ARG, " full_uri = \"%s\"\n", full_uri); + debug_print (DB_ARG, " doc_uri = \"%s\"\n", doc_uri); g_free (full_uri); @@ -226,8 +221,8 @@ yelp_doc_info_get (const gchar *uri, gboolean trust_uri) g_return_val_if_fail (uri != NULL, NULL); - d (g_print ("yelp_doc_info_get\n")); - d (g_print (" uri = \"%s\"\n", uri)); + debug_print (DB_FUNCTION, "entering\n"); + debug_print (DB_ARG, " uri = \"%s\"\n", uri); if (!doc_info_table) doc_info_table = @@ -306,8 +301,8 @@ yelp_doc_info_free (YelpDocInfo *doc) { gint i; - d (g_print ("yelp_doc_info_free\n")); - d (g_print (" uri = \"%s\"\n", doc->uris->uri)); + debug_print (DB_FUNCTION, "entering\n"); + debug_print (DB_ARG, " uri = \"%s\"\n", doc->uris->uri); if (!doc) return; @@ -606,7 +601,7 @@ yelp_doc_info_add_uri (YelpDocInfo *doc_info, { DocInfoURI *info_uri; - d (g_print ("yelp_doc_add_uri\n")); + debug_print (DB_FUNCTION, "entering\n"); g_assert (doc_info->num_uris <= doc_info->max_uris); @@ -624,9 +619,9 @@ yelp_doc_info_add_uri (YelpDocInfo *doc_info, doc_info->num_uris++; - d (g_print (" uri = \"%s\"\n", uri)); - d (g_print (" num_uris = %i\n", doc_info->num_uris)); - d (g_print (" max_uris = %i\n", doc_info->max_uris)); + debug_print (DB_ARG, " uri = \"%s\"\n", uri); + debug_print (DB_ARG, " num_uris = %i\n", doc_info->num_uris); + debug_print (DB_ARG, " max_uris = %i\n", doc_info->max_uris); } /******************************************************************************/ -- cgit v1.2.1