21
21
#include "ext-variables-namespaces.h"
22
22
#include "ext-variables-arguments.h"
25
25
* Variable argument implementation
28
28
static bool arg_variable_generate
29
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
29
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
30
30
struct sieve_command *context);
32
const struct sieve_argument_def variable_argument = {
32
const struct sieve_argument_def variable_argument = {
34
34
NULL, NULL, NULL, NULL,
38
38
static bool ext_variables_variable_argument_activate
39
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
39
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
40
40
struct sieve_ast_argument *arg, const char *variable)
42
42
struct sieve_ast *ast = arg->ast;
43
43
struct sieve_variable *var;
45
45
var = ext_variables_validator_get_variable(this_ext, valdtr, variable, TRUE);
47
47
if ( var == NULL ) {
48
sieve_argument_validate_error(valdtr, arg,
48
sieve_argument_validate_error(valdtr, arg,
49
49
"(implicit) declaration of new variable '%s' exceeds the limit "
50
"(max variables: %u)", variable,
50
"(max variables: %u)", variable,
51
51
EXT_VARIABLES_MAX_SCOPE_SIZE);
55
55
arg->argument = sieve_argument_create(ast, &variable_argument, this_ext, 0);
56
56
arg->argument->data = (void *) var;
61
61
static struct sieve_ast_argument *ext_variables_variable_argument_create
62
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
62
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
63
63
struct sieve_ast_argument *parent_arg, const char *variable)
65
65
struct sieve_ast *ast = parent_arg->ast;
66
66
struct sieve_ast_argument *new_arg;
68
68
new_arg = sieve_ast_argument_create(ast, sieve_ast_argument_line(parent_arg));
69
69
new_arg->type = SAAT_STRING;
71
71
if ( !ext_variables_variable_argument_activate
72
72
(this_ext, valdtr, new_arg, variable) )
78
78
static bool arg_variable_generate
79
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
79
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
80
80
struct sieve_command *context ATTR_UNUSED)
82
82
struct sieve_argument *argument = arg->argument;
83
83
struct sieve_variable *var = (struct sieve_variable *) argument->data;
85
85
sieve_variables_opr_variable_emit(cgenv->sbin, argument->ext, var);
91
91
* Match value argument implementation
94
94
static bool arg_match_value_generate
95
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
95
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
96
96
struct sieve_command *context ATTR_UNUSED);
98
const struct sieve_argument_def match_value_argument = {
98
const struct sieve_argument_def match_value_argument = {
100
100
NULL, NULL, NULL, NULL,
101
arg_match_value_generate
101
arg_match_value_generate
104
104
static bool ext_variables_match_value_argument_activate
105
(const struct sieve_extension *this_ext,
106
struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
105
(const struct sieve_extension *this_ext,
106
struct sieve_validator *valdtr, struct sieve_ast_argument *arg,
107
107
unsigned int index, bool assignment)
109
109
struct sieve_ast *ast = arg->ast;
111
111
if ( assignment ) {
112
sieve_argument_validate_error(valdtr, arg,
112
sieve_argument_validate_error(valdtr, arg,
113
113
"cannot assign to match variable");
117
117
if ( index > EXT_VARIABLES_MAX_MATCH_INDEX ) {
118
sieve_argument_validate_error(valdtr, arg,
119
"match value index %u out of range (max: %u)", index,
118
sieve_argument_validate_error(valdtr, arg,
119
"match value index %u out of range (max: %u)", index,
120
120
EXT_VARIABLES_MAX_MATCH_INDEX);
124
124
arg->argument = sieve_argument_create
125
125
(ast, &match_value_argument, this_ext, 0);
141
141
(this_ext, valdtr, new_arg, index, FALSE) ) {
148
148
static bool arg_match_value_generate
149
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
149
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
150
150
struct sieve_command *context ATTR_UNUSED)
152
152
struct sieve_argument *argument = arg->argument;
153
153
unsigned int index = POINTER_CAST_TO(argument->data, unsigned int);
155
155
sieve_variables_opr_match_value_emit(cgenv->sbin, argument->ext, index);
161
161
* Variable string argument implementation
164
164
static bool arg_variable_string_validate
165
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
165
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
166
166
struct sieve_command *cmd);
168
const struct sieve_argument_def variable_string_argument = {
168
const struct sieve_argument_def variable_string_argument = {
171
arg_variable_string_validate,
171
arg_variable_string_validate,
173
173
sieve_arg_catenated_string_generate,
176
176
static bool arg_variable_string_validate
177
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
177
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
178
178
struct sieve_command *cmd)
180
180
const struct sieve_extension *this_ext = (*arg)->argument->ext;
212
212
if ( *p == '{' ) {
213
213
state = ST_VARIABLE;
220
220
case ST_VARIABLE:
221
221
nelements = ext_variable_name_parse(&substitution, &p, strend);
223
223
if ( nelements < 0 )
226
226
state = ST_CLOSE;
230
230
/* Finished parsing name, expecting '}' */
233
233
struct sieve_ast_argument *strarg;
235
/* We now know that the substitution is valid */
235
/* We now know that the substitution is valid */
237
237
if ( catstr == NULL ) {
238
238
catstr = sieve_arg_catenated_string_create(*arg);
241
/* Add the substring that is before the substitution to the
241
/* Add the substring that is before the substitution to the
242
242
* variable-string AST.
244
* FIXME: For efficiency, if the variable is not found we should
244
* FIXME: For efficiency, if the variable is not found we should
245
245
* coalesce this substring with the one after the substitution.
247
247
if ( substart > strstart ) {
248
248
string_t *newstr = str_new(pool, substart - strstart);
249
str_append_n(newstr, strstart, substart - strstart);
249
str_append_n(newstr, strstart, substart - strstart);
251
251
strarg = sieve_ast_argument_string_create_raw
252
252
((*arg)->ast, newstr, (*arg)->source_line);
253
253
sieve_arg_catenated_string_add_element(catstr, strarg);
255
255
/* Give other substitution extensions a chance to do their work */
256
256
if ( !sieve_validator_argument_activate_super
257
257
(valdtr, cmd, strarg, FALSE) ) {
312
312
return sieve_validator_argument_activate_super(valdtr, cmd, *arg, TRUE);
315
/* Add the final substring that comes after the last substitution to the
315
/* Add the final substring that comes after the last substitution to the
316
316
* variable-string AST.
318
318
if ( strend > strstart ) {
319
319
struct sieve_ast_argument *strarg;
320
320
string_t *newstr = str_new(pool, strend - strstart);
321
str_append_n(newstr, strstart, strend - strstart);
321
str_append_n(newstr, strstart, strend - strstart);
323
323
strarg = sieve_ast_argument_string_create_raw
324
324
((*arg)->ast, newstr, (*arg)->source_line);
325
325
sieve_arg_catenated_string_add_element(catstr, strarg);
327
/* Give other substitution extensions a chance to do their work */
327
/* Give other substitution extensions a chance to do their work */
328
328
if ( !sieve_validator_argument_activate_super
329
329
(valdtr, cmd, strarg, FALSE) )
340
340
static bool _sieve_variable_argument_activate
341
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
341
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
342
342
struct sieve_command *cmd, struct sieve_ast_argument *arg, bool assignment)
344
344
bool result = FALSE;
345
345
string_t *variable;
346
346
const char *varstr, *varend;
347
ARRAY_TYPE(sieve_variable_name) vname;
347
ARRAY_TYPE(sieve_variable_name) vname;
348
348
int nelements = 0;
351
t_array_init(&vname, 2);
351
t_array_init(&vname, 2);
353
353
variable = sieve_ast_argument_str(arg);
354
354
varstr = str_c(variable);
355
355
varend = PTR_OFFSET(varstr, str_len(variable));
356
356
nelements = ext_variable_name_parse(&vname, &varstr, varend);
358
/* Check whether name parsing succeeded */
358
/* Check whether name parsing succeeded */
359
359
if ( nelements < 0 || varstr != varend ) {
360
360
/* Parse failed */
361
sieve_argument_validate_error(valdtr, arg,
361
sieve_argument_validate_error(valdtr, arg,
362
362
"invalid variable name '%s'", str_sanitize(str_c(variable),80));
363
363
} else if ( nelements == 1 ) {
364
364
/* Normal (match) variable */
366
const struct sieve_variable_name *cur_element =
366
const struct sieve_variable_name *cur_element =
367
367
array_idx(&vname, 0);
369
369
if ( cur_element->num_variable < 0 ) {
390
390
bool sieve_variable_argument_activate
391
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
392
struct sieve_command *cmd, struct sieve_ast_argument *arg,
391
(const struct sieve_extension *this_ext, struct sieve_validator *valdtr,
392
struct sieve_command *cmd, struct sieve_ast_argument *arg,
395
395
if ( sieve_ast_argument_type(arg) == SAAT_STRING ) {
396
396
/* Single string */
397
397
return _sieve_variable_argument_activate
398
398
(this_ext, valdtr, cmd, arg, assignment);
400
400
} else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) {
401
401
/* String list */
402
402
struct sieve_ast_argument *stritem;
404
404
i_assert ( !assignment );
406
406
stritem = sieve_ast_strlist_first(arg);
407
407
while ( stritem != NULL ) {
408
408
if ( !_sieve_variable_argument_activate
409
409
(this_ext, valdtr, cmd, stritem, assignment) )
412
412
stritem = sieve_ast_strlist_next(stritem);
415
415
arg->argument = sieve_argument_create
416
416
(arg->ast, &string_list_argument, NULL, 0);