From 3cc0395dd54eb32b0a479b44c451b0d5927cb78c Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Sun, 30 Dec 2007 03:35:40 +0100 Subject: [PATCH] Added variable operand to the variables extension. --- src/lib-sieve/plugins/variables/cmd-set.c | 1 + .../plugins/variables/ext-variables-common.c | 69 ++++++++++++++++- .../plugins/variables/ext-variables-common.h | 3 + .../plugins/variables/ext-variables.c | 6 +- src/lib-sieve/sieve-actions.c | 5 +- src/lib-sieve/sieve-address-parts.c | 5 +- src/lib-sieve/sieve-code.c | 75 ++++++------------- src/lib-sieve/sieve-code.h | 11 ++- src/lib-sieve/sieve-comparators.c | 5 +- src/lib-sieve/sieve-match-types.c | 5 +- 10 files changed, 118 insertions(+), 67 deletions(-) diff --git a/src/lib-sieve/plugins/variables/cmd-set.c b/src/lib-sieve/plugins/variables/cmd-set.c index 157cd69a0..4a2dae086 100644 --- a/src/lib-sieve/plugins/variables/cmd-set.c +++ b/src/lib-sieve/plugins/variables/cmd-set.c @@ -199,6 +199,7 @@ static bool cmd_set_operation_dump sieve_code_descend(denv); return + sieve_opr_string_dump(denv, address) && sieve_opr_string_dump(denv, address); } diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.c b/src/lib-sieve/plugins/variables/ext-variables-common.c index c21c7d1a0..ef8aa49e2 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.c +++ b/src/lib-sieve/plugins/variables/ext-variables-common.c @@ -1,10 +1,16 @@ #include "lib.h" #include "hash.h" +#include "str.h" #include "sieve-common.h" #include "sieve-ast.h" +#include "sieve-binary.h" +#include "sieve-code.h" #include "sieve-commands.h" #include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-code-dumper.h" +#include "sieve-interpreter.h" #include "ext-variables-common.h" @@ -127,7 +133,7 @@ static bool arg_variable_generate (struct sieve_generator *generator, struct sieve_ast_argument *arg, struct sieve_command_context *context); -const struct sieve_argument variable_argument = +const struct sieve_argument variable_argument = { "@variable", NULL, NULL, NULL, arg_variable_generate }; void ext_variables_variable_argument_activate @@ -146,11 +152,70 @@ void ext_variables_variable_argument_activate static bool arg_variable_generate (struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *context) + struct sieve_command_context *context ATTR_UNUSED) { + struct sieve_variable *var = (struct sieve_variable *) arg->context; + + ext_variables_variable_emit(sieve_generator_get_binary(generator), var); + return TRUE; } +/* Variable operands */ + +static bool opr_variable_read + (struct sieve_binary *sbin, sieve_size_t *address, string_t **str); +static bool opr_variable_dump + (const struct sieve_dumptime_env *denv, sieve_size_t *address); + +const struct sieve_opr_string_interface variable_interface = { + opr_variable_dump, + opr_variable_read +}; + +const struct sieve_operand variable_operand = { + "variable", + &variables_extension, 0, + &string_class, + &variable_interface +}; + +void ext_variables_variable_emit + (struct sieve_binary *sbin, struct sieve_variable *var) +{ + (void) sieve_operand_emit_code(sbin, &variable_operand, ext_variables_my_id); + (void) sieve_binary_emit_integer(sbin, var->index); +} + +static bool opr_variable_dump + (const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + sieve_size_t number = 0; + + if (sieve_binary_read_integer(denv->sbin, address, &number) ) { + sieve_code_dumpf(denv, "VARIABLE: %ld [?]", (long) number); + + return TRUE; + } + + return FALSE; +} + +static bool opr_variable_read + (struct sieve_binary *sbin, sieve_size_t *address, string_t **str) +{ + sieve_size_t number = 0; + + if (sieve_binary_read_integer(sbin, address, &number) ) { + *str = t_str_new(10); + str_append(*str, "VARIABLE"); + + return TRUE; + } + + return FALSE; +} + /* Set modifier registration */ const struct ext_variables_set_modifier *ext_variables_set_modifier_find diff --git a/src/lib-sieve/plugins/variables/ext-variables-common.h b/src/lib-sieve/plugins/variables/ext-variables-common.h index e8420cc18..5768717d0 100644 --- a/src/lib-sieve/plugins/variables/ext-variables-common.h +++ b/src/lib-sieve/plugins/variables/ext-variables-common.h @@ -41,6 +41,9 @@ const struct ext_variables_set_modifier *ext_variables_set_modifier_find /* Variables */ +void ext_variables_variable_emit + (struct sieve_binary *sbin, struct sieve_variable *var); + void ext_variables_variable_argument_activate (struct sieve_validator *validator, struct sieve_ast_argument *arg); diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c index e25fa996e..b3b2c0494 100644 --- a/src/lib-sieve/plugins/variables/ext-variables.c +++ b/src/lib-sieve/plugins/variables/ext-variables.c @@ -38,6 +38,10 @@ const struct sieve_operation *ext_variables_operations[] = { &cmd_set_operation, &tst_string_operation }; +/* Operands */ + +extern const struct sieve_operand variable_operand; + /* Extension definitions */ int ext_variables_my_id; @@ -48,7 +52,7 @@ struct sieve_extension variables_extension = { ext_variables_validator_load, NULL, NULL, NULL, SIEVE_EXT_DEFINE_OPERATIONS(ext_variables_operations), - SIEVE_EXT_DEFINE_NO_OPERANDS + SIEVE_EXT_DEFINE_OPERAND(variable_operand) }; static bool ext_variables_load(int ext_id) diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 12f336bcf..036eacea6 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -88,12 +88,13 @@ static bool seffect_binary_load(struct sieve_binary *sbin) */ static struct sieve_operand_class side_effect_class = - { "side-effect", NULL }; + { "side-effect" }; struct sieve_operand side_effect_operand = { "side-effect", NULL, SIEVE_OPERAND_SIDE_EFFECT, - &side_effect_class + &side_effect_class, + NULL }; void sieve_opr_side_effect_emit diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 6e1474372..42806dfc6 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -197,12 +197,13 @@ static bool addrp_binary_load(struct sieve_binary *sbin) */ struct sieve_operand_class address_part_class = - { "address-part", NULL }; + { "address-part" }; struct sieve_operand address_part_operand = { "address-part", NULL, SIEVE_OPERAND_ADDRESS_PART, - &address_part_class + &address_part_class, + NULL }; /* diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index f6c14515f..1dfa9dc67 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -119,11 +119,9 @@ bool sieve_coded_stringlist_read_all } /* - * Operands + * Core operands */ -/* Core operands */ - const struct sieve_operand number_operand; const struct sieve_operand string_operand; const struct sieve_operand stringlist_operand; @@ -149,7 +147,9 @@ const unsigned int sieve_operand_count = static struct sieve_extension_obj_registry oprd_default_reg = SIEVE_EXT_DEFINE_OPERANDS(sieve_operands); -/* Operand functions */ +/* + * Operand functions + */ inline sieve_size_t sieve_operand_emit_code (struct sieve_binary *sbin, const struct sieve_operand *opr, int ext_id) @@ -180,42 +180,6 @@ const struct sieve_operand *sieve_operand_read sieve_operand_registry_get); } -/* -inline sieve_size_t sieve_operand_emit_code - (struct sieve_binary *sbin, int operand) -{ - unsigned char op = operand; - - return sieve_binary_emit_byte(sbin, op); -} - -const struct sieve_operand *sieve_operand_read - (struct sieve_binary *sbin, sieve_size_t *address) -{ - unsigned int operand; - - if ( sieve_binary_read_byte(sbin, address, &operand) ) { - if ( operand < SIEVE_OPERAND_CUSTOM ) { - if ( operand < sieve_operand_count ) - return sieve_operands[operand]; - else - return NULL; - } else { -/ * int ext_id = -1; - const struct sieve_extension *ext = - sieve_binary_extension_get_by_index - (sbin, operand - SIEVE_OPERAND_CUSTOM, &ext_id); - - if ( ext != NULL ) - return ext->operand; - else * / - return NULL; - } - } - - return NULL; -}*/ - bool sieve_operand_optional_present (struct sieve_binary *sbin, sieve_size_t *address) { @@ -259,12 +223,13 @@ const struct sieve_opr_number_interface number_interface = { }; const struct sieve_operand_class number_class = - { "number", &number_interface }; + { "number" }; const struct sieve_operand number_operand = { "@number", NULL, SIEVE_OPERAND_NUMBER, - &number_class + &number_class, + &number_interface }; /* String */ @@ -280,12 +245,13 @@ const struct sieve_opr_string_interface string_interface ={ }; const struct sieve_operand_class string_class = - { "string", &string_interface }; + { "string" }; const struct sieve_operand string_operand = { "@string", NULL, SIEVE_OPERAND_STRING, - &string_class + &string_class, + &string_interface }; /* String List */ @@ -301,12 +267,13 @@ const struct sieve_opr_stringlist_interface stringlist_interface = { }; const struct sieve_operand_class stringlist_class = - { "string-list", &stringlist_interface }; + { "string-list" }; const struct sieve_operand stringlist_operand = { "@string-list", NULL, SIEVE_OPERAND_STRING_LIST, - &stringlist_class + &stringlist_class, + &stringlist_interface }; /* @@ -334,7 +301,7 @@ bool sieve_opr_number_dump if ( operand == NULL || operand->class != &number_class ) return FALSE; - intf = (const struct sieve_opr_number_interface *) operand->class->interface; + intf = (const struct sieve_opr_number_interface *) operand->interface; if ( intf->dump == NULL ) return FALSE; @@ -351,7 +318,7 @@ bool sieve_opr_number_read if ( operand == NULL || operand->class != &number_class ) return FALSE; - intf = (const struct sieve_opr_number_interface *) operand->class->interface; + intf = (const struct sieve_opr_number_interface *) operand->interface; if ( intf->read == NULL ) return FALSE; @@ -399,7 +366,7 @@ bool sieve_opr_string_dump if ( operand == NULL || operand->class != &string_class ) return FALSE; - intf = (const struct sieve_opr_string_interface *) operand->class->interface; + intf = (const struct sieve_opr_string_interface *) operand->interface; if ( intf->dump == NULL ) return FALSE; @@ -416,7 +383,7 @@ bool sieve_opr_string_read if ( operand == NULL || operand->class != &string_class ) return FALSE; - intf = (const struct sieve_opr_string_interface *) operand->class->interface; + intf = (const struct sieve_opr_string_interface *) operand->interface; if ( intf->read == NULL ) return FALSE; @@ -500,7 +467,7 @@ bool sieve_opr_stringlist_dump if ( operand->class == &stringlist_class ) { const struct sieve_opr_stringlist_interface *intf = - (const struct sieve_opr_stringlist_interface *) operand->class->interface; + (const struct sieve_opr_stringlist_interface *) operand->interface; if ( intf->dump == NULL ) return FALSE; @@ -508,7 +475,7 @@ bool sieve_opr_stringlist_dump return intf->dump(denv, address); } else if ( operand->class == &string_class ) { const struct sieve_opr_string_interface *intf = - (const struct sieve_opr_string_interface *) operand->class->interface; + (const struct sieve_opr_string_interface *) operand->interface; if ( intf->dump == NULL ) return FALSE; @@ -530,7 +497,7 @@ struct sieve_coded_stringlist *sieve_opr_stringlist_read if ( operand->class == &stringlist_class ) { const struct sieve_opr_stringlist_interface *intf = - (const struct sieve_opr_stringlist_interface *) operand->class->interface; + (const struct sieve_opr_stringlist_interface *) operand->interface; if ( intf->read == NULL ) return NULL; @@ -539,7 +506,7 @@ struct sieve_coded_stringlist *sieve_opr_stringlist_read } else if ( operand->class == &string_class ) { /* Special case, accept single string as string list as well. */ const struct sieve_opr_string_interface *intf = - (const struct sieve_opr_string_interface *) operand->class->interface; + (const struct sieve_opr_string_interface *) operand->interface; if ( intf->read == NULL || !intf->read(sbin, address, NULL) ) { printf("FAILED TO SKIP\n"); diff --git a/src/lib-sieve/sieve-code.h b/src/lib-sieve/sieve-code.h index a05d9074c..82eabe4f7 100644 --- a/src/lib-sieve/sieve-code.h +++ b/src/lib-sieve/sieve-code.h @@ -31,8 +31,6 @@ inline sieve_size_t sieve_coded_stringlist_get_current_offset struct sieve_operand_class { const char *name; - - const void *interface; }; struct sieve_operand { @@ -42,6 +40,7 @@ struct sieve_operand { unsigned int code; const struct sieve_operand_class *class; + const void *interface; }; struct sieve_opr_number_interface { @@ -78,6 +77,14 @@ enum sieve_core_operand { SIEVE_OPERAND_CUSTOM }; +const struct sieve_operand_class number_class; +const struct sieve_operand_class string_class; +const struct sieve_operand_class stringlist_class; + +extern const struct sieve_operand number_operand; +extern const struct sieve_operand string_operand; +extern const struct sieve_operand stringlist_operand; + extern const struct sieve_operand *sieve_operands[]; extern const unsigned int sieve_operand_count; diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c index e018663d8..6ab9de191 100644 --- a/src/lib-sieve/sieve-comparators.c +++ b/src/lib-sieve/sieve-comparators.c @@ -200,12 +200,13 @@ static bool cmp_binary_load(struct sieve_binary *sbin) */ struct sieve_operand_class comparator_class = - { "comparator", NULL }; + { "comparator" }; struct sieve_operand comparator_operand = { "comparator", NULL, SIEVE_OPERAND_COMPARATOR, - &comparator_class + &comparator_class, + NULL }; /* diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index 1cf22c434..e312de4cd 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -194,13 +194,14 @@ static bool mtch_binary_load(struct sieve_binary *sbin) */ struct sieve_operand_class match_type_class = - { "match-type", NULL }; + { "match-type" }; struct sieve_operand match_type_operand = { "match-type", NULL, SIEVE_OPERAND_MATCH_TYPE, - &match_type_class + &match_type_class, + NULL }; /* -- GitLab