summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/numaddr.c5
-rw-r--r--include/mailutils/sieve.h103
-rw-r--r--libmu_sieve/Makefile.am2
-rw-r--r--libmu_sieve/comparator.c80
-rw-r--r--libmu_sieve/extensions/editheader.c25
-rw-r--r--libmu_sieve/extensions/list.c5
-rw-r--r--libmu_sieve/extensions/moderator.c11
-rw-r--r--libmu_sieve/extensions/pipe.c12
-rw-r--r--libmu_sieve/extensions/spamd.c5
-rw-r--r--libmu_sieve/extensions/timestamp.c5
-rw-r--r--libmu_sieve/extensions/vacation.c5
-rw-r--r--libmu_sieve/load.c38
-rw-r--r--libmu_sieve/mem.c65
-rw-r--r--libmu_sieve/prog.c22
-rw-r--r--libmu_sieve/register.c171
-rw-r--r--libmu_sieve/registry.c177
-rw-r--r--libmu_sieve/require.c44
-rw-r--r--libmu_sieve/runtime.c36
-rw-r--r--libmu_sieve/sieve-priv.h22
-rw-r--r--libmu_sieve/sieve.l32
-rw-r--r--libmu_sieve/sieve.y190
-rw-r--r--libmu_sieve/tests.c10
22 files changed, 553 insertions, 512 deletions
diff --git a/examples/numaddr.c b/examples/numaddr.c
index 584d2b9f7..dd4329334 100644
--- a/examples/numaddr.c
+++ b/examples/numaddr.c
@@ -131,6 +131,7 @@ static mu_sieve_tag_group_t numaddr_tag_groups[] = {
int
SIEVE_EXPORT(numaddr,init) (mu_sieve_machine_t mach)
{
- return mu_sieve_register_test (mach, "numaddr", numaddr_test,
- numaddr_req_args, numaddr_tag_groups, 1);
+ mu_sieve_register_test (mach, "numaddr", numaddr_test,
+ numaddr_req_args, numaddr_tag_groups, 1);
+ return 0;
}
diff --git a/include/mailutils/sieve.h b/include/mailutils/sieve.h
index 42836f0d9..6316332b8 100644
--- a/include/mailutils/sieve.h
+++ b/include/mailutils/sieve.h
@@ -100,17 +100,13 @@ typedef struct
mu_sieve_tag_checker_t checker;
} mu_sieve_tag_group_t;
-typedef struct
+struct mu_sieve_command /* test or action */
{
- const char *name;
- int required;
mu_sieve_handler_t handler;
mu_sieve_data_type *req_args;
mu_sieve_data_type *opt_args;
mu_sieve_tag_group_t *tags;
-} mu_sieve_register_t;
-
-#define MU_SIEVE_CHARSET "UTF-8"
+};
#define MU_SIEVE_MATCH_IS 1
#define MU_SIEVE_MATCH_CONTAINS 2
@@ -119,6 +115,28 @@ typedef struct
#define MU_SIEVE_MATCH_EQ 5
#define MU_SIEVE_MATCH_LAST 6
+enum mu_sieve_record
+ {
+ mu_sieve_record_action,
+ mu_sieve_record_test,
+ mu_sieve_record_comparator
+ };
+
+typedef struct
+{
+ const char *name;
+ int required;
+ void *handle;
+ enum mu_sieve_record type;
+ union
+ {
+ struct mu_sieve_command command;
+ mu_sieve_comparator_t comp[MU_SIEVE_MATCH_LAST];
+ } v;
+} mu_sieve_registry_t;
+
+#define MU_SIEVE_CHARSET "UTF-8"
+
extern mu_debug_handle_t mu_sieve_debug_handle;
extern mu_list_t mu_sieve_include_path;
extern mu_list_t mu_sieve_library_path;
@@ -143,41 +161,46 @@ size_t mu_sieve_value_create (mu_sieve_machine_t mach,
mu_sieve_data_type type, void *data);
/* Symbol space functions */
-mu_sieve_register_t *mu_sieve_test_lookup (mu_sieve_machine_t mach,
- const char *name);
-mu_sieve_register_t *mu_sieve_action_lookup (mu_sieve_machine_t mach,
- const char *name);
-int mu_sieve_register_test_ext (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *req_args,
- mu_sieve_data_type *opt_args,
- mu_sieve_tag_group_t *tags, int required);
-int mu_sieve_register_test (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *arg_types,
- mu_sieve_tag_group_t *tags, int required);
-
-int mu_sieve_register_action_ext (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *req_args,
- mu_sieve_data_type *opt_args,
- mu_sieve_tag_group_t *tags, int required);
-int mu_sieve_register_action (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *arg_types,
- mu_sieve_tag_group_t *tags, int required);
-int mu_sieve_register_comparator (mu_sieve_machine_t mach, const char *name,
- int required, mu_sieve_comparator_t is,
- mu_sieve_comparator_t contains,
- mu_sieve_comparator_t matches,
- mu_sieve_comparator_t regex,
- mu_sieve_comparator_t eq);
-int mu_sieve_require_action (mu_sieve_machine_t mach, const char *name);
-int mu_sieve_require_test (mu_sieve_machine_t mach, const char *name);
-int mu_sieve_require_comparator (mu_sieve_machine_t mach, const char *name);
+mu_sieve_registry_t *mu_sieve_registry_add (mu_sieve_machine_t mach,
+ const char *name);
+mu_sieve_registry_t *mu_sieve_registry_lookup (mu_sieve_machine_t mach,
+ const char *name,
+ enum mu_sieve_record type);
+int mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name,
+ enum mu_sieve_record type);
+
+void mu_sieve_register_test_ext (mu_sieve_machine_t mach,
+ const char *name, mu_sieve_handler_t handler,
+ mu_sieve_data_type *req_args,
+ mu_sieve_data_type *opt_args,
+ mu_sieve_tag_group_t *tags, int required);
+void mu_sieve_register_test (mu_sieve_machine_t mach,
+ const char *name, mu_sieve_handler_t handler,
+ mu_sieve_data_type *arg_types,
+ mu_sieve_tag_group_t *tags, int required);
+
+void mu_sieve_register_action_ext (mu_sieve_machine_t mach,
+ const char *name, mu_sieve_handler_t handler,
+ mu_sieve_data_type *req_args,
+ mu_sieve_data_type *opt_args,
+ mu_sieve_tag_group_t *tags, int required);
+void mu_sieve_register_action (mu_sieve_machine_t mach,
+ const char *name, mu_sieve_handler_t handler,
+ mu_sieve_data_type *arg_types,
+ mu_sieve_tag_group_t *tags, int required);
+
+void mu_sieve_register_comparator (mu_sieve_machine_t mach, const char *name,
+ int required, mu_sieve_comparator_t is,
+ mu_sieve_comparator_t contains,
+ mu_sieve_comparator_t matches,
+ mu_sieve_comparator_t regex,
+ mu_sieve_comparator_t eq);
+
int mu_sieve_require_relational (mu_sieve_machine_t mach, const char *name);
-int mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name);
+void *mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name);
+void mu_sieve_unload_ext (void *handle);
+
int mu_sieve_match_part_checker (mu_sieve_machine_t mach);
mu_sieve_comparator_t mu_sieve_comparator_lookup (mu_sieve_machine_t mach,
@@ -229,7 +252,7 @@ int mu_sieve_vlist_compare (mu_sieve_machine_t mach,
int mu_sieve_machine_create (mu_sieve_machine_t *mach);
int mu_sieve_machine_dup (mu_sieve_machine_t const in,
mu_sieve_machine_t *out);
-int mu_sieve_machine_inherit (mu_sieve_machine_t const in,
+int mu_sieve_machine_clone (mu_sieve_machine_t const in,
mu_sieve_machine_t *out);
void mu_sieve_machine_destroy (mu_sieve_machine_t *pmach);
void mu_sieve_machine_add_destructor (mu_sieve_machine_t mach,
diff --git a/libmu_sieve/Makefile.am b/libmu_sieve/Makefile.am
index b9f3a0ada..d0a77a967 100644
--- a/libmu_sieve/Makefile.am
+++ b/libmu_sieve/Makefile.am
@@ -34,7 +34,7 @@ libmu_sieve_la_SOURCES = \
load.c\
mem.c\
prog.c\
- register.c\
+ registry.c\
relational.c\
require.c\
runtime.c\
diff --git a/libmu_sieve/comparator.c b/libmu_sieve/comparator.c
index 44dd05bbf..591b4d4a8 100644
--- a/libmu_sieve/comparator.c
+++ b/libmu_sieve/comparator.c
@@ -30,13 +30,7 @@
#include <mailutils/cctype.h>
#include <mailutils/cstr.h>
-typedef struct {
- const char *name;
- int required;
- mu_sieve_comparator_t comp[MU_SIEVE_MATCH_LAST];
-} sieve_comparator_record_t;
-
-int
+void
mu_sieve_register_comparator (mu_sieve_machine_t mach,
const char *name,
int required,
@@ -46,70 +40,26 @@ mu_sieve_register_comparator (mu_sieve_machine_t mach,
mu_sieve_comparator_t regex,
mu_sieve_comparator_t eq)
{
- sieve_comparator_record_t *rp;
-
- if (!mach->comp_list)
- {
- int rc = mu_list_create (&mach->comp_list);
- if (rc)
- return rc;
- }
-
- rp = mu_sieve_malloc (mach, sizeof (*rp));
- rp->required = required;
- rp->name = name;
- rp->comp[MU_SIEVE_MATCH_IS] = is;
- rp->comp[MU_SIEVE_MATCH_CONTAINS] = contains;
- rp->comp[MU_SIEVE_MATCH_MATCHES] = matches;
- rp->comp[MU_SIEVE_MATCH_REGEX] = regex;
- rp->comp[MU_SIEVE_MATCH_EQ] = eq;
-
- return mu_list_append (mach->comp_list, rp);
-}
-
-sieve_comparator_record_t *
-_lookup (mu_list_t list, const char *name)
-{
- mu_iterator_t itr;
- sieve_comparator_record_t *reg;
-
- if (!list || mu_list_get_iterator (list, &itr))
- return NULL;
-
- for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
- {
- mu_iterator_current (itr, (void **)&reg);
- if (strcmp (reg->name, name) == 0)
- break;
- else
- reg = NULL;
- }
- mu_iterator_destroy (&itr);
- return reg;
-}
-
-int
-mu_sieve_require_comparator (mu_sieve_machine_t mach, const char *name)
-{
- sieve_comparator_record_t *reg = _lookup (mach->comp_list, name);
- if (!reg)
- {
- if (!(mu_sieve_load_ext (mach, name) == 0
- && (reg = _lookup (mach->comp_list, name)) != NULL))
- return 1;
- }
-
- reg->required = 1;
- return 0;
+ mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name);
+
+ reg->type = mu_sieve_record_comparator;
+ reg->required = required;
+ reg->name = name;
+ reg->v.comp[MU_SIEVE_MATCH_IS] = is;
+ reg->v.comp[MU_SIEVE_MATCH_CONTAINS] = contains;
+ reg->v.comp[MU_SIEVE_MATCH_MATCHES] = matches;
+ reg->v.comp[MU_SIEVE_MATCH_REGEX] = regex;
+ reg->v.comp[MU_SIEVE_MATCH_EQ] = eq;
}
mu_sieve_comparator_t
mu_sieve_comparator_lookup (mu_sieve_machine_t mach, const char *name,
int matchtype)
{
- sieve_comparator_record_t *reg = _lookup (mach->comp_list, name);
- if (reg && reg->comp[matchtype])
- return reg->comp[matchtype];
+ mu_sieve_registry_t *reg =
+ mu_sieve_registry_lookup (mach, name, mu_sieve_record_comparator);
+ if (reg && reg->v.comp[matchtype])
+ return reg->v.comp[matchtype];
return NULL;
}
diff --git a/libmu_sieve/extensions/editheader.c b/libmu_sieve/extensions/editheader.c
index 3ef017f0d..dfb51acfc 100644
--- a/libmu_sieve/extensions/editheader.c
+++ b/libmu_sieve/extensions/editheader.c
@@ -272,22 +272,13 @@ static mu_sieve_data_type deleteheader_args[] = {
int
SIEVE_EXPORT (editheader, init) (mu_sieve_machine_t mach)
{
- int rc;
-
/* This dummy record is required by libmu_sieve */
- rc = mu_sieve_register_action (mach, "editheader", NULL, NULL, NULL, 1);
- if (rc)
- return rc;
- rc = mu_sieve_register_action (mach, "addheader", sieve_addheader,
- addheader_args, addheader_tag_groups, 1);
- if (rc)
- return rc;
- rc = mu_sieve_register_action_ext (mach, "deleteheader", sieve_deleteheader,
- deleteheader_args, deleteheader_args,
- deleteheader_tag_groups,
- 1);
- if (rc)
- return rc;
-
- return rc;
+ mu_sieve_register_action (mach, "editheader", NULL, NULL, NULL, 1);
+ mu_sieve_register_action (mach, "addheader", sieve_addheader,
+ addheader_args, addheader_tag_groups, 1);
+ mu_sieve_register_action_ext (mach, "deleteheader", sieve_deleteheader,
+ deleteheader_args, deleteheader_args,
+ deleteheader_tag_groups,
+ 1);
+ return 0;
}
diff --git a/libmu_sieve/extensions/list.c b/libmu_sieve/extensions/list.c
index 3a64e0a69..e31e76358 100644
--- a/libmu_sieve/extensions/list.c
+++ b/libmu_sieve/extensions/list.c
@@ -203,8 +203,9 @@ static mu_sieve_tag_group_t list_tag_groups[] = {
int
SIEVE_EXPORT(list,init) (mu_sieve_machine_t mach)
{
- return mu_sieve_register_test (mach, "list", list_test,
- list_req_args, list_tag_groups, 1);
+ mu_sieve_register_test (mach, "list", list_test,
+ list_req_args, list_tag_groups, 1);
+ return 0;
}
/* End of list.c */
diff --git a/libmu_sieve/extensions/moderator.c b/libmu_sieve/extensions/moderator.c
index 249611cad..f2ccd8284 100644
--- a/libmu_sieve/extensions/moderator.c
+++ b/libmu_sieve/extensions/moderator.c
@@ -84,7 +84,7 @@ moderator_filter_message (mu_sieve_machine_t mach,
if (mu_sieve_get_tag (mach, "source", SVT_STRING, &arg))
{
- rc = mu_sieve_machine_inherit (mach, &newmach);
+ rc = mu_sieve_machine_clone (mach, &newmach);
if (rc)
{
mu_sieve_error (mach, _("cannot initialize sieve machine: %s"),
@@ -105,7 +105,7 @@ moderator_filter_message (mu_sieve_machine_t mach,
{
struct mu_locus locus;
- rc = mu_sieve_machine_inherit (mach, &newmach);
+ rc = mu_sieve_machine_clone (mach, &newmach);
if (rc)
{
mu_sieve_error (mach, _("cannot initialize sieve machine: %s"),
@@ -363,8 +363,9 @@ static mu_sieve_tag_group_t moderator_tag_groups[] = {
int
SIEVE_EXPORT(moderator,init) (mu_sieve_machine_t mach)
{
- return mu_sieve_register_action (mach, "moderator", moderator_action,
- moderator_req_args,
- moderator_tag_groups, 1);
+ mu_sieve_register_action (mach, "moderator", moderator_action,
+ moderator_req_args,
+ moderator_tag_groups, 1);
+ return 0;
}
diff --git a/libmu_sieve/extensions/pipe.c b/libmu_sieve/extensions/pipe.c
index 3aedf16ac..5ba6c134b 100644
--- a/libmu_sieve/extensions/pipe.c
+++ b/libmu_sieve/extensions/pipe.c
@@ -275,11 +275,9 @@ static mu_sieve_data_type pipe_args[] = {
int
SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach)
{
- int rc;
- rc = mu_sieve_register_action (mach, "pipe", sieve_action_pipe,
- pipe_args, pipe_action_tag_groups, 1);
- if (rc)
- return rc;
- return mu_sieve_register_test (mach, "pipe", sieve_test_pipe,
- pipe_args, pipe_test_tag_groups, 1);
+ mu_sieve_register_action (mach, "pipe", sieve_action_pipe,
+ pipe_args, pipe_action_tag_groups, 1);
+ mu_sieve_register_test (mach, "pipe", sieve_test_pipe,
+ pipe_args, pipe_test_tag_groups, 1);
+ return 0;
}
diff --git a/libmu_sieve/extensions/spamd.c b/libmu_sieve/extensions/spamd.c
index 692f49ae2..2ea2efd35 100644
--- a/libmu_sieve/extensions/spamd.c
+++ b/libmu_sieve/extensions/spamd.c
@@ -544,7 +544,8 @@ static mu_sieve_tag_group_t spamd_tag_groups[] = {
int
SIEVE_EXPORT(spamd,init) (mu_sieve_machine_t mach)
{
- return mu_sieve_register_test (mach, "spamd", spamd_test,
- spamd_req_args, spamd_tag_groups, 1);
+ mu_sieve_register_test (mach, "spamd", spamd_test,
+ spamd_req_args, spamd_tag_groups, 1);
+ return 0;
}
diff --git a/libmu_sieve/extensions/timestamp.c b/libmu_sieve/extensions/timestamp.c
index e96f4ddcf..5adf4decc 100644
--- a/libmu_sieve/extensions/timestamp.c
+++ b/libmu_sieve/extensions/timestamp.c
@@ -123,6 +123,7 @@ static mu_sieve_tag_group_t timestamp_tag_groups[] = {
int
SIEVE_EXPORT(timestamp,init) (mu_sieve_machine_t mach)
{
- return mu_sieve_register_test (mach, "timestamp", timestamp_test,
- timestamp_req_args, timestamp_tag_groups, 1);
+ mu_sieve_register_test (mach, "timestamp", timestamp_test,
+ timestamp_req_args, timestamp_tag_groups, 1);
+ return 0;
}
diff --git a/libmu_sieve/extensions/vacation.c b/libmu_sieve/extensions/vacation.c
index fa19c8785..ecff9386b 100644
--- a/libmu_sieve/extensions/vacation.c
+++ b/libmu_sieve/extensions/vacation.c
@@ -868,6 +868,7 @@ static mu_sieve_data_type vacation_args[] = {
int SIEVE_EXPORT (vacation, init) (mu_sieve_machine_t mach)
{
- return mu_sieve_register_action (mach, "vacation", sieve_action_vacation,
- vacation_args, vacation_tag_groups, 1);
+ mu_sieve_register_action (mach, "vacation", sieve_action_vacation,
+ vacation_args, vacation_tag_groups, 1);
+ return 0;
}
diff --git a/libmu_sieve/load.c b/libmu_sieve/load.c
index c164c2741..deddcd2d8 100644
--- a/libmu_sieve/load.c
+++ b/libmu_sieve/load.c
@@ -31,16 +31,6 @@
typedef int (*sieve_module_init_t) (mu_sieve_machine_t mach);
-#if 0
-/* FIXME: See comment below */
-static void
-_free_loaded_module (void *data)
-{
- lt_dlclose ((lt_dlhandle)data);
- lt_dlexit ();
-}
-#endif
-
static int _add_load_dir (void *, void *);
static int
@@ -61,8 +51,7 @@ sieve_init_load_path ()
}
return 0;
}
-
-
+
static lt_dlhandle
load_module (mu_sieve_machine_t mach, const char *name)
{
@@ -74,18 +63,12 @@ load_module (mu_sieve_machine_t mach, const char *name)
handle = lt_dlopenext (name);
if (handle)
{
- sieve_module_init_t init = (sieve_module_init_t)
- lt_dlsym (handle, "init");
+ sieve_module_init_t init;
+
+ init = (sieve_module_init_t) lt_dlsym (handle, "init");
if (init)
{
init (mach);
- /* FIXME: We used to have this:
- mu_sieve_machine_add_destructor (mach, _free_loaded_module,
- handle);
- However, unloading modules can lead to random segfaults in
- case they allocated any global-access data (e.g. mach->msg).
- In particular, this was the case with extensions/pipe.c.
- */
return handle;
}
else
@@ -114,7 +97,7 @@ fix_module_name (char *name)
}
}
-int
+void *
mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name)
{
lt_dlhandle handle;
@@ -122,11 +105,18 @@ mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name)
modname = strdup (name);
if (!modname)
- return 1;
+ return NULL;
fix_module_name (modname);
handle = load_module (mach, modname);
free (modname);
- return handle == NULL;
+ return handle;
+}
+
+void
+mu_sieve_unload_ext (void *data)
+{
+ if (data)
+ lt_dlclose ((lt_dlhandle)data);
}
static int
diff --git a/libmu_sieve/mem.c b/libmu_sieve/mem.c
index 3c39a3d10..565ba3228 100644
--- a/libmu_sieve/mem.c
+++ b/libmu_sieve/mem.c
@@ -83,6 +83,9 @@ mu_sieve_free (mu_sieve_machine_t mach, void *ptr)
int rc;
struct memory_cell mcell;
+ if (!ptr)
+ return;
+
mcell.ptr = ptr;
rc = mu_list_remove (mach->memory_pool, &mcell);
if (rc)
@@ -228,3 +231,65 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb,
*pptr = ptr;
*pnmemb = nmemb;
}
+
+char *
+mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name)
+{
+ size_t i;
+ char *p;
+
+ if (!name)
+ return NULL;
+
+ for (i = 0; i < mach->idcount; i++)
+ {
+ if (strcmp (mach->idspace[i], name) == 0)
+ return mach->idspace[i];
+ }
+
+ if (mach->idcount == mach->idmax)
+ {
+ mu_i_sv_2nrealloc (mach,
+ (void **) &mach->idspace,
+ &mach->idmax,
+ sizeof mach->idspace[0]);
+ }
+
+ p = mu_sieve_strdup (mach, name);
+ mach->idspace[mach->idcount++] = p;
+
+ return p;
+}
+
+size_t
+mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name)
+{
+ size_t i;
+
+ for (i = 0; i < mach->idcount; i++)
+ {
+ if (mach->idspace[i] == name || strcmp (mach->idspace[i], name) == 0)
+ return i;
+ }
+ abort ();
+}
+
+char *
+mu_i_sv_id_str (mu_sieve_machine_t mach, size_t n)
+{
+ if (n >= mach->idcount)
+ abort ();
+ return mach->idspace[n];
+}
+
+void
+mu_i_sv_free_idspace (mu_sieve_machine_t mach)
+{
+ size_t i;
+
+ for (i = 0; i < mach->idcount; i++)
+ mu_sieve_free (mach, mach->idspace[i]);
+ mach->idcount = 0;
+}
+
+
diff --git a/libmu_sieve/prog.c b/libmu_sieve/prog.c
index 17b65870f..6ab96091e 100644
--- a/libmu_sieve/prog.c
+++ b/libmu_sieve/prog.c
@@ -52,7 +52,7 @@ mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr)
if (!file_eq (mach->locus.mu_file, lr->beg.mu_file))
{
mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_source);
- mu_i_sv_code (mach, (sieve_op_t) lr->beg.mu_file);
+ mu_i_sv_code (mach, (sieve_op_t) mu_i_sv_id_num (mach, lr->beg.mu_file));
}
if (mach->locus.mu_line != lr->beg.mu_line)
{
@@ -133,8 +133,8 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
struct mu_sieve_node *node)
{
size_t i;
- mu_sieve_register_t *reg = node->v.command.reg;
-
+ mu_sieve_registry_t *reg = node->v.command.reg;
+
mu_sieve_value_t *start = mach->valspace + node->v.command.argstart;
mu_list_t chk_list = NULL;
@@ -142,8 +142,11 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
int opt_args = 0;
int rc, err = 0;
static mu_sieve_data_type empty[] = { SVT_VOID };
+
+ if (!reg)
+ return;
- exp_arg = reg->req_args ? reg->req_args : empty;
+ exp_arg = reg->v.command.req_args ? reg->v.command.req_args : empty;
/* Pass 1: consolidation */
for (i = 0; i < node->v.command.argcount; i++)
@@ -153,7 +156,8 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
if (val->type == SVT_TAG)
{
mu_sieve_tag_checker_t cf;
- mu_sieve_tag_def_t *tag = find_tag (reg->tags, val->v.string, &cf);
+ mu_sieve_tag_def_t *tag = find_tag (reg->v.command.tags,
+ val->v.string, &cf);
if (!tag)
{
@@ -228,9 +232,9 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
{
if (*exp_arg == SVT_VOID)
{
- if (reg->opt_args)
+ if (reg->v.command.opt_args)
{
- exp_arg = reg->opt_args;
+ exp_arg = reg->v.command.opt_args;
opt_args = 1;
}
else
@@ -252,7 +256,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach,
{
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("type mismatch in argument %lu to `%s'"),
- (unsigned long) (exp_arg - reg->req_args + 1),
+ (unsigned long) (exp_arg - reg->v.command.req_args + 1),
reg->name);
mu_diag_at_locus (MU_LOG_ERROR, &mach->locus,
_("expected %s but passed %s"),
@@ -316,7 +320,7 @@ static void
sv_code_command (struct mu_sieve_machine *mach,
struct mu_sieve_node *node)
{
- mu_i_sv_code (mach, (sieve_op_t) node->v.command.reg->handler);
+ mu_i_sv_code (mach, (sieve_op_t) node->v.command.reg->v.command.handler);
mu_i_sv_code (mach, (sieve_op_t) node->v.command.argstart);
mu_i_sv_code (mach, (sieve_op_t) node->v.command.argcount);
mu_i_sv_code (mach, (sieve_op_t) node->v.command.tagcount);
diff --git a/libmu_sieve/register.c b/libmu_sieve/register.c
deleted file mode 100644
index acd387645..000000000
--- a/libmu_sieve/register.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/* GNU Mailutils -- a suite of utilities for electronic mail
- Copyright (C) 1999-2002, 2004-2005, 2007-2008, 2010-2012, 2014-2016
- Free Software Foundation, Inc.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 3 of the License, or (at your option) any later version.
-
- This library 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General
- Public License along with this library. If not, see
- <http://www.gnu.org/licenses/>. */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sieve-priv.h>
-
-static mu_sieve_register_t *
-reg_lookup (mu_list_t list, const char *name)
-{
- mu_iterator_t itr;
- mu_sieve_register_t *reg;
-
- if (!list || mu_list_get_iterator (list, &itr))
- return NULL;
-
- for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr))
- {
- mu_iterator_current (itr, (void **)&reg);
- if (strcmp (reg->name, name) == 0)
- break;
- else
- reg = NULL;
- }
- mu_iterator_destroy (&itr);
- return reg;
-}
-
-mu_sieve_register_t *
-mu_sieve_test_lookup (mu_sieve_machine_t mach, const char *name)
-{
- mu_sieve_register_t *reg = reg_lookup (mach->test_list, name);
- return (reg && reg->handler) ? reg : NULL;
-}
-
-mu_sieve_register_t *
-mu_sieve_action_lookup (mu_sieve_machine_t mach, const char *name)
-{
- mu_sieve_register_t *reg = reg_lookup (mach->action_list, name);
- return (reg && reg->handler) ? reg : NULL;
-}
-
-static int
-reg_require (mu_sieve_machine_t mach, mu_list_t list, const char *name)
-{
- mu_sieve_register_t *reg = reg_lookup (list, name);
- if (!reg)
- {
- if (!(mu_sieve_load_ext (mach, name) == 0
- && (reg = reg_lookup (list, name)) != NULL))
- return 1;
- }
- reg->required = 1;
- return 0;
-}
-
-int
-mu_sieve_require_action (mu_sieve_machine_t mach, const char *name)
-{
- return reg_require (mach, mach->action_list, name);
-}
-
-int
-mu_sieve_require_test (mu_sieve_machine_t mach, const char *name)
-{
- return reg_require (mach, mach->test_list, name);
-}
-
-
-static int
-sieve_register (mu_sieve_machine_t mach,
- mu_list_t *list,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *req_arg_types,
- mu_sieve_data_type *opt_arg_types,
- mu_sieve_tag_group_t *tags, int required)
-{
- mu_sieve_register_t *reg = mu_sieve_malloc (mach, sizeof (*reg));
-
- if (!reg)
- return ENOMEM;
- reg->name = name;
- reg->handler = handler;
-
- reg->req_args = req_arg_types;
- reg->opt_args = opt_arg_types;
- reg->tags = tags;
- reg->required = required;
-
- if (!*list)
- {
- int rc = mu_list_create (list);
- if (rc)
- {
- free (reg);
- return rc;
- }
- }
-
- return mu_list_append (*list, reg);
-}
-
-
-int
-mu_sieve_register_test_ext (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *req_args,
- mu_sieve_data_type *opt_args,
- mu_sieve_tag_group_t *tags, int required)
-{
- return sieve_register (mach,
- &mach->test_list, name, handler,
- req_args, opt_args, tags, required);
-}
-
-int
-mu_sieve_register_test (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *arg_types,
- mu_sieve_tag_group_t *tags, int required)
-{
- return mu_sieve_register_test_ext (mach, name, handler,
- arg_types, NULL,
- tags,
- required);
-}
-
-int
-mu_sieve_register_action_ext (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *req_args,
- mu_sieve_data_type *opt_args,
- mu_sieve_tag_group_t *tags, int required)
-{
- return sieve_register (mach,
- &mach->action_list, name, handler,
- req_args, opt_args, tags, required);
-}
-
-int
-mu_sieve_register_action (mu_sieve_machine_t mach,
- const char *name, mu_sieve_handler_t handler,
- mu_sieve_data_type *arg_types,
- mu_sieve_tag_group_t *tags, int required)
-{
- return mu_sieve_register_action_ext (mach, name, handler,
- arg_types, NULL,
- tags,
- required);
-}
diff --git a/libmu_sieve/registry.c b/libmu_sieve/registry.c
new file mode 100644
index 000000000..a5cbdfca9
--- /dev/null
+++ b/libmu_sieve/registry.c
@@ -0,0 +1,177 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 1999-2002, 2004-2005, 2007-2008, 2010-2012, 2014-2016
+ Free Software Foundation, Inc.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 3 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General
+ Public License along with this library. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sieve-priv.h>
+
+int
+mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name,
+ enum mu_sieve_record type)
+{
+ mu_sieve_registry_t *reg;
+
+ reg = mu_sieve_registry_lookup (mach, name, type);
+ if (!reg)
+ {
+ void *handle = mu_sieve_load_ext (mach, name);
+ if (!handle)
+ return 1;
+ reg = mu_sieve_registry_lookup (mach, name, type);
+ if (!reg)
+ return 1;
+ reg->handle = handle;
+ }
+
+ reg->required = 1;
+ return 0;
+}
+
+
+static void
+regunload (void *data)
+{
+ mu_sieve_registry_t *reg = data;
+ mu_sieve_unload_ext (reg->handle);
+}
+
+static int
+regcmp (void const *a, void const *