diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c index 1b83e518bd4747e6400b3bd504ee6c8b187be85d..6d1a98d8bca59d2b780a731cf4d1b49d0d08eddf 100644 --- a/src/lib-sieve/sieve-commands.c +++ b/src/lib-sieve/sieve-commands.c @@ -12,31 +12,35 @@ /* Default arguments implemented in this file */ static bool arg_number_generate -(struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + (struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *context); static bool arg_string_generate -(struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + (struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *context); +static bool arg_string_list_validate + (struct sieve_validator *validator, struct sieve_ast_argument **arg, + struct sieve_command_context *context); static bool arg_string_list_generate -(struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *context); + (struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *context); const struct sieve_argument number_argument = { "@number", NULL, NULL, NULL, arg_number_generate }; const struct sieve_argument string_argument = { "@string", NULL, NULL, NULL, arg_string_generate }; -const struct sieve_argument string_list_argument = - { "@string-list", NULL, NULL, NULL, arg_string_list_generate }; + +const struct sieve_argument string_list_argument = { + "@string-list", NULL, + arg_string_list_validate, + NULL, + arg_string_list_generate +}; static bool arg_number_generate (struct sieve_generator *generator, struct sieve_ast_argument *arg, struct sieve_command_context *context ATTR_UNUSED) { struct sieve_binary *sbin = sieve_generator_get_binary(generator); - - if ( sieve_ast_argument_type(arg) != SAAT_NUMBER ) { - return FALSE; - } sieve_opr_number_emit(sbin, sieve_ast_argument_number(arg)); @@ -49,56 +53,69 @@ static bool arg_string_generate { struct sieve_binary *sbin = sieve_generator_get_binary(generator); - if ( sieve_ast_argument_type(arg) != SAAT_STRING ) { - return FALSE; - } - sieve_opr_string_emit(sbin, sieve_ast_argument_str(arg)); return TRUE; } -static void emit_string_list_operand - (struct sieve_generator *generator, const struct sieve_ast_argument *strlist) +static bool arg_string_list_validate +(struct sieve_validator *validator, struct sieve_ast_argument **arg, + struct sieve_command_context *context) +{ + struct sieve_ast_argument *stritem; + + stritem = sieve_ast_strlist_first(*arg); + while ( stritem != NULL ) { + if ( !sieve_validator_argument_activate(validator, context, stritem, FALSE) ) + return FALSE; + + stritem = sieve_ast_strlist_next(stritem); + } + + return FALSE; +} + +static inline bool emit_string_list_operand +(struct sieve_generator *generator, const struct sieve_ast_argument *strlist, + struct sieve_command_context *context) { struct sieve_binary *sbin = sieve_generator_get_binary(generator); void *list_context; - const struct sieve_ast_argument *stritem; - - T_FRAME( - sieve_opr_stringlist_emit_start - (sbin, sieve_ast_strlist_count(strlist), &list_context); - - stritem = sieve_ast_strlist_first(strlist); - while ( stritem != NULL ) { - sieve_opr_stringlist_emit_item - (sbin, list_context, sieve_ast_strlist_str(stritem)); - stritem = sieve_ast_strlist_next(stritem); - } - - sieve_opr_stringlist_emit_end(sbin, list_context); - ); + struct sieve_ast_argument *stritem; + + sieve_opr_stringlist_emit_start + (sbin, sieve_ast_strlist_count(strlist), &list_context); + + stritem = sieve_ast_strlist_first(strlist); + while ( stritem != NULL ) { + if ( !sieve_generate_argument(generator, stritem, context) ) + return FALSE; + + stritem = sieve_ast_strlist_next(stritem); + } + + sieve_opr_stringlist_emit_end(sbin, list_context); + + return TRUE; } static bool arg_string_list_generate (struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *context ATTR_UNUSED) + struct sieve_command_context *context) { - struct sieve_binary *sbin = sieve_generator_get_binary(generator); - if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { - sieve_opr_string_emit(sbin, sieve_ast_argument_str(arg)); - - return TRUE; - + return ( sieve_generate_argument(generator, arg, context) ); + } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { + bool result = TRUE; + if ( sieve_ast_strlist_count(arg) == 1 ) - sieve_opr_string_emit(sbin, - sieve_ast_argument_str(sieve_ast_strlist_first(arg))); + return ( sieve_generate_argument + (generator, sieve_ast_strlist_first(arg), context) ); else - (void) emit_string_list_operand(generator, arg); + T_FRAME( result=emit_string_list_operand(generator, arg, context) ); - return TRUE; + return result; } return FALSE; diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index 88e026a482a702a0d7a819d6aea3bc0e065da354..9e5bd09ba08fc50428c558564411c7bf406d8b0f 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -193,6 +193,18 @@ inline sieve_size_t sieve_generator_emit_operation_ext /* Generator functions */ +bool sieve_generate_argument +(struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd) +{ + const struct sieve_argument *argument = arg->argument; + + if ( argument == NULL ) return FALSE; + + return ( argument->generate == NULL || + argument->generate(generator, arg, cmd) ); +} + bool sieve_generate_arguments(struct sieve_generator *generator, struct sieve_command_context *cmd, struct sieve_ast_argument **last_arg) { diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index 57fec8d524c880bf9ab29cdddd2161589edf3a01..979e118adb49550e7d3bcdfd344bccf862a90797 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -82,6 +82,9 @@ inline sieve_size_t sieve_generator_emit_string /* API */ +bool sieve_generate_argument +(struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd); bool sieve_generate_arguments(struct sieve_generator *generator, struct sieve_command_context *cmd, struct sieve_ast_argument **arg); bool sieve_generate_argument_parameters(struct sieve_generator *gentr, diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 87a9107d9f36024cce2c8cb4acb392af0cd37434..e8a6da6b4808929ec6695d194c369e7bfbe58933 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -105,7 +105,7 @@ struct sieve_validator *sieve_validator_create argument = &number_argument; validator->default_arguments[SAT_CONST_STRING]. argument = &string_argument; - validator->default_arguments[SAT_CONST_STRING_LIST]. + validator->default_arguments[SAT_STRING_LIST]. argument = &string_list_argument; /* Setup storage for extension contexts */ @@ -482,11 +482,7 @@ bool sieve_validator_argument_activate defarg = &validator->default_arguments[SAT_VAR_STRING]; break; case SAAT_STRING_LIST: - if ( validator->default_arguments[SAT_VAR_STRING_LIST].argument == NULL || - constant ) - defarg = &validator->default_arguments[SAT_CONST_STRING_LIST]; - else - defarg = &validator->default_arguments[SAT_VAR_STRING_LIST]; + defarg = &validator->default_arguments[SAT_STRING_LIST]; break; default: return FALSE; diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h index c3f7d2f61e8df19aaa91ee402b6aac9af3fa2656..ebfcf519c03c5b3f2f56e5eb27017d0a45d61f57 100644 --- a/src/lib-sieve/sieve-validator.h +++ b/src/lib-sieve/sieve-validator.h @@ -8,9 +8,8 @@ enum sieve_argument_type { SAT_NUMBER, SAT_CONST_STRING, - SAT_CONST_STRING_LIST, SAT_VAR_STRING, - SAT_VAR_STRING_LIST, + SAT_STRING_LIST, SAT_COUNT };