From 286046df7d052dcb5c2936a82b03611b621ee682 Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sat, 27 Oct 2007 02:31:18 +0200 Subject: [PATCH] Changed argument to operand processing to be much more flexible. --- src/lib-sieve/ext-envelope.c | 22 ++--- src/lib-sieve/ext-fileinto.c | 11 +-- src/lib-sieve/ext-reject.c | 12 +-- src/lib-sieve/plugins/vacation/ext-vacation.c | 18 ++-- src/lib-sieve/sieve-binary.h | 5 +- src/lib-sieve/sieve-code.c | 48 +++++++++- src/lib-sieve/sieve-code.h | 17 +++- src/lib-sieve/sieve-commands.c | 94 ++++++++++++++++++ src/lib-sieve/sieve-commands.h | 17 ++-- src/lib-sieve/sieve-generator.c | 95 ++++--------------- src/lib-sieve/sieve-generator.h | 16 +--- src/lib-sieve/sieve-interpreter.c | 2 +- src/lib-sieve/sieve-validator.c | 38 +++++--- src/lib-sieve/sieve-validator.h | 6 +- src/lib-sieve/tst-address.c | 14 +-- src/lib-sieve/tst-exists.c | 10 +- src/lib-sieve/tst-header.c | 16 +--- src/lib-sieve/tst-size.c | 6 +- 18 files changed, 264 insertions(+), 183 deletions(-) diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 924d21657..791029b41 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -52,15 +52,14 @@ static bool tst_envelope_validate(struct sieve_validator *validator, struct siev !sieve_validate_command_subtests(validator, tst, 0) ) { return FALSE; } - - tst->data = (void *) arg; - + if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { sieve_command_validate_error(validator, tst, "the envelope test expects a string-list as first argument (envelope part), but %s was found", sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); arg = sieve_ast_argument_next(arg); if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { @@ -69,6 +68,7 @@ static bool tst_envelope_validate(struct sieve_validator *validator, struct siev sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -89,20 +89,12 @@ static bool ext_envelope_validator_load(struct sieve_validator *validator) static bool tst_envelope_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_ext_opcode(generator, &envelope_extension); - /* Emit envelope-part */ - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) - return FALSE; - - arg = sieve_ast_argument_next(arg); - - /* Emit key-list */ - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) - return FALSE; - + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; + return TRUE; } diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index 37a752776..20de6ef50 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -39,7 +39,8 @@ static bool cmd_fileinto_validate(struct sieve_validator *validator, struct siev return FALSE; } - cmd->data = (void *) arg; + + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -60,13 +61,11 @@ static bool ext_fileinto_validator_load(struct sieve_validator *validator) static bool cmd_fileinto_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_ext_opcode(generator, &fileinto_extension); - /* Emit folder string */ - if ( !sieve_generator_emit_string_argument(generator, arg) ) - return FALSE; + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; return TRUE; } diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index c98a82cf3..610d9a56f 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -39,8 +39,8 @@ static bool cmd_reject_validate(struct sieve_validator *validator, struct sieve_ return FALSE; } - - cmd->data = (void *) arg; + + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -61,13 +61,11 @@ static bool ext_reject_validator_load(struct sieve_validator *validator) static bool cmd_reject_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_ext_opcode(generator, &reject_extension); - /* Emit reason string */ - if ( !sieve_generator_emit_string_argument(generator, arg) ) - return FALSE; + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; return TRUE; } diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c index a24ffc338..9638e2e4a 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation.c +++ b/src/lib-sieve/plugins/vacation/ext-vacation.c @@ -198,8 +198,8 @@ static bool cmd_vacation_validate(struct sieve_validator *validator, struct siev /* Check valid syntax: * vacation [":days" number] [":subject" string] - * [":from" string] [":addresses" string-list] - * [":mime"] [":handle" string] <reason: string> + * [":from" string] [":addresses" string-list] + * [":mime"] [":handle" string] <reason: string> */ if ( !sieve_validate_command_arguments(validator, cmd, 1, &arg) || !sieve_validate_command_subtests(validator, cmd, 0) || @@ -207,8 +207,8 @@ static bool cmd_vacation_validate(struct sieve_validator *validator, struct siev return FALSE; } - - cmd->data = (void *) arg; + + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -229,14 +229,12 @@ static bool ext_vacation_validator_load(struct sieve_validator *validator) static bool cmd_vacation_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; - sieve_generator_emit_ext_opcode(generator, &vacation_extension); - /* Emit folder string */ - if ( !sieve_generator_emit_string_argument(generator, arg) ) - return FALSE; - + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; + return TRUE; } diff --git a/src/lib-sieve/sieve-binary.h b/src/lib-sieve/sieve-binary.h index f27b615df..f731deea8 100644 --- a/src/lib-sieve/sieve-binary.h +++ b/src/lib-sieve/sieve-binary.h @@ -1,8 +1,11 @@ #ifndef __SIEVE_BINARY_H #define __SIEVE_BINARY_H -#include "sieve-extensions.h" +#include "lib.h" +#include "str.h" + #include "sieve-code.h" +#include "sieve-extensions.h" struct sieve_binary; diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index b3c6ecde1..d1c13b5fa 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -1,11 +1,55 @@ -#include <stdio.h> +#include "lib.h" +#include "str.h" -#include "sieve-code.h" +#include "sieve-generator.h" #include "sieve-interpreter.h" +#include "sieve-code.h" + +#include <stdio.h> + /* Operands */ +void sieve_operand_number_emit(struct sieve_generator *generator, sieve_size_t number) { + (void) sieve_generator_emit_operand(generator, SIEVE_OPERAND_NUMBER); + (void) sieve_generator_emit_integer(generator, number); +} +void sieve_operand_string_emit(struct sieve_generator *generator, string_t *str) +{ + (void) sieve_generator_emit_operand(generator, SIEVE_OPERAND_STRING); + (void) sieve_generator_emit_string(generator, str); +} + +void sieve_operand_stringlist_emit_start + (struct sieve_generator *generator, unsigned int listlen, void **context) +{ + sieve_size_t *end_offset = t_new(sieve_size_t, 1); + + /* Emit byte identifying the type of operand */ + (void) sieve_generator_emit_operand(generator, SIEVE_OPERAND_STRING_LIST); + + /* Give the interpreter an easy way to skip over this string list */ + *end_offset = sieve_generator_emit_offset(generator, 0); + *context = (void *) end_offset; + + /* Emit the length of the list */ + (void) sieve_generator_emit_integer(generator, (int) listlen); +} + +void sieve_operand_stringlist_emit_item + (struct sieve_generator *generator, void *context ATTR_UNUSED, string_t *item) +{ + (void) sieve_generator_emit_string(generator, item); +} + +void sieve_operand_stringlist_emit_end + (struct sieve_generator *generator, void *context) +{ + sieve_size_t *end_offset = (sieve_size_t *) context; + + (void) sieve_generator_resolve_offset(generator, *end_offset); +} /* Opcodes */ diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index c3a2041c1..56389a84d 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -34,8 +34,11 @@ extern const unsigned int sieve_opcode_count; /* Operand: argument to and opcode */ struct sieve_operand { + /* Code generator */ + bool (*emit)(struct sieve_generator *generator, struct sieve_ast_argument *arg); + + /* Interpreter */ bool (*dump)(struct sieve_interpreter *interpreter); - bool (*execute)(struct sieve_interpreter *interpreter); }; enum sieve_core_operand { @@ -47,10 +50,18 @@ enum sieve_core_operand { SIEVE_OPERAND_ADDR_PART }; +void sieve_operand_number_emit(struct sieve_generator *generator, sieve_size_t number); +void sieve_operand_string_emit(struct sieve_generator *generator, string_t *str); +void sieve_operand_stringlist_emit_start + (struct sieve_generator *generator, unsigned int listlen, void **context); +void sieve_operand_stringlist_emit_item + (struct sieve_generator *generator, void *context ATTR_UNUSED, string_t *item); +void sieve_operand_stringlist_emit_end + (struct sieve_generator *generator, void *context); + #define SIEVE_OPCODE_CORE_MASK 0x1F #define SIEVE_OPCODE_EXT_OFFSET (SIEVE_OPCODE_CORE_MASK + 1) -#define SIEVE_CORE_OPERAND_MASK 0x0F -#define SIEVE_CORE_OPERAND_BITS 4 +#define SIEVE_OPERAND_CORE_MASK 0x1F #endif diff --git a/src/lib-sieve/sieve-commands.c b/src/lib-sieve/sieve-commands.c index a9959202b..d5030d2df 100644 --- a/src/lib-sieve/sieve-commands.c +++ b/src/lib-sieve/sieve-commands.c @@ -8,6 +8,100 @@ #include "sieve-commands-private.h" #include "sieve-interpreter.h" +/* 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); +static bool arg_string_generate(struct sieve_generator *generator, 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); + +const struct sieve_argument number_argument = + { "@number", NULL, arg_number_generate }; +const struct sieve_argument string_argument = + { "@string", NULL, arg_string_generate }; +const struct sieve_argument string_list_argument = + { "@string-list", 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) +{ + if ( sieve_ast_argument_type(*arg) != SAAT_NUMBER ) { + return FALSE; + } + + sieve_operand_number_emit(generator, sieve_ast_argument_number(*arg)); + + *arg = sieve_ast_argument_next(*arg); + + return TRUE; +} + +static bool arg_string_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, + struct sieve_command_context *context ATTR_UNUSED) +{ + if ( sieve_ast_argument_type(*arg) != SAAT_STRING ) { + return FALSE; + } + + sieve_operand_string_emit(generator, sieve_ast_argument_str(*arg)); + + *arg = sieve_ast_argument_next(*arg); + return TRUE; +} + +static void emit_string_list_operand + (struct sieve_generator *generator, const struct sieve_ast_argument *strlist) +{ + void *list_context; + const struct sieve_ast_argument *stritem; + + t_push(); + + printf("STRLIST: %d\n", sieve_ast_strlist_count(strlist)); + sieve_operand_stringlist_emit_start + (generator, sieve_ast_strlist_count(strlist), &list_context); + + stritem = sieve_ast_strlist_first(strlist); + while ( stritem != NULL ) { + sieve_operand_stringlist_emit_item + (generator, list_context, sieve_ast_strlist_str(stritem)); + printf("STR: %s\n", sieve_ast_strlist_strc(stritem)); + stritem = sieve_ast_strlist_next(stritem); + } + + sieve_operand_stringlist_emit_end + (generator, list_context); + + t_pop(); +} + +static bool arg_string_list_generate(struct sieve_generator *generator, struct sieve_ast_argument **arg, + struct sieve_command_context *context ATTR_UNUSED) +{ + if ( sieve_ast_argument_type(*arg) == SAAT_STRING ) { + + sieve_operand_string_emit(generator, sieve_ast_argument_str(*arg)); + + *arg = sieve_ast_argument_next(*arg); + return TRUE; + + } else if ( sieve_ast_argument_type(*arg) == SAAT_STRING_LIST ) { + + if ( sieve_ast_strlist_count(*arg) == 1 ) + sieve_operand_string_emit(generator, + sieve_ast_argument_str(sieve_ast_strlist_first(*arg))); + else + (void) emit_string_list_operand(generator, *arg); + + *arg = sieve_ast_argument_next(*arg); + return TRUE; + } + + return FALSE; +} + /* Trivial commands implemented in this file */ const struct sieve_command sieve_core_tests[] = { diff --git a/src/lib-sieve/sieve-commands.h b/src/lib-sieve/sieve-commands.h index 42a9efb55..128289ba4 100644 --- a/src/lib-sieve/sieve-commands.h +++ b/src/lib-sieve/sieve-commands.h @@ -1,5 +1,5 @@ -#ifndef __SIEVE_COMMANDS_H__ -#define __SIEVE_COMMANDS_H__ +#ifndef __SIEVE_COMMANDS_H +#define __SIEVE_COMMANDS_H #include "lib.h" @@ -8,10 +8,7 @@ #include "sieve-validator.h" #include "sieve-generator.h" -struct sieve_test_context; -struct sieve_command_context; - -/* Command */ +/* Argument */ struct sieve_argument { const char *identifier; @@ -22,6 +19,12 @@ struct sieve_argument { struct sieve_command_context *context); }; +extern const struct sieve_argument number_argument; +extern const struct sieve_argument string_argument; +extern const struct sieve_argument string_list_argument; + +/* Command */ + enum sieve_command_type { SCT_COMMAND, SCT_TEST @@ -63,4 +66,4 @@ const char *sieve_command_type_name(const struct sieve_command *command); struct sieve_command_context *sieve_command_prev_context (struct sieve_command_context *context); -#endif /* __SIEVE_COMMANDS_H__ */ +#endif /* __SIEVE_COMMANDS_H */ diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index 5a58a3650..29aa55555 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -127,90 +127,22 @@ inline sieve_size_t sieve_generator_emit_integer(struct sieve_generator *generat return sieve_binary_emit_integer(generator->binary, integer); } -inline static sieve_size_t sieve_generator_emit_string_item(struct sieve_generator *generator, const string_t *str) +inline sieve_size_t sieve_generator_emit_string(struct sieve_generator *generator, const string_t *str) { return sieve_binary_emit_string(generator->binary, str); } -/* Operand emission */ +/* Emit operands */ -sieve_size_t sieve_generator_emit_number(struct sieve_generator *generator, sieve_size_t number) +sieve_size_t sieve_generator_emit_operand + (struct sieve_generator *generator, int operand) { - sieve_size_t address = sieve_binary_emit_byte(generator->binary, SIEVE_OPERAND_NUMBER); - - (void) sieve_generator_emit_integer(generator, number); - - return address; -} - -sieve_size_t sieve_generator_emit_string(struct sieve_generator *generator, const string_t *str) -{ - sieve_size_t address = sieve_binary_emit_byte(generator->binary, SIEVE_OPERAND_STRING); - - (void) sieve_generator_emit_string_item(generator, str); - - return address; -} - -bool sieve_generator_emit_stringlist_argument - (struct sieve_generator *generator, struct sieve_ast_argument *arg) -{ - if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { - (void) sieve_generator_emit_string(generator, sieve_ast_argument_str(arg)); - return TRUE; - } else if ( sieve_ast_argument_type(arg) == SAAT_STRING_LIST ) { - if ( sieve_ast_strlist_count(arg) == 1 ) - sieve_generator_emit_string(generator, - sieve_ast_argument_str(sieve_ast_strlist_first(arg))); - else - (void) sieve_generator_emit_string_list(generator, arg); - return TRUE; - } + unsigned char op = operand & SIEVE_OPERAND_CORE_MASK; - return FALSE; -} - -bool sieve_generator_emit_string_argument - (struct sieve_generator *generator, struct sieve_ast_argument *arg) -{ - if ( sieve_ast_argument_type(arg) == SAAT_STRING ) { - (void) sieve_generator_emit_string(generator, sieve_ast_argument_str(arg)); - return TRUE; - } - - return FALSE; -} - -sieve_size_t sieve_generator_emit_string_list - (struct sieve_generator *generator, const struct sieve_ast_argument *strlist) -{ - sieve_size_t address; - const struct sieve_ast_argument *stritem; - unsigned int listlen = sieve_ast_strlist_count(strlist); - sieve_size_t end_offset = 0; - - /* Emit byte identifying the type of operand */ - address = sieve_binary_emit_byte(generator->binary, SIEVE_OPERAND_STRING_LIST); - - /* Give the interpreter an easy way to skip over this string list */ - end_offset = sieve_generator_emit_offset(generator, 0); - - /* Emit the length of the list */ - (void) sieve_generator_emit_integer(generator, (int) listlen); - - stritem = sieve_ast_strlist_first(strlist); - while ( stritem != NULL ) { - (void) sieve_generator_emit_string_item(generator, sieve_ast_strlist_str(stritem)); - - stritem = sieve_ast_strlist_next(stritem); - } - - (void) sieve_generator_resolve_offset(generator, end_offset); - - return address; + return sieve_binary_emit_byte(generator->binary, op); } -/* Emit commands */ +/* Emit opcodes */ sieve_size_t sieve_generator_emit_opcode (struct sieve_generator *generator, int opcode) @@ -231,19 +163,24 @@ sieve_size_t sieve_generator_emit_ext_opcode /* Generator functions */ bool sieve_generate_arguments(struct sieve_generator *generator, - struct sieve_command_context *cmd, struct sieve_ast_argument **arg) + struct sieve_command_context *cmd, struct sieve_ast_argument **last_arg) { + struct sieve_ast_argument *arg = sieve_ast_argument_first(cmd->ast_node); + /* Parse all arguments with assigned generator function */ - while ( *arg != NULL && (*arg)->argument != NULL) { - const struct sieve_argument *argument = (*arg)->argument; + while ( arg != NULL && arg->argument != NULL) { + const struct sieve_argument *argument = arg->argument; /* Call the generation function for the argument */ if ( argument->generate != NULL ) { - if ( !argument->generate(generator, arg, cmd) ) + if ( !argument->generate(generator, &arg, cmd) ) return FALSE; } else break; } + if ( last_arg != NULL ) + *last_arg = arg; + return TRUE; } diff --git a/src/lib-sieve/sieve-generator.h b/src/lib-sieve/sieve-generator.h index 1ded70727..0079b5834 100644 --- a/src/lib-sieve/sieve-generator.h +++ b/src/lib-sieve/sieve-generator.h @@ -31,6 +31,8 @@ inline void sieve_generator_update_data (struct sieve_generator *generator, sieve_size_t address, void *data, sieve_size_t size); inline sieve_size_t sieve_generator_get_current_address(struct sieve_generator *generator); +sieve_size_t sieve_generator_emit_operand + (struct sieve_generator *generator, int operand); sieve_size_t sieve_generator_emit_opcode (struct sieve_generator *generator, int opcode); sieve_size_t sieve_generator_emit_ext_opcode @@ -45,21 +47,9 @@ inline void sieve_generator_resolve_offset(struct sieve_generator *generator, si inline sieve_size_t sieve_generator_emit_integer (struct sieve_generator *generator, sieve_size_t integer); - -/* Operand emission */ - -sieve_size_t sieve_generator_emit_number - (struct sieve_generator *generator, sieve_size_t number); -sieve_size_t sieve_generator_emit_string +inline sieve_size_t sieve_generator_emit_string (struct sieve_generator *generator, const string_t *str); -sieve_size_t sieve_generator_emit_string_list - (struct sieve_generator *generator, const struct sieve_ast_argument *strlist); -bool sieve_generator_emit_string_argument - (struct sieve_generator *generator, struct sieve_ast_argument *arg); -bool sieve_generator_emit_stringlist_argument - (struct sieve_generator *generator, struct sieve_ast_argument *arg); - /* AST generation API */ bool sieve_generate_arguments(struct sieve_generator *generator, struct sieve_command_context *cmd, struct sieve_ast_argument **arg); diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index a1702edfb..771dcadcc 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -472,7 +472,7 @@ bool sieve_interpreter_dump_operand printf("%08x: ", interpreter->pc); CODE_JUMP(interpreter, 1); - if ( opcode < SIEVE_CORE_OPERAND_MASK ) { + if ( opcode < SIEVE_OPERAND_CORE_MASK ) { switch (opcode) { case SIEVE_OPERAND_NUMBER: sieve_interpreter_dump_number(interpreter); diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index 22b501d8c..51e8ef50f 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -269,15 +269,12 @@ static bool sieve_validate_match_type_tag struct sieve_ast_argument **arg, struct sieve_command_context *cmd ATTR_UNUSED) { - /* Skip tag */ - *arg = sieve_ast_argument_next(*arg); - - /* Syntax: * ":is" / ":contains" / ":matches" */ - - /* FIXME: Set appropriate setting somewhere */ + + /* Not implemented, so delete it */ + *arg = sieve_ast_arguments_delete(*arg, 1); return TRUE; } @@ -304,15 +301,13 @@ static bool sieve_validate_address_part_tag struct sieve_ast_argument **arg, struct sieve_command_context *cmd ATTR_UNUSED) { - /* Skip argument */ - *arg = sieve_ast_argument_next(*arg); - /* Syntax: * ":localpart" / ":domain" / ":all" */ - /* FIXME: Set appropriate setting somewhere */ - + /* Not implemented, so delete it */ + *arg = sieve_ast_arguments_delete(*arg, 1); + return TRUE; } @@ -421,6 +416,27 @@ bool sieve_validate_command_arguments return TRUE; } + +void sieve_validator_argument_activate + (struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument *arg) +{ + switch ( sieve_ast_argument_type(arg) ) { + case SAAT_NUMBER: + arg->argument = &number_argument; + break; + case SAAT_STRING: + arg->argument = &string_argument; + break; + case SAAT_STRING_LIST: + arg->argument = &string_list_argument; + break; + case SAAT_TAG: + i_error("!!BUG!!: sieve_validator_argument_activate: cannot activate tagged argument."); + break; + default: + break; + } +} /* Command Validation API */ diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h index 9ee059aee..e3aaf3b80 100644 --- a/src/lib-sieve/sieve-validator.h +++ b/src/lib-sieve/sieve-validator.h @@ -45,10 +45,14 @@ void sieve_validator_link_match_type_tags void sieve_validator_link_address_part_tags (struct sieve_validator *validator, struct sieve_command_registration *cmd_reg); -/* Command validation */ +/* Argument validation */ bool sieve_validate_command_arguments (struct sieve_validator *validator, struct sieve_command_context *tst, const unsigned int count, struct sieve_ast_argument **first_positional); +void sieve_validator_argument_activate + (struct sieve_validator *validator, struct sieve_ast_argument *arg); + +/* Command validation */ bool sieve_validate_command_subtests (struct sieve_validator *validator, struct sieve_command_context *cmd, const unsigned int count); bool sieve_validate_command_block(struct sieve_validator *validator, struct sieve_command_context *cmd, diff --git a/src/lib-sieve/tst-address.c b/src/lib-sieve/tst-address.c index ed849e8a6..e7957f506 100644 --- a/src/lib-sieve/tst-address.c +++ b/src/lib-sieve/tst-address.c @@ -48,6 +48,7 @@ bool tst_address_validate(struct sieve_validator *validator, struct sieve_comman sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); arg = sieve_ast_argument_next(arg); if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { @@ -56,6 +57,7 @@ bool tst_address_validate(struct sieve_validator *validator, struct sieve_comman sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -64,18 +66,12 @@ bool tst_address_validate(struct sieve_validator *validator, struct sieve_comman bool tst_address_generate (struct sieve_generator *generator, - struct sieve_command_context *ctx ATTR_UNUSED) + struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; sieve_generator_emit_opcode(generator, SIEVE_OPCODE_ADDRESS); - /* Emit header names */ - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) - return FALSE; - - /* Emit key list */ - arg = sieve_ast_argument_next(arg); - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) return FALSE; return TRUE; diff --git a/src/lib-sieve/tst-exists.c b/src/lib-sieve/tst-exists.c index 30f8b25f6..1d08e7081 100644 --- a/src/lib-sieve/tst-exists.c +++ b/src/lib-sieve/tst-exists.c @@ -34,6 +34,7 @@ bool tst_exists_validate(struct sieve_validator *validator, struct sieve_command sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); tst->data = arg; @@ -46,12 +47,11 @@ bool tst_exists_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; sieve_generator_emit_opcode(generator, SIEVE_OPCODE_EXISTS); - - /* Emit header names */ - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) - return FALSE; + + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; return TRUE; } diff --git a/src/lib-sieve/tst-header.c b/src/lib-sieve/tst-header.c index 3c29357a6..164e958a9 100644 --- a/src/lib-sieve/tst-header.c +++ b/src/lib-sieve/tst-header.c @@ -39,14 +39,13 @@ bool tst_header_validate(struct sieve_validator *validator, struct sieve_command !sieve_validate_command_subtests(validator, tst, 0) ) return FALSE; - tst->data = arg; - if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { sieve_command_validate_error(validator, tst, "the header test expects a string-list as first argument (header names), but %s was found", sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); arg = sieve_ast_argument_next(arg); if ( sieve_ast_argument_type(arg) != SAAT_STRING && sieve_ast_argument_type(arg) != SAAT_STRING_LIST ) { @@ -55,6 +54,7 @@ bool tst_header_validate(struct sieve_validator *validator, struct sieve_command sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -64,18 +64,12 @@ bool tst_header_validate(struct sieve_validator *validator, struct sieve_command bool tst_header_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = (struct sieve_ast_argument *) ctx->data; sieve_generator_emit_opcode(generator, SIEVE_OPCODE_HEADER); - /* Emit header names */ - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) - return FALSE; + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; - /* Emit key list */ - arg = sieve_ast_argument_next(arg); - if ( !sieve_generator_emit_stringlist_argument(generator, arg) ) - return FALSE; - return TRUE; } diff --git a/src/lib-sieve/tst-size.c b/src/lib-sieve/tst-size.c index 4a1bb8288..4af67cb98 100644 --- a/src/lib-sieve/tst-size.c +++ b/src/lib-sieve/tst-size.c @@ -116,6 +116,7 @@ bool tst_size_validate(struct sieve_validator *validator, struct sieve_command_c sieve_ast_argument_name(arg)); return FALSE; } + sieve_validator_argument_activate(validator, arg); return TRUE; } @@ -126,7 +127,6 @@ bool tst_size_generate (struct sieve_generator *generator, struct sieve_command_context *ctx) { - struct sieve_ast_argument *arg = sieve_ast_argument_first(ctx->ast_node); struct tst_size_context_data *ctx_data = (struct tst_size_context_data *) ctx->data; if ( ctx_data->type == SIZE_OVER ) @@ -134,7 +134,9 @@ bool tst_size_generate else sieve_generator_emit_opcode(generator, SIEVE_OPCODE_SIZEUNDER); - sieve_generator_emit_number(generator, sieve_ast_argument_number(arg)); + /* Generate arguments */ + if ( !sieve_generate_arguments(generator, ctx, NULL) ) + return FALSE; return TRUE; } -- GitLab