From 5523de35762160214ea3f1405416959a15ce9bc2 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Wed, 23 Dec 2009 12:27:38 +0100 Subject: [PATCH] Include extension: implemented global variables namespace. --- TODO | 1 - src/lib-sieve/plugins/include/cmd-global.c | 2 +- .../plugins/include/ext-include-common.c | 5 +- .../plugins/include/ext-include-variables.c | 104 ++++++++++++++++++ .../plugins/include/ext-include-variables.h | 7 ++ src/lib-sieve/plugins/include/ext-include.c | 16 ++- 6 files changed, 126 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index ce91b4ae3..1bc9ae1a8 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,6 @@ Current activities: Next (in order of descending priority/precedence): * Update include extension to latest draft: - - Implement global namespace - Allow placing the global command anywhere in the script - Implement required ManageSieve behavior * Implement mechanism for implicitly including an account's aliases in the diff --git a/src/lib-sieve/plugins/include/cmd-global.c b/src/lib-sieve/plugins/include/cmd-global.c index b8952547e..8a5f5322d 100644 --- a/src/lib-sieve/plugins/include/cmd-global.c +++ b/src/lib-sieve/plugins/include/cmd-global.c @@ -128,7 +128,7 @@ static bool cmd_global_validate if ( !sieve_command_is(prev, cmd_import) && !sieve_command_is(prev, cmd_export) ) { sieve_command_validate_error(valdtr, cmd, - "the DEPRICATED %s command can only be placed at top level " + "the DEPRECATED %s command can only be placed at top level " "at the beginning of the file after any require or " "import/export commands", sieve_command_identifier(cmd)); diff --git a/src/lib-sieve/plugins/include/ext-include-common.c b/src/lib-sieve/plugins/include/ext-include-common.c index ce0a7f716..9f9ba6742 100644 --- a/src/lib-sieve/plugins/include/ext-include-common.c +++ b/src/lib-sieve/plugins/include/ext-include-common.c @@ -464,7 +464,8 @@ bool ext_include_generate_include /* Validate */ if ( !sieve_validate(ast, ehandler) ) { sieve_command_generate_error(gentr, cmd, - "failed to validate included script '%s'", str_sanitize(script_name, 80)); + "failed to validate included script '%s'", + str_sanitize(script_name, 80)); sieve_ast_unref(&ast); return FALSE; } @@ -487,7 +488,9 @@ bool ext_include_generate_include if ( sbin != NULL ) (void) sieve_binary_block_set_active(sbin, this_block_id, NULL); + sieve_generator_free(&subgentr); + } else { sieve_sys_error("include: failed to activate binary block %d for " "generating code for the included script", inc_block_id); diff --git a/src/lib-sieve/plugins/include/ext-include-variables.c b/src/lib-sieve/plugins/include/ext-include-variables.c index a0fb7c8b8..c9083627a 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.c +++ b/src/lib-sieve/plugins/include/ext-include-variables.c @@ -150,3 +150,107 @@ bool ext_include_variables_dump return TRUE; } + +/* + * Global variables namespace + */ + +bool vnspc_global_variables_validate + (struct sieve_validator *valdtr, const struct sieve_variables_namespace *nspc, + struct sieve_ast_argument *arg, struct sieve_command *cmd, + ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, + bool assignment); +bool vnspc_global_variables_generate + (const struct sieve_codegen_env *cgenv, + const struct sieve_variables_namespace *nspc, + struct sieve_ast_argument *arg, struct sieve_command *cmd, void *var_data); + +static const struct sieve_variables_namespace_def global_variables_namespace = { + SIEVE_OBJECT("global", NULL, 0), + vnspc_global_variables_validate, + vnspc_global_variables_generate, + NULL, NULL +}; + + +bool vnspc_global_variables_validate +(struct sieve_validator *valdtr, + const struct sieve_variables_namespace *nspc, struct sieve_ast_argument *arg, + struct sieve_command *cmd ATTR_UNUSED, + ARRAY_TYPE(sieve_variable_name) *var_name, void **var_data, + bool assignment ATTR_UNUSED) +{ + const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); + struct sieve_ast *ast = arg->ast; + struct ext_include_ast_context *ctx = + ext_include_get_ast_context(this_ext, ast); + struct sieve_variable *var = NULL; + const struct sieve_variable_name *name_element; + const char *variable; + + /* Sanity safeguard */ + i_assert ( ctx->global_vars != NULL ); + + /* Check variable name */ + + if ( array_count(var_name) != 2 ) { + sieve_argument_validate_error(valdtr, arg, + "invalid variable name within global namespace: " + "encountered sub-namespace"); + return FALSE; + } + + name_element = array_idx(var_name, 1); + if ( name_element->num_variable >= 0 ) { + sieve_argument_validate_error(valdtr, arg, + "invalid variable name within global namespace: " + "encountered numeric variable name"); + return FALSE; + } + + variable = str_c(name_element->identifier); + + /* Get/Declare the variable in the global scope */ + + var = sieve_variable_scope_get_variable(ctx->global_vars, variable, TRUE); + + if ( var == NULL ) { + sieve_argument_validate_error(valdtr, arg, + "(implicit) declaration of new global variable '%s' exceeds the limit " + "(max variables: %u)", variable, + SIEVE_VARIABLES_MAX_SCOPE_SIZE); + return FALSE; + } + + *var_data = (void *) var; + + return TRUE; +} + +bool vnspc_global_variables_generate +(const struct sieve_codegen_env *cgenv, + const struct sieve_variables_namespace *nspc, + struct sieve_ast_argument *arg ATTR_UNUSED, + struct sieve_command *cmd ATTR_UNUSED, void *var_data) +{ + const struct sieve_extension *this_ext = SIEVE_OBJECT_EXTENSION(nspc); + struct ext_include_context *ectx = ext_include_get_context(this_ext); + + struct sieve_variable *var = (struct sieve_variable *) var_data; + + sieve_variables_opr_variable_emit(cgenv->sbin, ectx->var_ext, var); + + return TRUE; +} + +void ext_include_variables_global_namespace_init +(const struct sieve_extension *this_ext, struct sieve_validator *valdtr) +{ + struct ext_include_context *ectx = ext_include_get_context(this_ext); + + sieve_variables_namespace_register + (ectx->var_ext, valdtr, this_ext, &global_variables_namespace); +} + + + diff --git a/src/lib-sieve/plugins/include/ext-include-variables.h b/src/lib-sieve/plugins/include/ext-include-variables.h index 231ed2c1d..382a2bd85 100644 --- a/src/lib-sieve/plugins/include/ext-include-variables.h +++ b/src/lib-sieve/plugins/include/ext-include-variables.h @@ -30,6 +30,13 @@ bool ext_include_variables_load struct sieve_variable_scope **global_vars_r); bool ext_include_variables_dump (struct sieve_dumptime_env *denv, struct sieve_variable_scope *global_vars); + +/* + * Validation + */ + +void ext_include_variables_global_namespace_init + (const struct sieve_extension *this_ext, struct sieve_validator *valdtr); #endif /* __EXT_INCLUDE_VARIABLES_H */ diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c index 90b40ad80..4ab6cfaac 100644 --- a/src/lib-sieve/plugins/include/ext-include.c +++ b/src/lib-sieve/plugins/include/ext-include.c @@ -31,6 +31,7 @@ #include "ext-include-common.h" #include "ext-include-binary.h" +#include "ext-include-variables.h" /* * Operations @@ -102,16 +103,19 @@ static void ext_include_unload } static bool ext_include_validator_load -(const struct sieve_extension *ext, struct sieve_validator *validator) +(const struct sieve_extension *ext, struct sieve_validator *valdtr) { /* Register new commands */ - sieve_validator_register_command(validator, ext, &cmd_include); - sieve_validator_register_command(validator, ext, &cmd_return); - sieve_validator_register_command(validator, ext, &cmd_global); + sieve_validator_register_command(valdtr, ext, &cmd_include); + sieve_validator_register_command(valdtr, ext, &cmd_return); + sieve_validator_register_command(valdtr, ext, &cmd_global); /* DEPRICATED */ - sieve_validator_register_command(validator, ext, &cmd_import); - sieve_validator_register_command(validator, ext, &cmd_export); + sieve_validator_register_command(valdtr, ext, &cmd_import); + sieve_validator_register_command(valdtr, ext, &cmd_export); + + /* Initialize global variables namespace */ + ext_include_variables_global_namespace_init(ext, valdtr); return TRUE; } -- GitLab