sieve: redo symbol registry support.
The purpose is to simplify the machine structure and to ensure its clones are completely independent of the master instance. * include/mailutils/sieve.h (mu_sieve_command): New struct. (mu_sieve_record): New enum (mu_sieve_registry_t): Generalize for storing various types of objects. (mu_sieve_test_lookup,mu_sieve_action_lookup) (mu_sieve_require_action,mu_sieve_require_test) (mu_sieve_require_comparator): Remove. (mu_sieve_register_test_ext,mu_sieve_register_test) (mu_sieve_register_action_ext,mu_sieve_register_action) (mu_sieve_register_comparator) (mu_sieve_load_ext): Change return type. (mu_sieve_registry_require,mu_sieve_unload_ext): New functions. (mu_sieve_machine_inherit): Rename to mu_sieve_machine_clone. * libmu_sieve/sieve-priv.h (mu_sieve_machine): Remove source_list, test_list, action_list, and comp_list. Add a single registry list instead. Add space for file and command (action and test) names: idspace, idcount, idmax. Remove unused field "stack"; (mu_i_sv_lex_finish): Change prototype. (_mu_i_sv_instr_push,_mu_i_sv_instr_pop): Remove protos. (mu_i_sv_id_canon,mu_i_sv_id_num) (mu_i_sv_id_str,mu_i_sv_free_idspace): New protos. * libmu_sieve/register.c: Rename to registry.c * libmu_sieve/registry.c (mu_sieve_test_lookup) (mu_sieve_action_lookup): Remove. (mu_sieve_require_test,mu_sieve_require_action): Remove. (mu_sieve_registry_require): New function. (mu_sieve_registry_add,mu_sieve_registry_lookup): New functions. * libmu_sieve/Makefile.am: Update. * libmu_sieve/comparator.c: Rewrite using new registry functions. * libmu_sieve/load.c (mu_sieve_load_ext): Return module handle. (mu_sieve_unload_ext): New function. * libmu_sieve/mem.c (mu_sieve_free): Gracefully handle NULL argument. (mu_i_sv_id_canon,mu_i_sv_id_num,mu_i_sv_id_str): New functions. * libmu_sieve/prog.c (mu_i_sv_locus): Store index of the file name in the id space, instead of pointer to the name itself. * libmu_sieve/require.c (mu_sieve_require): Rewrite. * libmu_sieve/runtime.c (_mu_i_sv_instr_source): Expect ID index as argument. (_mu_i_sv_instr_push) (_mu_i_sv_instr_pop): Remove unused instructions. * libmu_sieve/sieve.l (file_names): Remove. Use mu_sieve_machine idspace instead. * libmu_sieve/sieve.y (mu_sieve_machine_clone) (mu_sieve_machine_dup): Rewrite. (mu_sieve_machine_destroy): Free idspace and registry * examples/numaddr.c: Reflect changes. * libmu_sieve/extensions/editheader.c: Likewise. * libmu_sieve/extensions/list.c: Likewise. * libmu_sieve/extensions/moderator.c: Likewise. * libmu_sieve/extensions/pipe.c: Likewise. * libmu_sieve/extensions/spamd.c: Likewise. * libmu_sieve/extensions/timestamp.c: Likewise. * libmu_sieve/extensions/vacation.c: Likewise.
Showing
21 changed files
with
404 additions
and
363 deletions
... | @@ -131,6 +131,7 @@ static mu_sieve_tag_group_t numaddr_tag_groups[] = { | ... | @@ -131,6 +131,7 @@ static mu_sieve_tag_group_t numaddr_tag_groups[] = { |
131 | int | 131 | int |
132 | SIEVE_EXPORT(numaddr,init) (mu_sieve_machine_t mach) | 132 | SIEVE_EXPORT(numaddr,init) (mu_sieve_machine_t mach) |
133 | { | 133 | { |
134 | return mu_sieve_register_test (mach, "numaddr", numaddr_test, | 134 | mu_sieve_register_test (mach, "numaddr", numaddr_test, |
135 | numaddr_req_args, numaddr_tag_groups, 1); | 135 | numaddr_req_args, numaddr_tag_groups, 1); |
136 | return 0; | ||
136 | } | 137 | } | ... | ... |
... | @@ -100,17 +100,13 @@ typedef struct | ... | @@ -100,17 +100,13 @@ typedef struct |
100 | mu_sieve_tag_checker_t checker; | 100 | mu_sieve_tag_checker_t checker; |
101 | } mu_sieve_tag_group_t; | 101 | } mu_sieve_tag_group_t; |
102 | 102 | ||
103 | typedef struct | 103 | struct mu_sieve_command /* test or action */ |
104 | { | 104 | { |
105 | const char *name; | ||
106 | int required; | ||
107 | mu_sieve_handler_t handler; | 105 | mu_sieve_handler_t handler; |
108 | mu_sieve_data_type *req_args; | 106 | mu_sieve_data_type *req_args; |
109 | mu_sieve_data_type *opt_args; | 107 | mu_sieve_data_type *opt_args; |
110 | mu_sieve_tag_group_t *tags; | 108 | mu_sieve_tag_group_t *tags; |
111 | } mu_sieve_register_t; | 109 | }; |
112 | |||
113 | #define MU_SIEVE_CHARSET "UTF-8" | ||
114 | 110 | ||
115 | #define MU_SIEVE_MATCH_IS 1 | 111 | #define MU_SIEVE_MATCH_IS 1 |
116 | #define MU_SIEVE_MATCH_CONTAINS 2 | 112 | #define MU_SIEVE_MATCH_CONTAINS 2 |
... | @@ -119,6 +115,28 @@ typedef struct | ... | @@ -119,6 +115,28 @@ typedef struct |
119 | #define MU_SIEVE_MATCH_EQ 5 | 115 | #define MU_SIEVE_MATCH_EQ 5 |
120 | #define MU_SIEVE_MATCH_LAST 6 | 116 | #define MU_SIEVE_MATCH_LAST 6 |
121 | 117 | ||
118 | enum mu_sieve_record | ||
119 | { | ||
120 | mu_sieve_record_action, | ||
121 | mu_sieve_record_test, | ||
122 | mu_sieve_record_comparator | ||
123 | }; | ||
124 | |||
125 | typedef struct | ||
126 | { | ||
127 | const char *name; | ||
128 | int required; | ||
129 | void *handle; | ||
130 | enum mu_sieve_record type; | ||
131 | union | ||
132 | { | ||
133 | struct mu_sieve_command command; | ||
134 | mu_sieve_comparator_t comp[MU_SIEVE_MATCH_LAST]; | ||
135 | } v; | ||
136 | } mu_sieve_registry_t; | ||
137 | |||
138 | #define MU_SIEVE_CHARSET "UTF-8" | ||
139 | |||
122 | extern mu_debug_handle_t mu_sieve_debug_handle; | 140 | extern mu_debug_handle_t mu_sieve_debug_handle; |
123 | extern mu_list_t mu_sieve_include_path; | 141 | extern mu_list_t mu_sieve_include_path; |
124 | extern mu_list_t mu_sieve_library_path; | 142 | extern mu_list_t mu_sieve_library_path; |
... | @@ -143,41 +161,46 @@ size_t mu_sieve_value_create (mu_sieve_machine_t mach, | ... | @@ -143,41 +161,46 @@ size_t mu_sieve_value_create (mu_sieve_machine_t mach, |
143 | mu_sieve_data_type type, void *data); | 161 | mu_sieve_data_type type, void *data); |
144 | 162 | ||
145 | /* Symbol space functions */ | 163 | /* Symbol space functions */ |
146 | mu_sieve_register_t *mu_sieve_test_lookup (mu_sieve_machine_t mach, | 164 | mu_sieve_registry_t *mu_sieve_registry_add (mu_sieve_machine_t mach, |
147 | const char *name); | ||
148 | mu_sieve_register_t *mu_sieve_action_lookup (mu_sieve_machine_t mach, | ||
149 | const char *name); | 165 | const char *name); |
150 | int mu_sieve_register_test_ext (mu_sieve_machine_t mach, | 166 | mu_sieve_registry_t *mu_sieve_registry_lookup (mu_sieve_machine_t mach, |
167 | const char *name, | ||
168 | enum mu_sieve_record type); | ||
169 | int mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name, | ||
170 | enum mu_sieve_record type); | ||
171 | |||
172 | void mu_sieve_register_test_ext (mu_sieve_machine_t mach, | ||
151 | const char *name, mu_sieve_handler_t handler, | 173 | const char *name, mu_sieve_handler_t handler, |
152 | mu_sieve_data_type *req_args, | 174 | mu_sieve_data_type *req_args, |
153 | mu_sieve_data_type *opt_args, | 175 | mu_sieve_data_type *opt_args, |
154 | mu_sieve_tag_group_t *tags, int required); | 176 | mu_sieve_tag_group_t *tags, int required); |
155 | int mu_sieve_register_test (mu_sieve_machine_t mach, | 177 | void mu_sieve_register_test (mu_sieve_machine_t mach, |
156 | const char *name, mu_sieve_handler_t handler, | 178 | const char *name, mu_sieve_handler_t handler, |
157 | mu_sieve_data_type *arg_types, | 179 | mu_sieve_data_type *arg_types, |
158 | mu_sieve_tag_group_t *tags, int required); | 180 | mu_sieve_tag_group_t *tags, int required); |
159 | 181 | ||
160 | int mu_sieve_register_action_ext (mu_sieve_machine_t mach, | 182 | void mu_sieve_register_action_ext (mu_sieve_machine_t mach, |
161 | const char *name, mu_sieve_handler_t handler, | 183 | const char *name, mu_sieve_handler_t handler, |
162 | mu_sieve_data_type *req_args, | 184 | mu_sieve_data_type *req_args, |
163 | mu_sieve_data_type *opt_args, | 185 | mu_sieve_data_type *opt_args, |
164 | mu_sieve_tag_group_t *tags, int required); | 186 | mu_sieve_tag_group_t *tags, int required); |
165 | int mu_sieve_register_action (mu_sieve_machine_t mach, | 187 | void mu_sieve_register_action (mu_sieve_machine_t mach, |
166 | const char *name, mu_sieve_handler_t handler, | 188 | const char *name, mu_sieve_handler_t handler, |
167 | mu_sieve_data_type *arg_types, | 189 | mu_sieve_data_type *arg_types, |
168 | mu_sieve_tag_group_t *tags, int required); | 190 | mu_sieve_tag_group_t *tags, int required); |
169 | int mu_sieve_register_comparator (mu_sieve_machine_t mach, const char *name, | 191 | |
192 | void mu_sieve_register_comparator (mu_sieve_machine_t mach, const char *name, | ||
170 | int required, mu_sieve_comparator_t is, | 193 | int required, mu_sieve_comparator_t is, |
171 | mu_sieve_comparator_t contains, | 194 | mu_sieve_comparator_t contains, |
172 | mu_sieve_comparator_t matches, | 195 | mu_sieve_comparator_t matches, |
173 | mu_sieve_comparator_t regex, | 196 | mu_sieve_comparator_t regex, |
174 | mu_sieve_comparator_t eq); | 197 | mu_sieve_comparator_t eq); |
175 | int mu_sieve_require_action (mu_sieve_machine_t mach, const char *name); | 198 | |
176 | int mu_sieve_require_test (mu_sieve_machine_t mach, const char *name); | ||
177 | int mu_sieve_require_comparator (mu_sieve_machine_t mach, const char *name); | ||
178 | int mu_sieve_require_relational (mu_sieve_machine_t mach, const char *name); | 199 | int mu_sieve_require_relational (mu_sieve_machine_t mach, const char *name); |
179 | 200 | ||
180 | int mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name); | 201 | void *mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name); |
202 | void mu_sieve_unload_ext (void *handle); | ||
203 | |||
181 | int mu_sieve_match_part_checker (mu_sieve_machine_t mach); | 204 | int mu_sieve_match_part_checker (mu_sieve_machine_t mach); |
182 | 205 | ||
183 | mu_sieve_comparator_t mu_sieve_comparator_lookup (mu_sieve_machine_t mach, | 206 | 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, | ... | @@ -229,7 +252,7 @@ int mu_sieve_vlist_compare (mu_sieve_machine_t mach, |
229 | int mu_sieve_machine_create (mu_sieve_machine_t *mach); | 252 | int mu_sieve_machine_create (mu_sieve_machine_t *mach); |
230 | int mu_sieve_machine_dup (mu_sieve_machine_t const in, | 253 | int mu_sieve_machine_dup (mu_sieve_machine_t const in, |
231 | mu_sieve_machine_t *out); | 254 | mu_sieve_machine_t *out); |
232 | int mu_sieve_machine_inherit (mu_sieve_machine_t const in, | 255 | int mu_sieve_machine_clone (mu_sieve_machine_t const in, |
233 | mu_sieve_machine_t *out); | 256 | mu_sieve_machine_t *out); |
234 | void mu_sieve_machine_destroy (mu_sieve_machine_t *pmach); | 257 | void mu_sieve_machine_destroy (mu_sieve_machine_t *pmach); |
235 | void mu_sieve_machine_add_destructor (mu_sieve_machine_t mach, | 258 | void mu_sieve_machine_add_destructor (mu_sieve_machine_t mach, | ... | ... |
... | @@ -30,13 +30,7 @@ | ... | @@ -30,13 +30,7 @@ |
30 | #include <mailutils/cctype.h> | 30 | #include <mailutils/cctype.h> |
31 | #include <mailutils/cstr.h> | 31 | #include <mailutils/cstr.h> |
32 | 32 | ||
33 | typedef struct { | 33 | void |
34 | const char *name; | ||
35 | int required; | ||
36 | mu_sieve_comparator_t comp[MU_SIEVE_MATCH_LAST]; | ||
37 | } sieve_comparator_record_t; | ||
38 | |||
39 | int | ||
40 | mu_sieve_register_comparator (mu_sieve_machine_t mach, | 34 | mu_sieve_register_comparator (mu_sieve_machine_t mach, |
41 | const char *name, | 35 | const char *name, |
42 | int required, | 36 | int required, |
... | @@ -46,70 +40,26 @@ mu_sieve_register_comparator (mu_sieve_machine_t mach, | ... | @@ -46,70 +40,26 @@ mu_sieve_register_comparator (mu_sieve_machine_t mach, |
46 | mu_sieve_comparator_t regex, | 40 | mu_sieve_comparator_t regex, |
47 | mu_sieve_comparator_t eq) | 41 | mu_sieve_comparator_t eq) |
48 | { | 42 | { |
49 | sieve_comparator_record_t *rp; | 43 | mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name); |
50 | 44 | ||
51 | if (!mach->comp_list) | 45 | reg->type = mu_sieve_record_comparator; |
52 | { | 46 | reg->required = required; |
53 | int rc = mu_list_create (&mach->comp_list); | 47 | reg->name = name; |
54 | if (rc) | 48 | reg->v.comp[MU_SIEVE_MATCH_IS] = is; |
55 | return rc; | 49 | reg->v.comp[MU_SIEVE_MATCH_CONTAINS] = contains; |
56 | } | 50 | reg->v.comp[MU_SIEVE_MATCH_MATCHES] = matches; |
57 | 51 | reg->v.comp[MU_SIEVE_MATCH_REGEX] = regex; | |
58 | rp = mu_sieve_malloc (mach, sizeof (*rp)); | 52 | reg->v.comp[MU_SIEVE_MATCH_EQ] = eq; |
59 | rp->required = required; | ||
60 | rp->name = name; | ||
61 | rp->comp[MU_SIEVE_MATCH_IS] = is; | ||
62 | rp->comp[MU_SIEVE_MATCH_CONTAINS] = contains; | ||
63 | rp->comp[MU_SIEVE_MATCH_MATCHES] = matches; | ||
64 | rp->comp[MU_SIEVE_MATCH_REGEX] = regex; | ||
65 | rp->comp[MU_SIEVE_MATCH_EQ] = eq; | ||
66 | |||
67 | return mu_list_append (mach->comp_list, rp); | ||
68 | } | ||
69 | |||
70 | sieve_comparator_record_t * | ||
71 | _lookup (mu_list_t list, const char *name) | ||
72 | { | ||
73 | mu_iterator_t itr; | ||
74 | sieve_comparator_record_t *reg; | ||
75 | |||
76 | if (!list || mu_list_get_iterator (list, &itr)) | ||
77 | return NULL; | ||
78 | |||
79 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) | ||
80 | { | ||
81 | mu_iterator_current (itr, (void **)®); | ||
82 | if (strcmp (reg->name, name) == 0) | ||
83 | break; | ||
84 | else | ||
85 | reg = NULL; | ||
86 | } | ||
87 | mu_iterator_destroy (&itr); | ||
88 | return reg; | ||
89 | } | ||
90 | |||
91 | int | ||
92 | mu_sieve_require_comparator (mu_sieve_machine_t mach, const char *name) | ||
93 | { | ||
94 | sieve_comparator_record_t *reg = _lookup (mach->comp_list, name); | ||
95 | if (!reg) | ||
96 | { | ||
97 | if (!(mu_sieve_load_ext (mach, name) == 0 | ||
98 | && (reg = _lookup (mach->comp_list, name)) != NULL)) | ||
99 | return 1; | ||
100 | } | ||
101 | |||
102 | reg->required = 1; | ||
103 | return 0; | ||
104 | } | 53 | } |
105 | 54 | ||
106 | mu_sieve_comparator_t | 55 | mu_sieve_comparator_t |
107 | mu_sieve_comparator_lookup (mu_sieve_machine_t mach, const char *name, | 56 | mu_sieve_comparator_lookup (mu_sieve_machine_t mach, const char *name, |
108 | int matchtype) | 57 | int matchtype) |
109 | { | 58 | { |
110 | sieve_comparator_record_t *reg = _lookup (mach->comp_list, name); | 59 | mu_sieve_registry_t *reg = |
111 | if (reg && reg->comp[matchtype]) | 60 | mu_sieve_registry_lookup (mach, name, mu_sieve_record_comparator); |
112 | return reg->comp[matchtype]; | 61 | if (reg && reg->v.comp[matchtype]) |
62 | return reg->v.comp[matchtype]; | ||
113 | return NULL; | 63 | return NULL; |
114 | } | 64 | } |
115 | 65 | ... | ... |
... | @@ -272,22 +272,13 @@ static mu_sieve_data_type deleteheader_args[] = { | ... | @@ -272,22 +272,13 @@ static mu_sieve_data_type deleteheader_args[] = { |
272 | int | 272 | int |
273 | SIEVE_EXPORT (editheader, init) (mu_sieve_machine_t mach) | 273 | SIEVE_EXPORT (editheader, init) (mu_sieve_machine_t mach) |
274 | { | 274 | { |
275 | int rc; | ||
276 | |||
277 | /* This dummy record is required by libmu_sieve */ | 275 | /* This dummy record is required by libmu_sieve */ |
278 | rc = mu_sieve_register_action (mach, "editheader", NULL, NULL, NULL, 1); | 276 | mu_sieve_register_action (mach, "editheader", NULL, NULL, NULL, 1); |
279 | if (rc) | 277 | mu_sieve_register_action (mach, "addheader", sieve_addheader, |
280 | return rc; | ||
281 | rc = mu_sieve_register_action (mach, "addheader", sieve_addheader, | ||
282 | addheader_args, addheader_tag_groups, 1); | 278 | addheader_args, addheader_tag_groups, 1); |
283 | if (rc) | 279 | mu_sieve_register_action_ext (mach, "deleteheader", sieve_deleteheader, |
284 | return rc; | ||
285 | rc = mu_sieve_register_action_ext (mach, "deleteheader", sieve_deleteheader, | ||
286 | deleteheader_args, deleteheader_args, | 280 | deleteheader_args, deleteheader_args, |
287 | deleteheader_tag_groups, | 281 | deleteheader_tag_groups, |
288 | 1); | 282 | 1); |
289 | if (rc) | 283 | return 0; |
290 | return rc; | ||
291 | |||
292 | return rc; | ||
293 | } | 284 | } | ... | ... |
... | @@ -203,8 +203,9 @@ static mu_sieve_tag_group_t list_tag_groups[] = { | ... | @@ -203,8 +203,9 @@ static mu_sieve_tag_group_t list_tag_groups[] = { |
203 | int | 203 | int |
204 | SIEVE_EXPORT(list,init) (mu_sieve_machine_t mach) | 204 | SIEVE_EXPORT(list,init) (mu_sieve_machine_t mach) |
205 | { | 205 | { |
206 | return mu_sieve_register_test (mach, "list", list_test, | 206 | mu_sieve_register_test (mach, "list", list_test, |
207 | list_req_args, list_tag_groups, 1); | 207 | list_req_args, list_tag_groups, 1); |
208 | return 0; | ||
208 | } | 209 | } |
209 | 210 | ||
210 | /* End of list.c */ | 211 | /* End of list.c */ | ... | ... |
... | @@ -84,7 +84,7 @@ moderator_filter_message (mu_sieve_machine_t mach, | ... | @@ -84,7 +84,7 @@ moderator_filter_message (mu_sieve_machine_t mach, |
84 | 84 | ||
85 | if (mu_sieve_get_tag (mach, "source", SVT_STRING, &arg)) | 85 | if (mu_sieve_get_tag (mach, "source", SVT_STRING, &arg)) |
86 | { | 86 | { |
87 | rc = mu_sieve_machine_inherit (mach, &newmach); | 87 | rc = mu_sieve_machine_clone (mach, &newmach); |
88 | if (rc) | 88 | if (rc) |
89 | { | 89 | { |
90 | mu_sieve_error (mach, _("cannot initialize sieve machine: %s"), | 90 | mu_sieve_error (mach, _("cannot initialize sieve machine: %s"), |
... | @@ -105,7 +105,7 @@ moderator_filter_message (mu_sieve_machine_t mach, | ... | @@ -105,7 +105,7 @@ moderator_filter_message (mu_sieve_machine_t mach, |
105 | { | 105 | { |
106 | struct mu_locus locus; | 106 | struct mu_locus locus; |
107 | 107 | ||
108 | rc = mu_sieve_machine_inherit (mach, &newmach); | 108 | rc = mu_sieve_machine_clone (mach, &newmach); |
109 | if (rc) | 109 | if (rc) |
110 | { | 110 | { |
111 | mu_sieve_error (mach, _("cannot initialize sieve machine: %s"), | 111 | mu_sieve_error (mach, _("cannot initialize sieve machine: %s"), |
... | @@ -363,8 +363,9 @@ static mu_sieve_tag_group_t moderator_tag_groups[] = { | ... | @@ -363,8 +363,9 @@ static mu_sieve_tag_group_t moderator_tag_groups[] = { |
363 | int | 363 | int |
364 | SIEVE_EXPORT(moderator,init) (mu_sieve_machine_t mach) | 364 | SIEVE_EXPORT(moderator,init) (mu_sieve_machine_t mach) |
365 | { | 365 | { |
366 | return mu_sieve_register_action (mach, "moderator", moderator_action, | 366 | mu_sieve_register_action (mach, "moderator", moderator_action, |
367 | moderator_req_args, | 367 | moderator_req_args, |
368 | moderator_tag_groups, 1); | 368 | moderator_tag_groups, 1); |
369 | return 0; | ||
369 | } | 370 | } |
370 | 371 | ... | ... |
... | @@ -275,11 +275,9 @@ static mu_sieve_data_type pipe_args[] = { | ... | @@ -275,11 +275,9 @@ static mu_sieve_data_type pipe_args[] = { |
275 | int | 275 | int |
276 | SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach) | 276 | SIEVE_EXPORT (pipe, init) (mu_sieve_machine_t mach) |
277 | { | 277 | { |
278 | int rc; | 278 | mu_sieve_register_action (mach, "pipe", sieve_action_pipe, |
279 | rc = mu_sieve_register_action (mach, "pipe", sieve_action_pipe, | ||
280 | pipe_args, pipe_action_tag_groups, 1); | 279 | pipe_args, pipe_action_tag_groups, 1); |
281 | if (rc) | 280 | mu_sieve_register_test (mach, "pipe", sieve_test_pipe, |
282 | return rc; | ||
283 | return mu_sieve_register_test (mach, "pipe", sieve_test_pipe, | ||
284 | pipe_args, pipe_test_tag_groups, 1); | 281 | pipe_args, pipe_test_tag_groups, 1); |
282 | return 0; | ||
285 | } | 283 | } | ... | ... |
... | @@ -544,7 +544,8 @@ static mu_sieve_tag_group_t spamd_tag_groups[] = { | ... | @@ -544,7 +544,8 @@ static mu_sieve_tag_group_t spamd_tag_groups[] = { |
544 | int | 544 | int |
545 | SIEVE_EXPORT(spamd,init) (mu_sieve_machine_t mach) | 545 | SIEVE_EXPORT(spamd,init) (mu_sieve_machine_t mach) |
546 | { | 546 | { |
547 | return mu_sieve_register_test (mach, "spamd", spamd_test, | 547 | mu_sieve_register_test (mach, "spamd", spamd_test, |
548 | spamd_req_args, spamd_tag_groups, 1); | 548 | spamd_req_args, spamd_tag_groups, 1); |
549 | return 0; | ||
549 | } | 550 | } |
550 | 551 | ... | ... |
... | @@ -123,6 +123,7 @@ static mu_sieve_tag_group_t timestamp_tag_groups[] = { | ... | @@ -123,6 +123,7 @@ static mu_sieve_tag_group_t timestamp_tag_groups[] = { |
123 | int | 123 | int |
124 | SIEVE_EXPORT(timestamp,init) (mu_sieve_machine_t mach) | 124 | SIEVE_EXPORT(timestamp,init) (mu_sieve_machine_t mach) |
125 | { | 125 | { |
126 | return mu_sieve_register_test (mach, "timestamp", timestamp_test, | 126 | mu_sieve_register_test (mach, "timestamp", timestamp_test, |
127 | timestamp_req_args, timestamp_tag_groups, 1); | 127 | timestamp_req_args, timestamp_tag_groups, 1); |
128 | return 0; | ||
128 | } | 129 | } | ... | ... |
... | @@ -868,6 +868,7 @@ static mu_sieve_data_type vacation_args[] = { | ... | @@ -868,6 +868,7 @@ static mu_sieve_data_type vacation_args[] = { |
868 | 868 | ||
869 | int SIEVE_EXPORT (vacation, init) (mu_sieve_machine_t mach) | 869 | int SIEVE_EXPORT (vacation, init) (mu_sieve_machine_t mach) |
870 | { | 870 | { |
871 | return mu_sieve_register_action (mach, "vacation", sieve_action_vacation, | 871 | mu_sieve_register_action (mach, "vacation", sieve_action_vacation, |
872 | vacation_args, vacation_tag_groups, 1); | 872 | vacation_args, vacation_tag_groups, 1); |
873 | return 0; | ||
873 | } | 874 | } | ... | ... |
... | @@ -31,16 +31,6 @@ | ... | @@ -31,16 +31,6 @@ |
31 | 31 | ||
32 | typedef int (*sieve_module_init_t) (mu_sieve_machine_t mach); | 32 | typedef int (*sieve_module_init_t) (mu_sieve_machine_t mach); |
33 | 33 | ||
34 | #if 0 | ||
35 | /* FIXME: See comment below */ | ||
36 | static void | ||
37 | _free_loaded_module (void *data) | ||
38 | { | ||
39 | lt_dlclose ((lt_dlhandle)data); | ||
40 | lt_dlexit (); | ||
41 | } | ||
42 | #endif | ||
43 | |||
44 | static int _add_load_dir (void *, void *); | 34 | static int _add_load_dir (void *, void *); |
45 | 35 | ||
46 | static int | 36 | static int |
... | @@ -62,7 +52,6 @@ sieve_init_load_path () | ... | @@ -62,7 +52,6 @@ sieve_init_load_path () |
62 | return 0; | 52 | return 0; |
63 | } | 53 | } |
64 | 54 | ||
65 | |||
66 | static lt_dlhandle | 55 | static lt_dlhandle |
67 | load_module (mu_sieve_machine_t mach, const char *name) | 56 | load_module (mu_sieve_machine_t mach, const char *name) |
68 | { | 57 | { |
... | @@ -74,18 +63,12 @@ load_module (mu_sieve_machine_t mach, const char *name) | ... | @@ -74,18 +63,12 @@ load_module (mu_sieve_machine_t mach, const char *name) |
74 | handle = lt_dlopenext (name); | 63 | handle = lt_dlopenext (name); |
75 | if (handle) | 64 | if (handle) |
76 | { | 65 | { |
77 | sieve_module_init_t init = (sieve_module_init_t) | 66 | sieve_module_init_t init; |
78 | lt_dlsym (handle, "init"); | 67 | |
68 | init = (sieve_module_init_t) lt_dlsym (handle, "init"); | ||
79 | if (init) | 69 | if (init) |
80 | { | 70 | { |
81 | init (mach); | 71 | init (mach); |
82 | /* FIXME: We used to have this: | ||
83 | mu_sieve_machine_add_destructor (mach, _free_loaded_module, | ||
84 | handle); | ||
85 | However, unloading modules can lead to random segfaults in | ||
86 | case they allocated any global-access data (e.g. mach->msg). | ||
87 | In particular, this was the case with extensions/pipe.c. | ||
88 | */ | ||
89 | return handle; | 72 | return handle; |
90 | } | 73 | } |
91 | else | 74 | else |
... | @@ -114,7 +97,7 @@ fix_module_name (char *name) | ... | @@ -114,7 +97,7 @@ fix_module_name (char *name) |
114 | } | 97 | } |
115 | } | 98 | } |
116 | 99 | ||
117 | int | 100 | void * |
118 | mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name) | 101 | mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name) |
119 | { | 102 | { |
120 | lt_dlhandle handle; | 103 | lt_dlhandle handle; |
... | @@ -122,11 +105,18 @@ mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name) | ... | @@ -122,11 +105,18 @@ mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name) |
122 | 105 | ||
123 | modname = strdup (name); | 106 | modname = strdup (name); |
124 | if (!modname) | 107 | if (!modname) |
125 | return 1; | 108 | return NULL; |
126 | fix_module_name (modname); | 109 | fix_module_name (modname); |
127 | handle = load_module (mach, modname); | 110 | handle = load_module (mach, modname); |
128 | free (modname); | 111 | free (modname); |
129 | return handle == NULL; | 112 | return handle; |
113 | } | ||
114 | |||
115 | void | ||
116 | mu_sieve_unload_ext (void *data) | ||
117 | { | ||
118 | if (data) | ||
119 | lt_dlclose ((lt_dlhandle)data); | ||
130 | } | 120 | } |
131 | 121 | ||
132 | static int | 122 | static int | ... | ... |
... | @@ -83,6 +83,9 @@ mu_sieve_free (mu_sieve_machine_t mach, void *ptr) | ... | @@ -83,6 +83,9 @@ mu_sieve_free (mu_sieve_machine_t mach, void *ptr) |
83 | int rc; | 83 | int rc; |
84 | struct memory_cell mcell; | 84 | struct memory_cell mcell; |
85 | 85 | ||
86 | if (!ptr) | ||
87 | return; | ||
88 | |||
86 | mcell.ptr = ptr; | 89 | mcell.ptr = ptr; |
87 | rc = mu_list_remove (mach->memory_pool, &mcell); | 90 | rc = mu_list_remove (mach->memory_pool, &mcell); |
88 | if (rc) | 91 | if (rc) |
... | @@ -228,3 +231,65 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb, | ... | @@ -228,3 +231,65 @@ mu_i_sv_2nrealloc (mu_sieve_machine_t mach, void **pptr, size_t *pnmemb, |
228 | *pptr = ptr; | 231 | *pptr = ptr; |
229 | *pnmemb = nmemb; | 232 | *pnmemb = nmemb; |
230 | } | 233 | } |
234 | |||
235 | char * | ||
236 | mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name) | ||
237 | { | ||
238 | size_t i; | ||
239 | char *p; | ||
240 | |||
241 | if (!name) | ||
242 | return NULL; | ||
243 | |||
244 | for (i = 0; i < mach->idcount; i++) | ||
245 | { | ||
246 | if (strcmp (mach->idspace[i], name) == 0) | ||
247 | return mach->idspace[i]; | ||
248 | } | ||
249 | |||
250 | if (mach->idcount == mach->idmax) | ||
251 | { | ||
252 | mu_i_sv_2nrealloc (mach, | ||
253 | (void **) &mach->idspace, | ||
254 | &mach->idmax, | ||
255 | sizeof mach->idspace[0]); | ||
256 | } | ||
257 | |||
258 | p = mu_sieve_strdup (mach, name); | ||
259 | mach->idspace[mach->idcount++] = p; | ||
260 | |||
261 | return p; | ||
262 | } | ||
263 | |||
264 | size_t | ||
265 | mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name) | ||
266 | { | ||
267 | size_t i; | ||
268 | |||
269 | for (i = 0; i < mach->idcount; i++) | ||
270 | { | ||
271 | if (mach->idspace[i] == name || strcmp (mach->idspace[i], name) == 0) | ||
272 | return i; | ||
273 | } | ||
274 | abort (); | ||
275 | } | ||
276 | |||
277 | char * | ||
278 | mu_i_sv_id_str (mu_sieve_machine_t mach, size_t n) | ||
279 | { | ||
280 | if (n >= mach->idcount) | ||
281 | abort (); | ||
282 | return mach->idspace[n]; | ||
283 | } | ||
284 | |||
285 | void | ||
286 | mu_i_sv_free_idspace (mu_sieve_machine_t mach) | ||
287 | { | ||
288 | size_t i; | ||
289 | |||
290 | for (i = 0; i < mach->idcount; i++) | ||
291 | mu_sieve_free (mach, mach->idspace[i]); | ||
292 | mach->idcount = 0; | ||
293 | } | ||
294 | |||
295 | ... | ... |
... | @@ -52,7 +52,7 @@ mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr) | ... | @@ -52,7 +52,7 @@ mu_i_sv_locus (struct mu_sieve_machine *mach, struct mu_locus_range *lr) |
52 | if (!file_eq (mach->locus.mu_file, lr->beg.mu_file)) | 52 | if (!file_eq (mach->locus.mu_file, lr->beg.mu_file)) |
53 | { | 53 | { |
54 | mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_source); | 54 | mu_i_sv_code (mach, (sieve_op_t) _mu_i_sv_instr_source); |
55 | mu_i_sv_code (mach, (sieve_op_t) lr->beg.mu_file); | 55 | mu_i_sv_code (mach, (sieve_op_t) mu_i_sv_id_num (mach, lr->beg.mu_file)); |
56 | } | 56 | } |
57 | if (mach->locus.mu_line != lr->beg.mu_line) | 57 | if (mach->locus.mu_line != lr->beg.mu_line) |
58 | { | 58 | { |
... | @@ -133,7 +133,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ... | @@ -133,7 +133,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, |
133 | struct mu_sieve_node *node) | 133 | struct mu_sieve_node *node) |
134 | { | 134 | { |
135 | size_t i; | 135 | size_t i; |
136 | mu_sieve_register_t *reg = node->v.command.reg; | 136 | mu_sieve_registry_t *reg = node->v.command.reg; |
137 | 137 | ||
138 | mu_sieve_value_t *start = mach->valspace + node->v.command.argstart; | 138 | mu_sieve_value_t *start = mach->valspace + node->v.command.argstart; |
139 | 139 | ||
... | @@ -143,7 +143,10 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ... | @@ -143,7 +143,10 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, |
143 | int rc, err = 0; | 143 | int rc, err = 0; |
144 | static mu_sieve_data_type empty[] = { SVT_VOID }; | 144 | static mu_sieve_data_type empty[] = { SVT_VOID }; |
145 | 145 | ||
146 | exp_arg = reg->req_args ? reg->req_args : empty; | 146 | if (!reg) |
147 | return; | ||
148 | |||
149 | exp_arg = reg->v.command.req_args ? reg->v.command.req_args : empty; | ||
147 | 150 | ||
148 | /* Pass 1: consolidation */ | 151 | /* Pass 1: consolidation */ |
149 | for (i = 0; i < node->v.command.argcount; i++) | 152 | for (i = 0; i < node->v.command.argcount; i++) |
... | @@ -153,7 +156,8 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ... | @@ -153,7 +156,8 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, |
153 | if (val->type == SVT_TAG) | 156 | if (val->type == SVT_TAG) |
154 | { | 157 | { |
155 | mu_sieve_tag_checker_t cf; | 158 | mu_sieve_tag_checker_t cf; |
156 | mu_sieve_tag_def_t *tag = find_tag (reg->tags, val->v.string, &cf); | 159 | mu_sieve_tag_def_t *tag = find_tag (reg->v.command.tags, |
160 | val->v.string, &cf); | ||
157 | 161 | ||
158 | if (!tag) | 162 | if (!tag) |
159 | { | 163 | { |
... | @@ -228,9 +232,9 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ... | @@ -228,9 +232,9 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, |
228 | { | 232 | { |
229 | if (*exp_arg == SVT_VOID) | 233 | if (*exp_arg == SVT_VOID) |
230 | { | 234 | { |
231 | if (reg->opt_args) | 235 | if (reg->v.command.opt_args) |
232 | { | 236 | { |
233 | exp_arg = reg->opt_args; | 237 | exp_arg = reg->v.command.opt_args; |
234 | opt_args = 1; | 238 | opt_args = 1; |
235 | } | 239 | } |
236 | else | 240 | else |
... | @@ -252,7 +256,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ... | @@ -252,7 +256,7 @@ mu_i_sv_lint_command (struct mu_sieve_machine *mach, |
252 | { | 256 | { |
253 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | 257 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, |
254 | _("type mismatch in argument %lu to `%s'"), | 258 | _("type mismatch in argument %lu to `%s'"), |
255 | (unsigned long) (exp_arg - reg->req_args + 1), | 259 | (unsigned long) (exp_arg - reg->v.command.req_args + 1), |
256 | reg->name); | 260 | reg->name); |
257 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | 261 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, |
258 | _("expected %s but passed %s"), | 262 | _("expected %s but passed %s"), |
... | @@ -316,7 +320,7 @@ static void | ... | @@ -316,7 +320,7 @@ static void |
316 | sv_code_command (struct mu_sieve_machine *mach, | 320 | sv_code_command (struct mu_sieve_machine *mach, |
317 | struct mu_sieve_node *node) | 321 | struct mu_sieve_node *node) |
318 | { | 322 | { |
319 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.reg->handler); | 323 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.reg->v.command.handler); |
320 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.argstart); | 324 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.argstart); |
321 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.argcount); | 325 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.argcount); |
322 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.tagcount); | 326 | mu_i_sv_code (mach, (sieve_op_t) node->v.command.tagcount); | ... | ... |
... | @@ -26,115 +26,116 @@ | ... | @@ -26,115 +26,116 @@ |
26 | #include <string.h> | 26 | #include <string.h> |
27 | #include <sieve-priv.h> | 27 | #include <sieve-priv.h> |
28 | 28 | ||
29 | static mu_sieve_register_t * | 29 | int |
30 | reg_lookup (mu_list_t list, const char *name) | 30 | mu_sieve_registry_require (mu_sieve_machine_t mach, const char *name, |
31 | { | 31 | enum mu_sieve_record type) |
32 | mu_iterator_t itr; | ||
33 | mu_sieve_register_t *reg; | ||
34 | |||
35 | if (!list || mu_list_get_iterator (list, &itr)) | ||
36 | return NULL; | ||
37 | |||
38 | for (mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr)) | ||
39 | { | ||
40 | mu_iterator_current (itr, (void **)®); | ||
41 | if (strcmp (reg->name, name) == 0) | ||
42 | break; | ||
43 | else | ||
44 | reg = NULL; | ||
45 | } | ||
46 | mu_iterator_destroy (&itr); | ||
47 | return reg; | ||
48 | } | ||
49 | |||
50 | mu_sieve_register_t * | ||
51 | mu_sieve_test_lookup (mu_sieve_machine_t mach, const char *name) | ||
52 | { | ||
53 | mu_sieve_register_t *reg = reg_lookup (mach->test_list, name); | ||
54 | return (reg && reg->handler) ? reg : NULL; | ||
55 | } | ||
56 | |||
57 | mu_sieve_register_t * | ||
58 | mu_sieve_action_lookup (mu_sieve_machine_t mach, const char *name) | ||
59 | { | 32 | { |
60 | mu_sieve_register_t *reg = reg_lookup (mach->action_list, name); | 33 | mu_sieve_registry_t *reg; |
61 | return (reg && reg->handler) ? reg : NULL; | ||
62 | } | ||
63 | 34 | ||
64 | static int | 35 | reg = mu_sieve_registry_lookup (mach, name, type); |
65 | reg_require (mu_sieve_machine_t mach, mu_list_t list, const char *name) | ||
66 | { | ||
67 | mu_sieve_register_t *reg = reg_lookup (list, name); | ||
68 | if (!reg) | 36 | if (!reg) |
69 | { | 37 | { |
70 | if (!(mu_sieve_load_ext (mach, name) == 0 | 38 | void *handle = mu_sieve_load_ext (mach, name); |
71 | && (reg = reg_lookup (list, name)) != NULL)) | 39 | if (!handle) |
40 | return 1; | ||
41 | reg = mu_sieve_registry_lookup (mach, name, type); | ||
42 | if (!reg) | ||
72 | return 1; | 43 | return 1; |
44 | reg->handle = handle; | ||
73 | } | 45 | } |
46 | |||
74 | reg->required = 1; | 47 | reg->required = 1; |
75 | return 0; | 48 | return 0; |
76 | } | 49 | } |
77 | 50 | ||
78 | int | ||
79 | mu_sieve_require_action (mu_sieve_machine_t mach, const char *name) | ||
80 | { | ||
81 | return reg_require (mach, mach->action_list, name); | ||
82 | } | ||
83 | 51 | ||
84 | int | 52 | static void |
85 | mu_sieve_require_test (mu_sieve_machine_t mach, const char *name) | 53 | regunload (void *data) |
86 | { | 54 | { |
87 | return reg_require (mach, mach->test_list, name); | 55 | mu_sieve_registry_t *reg = data; |
56 | mu_sieve_unload_ext (reg->handle); | ||
88 | } | 57 | } |
89 | 58 | ||
90 | |||
91 | static int | 59 | static int |
92 | sieve_register (mu_sieve_machine_t mach, | 60 | regcmp (void const *a, void const *b) |
93 | mu_list_t *list, | ||
94 | const char *name, mu_sieve_handler_t handler, | ||
95 | mu_sieve_data_type *req_arg_types, | ||
96 | mu_sieve_data_type *opt_arg_types, | ||
97 | mu_sieve_tag_group_t *tags, int required) | ||
98 | { | 61 | { |
99 | mu_sieve_register_t *reg = mu_sieve_malloc (mach, sizeof (*reg)); | 62 | mu_sieve_registry_t const *rega = a; |
100 | 63 | mu_sieve_registry_t const *regb = b; | |
101 | if (!reg) | 64 | if (rega->type != regb->type) |
102 | return ENOMEM; | 65 | return rega->type - regb->type; |
103 | reg->name = name; | 66 | return strcmp (rega->name, regb->name); |
104 | reg->handler = handler; | 67 | } |
105 | 68 | ||
106 | reg->req_args = req_arg_types; | 69 | mu_sieve_registry_t * |
107 | reg->opt_args = opt_arg_types; | 70 | mu_sieve_registry_add (mu_sieve_machine_t mach, const char *name) |
108 | reg->tags = tags; | 71 | { |
109 | reg->required = required; | 72 | mu_sieve_registry_t *reg; |
73 | int rc; | ||
110 | 74 | ||
111 | if (!*list) | 75 | if (!mach->registry) |
112 | { | 76 | { |
113 | int rc = mu_list_create (list); | 77 | rc = mu_list_create (&mach->registry); |
114 | if (rc) | 78 | if (rc) |
115 | { | 79 | { |
116 | free (reg); | 80 | mu_sieve_error (mach, "mu_list_create: %s", mu_strerror (rc)); |
117 | return rc; | 81 | mu_sieve_abort (mach); |
118 | } | 82 | } |
83 | mu_list_set_destroy_item (mach->registry, regunload); | ||
84 | mu_list_set_comparator (mach->registry, regcmp); | ||
119 | } | 85 | } |
120 | 86 | reg = mu_sieve_malloc (mach, sizeof (*reg)); | |
121 | return mu_list_append (*list, reg); | 87 | reg->name = name; |
88 | reg->handle = NULL; | ||
89 | reg->required = 0; | ||
90 | memset (®->v, 0, sizeof reg->v); | ||
91 | rc = mu_list_append (mach->registry, reg); | ||
92 | if (rc) | ||
93 | { | ||
94 | mu_sieve_error (mach, "mu_list_append: %s", mu_strerror (rc)); | ||
95 | mu_sieve_abort (mach); | ||
96 | } | ||
97 | return reg; | ||
122 | } | 98 | } |
123 | 99 | ||
100 | mu_sieve_registry_t * | ||
101 | mu_sieve_registry_lookup (mu_sieve_machine_t mach, const char *name, | ||
102 | enum mu_sieve_record type) | ||
103 | { | ||
104 | mu_sieve_registry_t key, *reg; | ||
105 | int rc; | ||
124 | 106 | ||
125 | int | 107 | key.name = name; |
108 | key.type = type; | ||
109 | |||
110 | rc = mu_list_locate (mach->registry, &key, (void**) ®); | ||
111 | if (rc == MU_ERR_NOENT) | ||
112 | return NULL; | ||
113 | else if (rc) | ||
114 | { | ||
115 | mu_sieve_error (mach, _("registry lookup failed: %s"), mu_strerror (rc)); | ||
116 | mu_sieve_abort (mach); | ||
117 | } | ||
118 | return reg; | ||
119 | } | ||
120 | |||
121 | void | ||
126 | mu_sieve_register_test_ext (mu_sieve_machine_t mach, | 122 | mu_sieve_register_test_ext (mu_sieve_machine_t mach, |
127 | const char *name, mu_sieve_handler_t handler, | 123 | const char *name, mu_sieve_handler_t handler, |
128 | mu_sieve_data_type *req_args, | 124 | mu_sieve_data_type *req_args, |
129 | mu_sieve_data_type *opt_args, | 125 | mu_sieve_data_type *opt_args, |
130 | mu_sieve_tag_group_t *tags, int required) | 126 | mu_sieve_tag_group_t *tags, int required) |
131 | { | 127 | { |
132 | return sieve_register (mach, | 128 | mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name); |
133 | &mach->test_list, name, handler, | 129 | |
134 | req_args, opt_args, tags, required); | 130 | reg->type = mu_sieve_record_test; |
131 | reg->required = required; | ||
132 | reg->v.command.handler = handler; | ||
133 | reg->v.command.req_args = req_args; | ||
134 | reg->v.command.opt_args = opt_args; | ||
135 | reg->v.command.tags = tags; | ||
135 | } | 136 | } |
136 | 137 | ||
137 | int | 138 | void |
138 | mu_sieve_register_test (mu_sieve_machine_t mach, | 139 | mu_sieve_register_test (mu_sieve_machine_t mach, |
139 | const char *name, mu_sieve_handler_t handler, | 140 | const char *name, mu_sieve_handler_t handler, |
140 | mu_sieve_data_type *arg_types, | 141 | mu_sieve_data_type *arg_types, |
... | @@ -146,19 +147,24 @@ mu_sieve_register_test (mu_sieve_machine_t mach, | ... | @@ -146,19 +147,24 @@ mu_sieve_register_test (mu_sieve_machine_t mach, |
146 | required); | 147 | required); |
147 | } | 148 | } |
148 | 149 | ||
149 | int | 150 | void |
150 | mu_sieve_register_action_ext (mu_sieve_machine_t mach, | 151 | mu_sieve_register_action_ext (mu_sieve_machine_t mach, |
151 | const char *name, mu_sieve_handler_t handler, | 152 | const char *name, mu_sieve_handler_t handler, |
152 | mu_sieve_data_type *req_args, | 153 | mu_sieve_data_type *req_args, |
153 | mu_sieve_data_type *opt_args, | 154 | mu_sieve_data_type *opt_args, |
154 | mu_sieve_tag_group_t *tags, int required) | 155 | mu_sieve_tag_group_t *tags, int required) |
155 | { | 156 | { |
156 | return sieve_register (mach, | 157 | mu_sieve_registry_t *reg = mu_sieve_registry_add (mach, name); |
157 | &mach->action_list, name, handler, | 158 | |
158 | req_args, opt_args, tags, required); | 159 | reg->type = mu_sieve_record_action; |
160 | reg->required = required; | ||
161 | reg->v.command.handler = handler; | ||
162 | reg->v.command.req_args = req_args; | ||
163 | reg->v.command.opt_args = opt_args; | ||
164 | reg->v.command.tags = tags; | ||
159 | } | 165 | } |
160 | 166 | ||
161 | int | 167 | void |
162 | mu_sieve_register_action (mu_sieve_machine_t mach, | 168 | mu_sieve_register_action (mu_sieve_machine_t mach, |
163 | const char *name, mu_sieve_handler_t handler, | 169 | const char *name, mu_sieve_handler_t handler, |
164 | mu_sieve_data_type *arg_types, | 170 | mu_sieve_data_type *arg_types, | ... | ... |
... | @@ -35,42 +35,26 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list) | ... | @@ -35,42 +35,26 @@ mu_sieve_require (mu_sieve_machine_t mach, mu_sieve_slice_t list) |
35 | { | 35 | { |
36 | struct mu_sieve_string *str = mu_sieve_string_raw (mach, list, i); | 36 | struct mu_sieve_string *str = mu_sieve_string_raw (mach, list, i); |
37 | char *name = str->orig; | 37 | char *name = str->orig; |
38 | int (*reqfn) (mu_sieve_machine_t mach, const char *name) = NULL; | 38 | int rc; |
39 | const char *text = NULL; | ||
40 | 39 | ||
41 | if (strncmp (name, "comparator-", 11) == 0) | 40 | if (strcmp (name, "relational") == 0) /* RFC 3431 */ |
42 | { | 41 | rc = mu_sieve_require_relational (mach, name); |
43 | name += 11; | ||
44 | reqfn = mu_sieve_require_comparator; | ||
45 | text = _("required comparator"); | ||
46 | } | ||
47 | else if (strncmp (name, "test-", 5) == 0) /* GNU extension */ | ||
48 | { | ||
49 | name += 5; | ||
50 | reqfn = mu_sieve_require_test; | ||
51 | text = _("required test"); | ||
52 | } | ||
53 | else if (strcmp (name, "relational") == 0) /* RFC 3431 */ | ||
54 | { | ||
55 | reqfn = mu_sieve_require_relational; | ||
56 | text = ""; | ||
57 | } | ||
58 | else if (strcmp (name, "encoded-character") == 0) /* RFC 5228, 2.4.2.4 */ | 42 | else if (strcmp (name, "encoded-character") == 0) /* RFC 5228, 2.4.2.4 */ |
59 | { | 43 | rc = mu_sieve_require_encoded_character (mach, name); |
60 | reqfn = mu_sieve_require_encoded_character; | 44 | else if (strncmp (name, "comparator-", 11) == 0) |
61 | text = ""; | 45 | rc = mu_sieve_registry_require (mach, name + 11, |
62 | } | 46 | mu_sieve_record_comparator); |
47 | else if (strncmp (name, "test-", 5) == 0) /* GNU extension */ | ||
48 | rc = mu_sieve_registry_require (mach, name + 5, | ||
49 | mu_sieve_record_test); | ||
63 | else | 50 | else |
64 | { | 51 | rc = mu_sieve_registry_require (mach, name, mu_sieve_record_action); |
65 | reqfn = mu_sieve_require_action; | ||
66 | text = _("required action"); | ||
67 | } | ||
68 | 52 | ||
69 | if (reqfn (mach, name)) | 53 | if (rc) |
70 | { | 54 | { |
71 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, | 55 | mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, |
72 | _("source for the %s %s is not available"), | 56 | _("can't require %s is not available"), |
73 | text, name); | 57 | name); |
74 | mu_i_sv_error (mach); | 58 | mu_i_sv_error (mach); |
75 | } | 59 | } |
76 | } | 60 | } | ... | ... |
... | @@ -34,7 +34,7 @@ | ... | @@ -34,7 +34,7 @@ |
34 | void | 34 | void |
35 | _mu_i_sv_instr_source (mu_sieve_machine_t mach) | 35 | _mu_i_sv_instr_source (mu_sieve_machine_t mach) |
36 | { | 36 | { |
37 | mach->locus.mu_file = (char*) SIEVE_RT_ARG (mach, 0, string); | 37 | mach->locus.mu_file = mu_i_sv_id_str (mach, SIEVE_RT_ARG (mach, 0, pc)); |
38 | mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, | 38 | mu_stream_ioctl (mach->errstream, MU_IOCTL_LOGSTREAM, |
39 | MU_IOCTL_LOGSTREAM_SET_LOCUS, | 39 | MU_IOCTL_LOGSTREAM_SET_LOCUS, |
40 | &mach->locus); | 40 | &mach->locus); |
... | @@ -98,38 +98,6 @@ _mu_i_sv_instr_test (mu_sieve_machine_t mach) | ... | @@ -98,38 +98,6 @@ _mu_i_sv_instr_test (mu_sieve_machine_t mach) |
98 | } | 98 | } |
99 | 99 | ||
100 | void | 100 | void |
101 | _mu_i_sv_instr_push (mu_sieve_machine_t mach) | ||
102 | { | ||
103 | if (INSTR_DEBUG (mach)) | ||
104 | mu_i_sv_debug (mach, mach->pc - 1, "PUSH"); | ||
105 | if (INSTR_DISASS (mach)) | ||
106 | return; | ||
107 | |||
108 | if (!mach->stack && mu_list_create (&mach->stack)) | ||
109 | { | ||
110 | mu_sieve_error (mach, _("cannot create stack")); | ||
111 | mu_sieve_abort (mach); | ||
112 | } | ||
113 | mu_list_push (mach->stack, (void*) mach->reg); | ||
114 | } | ||
115 | |||
116 | void | ||
117 | _mu_i_sv_instr_pop (mu_sieve_machine_t mach) | ||
118 | { | ||
119 | if (INSTR_DEBUG (mach)) | ||
120 | mu_i_sv_debug (mach, mach->pc - 1, "POP"); | ||
121 | if (INSTR_DISASS (mach)) | ||
122 | return; | ||
123 | |||
124 | if (!mach->stack || mu_list_is_empty (mach->stack)) | ||
125 | { | ||
126 | mu_sieve_error (mach, _("stack underflow")); | ||
127 | mu_sieve_abort (mach); | ||
128 | } | ||
129 | mu_list_pop (mach->stack, (void **)&mach->reg); | ||
130 | } | ||
131 | |||
132 | void | ||
133 | _mu_i_sv_instr_not (mu_sieve_machine_t mach) | 101 | _mu_i_sv_instr_not (mu_sieve_machine_t mach) |
134 | { | 102 | { |
135 | if (INSTR_DEBUG (mach)) | 103 | if (INSTR_DEBUG (mach)) |
... | @@ -207,7 +175,7 @@ mu_sieve_get_data (mu_sieve_machine_t mach) | ... | @@ -207,7 +175,7 @@ mu_sieve_get_data (mu_sieve_machine_t mach) |
207 | int | 175 | int |
208 | mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus *loc) | 176 | mu_sieve_get_locus (mu_sieve_machine_t mach, struct mu_locus *loc) |
209 | { | 177 | { |
210 | if (mach->source_list) | 178 | if (mach->locus.mu_file) |
211 | { | 179 | { |
212 | *loc = mach->locus; | 180 | *loc = mach->locus; |
213 | return 0; | 181 | return 0; | ... | ... |
... | @@ -68,10 +68,11 @@ struct mu_sieve_machine | ... | @@ -68,10 +68,11 @@ struct mu_sieve_machine |
68 | 68 | ||
69 | /* Symbol space: */ | 69 | /* Symbol space: */ |
70 | mu_opool_t string_pool; /* String constants */ | 70 | mu_opool_t string_pool; /* String constants */ |
71 | mu_list_t source_list; /* Source names (for diagnostics) */ | 71 | mu_list_t registry; /* Tests, Actions, Comparators */ |
72 | mu_list_t test_list; /* Tests */ | 72 | |
73 | mu_list_t action_list; /* Actions */ | 73 | char **idspace; /* Source and identifier names */ |
74 | mu_list_t comp_list; /* Comparators */ | 74 | size_t idcount; |
75 | size_t idmax; | ||
75 | 76 | ||
76 | mu_sieve_string_t *stringspace; | 77 | mu_sieve_string_t *stringspace; |
77 | size_t stringcount; | 78 | size_t stringcount; |
... | @@ -88,7 +89,6 @@ struct mu_sieve_machine | ... | @@ -88,7 +89,6 @@ struct mu_sieve_machine |
88 | enum mu_sieve_state state; /* Machine state */ | 89 | enum mu_sieve_state state; /* Machine state */ |
89 | size_t pc; /* Current program counter */ | 90 | size_t pc; /* Current program counter */ |
90 | long reg; /* Numeric register */ | 91 | long reg; /* Numeric register */ |
91 | mu_list_t stack; /* Runtime stack */ | ||
92 | 92 | ||
93 | /* Call environment */ | 93 | /* Call environment */ |
94 | const char *identifier; /* Name of action or test being executed */ | 94 | const char *identifier; /* Name of action or test being executed */ |
... | @@ -152,7 +152,7 @@ struct mu_sieve_node | ... | @@ -152,7 +152,7 @@ struct mu_sieve_node |
152 | } cond; | 152 | } cond; |
153 | struct | 153 | struct |
154 | { | 154 | { |
155 | mu_sieve_register_t *reg; | 155 | mu_sieve_registry_t *reg; |
156 | size_t argstart; | 156 | size_t argstart; |
157 | size_t argcount; | 157 | size_t argcount; |
158 | size_t tagcount; | 158 | size_t tagcount; |
... | @@ -167,7 +167,7 @@ int mu_sieve_yylex (void); | ... | @@ -167,7 +167,7 @@ int mu_sieve_yylex (void); |
167 | int mu_i_sv_lex_begin (const char *name); | 167 | int mu_i_sv_lex_begin (const char *name); |
168 | int mu_i_sv_lex_begin_string (const char *buf, int bufsize, | 168 | int mu_i_sv_lex_begin_string (const char *buf, int bufsize, |
169 | const char *fname, int line); | 169 | const char *fname, int line); |
170 | void mu_i_sv_lex_finish (struct mu_sieve_machine *mach); | 170 | void mu_i_sv_lex_finish (void); |
171 | 171 | ||
172 | extern mu_sieve_machine_t mu_sieve_machine; | 172 | extern mu_sieve_machine_t mu_sieve_machine; |
173 | 173 | ||
... | @@ -182,8 +182,6 @@ void mu_i_sv_code_test (struct mu_sieve_machine *mach, | ... | @@ -182,8 +182,6 @@ void mu_i_sv_code_test (struct mu_sieve_machine *mach, |
182 | /* Opcodes */ | 182 | /* Opcodes */ |
183 | void _mu_i_sv_instr_action (mu_sieve_machine_t mach); | 183 | void _mu_i_sv_instr_action (mu_sieve_machine_t mach); |
184 | void _mu_i_sv_instr_test (mu_sieve_machine_t mach); | 184 | void _mu_i_sv_instr_test (mu_sieve_machine_t mach); |
185 | void _mu_i_sv_instr_push (mu_sieve_machine_t mach); | ||
186 | void _mu_i_sv_instr_pop (mu_sieve_machine_t mach); | ||
187 | void _mu_i_sv_instr_not (mu_sieve_machine_t mach); | 185 | void _mu_i_sv_instr_not (mu_sieve_machine_t mach); |
188 | void _mu_i_sv_instr_branch (mu_sieve_machine_t mach); | 186 | void _mu_i_sv_instr_branch (mu_sieve_machine_t mach); |
189 | void _mu_i_sv_instr_brz (mu_sieve_machine_t mach); | 187 | void _mu_i_sv_instr_brz (mu_sieve_machine_t mach); |
... | @@ -230,3 +228,9 @@ void mu_i_sv_lint_command (struct mu_sieve_machine *mach, | ... | @@ -230,3 +228,9 @@ void mu_i_sv_lint_command (struct mu_sieve_machine *mach, |
230 | 228 | ||
231 | size_t mu_i_sv_string_create (mu_sieve_machine_t mach, char *str); | 229 | size_t mu_i_sv_string_create (mu_sieve_machine_t mach, char *str); |
232 | 230 | ||
231 | char *mu_i_sv_id_canon (mu_sieve_machine_t mach, char const *name); | ||
232 | size_t mu_i_sv_id_num (mu_sieve_machine_t mach, char const *name); | ||
233 | char *mu_i_sv_id_str (mu_sieve_machine_t mach, size_t n); | ||
234 | void mu_i_sv_free_idspace (mu_sieve_machine_t mach); | ||
235 | |||
236 | ... | ... |
... | @@ -56,7 +56,6 @@ static int isemptystr (char *text); | ... | @@ -56,7 +56,6 @@ static int isemptystr (char *text); |
56 | static ino_t sieve_source_inode; | 56 | static ino_t sieve_source_inode; |
57 | struct mu_locus mu_sieve_locus; | 57 | struct mu_locus mu_sieve_locus; |
58 | static int newline; | 58 | static int newline; |
59 | static mu_list_t file_names; | ||
60 | 59 | ||
61 | static mu_stream_t input_stream; | 60 | static mu_stream_t input_stream; |
62 | 61 | ||
... | @@ -90,35 +89,10 @@ fillbuf (char *buf, size_t max_size) | ... | @@ -90,35 +89,10 @@ fillbuf (char *buf, size_t max_size) |
90 | yy_switch_to_buffer (s); \ | 89 | yy_switch_to_buffer (s); \ |
91 | } while (0) | 90 | } while (0) |
92 | 91 | ||
93 | static int | ||
94 | file_name_cmp (const void *a, const void *b) | ||
95 | { | ||
96 | return strcmp (a, b); | ||
97 | } | ||
98 | |||
99 | static void | 92 | static void |
100 | init_locus (char const *name, ino_t ino) | 93 | init_locus (char const *name, ino_t ino) |
101 | { | 94 | { |
102 | mu_sieve_locus.mu_file = NULL; | 95 | mu_sieve_locus.mu_file = mu_i_sv_id_canon (mu_sieve_machine, name); |
103 | if (name) | ||
104 | { | ||
105 | if (!file_names) | ||
106 | { | ||
107 | mu_list_create (&file_names); | ||
108 | mu_list_set_comparator (file_names, file_name_cmp); | ||
109 | mu_list_set_destroy_item (file_names, mu_list_free_item); | ||
110 | } | ||
111 | else | ||
112 | { | ||
113 | mu_list_locate (file_names, (void*) name, | ||
114 | (void**) &mu_sieve_locus.mu_file); | ||
115 | } | ||
116 | if (!mu_sieve_locus.mu_file) | ||
117 | { | ||
118 | mu_sieve_locus.mu_file = strdup (name);//FIXME: Error checking | ||
119 | mu_list_append (file_names, mu_sieve_locus.mu_file); | ||
120 | } | ||
121 | } | ||
122 | mu_sieve_locus.mu_line = 1; | 96 | mu_sieve_locus.mu_line = 1; |
123 | mu_sieve_locus.mu_col = 0; | 97 | mu_sieve_locus.mu_col = 0; |
124 | newline = 0; | 98 | newline = 0; |
... | @@ -496,12 +470,10 @@ mu_i_sv_lex_begin_string (const char *buf, int bufsize, | ... | @@ -496,12 +470,10 @@ mu_i_sv_lex_begin_string (const char *buf, int bufsize, |
496 | } | 470 | } |
497 | 471 | ||
498 | void | 472 | void |
499 | mu_i_sv_lex_finish (struct mu_sieve_machine *mach) | 473 | mu_i_sv_lex_finish (void) |
500 | { | 474 | { |
501 | while (pop_source () == 0) | 475 | while (pop_source () == 0) |
502 | ; | 476 | ; |
503 | mach->source_list = file_names; | ||
504 | file_names = NULL; | ||
505 | } | 477 | } |
506 | 478 | ||
507 | static int | 479 | static int | ... | ... |
... | @@ -245,10 +245,11 @@ cond : test | ... | @@ -245,10 +245,11 @@ cond : test |
245 | 245 | ||
246 | test : command | 246 | test : command |
247 | { | 247 | { |
248 | mu_sieve_register_t *reg; | 248 | mu_sieve_registry_t *reg; |
249 | 249 | ||
250 | mu_sieve_machine->locus = @1.beg; | 250 | mu_sieve_machine->locus = @1.beg; |
251 | reg = mu_sieve_test_lookup (mu_sieve_machine, $1.ident); | 251 | reg = mu_sieve_registry_lookup (mu_sieve_machine, $1.ident, |
252 | mu_sieve_record_test); | ||
252 | if (!reg) | 253 | if (!reg) |
253 | { | 254 | { |
254 | mu_diag_at_locus (MU_LOG_ERROR, &@1.beg, | 255 | mu_diag_at_locus (MU_LOG_ERROR, &@1.beg, |
... | @@ -292,10 +293,11 @@ command : IDENT maybe_arglist | ... | @@ -292,10 +293,11 @@ command : IDENT maybe_arglist |
292 | 293 | ||
293 | action : command | 294 | action : command |
294 | { | 295 | { |
295 | mu_sieve_register_t *reg; | 296 | mu_sieve_registry_t *reg; |
296 | 297 | ||
297 | mu_sieve_machine->locus = @1.beg; | 298 | mu_sieve_machine->locus = @1.beg; |
298 | reg = mu_sieve_action_lookup (mu_sieve_machine, $1.ident); | 299 | reg = mu_sieve_registry_lookup (mu_sieve_machine, $1.ident, |
300 | mu_sieve_record_action); | ||
299 | 301 | ||
300 | if (!reg) | 302 | if (!reg) |
301 | { | 303 | { |
... | @@ -999,8 +1001,6 @@ mu_sieve_machine_create (mu_sieve_machine_t *pmach) | ... | @@ -999,8 +1001,6 @@ mu_sieve_machine_create (mu_sieve_machine_t *pmach) |
999 | return rc; | 1001 | return rc; |
1000 | } | 1002 | } |
1001 | 1003 | ||
1002 | mach->source_list = NULL; | ||
1003 | |||
1004 | mach->data = NULL; | 1004 | mach->data = NULL; |
1005 | 1005 | ||
1006 | mu_sieve_set_diag_stream (mach, mu_strerr); | 1006 | mu_sieve_set_diag_stream (mach, mu_strerr); |
... | @@ -1053,10 +1053,8 @@ mu_sieve_machine_reset (mu_sieve_machine_t mach) | ... | @@ -1053,10 +1053,8 @@ mu_sieve_machine_reset (mu_sieve_machine_t mach) |
1053 | mu_list_clear (mach->memory_pool); | 1053 | mu_list_clear (mach->memory_pool); |
1054 | mu_list_clear (mach->destr_list); | 1054 | mu_list_clear (mach->destr_list); |
1055 | mu_opool_free (mach->string_pool, NULL); | 1055 | mu_opool_free (mach->string_pool, NULL); |
1056 | mu_list_clear (mach->source_list); | 1056 | mu_i_sv_free_idspace (mach); |
1057 | mu_list_clear (mach->test_list); | 1057 | mu_list_clear (mach->registry); |
1058 | mu_list_clear (mach->action_list); | ||
1059 | mu_list_clear (mach->comp_list); | ||
1060 | 1058 | ||
1061 | mach->stringspace = NULL; | 1059 | mach->stringspace = NULL; |
1062 | mach->stringcount = 0; | 1060 | mach->stringcount = 0; |
... | @@ -1074,22 +1072,19 @@ mu_sieve_machine_reset (mu_sieve_machine_t mach) | ... | @@ -1074,22 +1072,19 @@ mu_sieve_machine_reset (mu_sieve_machine_t mach) |
1074 | return 0; | 1072 | return 0; |
1075 | } | 1073 | } |
1076 | 1074 | ||
1077 | int | 1075 | static int |
1078 | mu_sieve_machine_inherit (mu_sieve_machine_t const parent, | 1076 | regdup (void *item, void *data) |
1079 | mu_sieve_machine_t *pmach) | ||
1080 | { | 1077 | { |
1081 | mu_sieve_machine_t child; | 1078 | mu_sieve_registry_t *reg = item; |
1082 | int rc; | 1079 | mu_sieve_machine_t mach = data; |
1083 | |||
1084 | if (!parent || parent->state == mu_sieve_state_error) | ||
1085 | return EINVAL; | ||
1086 | 1080 | ||
1087 | rc = mu_sieve_machine_create (&child); | 1081 | mu_sieve_registry_require (mach, reg->name, reg->type); |
1088 | if (rc) | 1082 | return 0; |
1089 | return rc; | 1083 | } |
1090 | |||
1091 | child->dry_run = parent->dry_run; | ||
1092 | 1084 | ||
1085 | static void | ||
1086 | copy_stream_state (mu_sieve_machine_t child, mu_sieve_machine_t parent) | ||
1087 | { | ||
1093 | child->state_flags = parent->state_flags; | 1088 | child->state_flags = parent->state_flags; |
1094 | child->err_mode = parent->err_mode; | 1089 | child->err_mode = parent->err_mode; |
1095 | child->err_locus = parent->err_locus; | 1090 | child->err_locus = parent->err_locus; |
... | @@ -1105,13 +1100,97 @@ mu_sieve_machine_inherit (mu_sieve_machine_t const parent, | ... | @@ -1105,13 +1100,97 @@ mu_sieve_machine_inherit (mu_sieve_machine_t const parent, |
1105 | mu_stream_ref (child->errstream); | 1100 | mu_stream_ref (child->errstream); |
1106 | child->dbgstream = parent->dbgstream; | 1101 | child->dbgstream = parent->dbgstream; |
1107 | mu_stream_ref (child->dbgstream); | 1102 | mu_stream_ref (child->dbgstream); |
1103 | } | ||
1104 | |||
1105 | int | ||
1106 | mu_sieve_machine_clone (mu_sieve_machine_t const parent, | ||
1107 | mu_sieve_machine_t *pmach) | ||
1108 | { | ||
1109 | size_t i; | ||
1110 | mu_sieve_machine_t child; | ||
1111 | int rc; | ||
1112 | |||
1113 | if (!parent || parent->state == mu_sieve_state_error) | ||
1114 | return EINVAL; | ||
1115 | |||
1116 | rc = mu_sieve_machine_create (&child); | ||
1117 | if (rc) | ||
1118 | return rc; | ||
1119 | |||
1120 | rc = setjmp (child->errbuf); | ||
1121 | |||
1122 | if (rc == 0) | ||
1123 | { | ||
1124 | child->state = mu_sieve_state_init; | ||
1125 | mu_i_sv_register_standard_actions (child); | ||
1126 | mu_i_sv_register_standard_tests (child); | ||
1127 | mu_i_sv_register_standard_comparators (child); | ||
1128 | |||
1129 | /* Load necessary modules */ | ||
1130 | mu_list_foreach (parent->registry, regdup, child); | ||
1131 | |||
1132 | /* Copy identifiers */ | ||
1133 | child->idspace = mu_sieve_calloc (child, parent->idcount, | ||
1134 | sizeof (child->idspace[0])); | ||
1135 | child->idcount = child->idmax = parent->idcount; | ||
1136 | for (i = 0; i < child->idcount; i++) | ||
1137 | child->idspace[i] = mu_sieve_strdup (parent, parent->idspace[i]); | ||
1138 | |||
1139 | /* Copy string constants */ | ||
1140 | child->stringspace = mu_sieve_calloc (child, parent->stringcount, | ||
1141 | sizeof (child->stringspace[0])); | ||
1142 | child->stringcount = child->stringmax = parent->stringcount; | ||
1143 | for (i = 0; i < parent->stringcount; i++) | ||
1144 | { | ||
1145 | memset (&child->stringspace[i], 0, sizeof (child->stringspace[0])); | ||
1146 | child->stringspace[i].orig = | ||
1147 | mu_sieve_strdup (parent, parent->stringspace[i].orig); | ||
1148 | } | ||
1149 | |||
1150 | /* Copy value space */ | ||
1151 | child->valspace = mu_sieve_calloc (parent, parent->valcount, | ||
1152 | sizeof child->valspace[0]); | ||
1153 | child->valcount = child->valmax = parent->valcount; | ||
1154 | for (i = 0; i < child->valcount; i++) | ||
1155 | { | ||
1156 | child->valspace[i].type = parent->valspace[i].type; | ||
1157 | child->valspace[i].tag = | ||
1158 | mu_sieve_strdup (parent, parent->valspace[i].tag); | ||
1159 | switch (child->valspace[i].type) | ||
1160 | { | ||
1161 | case SVT_TAG: | ||
1162 | child->valspace[i].v.string = | ||
1163 | mu_sieve_strdup (parent, parent->valspace[i].v.string); | ||
1164 | break; | ||
1165 | |||
1166 | default: | ||
1167 | child->valspace[i].v = parent->valspace[i].v; | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | /* Copy progspace */ | ||
1172 | child->progsize = parent->progsize; | ||
1173 | child->prog = mu_sieve_calloc (child, parent->progsize, | ||
1174 | sizeof child->prog[0]); | ||
1175 | memcpy (child->prog, parent->prog, | ||
1176 | parent->progsize * sizeof (child->prog[0])); | ||
1177 | |||
1178 | /* Copy user-defined settings */ | ||
1179 | |||
1180 | child->dry_run = parent->dry_run; | ||
1181 | |||
1182 | copy_stream_state (child, parent); | ||
1108 | 1183 | ||
1109 | child->data = parent->data; | 1184 | child->data = parent->data; |
1110 | child->logger = parent->logger; | 1185 | child->logger = parent->logger; |
1111 | child->daemon_email = parent->daemon_email; | 1186 | child->daemon_email = parent->daemon_email; |
1112 | 1187 | ||
1113 | *pmach = child; | 1188 | *pmach = child; |
1114 | return 0; | 1189 | } |
1190 | else | ||
1191 | mu_sieve_machine_destroy (&child); | ||
1192 | |||
1193 | return rc; | ||
1115 | } | 1194 | } |
1116 | 1195 | ||
1117 | int | 1196 | int |
... | @@ -1133,9 +1212,7 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) | ... | @@ -1133,9 +1212,7 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) |
1133 | return rc; | 1212 | return rc; |
1134 | } | 1213 | } |
1135 | mach->destr_list = NULL; | 1214 | mach->destr_list = NULL; |
1136 | mach->test_list = NULL; | 1215 | mach->registry = NULL; |
1137 | mach->action_list = NULL; | ||
1138 | mach->comp_list = NULL; | ||
1139 | 1216 | ||
1140 | mach->progsize = in->progsize; | 1217 | mach->progsize = in->progsize; |
1141 | mach->prog = in->prog; | 1218 | mach->prog = in->prog; |
... | @@ -1151,9 +1228,12 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) | ... | @@ -1151,9 +1228,12 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) |
1151 | mach->state = in->state; | 1228 | mach->state = in->state; |
1152 | } | 1229 | } |
1153 | 1230 | ||
1231 | rc = setjmp (mach->errbuf); | ||
1232 | |||
1233 | if (rc == 0) | ||
1234 | { | ||
1154 | mach->pc = 0; | 1235 | mach->pc = 0; |
1155 | mach->reg = 0; | 1236 | mach->reg = 0; |
1156 | mach->stack = NULL; | ||
1157 | 1237 | ||
1158 | mach->dry_run = in->dry_run; | 1238 | mach->dry_run = in->dry_run; |
1159 | 1239 | ||
... | @@ -1163,17 +1243,18 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) | ... | @@ -1163,17 +1243,18 @@ mu_sieve_machine_dup (mu_sieve_machine_t const in, mu_sieve_machine_t *out) |
1163 | mach->dbg_mode = in->dbg_mode; | 1243 | mach->dbg_mode = in->dbg_mode; |
1164 | mach->dbg_locus = in->dbg_locus; | 1244 | mach->dbg_locus = in->dbg_locus; |
1165 | 1245 | ||
1166 | mach->errstream = in->errstream; | 1246 | copy_stream_state (mach, in); |
1167 | mu_stream_ref (mach->errstream); | ||
1168 | mach->dbgstream = in->dbgstream; | ||
1169 | mu_stream_ref (mach->dbgstream); | ||
1170 | 1247 | ||
1171 | mach->data = in->data; | 1248 | mach->data = in->data; |
1172 | mach->logger = in->logger; | 1249 | mach->logger = in->logger; |
1173 | mach->daemon_email = in->daemon_email; | 1250 | mach->daemon_email = in->daemon_email; |
1174 | 1251 | ||
1175 | *out = mach; | 1252 | *out = mach; |
1176 | return 0; | 1253 | } |
1254 | else | ||
1255 | mu_sieve_machine_destroy (&mach); | ||
1256 | |||
1257 | return rc; | ||
1177 | } | 1258 | } |
1178 | 1259 | ||
1179 | void | 1260 | void |
... | @@ -1334,14 +1415,13 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach) | ... | @@ -1334,14 +1415,13 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach) |
1334 | mu_sieve_machine_t mach = *pmach; | 1415 | mu_sieve_machine_t mach = *pmach; |
1335 | 1416 | ||
1336 | mu_i_sv_free_stringspace (mach); | 1417 | mu_i_sv_free_stringspace (mach); |
1418 | mu_sieve_free (mach, mach->stringspace); | ||
1337 | mu_stream_destroy (&mach->errstream); | 1419 | mu_stream_destroy (&mach->errstream); |
1338 | mu_stream_destroy (&mach->dbgstream); | 1420 | mu_stream_destroy (&mach->dbgstream); |
1339 | mu_mailer_destroy (&mach->mailer); | 1421 | mu_mailer_destroy (&mach->mailer); |
1340 | mu_list_destroy (&mach->destr_list); | 1422 | mu_list_destroy (&mach->destr_list); |
1341 | mu_list_destroy (&mach->action_list); | 1423 | mu_list_destroy (&mach->registry); |
1342 | mu_list_destroy (&mach->test_list); | 1424 | mu_sieve_free (mach, mach->idspace); |
1343 | mu_list_destroy (&mach->comp_list); | ||
1344 | mu_list_destroy (&mach->source_list); | ||
1345 | mu_opool_destroy (&mach->string_pool); | 1425 | mu_opool_destroy (&mach->string_pool); |
1346 | mu_list_destroy (&mach->memory_pool); | 1426 | mu_list_destroy (&mach->memory_pool); |
1347 | free (mach); | 1427 | free (mach); |
... | @@ -1397,7 +1477,7 @@ sieve_parse (void) | ... | @@ -1397,7 +1477,7 @@ sieve_parse (void) |
1397 | yydebug = mu_debug_level_p (mu_sieve_debug_handle, MU_DEBUG_TRACE3); | 1477 | yydebug = mu_debug_level_p (mu_sieve_debug_handle, MU_DEBUG_TRACE3); |
1398 | 1478 | ||
1399 | rc = yyparse (); | 1479 | rc = yyparse (); |
1400 | mu_i_sv_lex_finish (mu_sieve_machine); | 1480 | mu_i_sv_lex_finish (); |
1401 | if (rc) | 1481 | if (rc) |
1402 | mu_i_sv_error (mu_sieve_machine); | 1482 | mu_i_sv_error (mu_sieve_machine); |
1403 | if (mu_sieve_machine->state == mu_sieve_state_init) | 1483 | if (mu_sieve_machine->state == mu_sieve_state_init) | ... | ... |
-
Please register or sign in to post a comment