Commit f617dd5d f617dd5dfc51dad7766c62c0cb70e5fcf0baf1b1 by Sergey Poznyakoff

Revamp debugging/tracing support

* bootstrap.conf (mu_sieve_debug, mu_sieve_trace): Remove.
* include/mailutils/sieve.h (mu_sieve_debug): Remove.

* examples/numaddr.c: Remove calls to mu_sieve_trace.
* libmu_sieve/extensions/list.c: Likewise.
* libmu_sieve/extensions/moderator.c: Likewise.
* libmu_sieve/extensions/pipe.c: Likewise.
* libmu_sieve/extensions/spamd.c: Likewise.
* libmu_sieve/extensions/timestamp.c: Likewise.
* libmu_sieve/extensions/vacation.c: Likewise.
* libmu_sieve/tests.c: Likewise.

* libmu_sieve/runtime.c: Use new debugging/tracing functions.
* libmu_sieve/sieve-priv.h (mu_i_sv_debug, mu_i_sv_trace)
(mu_i_sv_debug_command)
(mu_i_sv_argf, mu_i_sv_valf): New prototypes.
* libmu_sieve/sieve.y (mu_i_sv_valf, mu_i_sv_argf): New functions.
* libmu_sieve/util.c (mu_sieve_debug): Remove.
(mu_i_sv_print_value_list): Remove.
(mu_i_sv_print_tag_list): Remove.
(mu_sieve_trace): Remove.
(mu_i_sv_tagf): New function.
(mu_i_sv_debug): New function.
(mu_i_sv_trace): New function.
(mu_i_sv_debug_command): New function.
1 parent ffa85e25
......@@ -47,7 +47,6 @@ XGETTEXT_OPTIONS=$XGETTEXT_OPTIONS'\\\
--flag=mu_debug_print:3:c-format\\\
--flag=mu_debug_printf:3:c-format\\\
--flag=mu_sieve_error:2:c-format\\\
--flag=mu_sieve_debug:2:c-format\\\
--flag=mu_sieve_log_action:3:c-format\\\
--flag=mu_nntp_writeline:2:c-format\\\
--flag=mu_pop3_writeline:2:c-format\\\
......
......@@ -84,8 +84,6 @@ numaddr_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
struct val_ctr vc;
int rc;
mu_sieve_trace (mach, "NUMADDR");
/* Retrieve required arguments: */
/* First argument: list of header names */
h = mu_sieve_value_get (args, 0);
......
......@@ -251,8 +251,6 @@ int mu_sieve_get_message_sender (mu_message_t msg, char **ptext);
void mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, ...)
MU_PRINTFLIKE(2,3);
void mu_sieve_debug (mu_sieve_machine_t mach, const char *fmt, ...)
MU_PRINTFLIKE(2,3);
void mu_sieve_log_action (mu_sieve_machine_t mach, const char *action,
const char *fmt, ...)
MU_PRINTFLIKE(3,4);
......
......@@ -152,8 +152,6 @@ list_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
struct header_closure clos;
int result;
mu_sieve_trace (mach, "LIST");
memset (&clos, 0, sizeof clos);
if (mu_sieve_tag_lookup (tags, "delim", &arg))
clos.delim = arg->v.string;
......
......@@ -273,9 +273,6 @@ moderator_action (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
int discard = 0;
int ismime;
mu_sieve_trace (mach, "moderator_test %lu",
(unsigned long) mu_sieve_get_message_num (mach));
msg = mu_sieve_get_message (mach);
mu_message_is_multipart (msg, &ismime);
......
......@@ -105,8 +105,6 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags, int test)
}
cmd = val->v.string;
mu_sieve_trace (mach, test ? "PIPE (test)" : "PIPE (action)");
if (mu_sieve_is_dry_run (mach))
return 0;
......
......@@ -368,9 +368,6 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
mu_header_t hdr;
mu_debug_handle_t lev = 0;
mu_sieve_trace (mach, "spamd_test %lu",
(unsigned long) mu_sieve_get_message_num (mach));
if (mu_sieve_is_dry_run (mach))
return 0;
......
......@@ -57,8 +57,6 @@ timestamp_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
time_t tlimit, tval;
int rc;
mu_sieve_trace (mach, "TIMESTAMP");
/* Retrieve required arguments: */
/* First argument: header name */
h = mu_sieve_value_get (args, 0);
......
......@@ -136,8 +136,6 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, mu_mime_t *pmime,
static int
diag (mu_sieve_machine_t mach)
{
mu_sieve_trace (mach, "VACATION");
mu_sieve_log_action (mach, "VACATION", NULL);
return mu_sieve_is_dry_run (mach);
}
......
......@@ -36,7 +36,7 @@ void
_mu_i_sv_instr_nop (mu_sieve_machine_t mach)
{
if (INSTR_DEBUG (mach))
mu_sieve_debug (mach, "%4lu: NOP", (unsigned long) (mach->pc - 1));
mu_i_sv_debug (mach, mach->pc - 1, "NOP");
}
void
......@@ -47,9 +47,7 @@ _mu_i_sv_instr_source (mu_sieve_machine_t mach)
MU_IOCTL_LOGSTREAM_SET_LOCUS,
&mach->locus);
if (INSTR_DEBUG (mach))
mu_sieve_debug (mach, "%4lu: SOURCE %s",
(unsigned long) (mach->pc - 1),
mach->locus.mu_file);
mu_i_sv_debug (mach, mach->pc - 1, "SOURCE %s", mach->locus.mu_file);
SIEVE_ADJUST (mach, 1);
}
......@@ -61,14 +59,13 @@ _mu_i_sv_instr_line (mu_sieve_machine_t mach)
MU_IOCTL_LOGSTREAM_SET_LOCUS,
&mach->locus);
if (INSTR_DEBUG (mach))
mu_sieve_debug (mach, "%4lu: LINE %u",
(unsigned long) (mach->pc - 1),
mu_i_sv_debug (mach, mach->pc - 1, "LINE %u",
mach->locus.mu_line);
SIEVE_ADJUST (mach, 1);
}
static int
instr_run (mu_sieve_machine_t mach)
instr_run (mu_sieve_machine_t mach, char const *what)
{
mu_sieve_handler_t han = SIEVE_ARG (mach, 0, handler);
mu_list_t arg_list = SIEVE_ARG (mach, 1, list);
......@@ -78,14 +75,10 @@ instr_run (mu_sieve_machine_t mach)
SIEVE_ADJUST(mach, 4);
if (INSTR_DEBUG (mach))
{
mu_stream_printf (mach->errstream,
"\033s<%d>Arguments: ", MU_LOG_DEBUG);
mu_i_sv_print_value_list (arg_list, mach->errstream);
mu_stream_printf (mach->errstream, "\n\033s<%d>Tags: ", MU_LOG_DEBUG);
mu_i_sv_print_tag_list (tag_list, mach->errstream);
mu_stream_printf (mach->errstream, "\n");
}
mu_i_sv_debug_command (mach, mach->pc - 1,
what, tag_list, arg_list);
else
mu_i_sv_trace (mach, what, tag_list, arg_list);
if (!INSTR_DISASS(mach))
rc = han (mach, arg_list, tag_list);
......@@ -96,12 +89,8 @@ void
_mu_i_sv_instr_action (mu_sieve_machine_t mach)
{
mach->identifier = SIEVE_ARG (mach, 3, string);
if (INSTR_DEBUG (mach))
mu_sieve_debug (mach, "%4lu: ACTION: %s",
(unsigned long) (mach->pc - 1),
mach->identifier);
mach->action_count++;
instr_run (mach);
instr_run (mach, "action");
mach->identifier = NULL;
}
......@@ -109,11 +98,7 @@ void
_mu_i_sv_instr_test (mu_sieve_machine_t mach)
{
mach->identifier = SIEVE_ARG (mach, 3, string);
if (INSTR_DEBUG (mach))
mu_sieve_debug (mach, "%4lu: TEST: %s",
(unsigned long) (mach->pc - 1),
mach->identifier);
mach->reg = instr_run (mach);
mach->reg = instr_run (mach, "test");
mach->identifier = NULL;
}
......@@ -122,7 +107,7 @@ _mu_i_sv_instr_push (mu_sieve_machine_t mach)
{
if (INSTR_DEBUG (mach))
{
mu_sieve_debug (mach, "%4lu: PUSH", (unsigned long)(mach->pc - 1));
mu_i_sv_debug (mach, mach->pc - 1, "PUSH");
if (INSTR_DISASS (mach))
return;
}
......@@ -140,7 +125,7 @@ _mu_i_sv_instr_pop (mu_sieve_machine_t mach)
{
if (INSTR_DEBUG (mach))
{
mu_sieve_debug (mach, "%4lu: POP", (unsigned long)(mach->pc - 1));
mu_i_sv_debug (mach, mach->pc - 1, "POP");
if (INSTR_DISASS (mach))
return;
}
......@@ -158,7 +143,7 @@ _mu_i_sv_instr_not (mu_sieve_machine_t mach)
{
if (INSTR_DEBUG (mach))
{
mu_sieve_debug (mach, "%4lu: NOT", (unsigned long)(mach->pc - 1));
mu_i_sv_debug (mach, mach->pc - 1, "NOT");
if (INSTR_DISASS (mach))
return;
}
......@@ -173,8 +158,7 @@ _mu_i_sv_instr_branch (mu_sieve_machine_t mach)
SIEVE_ADJUST (mach, 1);
if (INSTR_DEBUG (mach))
{
mu_sieve_debug (mach, "%4lu: BRANCH %lu",
(unsigned long)(mach->pc-2),
mu_i_sv_debug (mach, mach->pc - 2, "BRANCH %lu",
(unsigned long)(mach->pc + num));
if (INSTR_DISASS (mach))
return;
......@@ -191,8 +175,7 @@ _mu_i_sv_instr_brz (mu_sieve_machine_t mach)
if (INSTR_DEBUG (mach))
{
mu_sieve_debug (mach, "%4lu: BRZ %lu",
(unsigned long)(mach->pc-2),
mu_i_sv_debug (mach, mach->pc - 2, "BRZ %lu",
(unsigned long)(mach->pc + num));
if (INSTR_DISASS (mach))
return;
......@@ -210,8 +193,7 @@ _mu_i_sv_instr_brnz (mu_sieve_machine_t mach)
if (INSTR_DEBUG (mach))
{
mu_sieve_debug (mach, "%4lu: BRNZ %lu",
(unsigned long)(mach->pc-2),
mu_i_sv_debug (mach, mach->pc - 2, "BRNZ %lu",
(unsigned long)(mach->pc + num));
if (INSTR_DISASS (mach))
return;
......@@ -299,7 +281,7 @@ sieve_run (mu_sieve_machine_t mach)
mu_sieve_log_action (mach, "IMPLICIT KEEP", NULL);
if (INSTR_DEBUG (mach))
mu_sieve_debug (mach, "%4lu: STOP", (unsigned long) mach->pc);
mu_i_sv_debug (mach, mach->pc, "STOP");
return 0;
}
......
......@@ -180,3 +180,15 @@ void mu_i_sv_print_tag_list (mu_list_t list, mu_stream_t str);
void mu_i_sv_error (mu_sieve_machine_t mach);
void mu_i_sv_debug (mu_sieve_machine_t mach, size_t pc, const char *fmt, ...)
MU_PRINTFLIKE(3,4);
void mu_i_sv_debug_command (mu_sieve_machine_t mach,
size_t pc,
char const *what,
mu_list_t taglist, mu_list_t arglist);
void mu_i_sv_trace (mu_sieve_machine_t mach, const char *what,
mu_list_t taglist, mu_list_t arglist);
void mu_i_sv_argf (mu_stream_t str, mu_list_t list);
void mu_i_sv_valf (mu_stream_t str, mu_sieve_value_t *val);
......
......@@ -502,12 +502,9 @@ string_dumper (void *item, void *data)
return 0;
}
static int
dump_val (void *item, void *data)
void
mu_i_sv_valf (mu_stream_t str, mu_sieve_value_t *val)
{
mu_sieve_value_t *val = item;
mu_stream_t str = data;
mu_stream_printf (str, " ");
switch (val->type)
{
......@@ -544,7 +541,7 @@ dump_val (void *item, void *data)
case SVT_VALUE_LIST:
mu_stream_printf (str, "[");
mu_list_foreach (val->v.list, dump_val, str);
mu_i_sv_argf (str, val->v.list);
mu_stream_printf (str, "]");
break;
......@@ -555,9 +552,23 @@ dump_val (void *item, void *data)
default:
abort ();
}
}
static int
dump_val (void *item, void *data)
{
mu_sieve_value_t *val = item;
mu_stream_t str = data;
mu_i_sv_valf (str, val);
return 0;
}
void
mu_i_sv_argf (mu_stream_t str, mu_list_t list)
{
mu_list_foreach (list, dump_val, str);
}
static void
dump_node_command (mu_stream_t str, struct mu_sieve_node *node, unsigned level)
{
......
......@@ -119,8 +119,6 @@ sieve_test_address (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
int rc;
size_t count;
mu_sieve_trace (mach, "ADDRESS");
h = mu_sieve_value_get (args, 0);
if (!h)
{
......@@ -182,8 +180,6 @@ sieve_test_header (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
size_t count, mcount = 0;
struct header_closure clos;
mu_sieve_trace (mach, "HEADER");
h = mu_sieve_value_get (args, 0);
if (!h)
{
......@@ -265,8 +261,6 @@ sieve_test_envelope (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
int rc;
size_t count;
mu_sieve_trace (mach, "ENVELOPE");
h = mu_sieve_value_get (args, 0);
if (!h)
{
......@@ -331,8 +325,6 @@ sieve_test_exists (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
mu_header_t header = NULL;
mu_sieve_value_t *val;
mu_sieve_trace (mach, "EXISTS");
mu_message_get_header (mu_sieve_get_message (mach), &header);
val = mu_sieve_value_get (args, 0);
if (!val)
......
......@@ -211,66 +211,6 @@ mu_sieve_arg_error (mu_sieve_machine_t mach, int n)
mu_sieve_error (mach, _("cannot retrieve argument %d"), n);
}
void
mu_sieve_debug (mu_sieve_machine_t mach, const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mu_stream_vprintf (mach->errstream, fmt, ap);
mu_stream_write (mach->errstream, "\n", 1, NULL);
va_end (ap);
}
void
mu_sieve_trace (mu_sieve_machine_t mach, const char *fmt, ...)
{
va_list ap;
if (!mu_debug_level_p (mu_sieve_debug_handle, MU_DEBUG_TRACE4))
return;
va_start (ap, fmt);
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mu_stream_vprintf (mach->errstream, fmt, ap);
mu_stream_write (mach->errstream, "\n", 1, NULL);
va_end (ap);
}
void
mu_sieve_log_action (mu_sieve_machine_t mach, const char *action,
const char *fmt, ...)
{
va_list ap;
if (!mach->logger)
return;
va_start (ap, fmt);
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_INFO);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mach->logger (mach->data, mach->errstream, mach->msgno, mach->msg,
action, fmt, ap);
va_end (ap);
}
const char *
mu_sieve_type_str (mu_sieve_data_type type)
{
......@@ -305,91 +245,102 @@ mu_sieve_type_str (mu_sieve_data_type type)
}
static int
string_printer (void *item, void *data)
tag_printer (void *item, void *data)
{
char *s = item;
mu_sieve_runtime_tag_t *val = item;
mu_stream_t str = data;
mu_stream_printf (str, "\"%s\" ", s);
mu_stream_printf (str, " :%s", val->tag);
if (val->arg)
mu_i_sv_valf (str, val->arg);
return 0;
}
static void sieve_print_value (mu_sieve_value_t *, mu_stream_t str);
static int
value_printer (void *item, void *data)
void
mu_i_sv_tagf (mu_stream_t str, mu_list_t taglist)
{
mu_sieve_value_t *val = item;
mu_stream_t str = data;
sieve_print_value (val, str);
mu_stream_printf (str, " ");
return 0;
mu_list_foreach (taglist, tag_printer, str);
}
static void
sieve_print_value (mu_sieve_value_t *val, mu_stream_t str)
void
mu_i_sv_debug (mu_sieve_machine_t mach, size_t pc, const char *fmt, ...)
{
mu_stream_printf (str, "%s(", mu_sieve_type_str (val->type));
switch (val->type)
{
case SVT_VOID:
break;
case SVT_NUMBER:
mu_stream_printf (str, "%lu", (unsigned long) val->v.number);
break;
case SVT_TAG:
case SVT_IDENT:
case SVT_STRING:
mu_stream_printf (str, "%s", val->v.string);
break;
case SVT_STRING_LIST:
mu_list_foreach (val->v.list, string_printer, str);
break;
case SVT_VALUE_LIST:
mu_list_foreach (val->v.list, value_printer, str);
va_list ap;
case SVT_POINTER:
mu_stream_printf (str, "%p", val->v.ptr);
}
mu_stream_printf (str, ")");
va_start (ap, fmt);
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mu_stream_printf (mach->errstream, "%4zu: ", pc);
mu_stream_vprintf (mach->errstream, fmt, ap);
mu_stream_write (mach->errstream, "\n", 1, NULL);
va_end (ap);
}
void
mu_i_sv_print_value_list (mu_list_t list, mu_stream_t str)
mu_i_sv_debug_command (mu_sieve_machine_t mach,
size_t pc,
char const *what,
mu_list_t taglist, mu_list_t arglist)
{
mu_sieve_value_t val;
val.type = SVT_VALUE_LIST;
val.v.list = list;
sieve_print_value (&val, str);
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mu_stream_printf (mach->errstream, "%4zu: %s: %s",
pc, what, mach->identifier);
mu_i_sv_tagf (mach->errstream, taglist);
mu_i_sv_argf (mach->errstream, arglist);
mu_stream_write (mach->errstream, "\n", 1, NULL);
}
static int
tag_printer (void *item, void *data)
void
mu_i_sv_trace (mu_sieve_machine_t mach, const char *what,
mu_list_t taglist, mu_list_t arglist)
{
mu_sieve_runtime_tag_t *val = item;
mu_stream_t str = data;
if (!mu_debug_level_p (mu_sieve_debug_handle, MU_DEBUG_TRACE4))
return;
mu_stream_printf (str, "%s", val->tag);
if (val->arg)
{
mu_stream_printf (str, "(");
sieve_print_value (val->arg, str);
mu_stream_printf (str, ")");
}
mu_stream_printf (str, " ");
return 0;
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_DEBUG);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mu_stream_printf (mach->errstream, "%zu: %s %s", mach->msgno, what,
mach->identifier);
mu_i_sv_tagf (mach->errstream, taglist);
mu_i_sv_argf (mach->errstream, arglist);
mu_stream_printf (mach->errstream, "\n");
}
void
mu_i_sv_print_tag_list (mu_list_t list, mu_stream_t str)
mu_sieve_log_action (mu_sieve_machine_t mach, const char *action,
const char *fmt, ...)
{
mu_list_foreach (list, tag_printer, str);
va_list ap;
if (!mach->logger)
return;
va_start (ap, fmt);
mu_stream_printf (mach->errstream, "\033s<%d>", MU_LOG_INFO);
if (mach->locus.mu_file)
mu_stream_printf (mach->errstream, "\033O<%d>\033f<%u>%s\033l<%u>",
MU_LOGMODE_LOCUS,
(unsigned) strlen (mach->locus.mu_file),
mach->locus.mu_file,
mach->locus.mu_line);
mach->logger (mach->data, mach->errstream, mach->msgno, mach->msg,
action, fmt, ap);
va_end (ap);
}
static int
......@@ -437,7 +388,8 @@ mu_sieve_vlist_do (mu_sieve_value_t *val, mu_list_action_t ac, void *data)
}
}
struct comp_data {
struct comp_data
{
mu_sieve_value_t *val;
mu_sieve_comparator_t comp;
mu_sieve_relcmp_t test;
......@@ -446,7 +398,8 @@ struct comp_data {
size_t count;
};
struct comp_data2 {
struct comp_data2
{
char *sample;
mu_sieve_comparator_t comp;
mu_sieve_relcmp_t test;
......