summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mailutils/debug.h11
-rw-r--r--libmailutils/diag/debug.c179
-rw-r--r--libmailutils/tests/.gitignore1
-rw-r--r--libmailutils/tests/Makefile.am2
-rw-r--r--libmailutils/tests/debugspec.at85
-rw-r--r--libmailutils/tests/debugspec.c81
-rw-r--r--libmailutils/tests/testsuite.at1
-rw-r--r--sieve/sieve.c20
8 files changed, 326 insertions, 54 deletions
diff --git a/include/mailutils/debug.h b/include/mailutils/debug.h
index a69b98aaa..7ccc46b91 100644
--- a/include/mailutils/debug.h
+++ b/include/mailutils/debug.h
@@ -48,6 +48,10 @@ extern int mu_debug_line_info;
#define MU_DEBUG_LEVEL_MASK(lev) (1 << (lev))
#define MU_DEBUG_LEVEL_UPTO(lev) ((1 << ((lev)+1)) - 1)
+#define MU_DEBUG_LEVEL_RANGE(a, b) \
+ ((a) == 0 ? MU_DEBUG_LEVEL_UPTO (b) : \
+ MU_DEBUG_LEVEL_UPTO (b) & ~MU_DEBUG_LEVEL_UPTO ((a) - 1))
+
struct sockaddr;
void mu_sockaddr_to_str (const struct sockaddr *sa, int salen,
@@ -67,8 +71,11 @@ int mu_debug_category_level (const char *catname, size_t catlen,
void mu_debug_parse_spec (const char *spec);
int mu_debug_format_spec(mu_stream_t str, const char *names, int showunset);
-void mu_debug_set_category_level (mu_debug_handle_t catn,
- mu_debug_level_t level);
+int mu_debug_get_category_level (mu_debug_handle_t catn,
+ mu_debug_level_t *plev);
+int mu_debug_set_category_level (mu_debug_handle_t catn,
+ mu_debug_level_t level);
+
void mu_debug_clear_all (void);
void mu_debug_log (const char *fmt, ...) MU_PRINTFLIKE(1,2);
diff --git a/libmailutils/diag/debug.c b/libmailutils/diag/debug.c
index c136f66c2..5916de1e2 100644
--- a/libmailutils/diag/debug.c
+++ b/libmailutils/diag/debug.c
@@ -175,18 +175,73 @@ mu_debug_category_level (const char *catname, size_t catlen,
return 0;
}
-void
+int
mu_debug_set_category_level (mu_debug_handle_t catn, mu_debug_level_t level)
{
if (catn < catcnt)
{
cattab[catn].isset = 1;
cattab[catn].level = level;
+ return 0;
}
- else
- abort ();
+ return MU_ERR_NOENT;
}
+int
+mu_debug_get_category_level (mu_debug_handle_t catn, mu_debug_level_t *plev)
+{
+ if (catn < catcnt)
+ {
+ if (!cattab[catn].isset)
+ *plev = 0;
+ else
+ *plev = cattab[catn].level;
+ return 0;
+ }
+ return MU_ERR_NOENT;
+}
+
+static char *mu_debug_level_str[] = {
+ "error",
+ "trace0",
+ "trace1",
+ "trace2",
+ "trace3",
+ "trace4",
+ "trace5",
+ "trace6",
+ "trace7",
+ "trace8",
+ "trace9",
+ "prot"
+};
+
+static int
+mu_debug_level_from_string (const char *str, mu_debug_level_t *lev,
+ char **endp)
+{
+ int i;
+ const char *p;
+ char *q;
+
+ for (i = 0; i < MU_ARRAY_SIZE (mu_debug_level_str); i++)
+ {
+ for (p = str, q = mu_debug_level_str[i]; ; p++, q++)
+ {
+ if (!*q)
+ {
+ if (endp)
+ *endp = (char*) p;
+ *lev = i;
+ return 0;
+ }
+ if (*q != *p)
+ break;
+ }
+ }
+ return MU_ERR_NOENT;
+}
+
static void
parse_spec (const char *spec)
{
@@ -231,18 +286,21 @@ parse_spec (const char *spec)
else
{
size_t i;
- unsigned lev = 0;
- unsigned xlev = 0;
+ mu_debug_level_t lev = 0;
+ mu_debug_level_t xlev = 0;
+ char *end;
for (i = 0; i < ws.ws_wordc; i++)
{
char *s = ws.ws_wordv[i];
int exact = 0;
- unsigned n;
- unsigned *tgt = &lev;
+ mu_debug_level_t n;
+ mu_debug_level_t *tgt = &lev;
if (*s == '!')
{
+ if (i == 0)
+ lev = MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT);
tgt = &xlev;
s++;
}
@@ -252,20 +310,37 @@ parse_spec (const char *spec)
s++;
}
- if (strcmp (s, "error") == 0)
- n = MU_DEBUG_ERROR;
- else if (strcmp (s, "prot") == 0)
- n = MU_DEBUG_PROT;
- else if (strlen (s) == 6 && memcmp (s, "trace", 5) == 0 &&
- mu_isdigit (s[5]))
- n = MU_DEBUG_TRACE0 + s[5] - '0';
- else
+ if (mu_debug_level_from_string (s, &n, &end))
{
mu_error (_("unknown level `%s'"), s);
continue;
}
-
- if (exact)
+ else if (*end == '-')
+ {
+ mu_debug_level_t l;
+
+ s = end + 1;
+ if (mu_debug_level_from_string (s, &l, &end))
+ {
+ mu_error (_("unknown level `%s'"), s);
+ continue;
+ }
+ else if (*end)
+ {
+ mu_error (_("invalid level: %s"), s);
+ continue;
+ }
+ if (n < l)
+ *tgt |= MU_DEBUG_LEVEL_RANGE (n, l);
+ else
+ *tgt |= MU_DEBUG_LEVEL_RANGE (l, n);
+ }
+ else if (*end)
+ {
+ mu_error (_("invalid level: %s"), s);
+ continue;
+ }
+ else if (exact)
*tgt |= MU_DEBUG_LEVEL_MASK (n);
else
*tgt |= MU_DEBUG_LEVEL_UPTO (n);
@@ -317,21 +392,6 @@ mu_debug_clear_all ()
#define _LEVEL_ALL MU_DEBUG_LEVEL_UPTO(MU_DEBUG_PROT)
-static char *mu_debug_level_str[] = {
- "error",
- "trace0",
- "trace1",
- "trace2",
- "trace3",
- "trace4",
- "trace5",
- "trace6",
- "trace7",
- "trace8",
- "trace9",
- "prot"
-};
-
static int
name_matches (char **names, char *str)
{
@@ -344,7 +404,7 @@ name_matches (char **names, char *str)
}
int
-mu_debug_format_spec(mu_stream_t str, const char *names, int showunset)
+mu_debug_format_spec (mu_stream_t str, const char *names, int showunset)
{
int i;
size_t cnt = 0;
@@ -364,6 +424,7 @@ mu_debug_format_spec(mu_stream_t str, const char *names, int showunset)
{
if (names && !name_matches (ws.ws_wordv, cattab[i].name))
continue;
+
if (cattab[i].isset && cattab[i].level)
{
if (cnt)
@@ -372,28 +433,58 @@ mu_debug_format_spec(mu_stream_t str, const char *names, int showunset)
if (rc)
break;
}
- rc = mu_stream_printf(str, "%s", cattab[i].name);
+ rc = mu_stream_printf (str, "%s", cattab[i].name);
if (rc)
break;
if (cattab[i].level != _LEVEL_ALL)
{
- int j;
+ mu_debug_level_t j = MU_DEBUG_ERROR, minl, maxl;
int delim = '.';
-
- for (j = MU_DEBUG_ERROR; j <= MU_DEBUG_PROT; j++)
- if (cattab[i].level & MU_DEBUG_LEVEL_MASK(j))
- {
- rc = mu_stream_printf(str, "%c%s", delim,
- mu_debug_level_str[j]);
- if (rc)
+
+ while (1)
+ {
+ /* Find the least bit set */
+ for (; j <= MU_DEBUG_PROT; j++)
+ if (cattab[i].level & MU_DEBUG_LEVEL_MASK (j))
break;
- delim = ',';
- }
+
+ if (j > MU_DEBUG_PROT)
+ break;
+
+ minl = j;
+
+ for (; j + 1 <= MU_DEBUG_PROT &&
+ cattab[i].level & MU_DEBUG_LEVEL_MASK (j + 1);
+ j++)
+ ;
+
+ maxl = j++;
+
+ if (minl == maxl)
+ rc = mu_stream_printf (str, "%c=%s", delim,
+ mu_debug_level_str[minl]);
+ else if (minl == 0)
+ rc = mu_stream_printf (str, "%c%s", delim,
+ mu_debug_level_str[maxl]);
+ else
+ rc = mu_stream_printf (str, "%c%s-%s", delim,
+ mu_debug_level_str[minl],
+ mu_debug_level_str[maxl]);
+ if (rc)
+ break;
+ delim = ',';
+ }
}
cnt++;
}
else if (showunset)
{
+ if (cnt)
+ {
+ rc = mu_stream_printf(str, ";");
+ if (rc)
+ break;
+ }
rc = mu_stream_printf(str, "!%s", cattab[i].name);
if (rc)
break;
diff --git a/libmailutils/tests/.gitignore b/libmailutils/tests/.gitignore
index 8bdc03960..d205efe63 100644
--- a/libmailutils/tests/.gitignore
+++ b/libmailutils/tests/.gitignore
@@ -6,6 +6,7 @@ testsuite.dir
testsuite.log
addr
argcv
+debugspec
decode2047
encode2047
fltst
diff --git a/libmailutils/tests/Makefile.am b/libmailutils/tests/Makefile.am
index 6add3b228..8128d8855 100644
--- a/libmailutils/tests/Makefile.am
+++ b/libmailutils/tests/Makefile.am
@@ -41,6 +41,7 @@ $(srcdir)/package.m4: $(top_srcdir)/configure.ac
INCLUDES = @MU_LIB_COMMON_INCLUDES@
noinst_PROGRAMS = \
addr\
+ debugspec\
decode2047\
encode2047\
fltst\
@@ -64,6 +65,7 @@ TESTSUITE_AT = \
address.at\
base64d.at\
base64e.at\
+ debugspec.at\
decode2047.at\
encode2047.at\
fromflt.at\
diff --git a/libmailutils/tests/debugspec.at b/libmailutils/tests/debugspec.at
new file mode 100644
index 000000000..a6d1c762f
--- /dev/null
+++ b/libmailutils/tests/debugspec.at
@@ -0,0 +1,85 @@
+# This file is part of GNU Mailutils. -*- Autotest -*-
+# Copyright (C) 2010 Free Software Foundation, Inc.
+#
+# GNU Mailutils 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 3, or (at
+# your option) any later version.
+#
+# GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>.
+
+dnl ------------------------------------------------------------
+dnl TESTDBG([KW = `'], [ARGS], [STDOUT = `'],
+dnl [STDERR = `'])
+dnl
+m4_pushdef([TESTDBG],[
+AT_SETUP([debugspec: $2])
+AT_KEYWORDS([debugspec debug dbgspec $1])
+AT_CHECK([debugspec $2],
+[0],
+[$3],
+[$4])
+AT_CLEANUP])
+
+dnl ------------------------------------------------------------
+TESTDBG([debugspec00],[mailbox],
+[mailbox
+])
+
+TESTDBG([debugspec01],[mailbox.=trace2],
+[mailbox.=trace2
+])
+
+TESTDBG([debugspec02],[mailbox.trace3],
+[mailbox.trace3
+])
+
+TESTDBG([debugspec03],[mailbox.!trace3],
+[mailbox.trace4-prot
+])
+
+TESTDBG([debugspec04],[mailbox.!=trace3],
+[mailbox.trace2,trace4-prot
+])
+
+TESTDBG([debugspec05],[mailbox.!=prot],
+[mailbox.trace9
+])
+
+TESTDBG([debugspec06],[mailbox.prot,!=trace4],
+[mailbox.trace3,trace5-prot
+])
+
+TESTDBG([debugspec07],[mailbox.prot,!trace4],
+[mailbox.trace5-prot
+])
+
+TESTDBG([debugspec08],[mailbox.trace2-trace5],
+[mailbox.trace2-trace5
+])
+
+TESTDBG([debugspec09],[mailbox.trace2-trace5,trace7-prot],
+[mailbox.trace2-trace5,trace7-prot
+])
+
+TESTDBG([debugspec10],
+['mailbox.error,=trace3,=trace7,=trace9;mailer.trace7,!trace2'],
+[mailbox.=error,=trace3,=trace7,=trace9;mailer.trace3-trace7
+])
+
+TESTDBG([debugspec11],
+[-showunset -names='mailbox;mailer;filter' dnl
+ 'mailbox.error,=trace3,=trace7,=trace9;mailer.trace7,!trace2'],
+[!filter;mailbox.=error,=trace3,=trace7,=trace9;mailer.trace3-trace7
+])
+
+dnl ------------------------------------------------------------
+
+m4_popdef([TESTDBG])
+
diff --git a/libmailutils/tests/debugspec.c b/libmailutils/tests/debugspec.c
new file mode 100644
index 000000000..f6d75fddb
--- /dev/null
+++ b/libmailutils/tests/debugspec.c
@@ -0,0 +1,81 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 1999, 2000, 2001, 2002, 2005, 2007, 2010 Free Software
+ Foundation, Inc.
+
+ GNU Mailutils 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 3, or (at your option)
+ any later version.
+
+ GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <unistd.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <string.h>
+#include <mailutils/mailutils.h>
+
+int
+main (int argc, char **argv)
+{
+ char *names = NULL;
+ int showunset = 0;
+ char *arg;
+
+ mu_set_program_name (argv[0]);
+ mu_stdstream_setup ();
+
+ if (argc == 1)
+ {
+ mu_printf ("usage: %s spec\n", argv[0]);
+ return 0;
+ }
+
+ while (argc--)
+ {
+ arg = *++argv;
+
+ if (strncmp (arg, "-names=", 7) == 0)
+ names = arg + 7;
+ else if (strcmp (arg, "-showunset") == 0)
+ showunset = 1;
+ else if (arg[0] == '-')
+ {
+ if (arg[1] == '-' && arg[2] == 0)
+ {
+ argc--;
+ argv++;
+ break;
+ }
+ mu_error ("unrecognised argument: %s", arg);
+ return 1;
+ }
+ else
+ break;
+ }
+
+ if (argc != 1)
+ {
+ mu_error ("usage: %s spec", mu_program_name);
+ return 1;
+ }
+
+ mu_debug_parse_spec (arg);
+
+ mu_debug_format_spec (mu_strout, names, showunset);
+ mu_printf ("\n");
+
+ return 0;
+}
+
+
diff --git a/libmailutils/tests/testsuite.at b/libmailutils/tests/testsuite.at
index d16cd9912..52cbf6110 100644
--- a/libmailutils/tests/testsuite.at
+++ b/libmailutils/tests/testsuite.at
@@ -68,4 +68,5 @@ m4_include([prop.at])
m4_include([inline-comment.at])
m4_include([hdrflt.at])
m4_include([linecon.at])
+m4_include([debugspec.at])
diff --git a/sieve/sieve.c b/sieve/sieve.c
index 5c9650f1d..8e3f33733 100644
--- a/sieve/sieve.c
+++ b/sieve/sieve.c
@@ -51,8 +51,8 @@ N_("GNU sieve -- a mail filtering tool.")
"\v"
N_("Debug flags:\n\
g - main parser traces\n\
- T - mailutils traces (MU_DEBUG_TRACE0-MU_DEBUG_TRACE1)\n\
- P - network protocols (MU_DEBUG_PROT)\n\
+ T - mailutils traces (same as --debug-level=sieve.trace0-trace1)\n\
+ P - network protocols (same as --debug-level=sieve.=prot)\n\
t - sieve trace (MU_SIEVE_DEBUG_TRACE)\n\
i - sieve instructions trace (MU_SIEVE_DEBUG_INSTR)\n");
@@ -104,7 +104,6 @@ static struct argp_option options[] =
int keep_going;
int compile_only;
char *mbox_url;
-int debug_level;
int sieve_debug;
int verbose;
char *script;
@@ -127,16 +126,24 @@ is_true_p (char *p)
static void
set_debug_level (const char *arg)
{
+ mu_debug_level_t lev;
+
for (; *arg; arg++)
{
switch (*arg)
{
case 'T':
- debug_level |= MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE7);
+ mu_debug_get_category_level (mu_sieve_debug_handle, &lev);
+ mu_debug_set_category_level (mu_sieve_debug_handle,
+ lev |
+ (MU_DEBUG_LEVEL_UPTO(MU_DEBUG_TRACE9) &
+ ~MU_DEBUG_LEVEL_MASK(MU_DEBUG_ERROR)));
break;
case 'P':
- debug_level |= MU_DEBUG_LEVEL_MASK (MU_DEBUG_PROT);
+ mu_debug_get_category_level (mu_sieve_debug_handle, &lev);
+ mu_debug_set_category_level (mu_sieve_debug_handle,
+ lev | MU_DEBUG_LEVEL_MASK(MU_DEBUG_PROT));
break;
case 'g':
@@ -456,9 +463,6 @@ main (int argc, char *argv[])
mu_register_all_formats ();
- debug_level = MU_DEBUG_LEVEL_MASK (MU_DEBUG_ERROR);
- mu_log_facility = 0;
-
if (mu_app_init (&argp, sieve_argp_capa, sieve_cfg_param,
argc, argv, ARGP_IN_ORDER, NULL, NULL))
exit (EX_USAGE);

Return to:

Send suggestions and report system problems to the System administrator.