diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index 8dbc976e10c2e11a42d1cbcbe93ca7d36190f9fb..157cd69a09ef452855186f162094e4b752f0cb2a 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -3,6 +3,7 @@ #include "sieve-common.h" #include "sieve-code.h" +#include "sieve-ast.h" #include "sieve-commands.h" #include "sieve-validator.h" #include "sieve-generator.h" @@ -62,7 +63,9 @@ const struct sieve_operation cmd_set_operation = { */ static bool tag_modifier_is_instance_of - (struct sieve_validator *validator, struct sieve_ast_argument *arg) +(struct sieve_validator *validator, + struct sieve_command_context *cmdctx ATTR_UNUSED, + struct sieve_ast_argument *arg) { return ext_variables_set_modifier_find (validator, sieve_ast_argument_tag(arg)) != NULL; @@ -149,13 +152,13 @@ static bool cmd_set_validate(struct sieve_validator *validator, struct sieve_command_context *cmd) { struct sieve_ast_argument *arg = cmd->first_positional; - + if ( !sieve_validate_positional_argument (validator, cmd, arg, "name", 1, SAAT_STRING) ) { return FALSE; } - sieve_validator_argument_activate(validator, cmd, arg, TRUE); - + ext_variables_variable_argument_activate(validator, arg); + arg = sieve_ast_argument_next(arg); if ( !sieve_validate_positional_argument @@ -196,7 +199,6 @@ static bool cmd_set_operation_dump sieve_code_descend(denv); return - sieve_opr_string_dump(denv, address) && sieve_opr_string_dump(denv, address); } diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index 932e7631905c0112ac17acdcadca7d68cf2bf448..c21c7d1a02c1431f698c4febfa97524745dba180 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -2,6 +2,8 @@ #include "hash.h" #include "sieve-common.h" +#include "sieve-ast.h" +#include "sieve-commands.h" #include "sieve-validator.h" #include "ext-variables-common.h" @@ -23,10 +25,51 @@ const struct ext_variables_set_modifier *default_set_modifiers[] = { const unsigned int default_set_modifiers_count = N_ELEMENTS(default_set_modifiers); +/* Variable scope */ + +struct sieve_variable_scope { + pool_t pool; + const char *identifier; + + unsigned int next_index; + struct hash_table *variables; +}; + +struct sieve_variable_scope *sieve_variable_scope_create(pool_t pool) +{ + struct sieve_variable_scope *scope; + + scope = p_new(pool, struct sieve_variable_scope, 1); + scope->pool = pool; + scope->variables = hash_create + (pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); + + return scope; +} + +struct sieve_variable *sieve_variable_scope_get_variable +(struct sieve_variable_scope *scope, const char *identifier) +{ + struct sieve_variable *var = + (struct sieve_variable *) hash_lookup(scope->variables, identifier); + + if ( var == NULL ) { + var = p_new(scope->pool, struct sieve_variable, 1); + var->identifier = identifier; + var->index = scope->next_index++; + + hash_insert(scope->variables, (void *) identifier, (void *) var); + } + + return var; +} + /* Validator context */ struct ext_variables_validator_context { struct hash_table *set_modifiers; + + struct sieve_variable_scope *main_scope; }; static struct ext_variables_validator_context * @@ -34,10 +77,12 @@ ext_variables_validator_context_create(struct sieve_validator *validator) { pool_t pool = sieve_validator_pool(validator); struct ext_variables_validator_context *ctx; + struct sieve_ast *ast = sieve_validator_ast(validator); ctx = p_new(pool, struct ext_variables_validator_context, 1); ctx->set_modifiers = hash_create (pool, pool, 0, str_hash, (hash_cmp_callback_t *)strcmp); + ctx->main_scope = sieve_variable_scope_create(sieve_ast_pool(ast)); sieve_validator_extension_set_context (validator, ext_variables_my_id, (void *) ctx); @@ -67,6 +112,45 @@ ext_variables_validator_context_get(struct sieve_validator *validator) sieve_validator_extension_get_context(validator, ext_variables_my_id); } +struct sieve_variable *ext_variables_validator_get_variable +(struct sieve_validator *validator, const char *variable) +{ + struct ext_variables_validator_context *ctx = + ext_variables_validator_context_get(validator); + + return sieve_variable_scope_get_variable(ctx->main_scope, variable); +} + +/* Variable arguments */ + +static bool arg_variable_generate + (struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *context); + +const struct sieve_argument variable_argument = + { "@variable", NULL, NULL, NULL, arg_variable_generate }; + +void ext_variables_variable_argument_activate +(struct sieve_validator *validator, struct sieve_ast_argument *arg) +{ + struct ext_variables_validator_context *ctx; + struct sieve_variable *var; + + ctx = ext_variables_validator_context_get(validator); + var = sieve_variable_scope_get_variable(ctx->main_scope, + sieve_ast_argument_strc(arg)); + + arg->argument = &variable_argument; + arg->context = (void *) var; +} + +static bool arg_variable_generate +(struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *context) +{ + return TRUE; +} + /* Set modifier registration */ const struct ext_variables_set_modifier *ext_variables_set_modifier_find @@ -79,3 +163,6 @@ const struct ext_variables_set_modifier *ext_variables_set_modifier_find hash_lookup(ctx->set_modifiers, identifier); } +/* Interpreter context */ + + diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h index 738b2a71305b523b763b6f791c7b23b5eaabe6fe..e8420cc18f0c3481f418f9df00de4d697f45fbd1 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.h +++ b/src/lib-sieve/plugins/variables/ext-variables-common.h @@ -3,6 +3,8 @@ #include "sieve-common.h" +#include "sieve-ext-variables.h" + extern int ext_variables_my_id; extern struct sieve_extension variables_extension; @@ -36,5 +38,13 @@ struct ext_variables_set_modifier { const struct ext_variables_set_modifier *ext_variables_set_modifier_find (struct sieve_validator *validator, const char *identifier); + +/* Variables */ + +void ext_variables_variable_argument_activate + (struct sieve_validator *validator, struct sieve_ast_argument *arg); + +struct sieve_variable *ext_variables_validator_get_variable +(struct sieve_validator *validator, const char *variable); #endif /* __EXT_VARIABLES_COMMON_H */ diff --git a/src/lib-sieve/plugins/variables/sieve-ext-variables.h b/src/lib-sieve/plugins/variables/sieve-ext-variables.h new file mode 100644 index 0000000000000000000000000000000000000000..42f8c9c63746c320c6f5c52c2583837790421686 --- /dev/null +++ b/src/lib-sieve/plugins/variables/sieve-ext-variables.h @@ -0,0 +1,18 @@ +#ifndef __SIEVE_EXT_VARIABLES_H +#define __SIEVE_EXT_VARIABLES_H + +/* Public interface for other extensions to use */ + +struct sieve_variable { + const char *identifier; + unsigned int index; +}; + +struct sieve_variable_scope; + +struct sieve_variable_scope *sieve_variable_scope_create(pool_t pool); +struct sieve_variable *sieve_variable_scope_get_variable + (struct sieve_variable_scope *scope, const char *identifier); + + +#endif /* __SIEVE_EXT_VARIABLES_H */