92 |
} |
} |
93 |
|
|
94 |
sieve_tag_def_t * |
sieve_tag_def_t * |
95 |
find_tag (sieve_tag_def_t *taglist, char *tagname) |
find_tag (sieve_tag_group_t *taglist, char *tagname, |
96 |
|
sieve_tag_checker_t *checker) |
97 |
{ |
{ |
98 |
|
*checker = NULL; |
99 |
|
|
100 |
if (!taglist) |
if (!taglist) |
101 |
return NULL; |
return NULL; |
102 |
|
|
103 |
for (; taglist->name; taglist++) |
for (; taglist->tags; taglist++) |
104 |
if (strcmp (taglist->name, tagname) == 0) |
{ |
105 |
return taglist; |
sieve_tag_def_t *def; |
106 |
|
for (def = taglist->tags; def->name; def++) |
107 |
|
if (strcmp (def->name, tagname) == 0) |
108 |
|
{ |
109 |
|
*checker = taglist->checker; |
110 |
|
return def; |
111 |
|
} |
112 |
|
} |
113 |
return NULL; |
return NULL; |
114 |
} |
} |
115 |
|
|
116 |
|
static int |
117 |
|
_compare_ptr (void *item, void *data) |
118 |
|
{ |
119 |
|
return item == data; |
120 |
|
} |
121 |
|
|
122 |
|
struct check_arg { |
123 |
|
char *name; |
124 |
|
list_t args; |
125 |
|
list_t tags; |
126 |
|
}; |
127 |
|
|
128 |
|
static int |
129 |
|
_run_checker (void *item, void *data) |
130 |
|
{ |
131 |
|
struct check_arg *arg = data; |
132 |
|
return (*(sieve_tag_checker_t)item) (arg->name, arg->tags, arg->args); |
133 |
|
} |
134 |
|
|
135 |
int |
int |
136 |
sieve_code_command (sieve_register_t *reg, list_t arglist) |
sieve_code_command (sieve_register_t *reg, list_t arglist) |
137 |
{ |
{ |
138 |
iterator_t itr; |
iterator_t itr; |
139 |
list_t arg_list = NULL; |
list_t arg_list = NULL; |
140 |
list_t tag_list = NULL; |
list_t tag_list = NULL; |
141 |
|
list_t chk_list = NULL; |
142 |
sieve_data_type *exp_arg; |
sieve_data_type *exp_arg; |
143 |
int rc, err = 0; |
int rc, err = 0; |
144 |
static sieve_data_type empty[] = { SVT_VOID }; |
static sieve_data_type empty[] = { SVT_VOID }; |
169 |
|
|
170 |
if (val->type == SVT_TAG) |
if (val->type == SVT_TAG) |
171 |
{ |
{ |
172 |
sieve_tag_def_t *tag = find_tag (reg->tags, val->v.string); |
sieve_tag_checker_t cf; |
173 |
|
sieve_tag_def_t *tag = find_tag (reg->tags, val->v.string, &cf); |
174 |
if (!tag) |
if (!tag) |
175 |
{ |
{ |
176 |
sieve_compile_error (sieve_filename, sieve_line_num, |
sieve_compile_error (sieve_filename, sieve_line_num, |
177 |
"invalid tag name `%s' for `%s'", |
"invalid tag name `%s' for `%s'", |
178 |
val->v.string, reg->name); |
val->v.string, reg->name); |
179 |
err = 1; |
err = 1; |
180 |
break; |
break; |
181 |
} |
} |
189 |
break; |
break; |
190 |
} |
} |
191 |
|
|
192 |
tagrec.tag = tag->num; |
tagrec.tag = tag->name; |
193 |
if (tag->argtype != SVT_VOID) |
if (tag->argtype != SVT_VOID) |
194 |
{ |
{ |
195 |
iterator_next (itr); |
iterator_next (itr); |
202 |
sizeof (*tagptr)); |
sizeof (*tagptr)); |
203 |
*tagptr = tagrec; |
*tagptr = tagrec; |
204 |
list_append (tag_list, tagptr); |
list_append (tag_list, tagptr); |
205 |
|
|
206 |
|
if (cf) |
207 |
|
{ |
208 |
|
if (!chk_list && (rc = list_create (&chk_list))) |
209 |
|
{ |
210 |
|
sieve_compile_error (sieve_filename, sieve_line_num, |
211 |
|
"%s:%d: can't create check list: %s", |
212 |
|
mu_errstring (rc)); |
213 |
|
err = 1; |
214 |
|
break; |
215 |
|
} |
216 |
|
if (list_do (chk_list, _compare_ptr, cf) == 0) |
217 |
|
list_append (chk_list, cf); |
218 |
|
} |
219 |
} |
} |
220 |
else if (*exp_arg == SVT_VOID) |
else if (*exp_arg == SVT_VOID) |
221 |
{ |
{ |
278 |
reg->name); |
reg->name); |
279 |
err = 1; |
err = 1; |
280 |
} |
} |
281 |
|
|
282 |
|
if (chk_list) |
283 |
|
{ |
284 |
|
struct check_arg chk_arg; |
285 |
|
|
286 |
|
chk_arg.name = reg->name; |
287 |
|
chk_arg.tags = tag_list; |
288 |
|
chk_arg.args = arg_list; |
289 |
|
err = list_do (chk_list, _run_checker, &chk_arg); |
290 |
|
} |
291 |
} |
} |
292 |
|
|
293 |
if (!err) |
if (!err) |
299 |
{ |
{ |
300 |
list_destroy (&arg_list); |
list_destroy (&arg_list); |
301 |
list_destroy (&tag_list); |
list_destroy (&tag_list); |
302 |
|
list_destroy (&chk_list); |
303 |
} |
} |
304 |
|
|
305 |
return err; |
return err; |