diff options
-rw-r--r-- | include/mailutils/debug.h | 11 | ||||
-rw-r--r-- | libmailutils/diag/debug.c | 179 | ||||
-rw-r--r-- | libmailutils/tests/.gitignore | 1 | ||||
-rw-r--r-- | libmailutils/tests/Makefile.am | 2 | ||||
-rw-r--r-- | libmailutils/tests/debugspec.at | 85 | ||||
-rw-r--r-- | libmailutils/tests/debugspec.c | 81 | ||||
-rw-r--r-- | libmailutils/tests/testsuite.at | 1 | ||||
-rw-r--r-- | sieve/sieve.c | 20 |
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); |