diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-12-07 09:46:57 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2016-12-07 13:03:42 +0200 |
commit | 799519539556b38fc9f84d44927861cb9239d14c (patch) | |
tree | 304982f21416f837c8b5a678b85ba99edce62d40 /libmu_sieve/sieve.y | |
parent | cab2fd5c0479d16a3dcd746c98de8be771a8963d (diff) | |
download | mailutils-799519539556b38fc9f84d44927861cb9239d14c.tar.gz mailutils-799519539556b38fc9f84d44927861cb9239d14c.tar.bz2 |
Implement the "variables" Sieve extension (RFC 5229)
* include/mailutils/sieve.h (mu_sieve_string): New fields
"constant" and "changed".
(mu_sieve_match_part_tags): New extern.
(mu_sieve_relational_count)
(mu_sieve_require_variables)
(mu_sieve_has_variables)
(mu_sieve_string_get): New functions.
* libmu_sieve/variables.c: New file.
* libmu_sieve/Makefile.am: Add variables.c
* libmu_sieve/comparator.c: Use mu_sieve_string_get to obtain
the actual value of the string.
* libmu_sieve/require.c: Support the "variables" extension.
* libmu_sieve/sieve-priv.h (mu_sieve_machine): New fields
vartab, match_string, match_buf, match_count, match_max.
(mu_i_sv_copy_variables)
(mu_i_sv_expand_variables): New protos.
* libmu_sieve/sieve.l (line_add): zero length means add entire
asciiz string.
* libmu_sieve/sieve.y (mu_sieve_machine_reset): Reset the new
fields.
(mu_sieve_machine_clone): Copy variables and initialize new
fields.
(string_rescan): New function.
(sieve_parse): Rescan string to determine their properties.
* libmu_sieve/strexp.c (update_len): Allow for NULL replacement
values.
* libmu_sieve/string.c (mu_sieve_string_get): New function.
(mu_sieve_string): Use it.
* libmu_sieve/tests.c (do_count): Rename to mu_sieve_relational_count,
make global. All uses changed.
(match_part_tags): Rename to mu_sieve_match_part_tags, make global.
All uses changed.
* sieve/tests/variables.at: New file.
* sieve/tests/Makefile.am: Add new testcases.
* sieve/tests/testsuite.at: Likewise.
Diffstat (limited to 'libmu_sieve/sieve.y')
-rw-r--r-- | libmu_sieve/sieve.y | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/libmu_sieve/sieve.y b/libmu_sieve/sieve.y index 46a8fba32..0a612f1ba 100644 --- a/libmu_sieve/sieve.y +++ b/libmu_sieve/sieve.y @@ -1067,6 +1067,12 @@ mu_sieve_machine_reset (mu_sieve_machine_t mach) mach->progsize = 0; mach->prog = NULL; + mu_assoc_destroy (&mach->vartab); + mach->match_string = NULL; + mach->match_buf = NULL; + mach->match_count = 0; + mach->match_max = 0; + mach->state = mu_sieve_state_init; return 0; @@ -1174,6 +1180,16 @@ mu_sieve_machine_clone (mu_sieve_machine_t const parent, sizeof child->prog[0]); memcpy (child->prog, parent->prog, parent->progsize * sizeof (child->prog[0])); + + /* Copy variables */ + if (mu_sieve_has_variables (parent)) + { + mu_i_sv_copy_variables (child, parent); + child->match_string = NULL; + child->match_buf = NULL; + child->match_count = 0; + child->match_max = 0; + } /* Copy user-defined settings */ @@ -1468,6 +1484,30 @@ with_machine (mu_sieve_machine_t mach, char const *name, return rc; } +/* Rescan all registered strings to determine their properties */ +static void +string_rescan (mu_sieve_machine_t mach) +{ + size_t i; + int hasvar = mu_sieve_has_variables (mach); + + for (i = 0; i < mach->stringcount; i++) + { + mach->stringspace[i].changed = 0; + if (hasvar) + { + mach->stringspace[i].constant = 0; + mu_sieve_string_get (mach, &mach->stringspace[i]); + mu_sieve_free (mach, mach->stringspace[i].exp); + mach->stringspace[i].exp = NULL; + mach->stringspace[i].constant = !mach->stringspace[i].changed; + mach->stringspace[i].changed = 0; + } + else + mach->stringspace[i].constant = 1; + } +} + static int sieve_parse (void) { @@ -1509,7 +1549,10 @@ sieve_parse (void) if (mu_sieve_machine->state == mu_sieve_state_error) rc = MU_ERR_PARSE; else - mu_sieve_machine->state = mu_sieve_state_compiled; + { + string_rescan (mu_sieve_machine); + mu_sieve_machine->state = mu_sieve_state_compiled; + } } tree_free (&sieve_tree); |