diff options
-rw-r--r-- | examples/numaddr.c | 5 | ||||
-rw-r--r-- | include/mailutils/sieve.h | 103 | ||||
-rw-r--r-- | libmu_sieve/Makefile.am | 2 | ||||
-rw-r--r-- | libmu_sieve/comparator.c | 80 | ||||
-rw-r--r-- | libmu_sieve/extensions/editheader.c | 25 | ||||
-rw-r--r-- | libmu_sieve/extensions/list.c | 5 | ||||
-rw-r--r-- | libmu_sieve/extensions/moderator.c | 11 | ||||
-rw-r--r-- | libmu_sieve/extensions/pipe.c | 12 | ||||
-rw-r--r-- | libmu_sieve/extensions/spamd.c | 5 | ||||
-rw-r--r-- | libmu_sieve/extensions/timestamp.c | 5 | ||||
-rw-r--r-- | libmu_sieve/extensions/vacation.c | 5 | ||||
-rw-r--r-- | libmu_sieve/load.c | 38 | ||||
-rw-r--r-- | libmu_sieve/mem.c | 65 | ||||
-rw-r--r-- | libmu_sieve/prog.c | 22 | ||||
-rw-r--r-- | libmu_sieve/register.c | 171 | ||||
-rw-r--r-- | libmu_sieve/registry.c | 177 | ||||
-rw-r--r-- | libmu_sieve/require.c | 44 | ||||
-rw-r--r-- | libmu_sieve/runtime.c | 36 | ||||
-rw-r--r-- | libmu_sieve/sieve-priv.h | 22 | ||||
-rw-r--r-- | libmu_sieve/sieve.l | 32 | ||||
-rw-r--r-- | libmu_sieve/sieve.y | 190 | ||||
-rw-r--r-- | libmu_sieve/tests.c | 10 |
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 **)®); - 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 **)®); - 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 * |