From 3be89fef58d5cf1b2eda0ff128c2791567032bf4 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 31 Aug 2008 19:09:46 +0200 Subject: [PATCH] Revised implementation of the require command. --- src/lib-sieve/cmd-require.c | 45 +++---------------------------- src/lib-sieve/sieve-ast.c | 26 +++++++++++++++--- src/lib-sieve/sieve-ast.h | 5 ++++ src/lib-sieve/sieve-generator.c | 45 +++++++++++++++++++------------ src/lib-sieve/sieve-generator.h | 5 +--- src/lib-sieve/sieve-interpreter.c | 12 ++++----- src/lib-sieve/sieve-validator.c | 2 ++ 7 files changed, 67 insertions(+), 73 deletions(-) diff --git a/src/lib-sieve/cmd-require.c b/src/lib-sieve/cmd-require.c index 5c6fc151e..f6d25a3a7 100644 --- a/src/lib-sieve/cmd-require.c +++ b/src/lib-sieve/cmd-require.c @@ -18,8 +18,6 @@ static bool cmd_require_validate (struct sieve_validator *validator, struct sieve_command_context *cmd); -static bool cmd_require_generate - (const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx); const struct sieve_command cmd_require = { "require", @@ -27,10 +25,9 @@ const struct sieve_command cmd_require = { 1, 0, FALSE, FALSE, NULL, NULL, cmd_require_validate, - cmd_require_generate, - NULL + NULL, NULL }; - + /* * Validation */ @@ -63,8 +60,7 @@ static bool cmd_require_validate (validator, cmd, sieve_ast_argument_str(arg)); if ( ext == NULL ) result = FALSE; - arg->context = (void *) ext; - + } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { /* String list */ struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); @@ -74,7 +70,6 @@ static bool cmd_require_validate (validator, cmd, sieve_ast_strlist_str(stritem)); if ( ext == NULL ) result = FALSE; - stritem->context = (void *) ext; stritem = sieve_ast_strlist_next(stritem); } @@ -89,37 +84,3 @@ static bool cmd_require_validate return result; } - -/* - * Code generation - */ - -static bool cmd_require_generate -(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx) -{ - struct sieve_ast_argument *arg = ctx->first_positional; - - if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { - /* Single string */ - const struct sieve_extension *ext = - (const struct sieve_extension *) arg->context; - - sieve_generator_link_extension(cgenv->gentr, ext); - } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { - /* String list */ - struct sieve_ast_argument *stritem = sieve_ast_strlist_first(arg); - - while ( stritem != NULL ) { - const struct sieve_extension *ext = - (const struct sieve_extension *) stritem->context; - - sieve_generator_link_extension(cgenv->gentr, ext); - - stritem = sieve_ast_strlist_next(stritem); - } - } else { - i_unreached(); - } - - return TRUE; -} diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c index c34c1d1ae..082c57db2 100644 --- a/src/lib-sieve/sieve-ast.c +++ b/src/lib-sieve/sieve-ast.c @@ -45,6 +45,7 @@ struct sieve_ast { struct sieve_ast_node *root; + ARRAY_DEFINE(linked_extensions, const struct sieve_extension *); ARRAY_DEFINE(extensions, struct sieve_ast_extension_reg); }; @@ -64,6 +65,7 @@ struct sieve_ast *sieve_ast_create(struct sieve_script *script) ast->root = sieve_ast_node_create(ast, NULL, SAT_ROOT, 0); ast->root->identifier = "ROOT"; + p_array_init(&ast->linked_extensions, pool, sieve_extensions_get_count()); p_array_init(&ast->extensions, pool, sieve_extensions_get_count()); return ast; @@ -120,19 +122,35 @@ struct sieve_script *sieve_ast_script(struct sieve_ast *ast) * Extension support */ +void sieve_ast_extension_link +(struct sieve_ast *ast, const struct sieve_extension *ext) +{ + int ext_id = *ext->id; + + if ( ext_id < 0 ) return; + + array_append(&ast->linked_extensions, &ext, 1); +} + +const struct sieve_extension * const *sieve_ast_extensions_get +(struct sieve_ast *ast, unsigned int *count_r) +{ + return array_get(&ast->linked_extensions, count_r); +} + void sieve_ast_extension_register (struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, void *context) { - struct sieve_ast_extension_reg reg; int ext_id = *ast_ext->ext->id; + struct sieve_ast_extension_reg reg; if ( ext_id < 0 ) return; + /* Initialize registration */ reg.ast_ext = ast_ext; - reg.context = context; - - array_idx_set(&ast->extensions, (unsigned int) ext_id, ®); + reg.context = context; + array_idx_set(&ast->extensions, (unsigned int) ext_id, ®); } void *sieve_ast_extension_get_context diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h index c92262568..564bd5f8b 100644 --- a/src/lib-sieve/sieve-ast.h +++ b/src/lib-sieve/sieve-ast.h @@ -189,6 +189,11 @@ struct sieve_ast_extension { void (*free)(struct sieve_ast *ast, void *context); }; +void sieve_ast_extension_link + (struct sieve_ast *ast, const struct sieve_extension *ext); +const struct sieve_extension * const *sieve_ast_extensions_get + (struct sieve_ast *ast, unsigned int *count_r); + void sieve_ast_extension_register (struct sieve_ast *ast, const struct sieve_ast_extension *ast_ext, void *context); diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index afac539c9..71443ade5 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -177,17 +177,6 @@ void sieve_generator_critical * Extension support */ -bool sieve_generator_link_extension -(struct sieve_generator *gentr, const struct sieve_extension *ext) -{ - (void)sieve_binary_extension_link(gentr->genenv.sbin, ext); - - if ( ext->generator_load != NULL ) - return ext->generator_load(&gentr->genenv); - - return TRUE; -} - void sieve_generator_extension_set_context (struct sieve_generator *gentr, const struct sieve_extension *ext, void *context) { @@ -369,24 +358,46 @@ bool sieve_generate_block } bool sieve_generator_run -(struct sieve_generator *generator, struct sieve_binary **sbin) +(struct sieve_generator *gentr, struct sieve_binary **sbin) { bool topmost = ( *sbin == NULL ); bool result = TRUE; + const struct sieve_extension *const *extensions; + unsigned int i, ext_count; + + /* Initialize */ if ( topmost ) - *sbin = sieve_binary_create_new(sieve_ast_script(generator->genenv.ast)); + *sbin = sieve_binary_create_new(sieve_ast_script(gentr->genenv.ast)); sieve_binary_ref(*sbin); - generator->genenv.sbin = *sbin; + gentr->genenv.sbin = *sbin; + + /* Load extensions linked to the AST */ + extensions = sieve_ast_extensions_get(gentr->genenv.ast, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + const struct sieve_extension *ext = extensions[i]; + + /* Link to binary */ + (void)sieve_binary_extension_link(*sbin, ext); + + /* Load */ + if ( ext->generator_load != NULL && !ext->generator_load(&gentr->genenv) ) + return FALSE; + } + + /* Generate code */ - if ( !sieve_generate_block(&generator->genenv, sieve_ast_root(generator->genenv.ast))) + if ( !sieve_generate_block + (&gentr->genenv, sieve_ast_root(gentr->genenv.ast))) result = FALSE; else if ( topmost ) sieve_binary_activate(*sbin); - - generator->genenv.sbin = NULL; + + /* Cleanup */ + + gentr->genenv.sbin = NULL; sieve_binary_unref(sbin); if ( topmost && !result ) { diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index 9b1f4ea8b..5ab6f651a 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -54,9 +54,6 @@ void sieve_generator_critical * Extension support */ -bool sieve_generator_link_extension - (struct sieve_generator *gentr, const struct sieve_extension *ext); - void sieve_generator_extension_set_context (struct sieve_generator *gentr, const struct sieve_extension *ext, void *context); @@ -103,7 +100,7 @@ bool sieve_generate_test (const struct sieve_codegen_env *cgenv, struct sieve_ast_node *tst_node, struct sieve_jumplist *jlist, bool jump_true); bool sieve_generator_run - (struct sieve_generator *generator, struct sieve_binary **sbin); + (struct sieve_generator *gentr, struct sieve_binary **sbin); #endif /* __SIEVE_GENERATOR_H */ diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index a730ff6fb..eb8e35073 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -474,12 +474,12 @@ int sieve_interpreter_start sieve_message_context_ref(msgctx); } - /* Signal registered extensions that the interpreter is being run */ - extrs = array_get(&interp->extensions, &ext_count); - for ( i = 0; i < ext_count; i++ ) { - if ( extrs[i].int_ext != NULL && extrs[i].int_ext->run != NULL ) - extrs[i].int_ext->run(&interp->runenv, extrs[i].context); - } + /* Signal registered extensions that the interpreter is being run */ + extrs = array_get(&interp->extensions, &ext_count); + for ( i = 0; i < ext_count; i++ ) { + if ( extrs[i].int_ext != NULL && extrs[i].int_ext->run != NULL ) + extrs[i].int_ext->run(&interp->runenv, extrs[i].context); + } return sieve_interpreter_continue(interp, interrupted); } diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index f6497aa7f..c134acf7a 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -503,6 +503,8 @@ const struct sieve_extension *sieve_validator_extension_load "unsupported sieve capability '%s'", name); return NULL; } + + sieve_ast_extension_link(validator->ast, ext); if ( ext->validator_load != NULL && !ext->validator_load(validator) ) { sieve_command_validate_error(validator, cmd, -- GitLab