Commit a3e15ed6 a3e15ed693508130d19ff79143163a6545a799b6 by Sergey Poznyakoff

More thorough checking of tags.

1 parent 04a9780c
...@@ -92,23 +92,53 @@ sieve_code_string (char *string) ...@@ -92,23 +92,53 @@ sieve_code_string (char *string)
92 } 92 }
93 93
94 sieve_tag_def_t * 94 sieve_tag_def_t *
95 find_tag (sieve_tag_def_t *taglist, char *tagname) 95 find_tag (sieve_tag_group_t *taglist, char *tagname,
96 sieve_tag_checker_t *checker)
96 { 97 {
98 *checker = NULL;
99
97 if (!taglist) 100 if (!taglist)
98 return NULL; 101 return NULL;
99 102
100 for (; taglist->name; taglist++) 103 for (; taglist->tags; taglist++)
101 if (strcmp (taglist->name, tagname) == 0) 104 {
102 return taglist; 105 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 }
103 return NULL; 113 return NULL;
104 } 114 }
105 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
106 int 135 int
107 sieve_code_command (sieve_register_t *reg, list_t arglist) 136 sieve_code_command (sieve_register_t *reg, list_t arglist)
108 { 137 {
109 iterator_t itr; 138 iterator_t itr;
110 list_t arg_list = NULL; 139 list_t arg_list = NULL;
111 list_t tag_list = NULL; 140 list_t tag_list = NULL;
141 list_t chk_list = NULL;
112 sieve_data_type *exp_arg; 142 sieve_data_type *exp_arg;
113 int rc, err = 0; 143 int rc, err = 0;
114 static sieve_data_type empty[] = { SVT_VOID }; 144 static sieve_data_type empty[] = { SVT_VOID };
...@@ -139,12 +169,13 @@ sieve_code_command (sieve_register_t *reg, list_t arglist) ...@@ -139,12 +169,13 @@ sieve_code_command (sieve_register_t *reg, list_t arglist)
139 169
140 if (val->type == SVT_TAG) 170 if (val->type == SVT_TAG)
141 { 171 {
142 sieve_tag_def_t *tag = find_tag (reg->tags, val->v.string); 172 sieve_tag_checker_t cf;
173 sieve_tag_def_t *tag = find_tag (reg->tags, val->v.string, &cf);
143 if (!tag) 174 if (!tag)
144 { 175 {
145 sieve_compile_error (sieve_filename, sieve_line_num, 176 sieve_compile_error (sieve_filename, sieve_line_num,
146 "invalid tag name `%s' for `%s'", 177 "invalid tag name `%s' for `%s'",
147 val->v.string, reg->name); 178 val->v.string, reg->name);
148 err = 1; 179 err = 1;
149 break; 180 break;
150 } 181 }
...@@ -158,7 +189,7 @@ sieve_code_command (sieve_register_t *reg, list_t arglist) ...@@ -158,7 +189,7 @@ sieve_code_command (sieve_register_t *reg, list_t arglist)
158 break; 189 break;
159 } 190 }
160 191
161 tagrec.tag = tag->num; 192 tagrec.tag = tag->name;
162 if (tag->argtype != SVT_VOID) 193 if (tag->argtype != SVT_VOID)
163 { 194 {
164 iterator_next (itr); 195 iterator_next (itr);
...@@ -171,6 +202,20 @@ sieve_code_command (sieve_register_t *reg, list_t arglist) ...@@ -171,6 +202,20 @@ sieve_code_command (sieve_register_t *reg, list_t arglist)
171 sizeof (*tagptr)); 202 sizeof (*tagptr));
172 *tagptr = tagrec; 203 *tagptr = tagrec;
173 list_append (tag_list, tagptr); 204 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 }
174 } 219 }
175 else if (*exp_arg == SVT_VOID) 220 else if (*exp_arg == SVT_VOID)
176 { 221 {
...@@ -233,6 +278,16 @@ sieve_code_command (sieve_register_t *reg, list_t arglist) ...@@ -233,6 +278,16 @@ sieve_code_command (sieve_register_t *reg, list_t arglist)
233 reg->name); 278 reg->name);
234 err = 1; 279 err = 1;
235 } 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 }
236 } 291 }
237 292
238 if (!err) 293 if (!err)
...@@ -244,6 +299,7 @@ sieve_code_command (sieve_register_t *reg, list_t arglist) ...@@ -244,6 +299,7 @@ sieve_code_command (sieve_register_t *reg, list_t arglist)
244 { 299 {
245 list_destroy (&arg_list); 300 list_destroy (&arg_list);
246 list_destroy (&tag_list); 301 list_destroy (&tag_list);
302 list_destroy (&chk_list);
247 } 303 }
248 304
249 return err; 305 return err;
......