diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-06-13 15:50:52 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2017-06-13 15:50:52 +0300 |
commit | 4f24c098704dd28622d1d653945388a4abbfb434 (patch) | |
tree | 31608dab06c33d10072c739355587be3435af230 | |
parent | fa5d4812fc4936dd470ded17116c9d966d0d645e (diff) | |
download | mailutils-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.h | 5 | ||||
-rw-r--r-- | libmu_sieve/actions.c | 2 | ||||
-rw-r--r-- | libmu_sieve/comparator.c | 22 | ||||
-rw-r--r-- | libmu_sieve/prog.c | 15 | ||||
-rw-r--r-- | libmu_sieve/sieve-gram.y | 14 | ||||
-rw-r--r-- | libmu_sieve/util.c | 13 | ||||
-rw-r--r-- | libmu_sieve/variables.c | 9 | ||||
-rw-r--r-- | sieve/tests/i-numeric.at | 2 |
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 |