From d622ff1aed6863e7d17767954f85de59cd0ee526 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 28 Dec 2008 13:37:18 +0100 Subject: [PATCH] Exported variable string argument into the Sieve engine itself as 'catenated string' (for similar use in other extensions like the testsuite). --- .../variables/ext-variables-arguments.c | 92 +++++-------------- src/lib-sieve/sieve-ast.c | 29 ++++-- src/lib-sieve/sieve-ast.h | 8 +- src/lib-sieve/sieve-commands.c | 65 +++++++++++++ src/lib-sieve/sieve-commands.h | 14 +++ 5 files changed, 130 insertions(+), 78 deletions(-) diff --git a/src/lib-sieve/plugins/variables/ext-variables-arguments.c b/src/lib-sieve/plugins/variables/ext-variables-arguments.c index d6aced2d2..53c6ccd71 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-arguments.c +++ b/src/lib-sieve/plugins/variables/ext-variables-arguments.c @@ -247,45 +247,26 @@ static bool arg_match_value_generate static bool arg_variable_string_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, struct sieve_command_context *context); -static bool arg_variable_string_generate -(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *context); const struct sieve_argument variable_string_argument = { "@variable-string", NULL, NULL, arg_variable_string_validate, NULL, - arg_variable_string_generate, -}; - -struct _variable_string_data { - struct sieve_ast_arg_list *str_parts; + sieve_arg_catenated_string_generate, }; -inline static struct sieve_ast_argument *_add_string_element -(struct sieve_ast_arg_list *list, struct sieve_ast_argument *arg) -{ - struct sieve_ast_argument *strarg = - sieve_ast_argument_create(arg->ast, arg->source_line); - sieve_ast_arg_list_add(list, strarg); - strarg->type = SAAT_STRING; - - return strarg; -} - static bool arg_variable_string_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, struct sieve_command_context *cmd) { enum { ST_NONE, ST_OPEN, ST_VARIABLE, ST_CLOSE } state = ST_NONE; pool_t pool = sieve_ast_pool((*arg)->ast); - struct sieve_ast_arg_list *arglist = NULL; + struct sieve_arg_catenated_string *catstr = NULL; string_t *str = sieve_ast_argument_str(*arg); const char *p, *strstart, *substart = NULL; const char *strval = (const char *) str_data(str); const char *strend = strval + str_len(str); - struct _variable_string_data *strdata; bool result = TRUE; ARRAY_TYPE(ext_variable_name) substitution; @@ -336,8 +317,8 @@ static bool arg_variable_string_validate /* We now know that the substitution is valid */ - if ( arglist == NULL ) { - arglist = sieve_ast_arg_list_create(pool); + if ( catstr == NULL ) { + catstr = sieve_arg_catenated_string_create(*arg); } /* Add the substring that is before the substitution to the @@ -347,9 +328,12 @@ static bool arg_variable_string_validate * coalesce this substring with the one after the substitution. */ if ( substart > strstart ) { - strarg = _add_string_element(arglist, *arg); - strarg->_value.str = str_new(pool, substart - strstart); - str_append_n(strarg->_value.str, strstart, substart - strstart); + string_t *newstr = str_new(pool, substart - strstart); + str_append_n(newstr, strstart, substart - strstart); + + strarg = sieve_ast_argument_string_create_raw + ((*arg)->ast, newstr, (*arg)->source_line); + sieve_arg_catenated_string_add_element(catstr, strarg); /* Give other substitution extensions a chance to do their work */ if ( !sieve_validator_argument_activate_super @@ -371,7 +355,7 @@ static bool arg_variable_string_validate strarg = ext_variables_variable_argument_create (validator, (*arg)->ast, (*arg)->source_line, str_c(cur_ident)); if ( strarg != NULL ) - sieve_ast_arg_list_add(arglist, strarg); + sieve_arg_catenated_string_add_element(catstr, strarg); else { _ext_variables_scope_size_error (validator, *arg, str_c(cur_element->identifier)); @@ -391,7 +375,7 @@ static bool arg_variable_string_validate (validator, (*arg)->ast, (*arg)->source_line, cur_element->num_variable); if ( strarg != NULL ) - sieve_ast_arg_list_add(arglist, strarg); + sieve_arg_catenated_string_add_element(catstr, strarg); } } else { const struct ext_variable_name *cur_element = @@ -425,62 +409,30 @@ static bool arg_variable_string_validate if ( !result ) return FALSE; /* Check whether any substitutions were found */ - if ( arglist == NULL ) { + if ( catstr == NULL ) { /* No substitutions in this string, pass it on to any other substution * extension. */ - return sieve_validator_argument_activate_super - (validator, cmd, *arg, TRUE); + return sieve_validator_argument_activate_super(validator, cmd, *arg, TRUE); } /* Add the final substring that comes after the last substitution to the * variable-string AST. */ if ( strend > strstart ) { - struct sieve_ast_argument *strarg = _add_string_element(arglist, *arg); - strarg->_value.str = str_new(pool, strend - strstart); - str_append_n(strarg->_value.str, strstart, strend - strstart); - + struct sieve_ast_argument *strarg; + string_t *newstr = str_new(pool, strend - strstart); + str_append_n(newstr, strstart, strend - strstart); + + strarg = sieve_ast_argument_string_create_raw + ((*arg)->ast, newstr, (*arg)->source_line); + sieve_arg_catenated_string_add_element(catstr, strarg); + /* Give other substitution extensions a chance to do their work */ if ( !sieve_validator_argument_activate_super (validator, cmd, strarg, FALSE) ) return FALSE; } - /* Assign the constructed variable-string AST-branch to the actual AST */ - strdata = p_new(pool, struct _variable_string_data, 1); - strdata->str_parts = arglist; - (*arg)->context = (void *) strdata; - - return TRUE; -} - -#define _string_data_first(data) __AST_LIST_FIRST((data)->str_parts) -#define _string_data_count(data) __AST_LIST_COUNT((data)->str_parts) -#define _string_data_next(item) __AST_LIST_NEXT(item) - -static bool arg_variable_string_generate -(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) -{ - struct sieve_binary *sbin = cgenv->sbin; - struct _variable_string_data *strdata = - (struct _variable_string_data *) arg->context; - struct sieve_ast_argument *strpart; - - if ( _string_data_count(strdata) == 1 ) - sieve_generate_argument(cgenv, _string_data_first(strdata), cmd); - else { - sieve_opr_catenated_string_emit(sbin, _string_data_count(strdata)); - - strpart = _string_data_first(strdata); - while ( strpart != NULL ) { - if ( !sieve_generate_argument(cgenv, strpart, cmd) ) - return FALSE; - - strpart = _string_data_next(strpart); - } - } - return TRUE; } diff --git a/src/lib-sieve/sieve-ast.c b/src/lib-sieve/sieve-ast.c index 1f5f4c350..4bb4ca054 100644 --- a/src/lib-sieve/sieve-ast.c +++ b/src/lib-sieve/sieve-ast.c @@ -459,18 +459,35 @@ static void sieve_ast_argument_substitute sieve_ast_arg_list_substitute(argument->list, argument, replacement); } -struct sieve_ast_argument *sieve_ast_argument_string_create -(struct sieve_ast_node *node, const string_t *str, unsigned int source_line) -{ +struct sieve_ast_argument *sieve_ast_argument_string_create_raw +(struct sieve_ast *ast, string_t *str, unsigned int source_line) +{ struct sieve_ast_argument *argument = sieve_ast_argument_create - (node->ast, source_line); + (ast, source_line); argument->type = SAAT_STRING; + argument->_value.str = str; + + return argument; +} + +struct sieve_ast_argument *sieve_ast_argument_string_create +(struct sieve_ast_node *node, const string_t *str, unsigned int source_line) +{ + struct sieve_ast_argument *argument; + string_t *newstr; + + /* Allocate new internal string buffer */ + newstr = str_new(node->ast->pool, str_len(str)); /* Clone string */ - argument->_value.str = str_new(node->ast->pool, str_len(str)); - str_append_str(argument->_value.str, str); + str_append_str(newstr, str); + + /* Create string argument */ + argument = sieve_ast_argument_string_create_raw + (node->ast, newstr, source_line); + /* Add argument to command/test node */ sieve_ast_node_add_argument(node, argument); return argument; diff --git a/src/lib-sieve/sieve-ast.h b/src/lib-sieve/sieve-ast.h index f2fc4e3e2..68c7175bf 100644 --- a/src/lib-sieve/sieve-ast.h +++ b/src/lib-sieve/sieve-ast.h @@ -230,13 +230,17 @@ bool sieve_ast_arg_list_insert (struct sieve_ast_arg_list *list, struct sieve_ast_argument *before, struct sieve_ast_argument *argument); void sieve_ast_arg_list_substitute -(struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument, - struct sieve_ast_argument *replacement); + (struct sieve_ast_arg_list *list, struct sieve_ast_argument *argument, + struct sieve_ast_argument *replacement); +struct sieve_ast_argument *sieve_ast_argument_string_create_raw + (struct sieve_ast *ast, string_t *str, unsigned int source_line); struct sieve_ast_argument *sieve_ast_argument_string_create (struct sieve_ast_node *node, const string_t *str, unsigned int source_line); + struct sieve_ast_argument *sieve_ast_argument_tag_create (struct sieve_ast_node *node, const char *tag, unsigned int source_line); + struct sieve_ast_argument *sieve_ast_argument_number_create (struct sieve_ast_node *node, unsigned int number, unsigned int source_line); diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c index 4dbd914be..58f712582 100644 --- a/src/lib-sieve/sieve-commands.c +++ b/src/lib-sieve/sieve-commands.c @@ -142,6 +142,71 @@ static bool arg_string_list_generate return FALSE; } +/* + * Abstract arguments + * + * (Generated by processing and not by parsing the grammar) + */ + +/* Catenated string */ + +struct sieve_arg_catenated_string { + struct sieve_ast_arg_list *str_parts; +}; + +struct sieve_arg_catenated_string *sieve_arg_catenated_string_create +(struct sieve_ast_argument *orig_arg) +{ + pool_t pool = sieve_ast_pool(orig_arg->ast); + struct sieve_ast_arg_list *arglist; + struct sieve_arg_catenated_string *catstr; + + arglist = sieve_ast_arg_list_create(pool); + + catstr = p_new(pool, struct sieve_arg_catenated_string, 1); + catstr->str_parts = arglist; + (orig_arg)->context = (void *) catstr; + + return catstr; +} + +void sieve_arg_catenated_string_add_element +(struct sieve_arg_catenated_string *catstr, + struct sieve_ast_argument *element) +{ + sieve_ast_arg_list_add(catstr->str_parts, element); +} + +#define _cat_string_first(catstr) __AST_LIST_FIRST((catstr)->str_parts) +#define _cat_string_count(catstr) __AST_LIST_COUNT((catstr)->str_parts) +#define _cat_string_next(item) __AST_LIST_NEXT(item) + +bool sieve_arg_catenated_string_generate +(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd) +{ + struct sieve_binary *sbin = cgenv->sbin; + struct sieve_arg_catenated_string *catstr = + (struct sieve_arg_catenated_string *) arg->context; + struct sieve_ast_argument *strpart; + + if ( _cat_string_count(catstr) == 1 ) + sieve_generate_argument(cgenv, _cat_string_first(catstr), cmd); + else { + sieve_opr_catenated_string_emit(sbin, _cat_string_count(catstr)); + + strpart = _cat_string_first(catstr); + while ( strpart != NULL ) { + if ( !sieve_generate_argument(cgenv, strpart, cmd) ) + return FALSE; + + strpart = _cat_string_next(strpart); + } + } + + return TRUE; +} + /* * Core tests and commands */ diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h index bcfd6c89c..710afed83 100644 --- a/src/lib-sieve/sieve-commands.h +++ b/src/lib-sieve/sieve-commands.h @@ -52,6 +52,20 @@ extern const struct sieve_argument number_argument; extern const struct sieve_argument string_argument; extern const struct sieve_argument string_list_argument; +/* Catenated string argument */ + +bool sieve_arg_catenated_string_generate + (const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg, + struct sieve_command_context *context); + +struct sieve_arg_catenated_string; + +struct sieve_arg_catenated_string *sieve_arg_catenated_string_create + (struct sieve_ast_argument *orig_arg); +void sieve_arg_catenated_string_add_element + (struct sieve_arg_catenated_string *strdata, + struct sieve_ast_argument *element); + /* * Command object */ -- GitLab