summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-06-13 15:50:52 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-06-13 15:50:52 +0300
commit4f24c098704dd28622d1d653945388a4abbfb434 (patch)
tree31608dab06c33d10072c739355587be3435af230
parentfa5d4812fc4936dd470ded17116c9d966d0d645e (diff)
downloadmailutils-4f24c098704dd28622d1d653945388a4abbfb434.tar.gz
mailutils-4f24c098704dd28622d1d653945388a4abbfb434.tar.bz2
Try to display exact error locations in Sieve diagnostics
* include/mailutils/sieve.h (mu_sieve_value_t)<locus>: New field. * libmu_sieve/util.c (mu_sieve_value_create): Take a pointer to mu_locus_range. Use it to initialize the locus field. * libmu_sieve/sieve-gram.y: Pass loci in calls to mu_sieve_value_create. * libmu_sieve/actions.c: Use the most specific locus when displaying the message. * libmu_sieve/comparator.c: Likewise. * libmu_sieve/prog.c: Likewise. * libmu_sieve/variables.c: Likewise. * sieve/tests/i-numeric.at: Update the expected error location.
-rw-r--r--include/mailutils/sieve.h5
-rw-r--r--libmu_sieve/actions.c2
-rw-r--r--libmu_sieve/comparator.c22
-rw-r--r--libmu_sieve/prog.c15
-rw-r--r--libmu_sieve/sieve-gram.y14
-rw-r--r--libmu_sieve/util.c13
-rw-r--r--libmu_sieve/variables.c9
-rw-r--r--sieve/tests/i-numeric.at2
8 files changed, 56 insertions, 26 deletions
diff --git a/include/mailutils/sieve.h b/include/mailutils/sieve.h
index 58a6037cb..99d328286 100644
--- a/include/mailutils/sieve.h
+++ b/include/mailutils/sieve.h
@@ -88,6 +88,7 @@ typedef struct
{
mu_sieve_data_type type;
char *tag;
+ struct mu_locus_range locus;
union mu_sieve_value_storage v;
} mu_sieve_value_t;
@@ -163,7 +164,9 @@ void mu_sieve_reclaim_default (void *p);
void mu_sieve_reclaim_value (void *p);
size_t mu_sieve_value_create (mu_sieve_machine_t mach,
- mu_sieve_data_type type, void *data);
+ mu_sieve_data_type type,
+ struct mu_locus_range const *locus,
+ void *data);
/* Symbol space functions */
mu_sieve_registry_t *mu_sieve_registry_add (mu_sieve_machine_t mach,
diff --git a/libmu_sieve/actions.c b/libmu_sieve/actions.c
index 17daa7ef6..39b66fc29 100644
--- a/libmu_sieve/actions.c
+++ b/libmu_sieve/actions.c
@@ -528,7 +528,7 @@ perms_tag_checker (mu_sieve_machine_t mach)
{
if (mu_parse_stream_perm_string (&flag, t->v.string, &p))
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &t->locus,
_("invalid permissions (near %s)"), p);
mu_i_sv_error (mach);
err = 1;
diff --git a/libmu_sieve/comparator.c b/libmu_sieve/comparator.c
index e401b90d4..1a3be1a54 100644
--- a/libmu_sieve/comparator.c
+++ b/libmu_sieve/comparator.c
@@ -174,7 +174,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
{
if (match)
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &t->locus,
_("match type specified twice in call to `%s'"),
mach->identifier);
mu_i_sv_error (mach);
@@ -209,7 +209,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
if (compname && strcmp (compname, "i;ascii-numeric"))
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &match->locus,
/* TRANSLATORS: Do not translate ':count'.
It is the name of a Sieve tag */
_("comparator %s is incompatible with "
@@ -235,7 +235,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
break;
/* fall through */
default:
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_(":count requires second argument to be a list of one element"));
mu_i_sv_error (mach);
return 1;
@@ -246,7 +246,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
char *p = mu_str_skip_class (argstr->orig, MU_CTYPE_DIGIT);
if (*p)
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_("second argument cannot be converted to number"));
mu_i_sv_error (mach);
return 1;
@@ -258,7 +258,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
if (mu_sieve_str_to_relcmp (str, NULL, NULL))
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &match->locus,
_("invalid relational match `%s' in call to `%s'"),
str, mach->identifier);
mu_i_sv_error (mach);
@@ -278,10 +278,16 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach)
compfun = mu_sieve_comparator_lookup (mach, compname, matchtype);
if (!compfun)
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ if (match)
+ mu_diag_at_locus_range (MU_LOG_ERROR, &match->locus,
+ _("comparator `%s' is incompatible with match type `%s' in call to `%s'"),
+ compname, match->tag,
+ mach->identifier);
+ else
+ mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
_("comparator `%s' is incompatible with match type `%s' in call to `%s'"),
- compname, match ? match->tag : "is",
- mach->identifier);
+ compname, "is",
+ mach->identifier);
mu_i_sv_error (mach);
return 1;
}
diff --git a/libmu_sieve/prog.c b/libmu_sieve/prog.c
index a1dead4e6..70e04538b 100644
--- a/libmu_sieve/prog.c
+++ b/libmu_sieve/prog.c
@@ -171,7 +171,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
if (!tag)
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_("invalid tag name `%s' for `%s'"),
val->v.string, reg->name);
mu_i_sv_error (mach);
@@ -191,6 +191,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
{
if (i + 1 == node->v.command.argcount)
{
+ /* FIXME: more exact locus */
mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
_("required argument for tag %s is missing"),
tag->name);
@@ -208,11 +209,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
if (val->type != tag->argtype)
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_("type mismatch in argument to "
"tag `%s'"),
tag->name);
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_("expected %s but passed %s"),
mu_sieve_type_str (tag->argtype),
mu_sieve_type_str (val->type));
@@ -274,11 +275,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
/* compatible types */;
else
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_("type mismatch in argument %lu to `%s'"),
(unsigned long) (exp_arg - reg->v.command.req_args + 1),
reg->name);
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
+ mu_diag_at_locus_range (MU_LOG_ERROR, &val->locus,
_("expected %s but passed %s"),
mu_sieve_type_str (*exp_arg),
mu_sieve_type_str (val->type));
@@ -294,8 +295,8 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
if (!err && !opt_args && *exp_arg != SVT_VOID)
{
mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
- _("too few arguments in call to `%s'"),
- reg->name);
+ _("too few arguments in call to `%s'"),
+ reg->name);
mu_i_sv_error (mach);
err = 1;
}
diff --git a/libmu_sieve/sieve-gram.y b/libmu_sieve/sieve-gram.y
index 5499a5ece..bf3db2442 100644
--- a/libmu_sieve/sieve-gram.y
+++ b/libmu_sieve/sieve-gram.y
@@ -305,23 +305,27 @@ arglist : arg
arg : stringlist
{
$$ = mu_sieve_value_create (mu_sieve_machine,
- SVT_STRING_LIST, &$1);
+ SVT_STRING_LIST, &@1, &$1);
}
| STRING
{
- $$ = mu_sieve_value_create (mu_sieve_machine, SVT_STRING, $1);
+ $$ = mu_sieve_value_create (mu_sieve_machine, SVT_STRING,
+ &@1, $1);
}
| MULTILINE
{
- $$ = mu_sieve_value_create (mu_sieve_machine, SVT_STRING, $1);
+ $$ = mu_sieve_value_create (mu_sieve_machine, SVT_STRING,
+ &@1, $1);
}
| NUMBER
{
- $$ = mu_sieve_value_create (mu_sieve_machine, SVT_NUMBER, &$1);
+ $$ = mu_sieve_value_create (mu_sieve_machine, SVT_NUMBER,
+ &@1, &$1);
}
| TAG
{
- $$ = mu_sieve_value_create (mu_sieve_machine, SVT_TAG, $1);
+ $$ = mu_sieve_value_create (mu_sieve_machine, SVT_TAG,
+ &@1, $1);
}
;
diff --git a/libmu_sieve/util.c b/libmu_sieve/util.c
index e70fb103f..3d4763ca7 100644
--- a/libmu_sieve/util.c
+++ b/libmu_sieve/util.c
@@ -28,6 +28,7 @@
size_t
mu_sieve_value_create (mu_sieve_machine_t mach, mu_sieve_data_type type,
+ struct mu_locus_range const *locus,
void *data)
{
size_t idx;
@@ -43,6 +44,18 @@ mu_sieve_value_create (mu_sieve_machine_t mach, mu_sieve_data_type type,
memset (val, 0, sizeof *val);
val->type = type;
+
+ /* Copy locus. */
+ val->locus.beg.mu_file =
+ mu_i_sv_id_str (mach, mu_i_sv_id_num (mach, locus->beg.mu_file));
+ val->locus.beg.mu_line = locus->beg.mu_line;
+ val->locus.beg.mu_col = locus->beg.mu_col;
+ val->locus.end.mu_file =
+ mu_i_sv_id_str (mach, mu_i_sv_id_num (mach, locus->end.mu_file));
+ val->locus.end.mu_line = locus->end.mu_line;
+ val->locus.end.mu_col = locus->end.mu_col;
+
+ mu_locus_range_copy (&val->locus, locus);
switch (type)
{
case SVT_NUMBER:
diff --git a/libmu_sieve/variables.c b/libmu_sieve/variables.c
index 212e1b6fc..ec242874b 100644
--- a/libmu_sieve/variables.c
+++ b/libmu_sieve/variables.c
@@ -226,9 +226,12 @@ set_tag_checker (mu_sieve_machine_t mach)
*mu_sieve_get_tag_n (mach, j + 1) = *t;
else if (prec == tmp_prec)
{
- mu_diag_at_locus_range (MU_LOG_ERROR, &mach->locus,
- _("%s and %s can't be used together"),
- tmp.tag, t->tag);
+ mu_diag_at_locus_range (MU_LOG_ERROR, &t->locus,
+ _("%s and %s can't be used together"),
+ tmp.tag, t->tag);
+ mu_diag_at_locus_range (MU_LOG_ERROR, &tmp.locus,
+ _("%s encountered here"),
+ tmp.tag);
mu_i_sv_error (mach);
return 1;
}
diff --git a/sieve/tests/i-numeric.at b/sieve/tests/i-numeric.at
index 8ec8a935d..a357db40d 100644
--- a/sieve/tests/i-numeric.at
+++ b/sieve/tests/i-numeric.at
@@ -38,7 +38,7 @@ if header :comparator "i;ascii-numeric" :contains "X-Number" "15"
discard;
}
],[78],[],
-[sieve: prog:4.4-65: comparator `i;ascii-numeric' is incompatible with match type `contains' in call to `header'
+[sieve: prog:4.41-49: comparator `i;ascii-numeric' is incompatible with match type `contains' in call to `header'
])
AT_CLEANUP

Return to:

Send suggestions and report system problems to the System administrator.