diff --git a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c index 6d02802985852ace3d09426f895436cf1898c4f4..650330e47a3d963eb1979a4a719bdfb358c59a85 100644 --- a/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c +++ b/src/lib-sieve/plugins/comparator-i-ascii-numeric/ext-cmp-i-ascii-numeric.c @@ -59,7 +59,6 @@ extern const struct sieve_comparator_extension i_ascii_numeric_comparator_ext; const struct sieve_comparator i_ascii_numeric_comparator = { "i;ascii-numeric", - SIEVE_COMPARATOR_CUSTOM, SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY, &i_ascii_numeric_comparator_ext, 0, @@ -70,8 +69,7 @@ const struct sieve_comparator i_ascii_numeric_comparator = { const struct sieve_comparator_extension i_ascii_numeric_comparator_ext = { &comparator_i_ascii_numeric_extension, - &i_ascii_numeric_comparator, - NULL + SIEVE_EXT_DEFINE_COMPARATOR(i_ascii_numeric_comparator) }; /* Load extension into validator */ diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c index 6fcb32a629c2ac789ef2dbdbeffbd28169a20f69..12b31e37330cb40e24b5fb7445d234abd4e2f3fc 100644 --- a/src/lib-sieve/plugins/regex/ext-regex.c +++ b/src/lib-sieve/plugins/regex/ext-regex.c @@ -78,9 +78,7 @@ bool mtch_regex_validate_context struct sieve_match_type_context *ctx, struct sieve_ast_argument *key_arg); const struct sieve_match_type regex_match_type = { - "regex", - SIEVE_MATCH_TYPE_CUSTOM, - TRUE, + "regex", TRUE, ®ex_match_extension, 0, NULL, @@ -92,8 +90,7 @@ const struct sieve_match_type regex_match_type = { const struct sieve_match_type_extension regex_match_extension = { ®ex_extension, - ®ex_match_type, - NULL + SIEVE_EXT_DEFINE_MATCH_TYPE(regex_match_type) }; /* Validation */ diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c index 12426b05f1e86114a828dacbafa934e8b38b0229..0d03d7ae44eb7405e7a9c24f263092d6a7bdb172 100644 --- a/src/lib-sieve/plugins/relational/ext-relational.c +++ b/src/lib-sieve/plugins/relational/ext-relational.c @@ -85,7 +85,7 @@ static bool ext_relational_load(int ext_id) /* Validation */ -static const struct sieve_match_type rel_match_types[]; +static const struct sieve_match_type *rel_match_types[]; static bool mtch_relational_validate (struct sieve_validator *validator, struct sieve_ast_argument **arg, @@ -177,8 +177,8 @@ static bool mtch_relational_validate ctx->ctx_data = (void *) rel_match; /* Override the actual match type with a parameter-specific one */ - ctx->match_type = &rel_match_types - [REL_MATCH_INDEX(ctx->match_type->ext_code, rel_match)]; + ctx->match_type = rel_match_types + [REL_MATCH_INDEX(ctx->match_type->code, rel_match)]; return TRUE; } @@ -190,7 +190,7 @@ static bool mtch_value_match const char *key, size_t key_size, int key_index ATTR_UNUSED) { const struct sieve_match_type *mtch = mctx->match_type; - unsigned int rel_match = REL_MATCH(mtch->ext_code); + unsigned int rel_match = REL_MATCH(mtch->code); int cmp_result = mctx->comparator-> compare(mctx->comparator, val, val_size, key, key_size); @@ -271,9 +271,7 @@ extern const struct sieve_match_type_extension relational_match_extension; /* Parameter-independent match type objects, only used during validation */ const struct sieve_match_type value_match_type = { - "value", - SIEVE_MATCH_TYPE_CUSTOM, - TRUE, + "value", TRUE, &relational_match_extension, RELATIONAL_VALUE, mtch_relational_validate, @@ -281,9 +279,7 @@ const struct sieve_match_type value_match_type = { }; const struct sieve_match_type count_match_type = { - "count", - SIEVE_MATCH_TYPE_CUSTOM, - FALSE, + "count", FALSE, &relational_match_extension, RELATIONAL_COUNT, mtch_relational_validate, @@ -296,58 +292,51 @@ const struct sieve_match_type count_match_type = { * not such a great idea. This needs more thought */ -#define VALUE_MATCH_TYPE(name, rel_match, func) { \ - "value-" name, \ - SIEVE_MATCH_TYPE_CUSTOM, \ - TRUE, \ - &relational_match_extension, \ - REL_MATCH_INDEX(RELATIONAL_VALUE, rel_match), \ - NULL, NULL, NULL, \ - mtch_value_match, \ - NULL \ - } +#define VALUE_MATCH_TYPE(name, rel_match) \ +const struct sieve_match_type rel_match_value_ ## name = { \ + "value-" #name, TRUE, \ + &relational_match_extension, \ + REL_MATCH_INDEX(RELATIONAL_VALUE, rel_match), \ + NULL, NULL, NULL, \ + mtch_value_match, \ + NULL \ +} -#define COUNT_MATCH_TYPE(name, rel_match, func) { \ - "count-" name, \ - SIEVE_MATCH_TYPE_CUSTOM, \ - FALSE, \ - &relational_match_extension, \ - REL_MATCH_INDEX(RELATIONAL_COUNT, rel_match), \ - NULL, NULL, \ - mtch_count_match_init, \ - mtch_count_match, \ - mtch_count_match_deinit \ - } +#define COUNT_MATCH_TYPE(name, rel_match) \ +const struct sieve_match_type rel_match_count_ ## name = { \ + "count-" #name, FALSE, \ + &relational_match_extension, \ + REL_MATCH_INDEX(RELATIONAL_COUNT, rel_match), \ + NULL, NULL, \ + mtch_count_match_init, \ + mtch_count_match, \ + mtch_count_match_deinit \ +} -static const struct sieve_match_type rel_match_types[] = { - VALUE_MATCH_TYPE("gt", REL_MATCH_GREATER, NULL), - VALUE_MATCH_TYPE("ge", REL_MATCH_GREATER_EQUAL, NULL), - VALUE_MATCH_TYPE("lt", REL_MATCH_LESS, NULL), - VALUE_MATCH_TYPE("le", REL_MATCH_LESS_EQUAL, NULL), - VALUE_MATCH_TYPE("eq", REL_MATCH_EQUAL, NULL), - VALUE_MATCH_TYPE("ne", REL_MATCH_NOT_EQUAL, NULL), - - COUNT_MATCH_TYPE("gt", REL_MATCH_GREATER, NULL), - COUNT_MATCH_TYPE("ge", REL_MATCH_GREATER_EQUAL, NULL), - COUNT_MATCH_TYPE("lt", REL_MATCH_LESS, NULL), - COUNT_MATCH_TYPE("le", REL_MATCH_LESS_EQUAL, NULL), - COUNT_MATCH_TYPE("eq", REL_MATCH_EQUAL, NULL), - COUNT_MATCH_TYPE("ne", REL_MATCH_NOT_EQUAL, NULL) +VALUE_MATCH_TYPE(gt, REL_MATCH_GREATER); +VALUE_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL); +VALUE_MATCH_TYPE(lt, REL_MATCH_LESS); +VALUE_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL); +VALUE_MATCH_TYPE(eq, REL_MATCH_EQUAL); +VALUE_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL); + +COUNT_MATCH_TYPE(gt, REL_MATCH_GREATER); +COUNT_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL); +COUNT_MATCH_TYPE(lt, REL_MATCH_LESS); +COUNT_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL); +COUNT_MATCH_TYPE(eq, REL_MATCH_EQUAL); +COUNT_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL); + +static const struct sieve_match_type *rel_match_types[] = { + &rel_match_value_gt, &rel_match_value_ge, &rel_match_value_lt, + &rel_match_value_le, &rel_match_value_eq, &rel_match_value_ne, + &rel_match_count_gt, &rel_match_count_ge, &rel_match_count_lt, + &rel_match_count_le, &rel_match_count_eq, &rel_match_count_ne }; -static const struct sieve_match_type *ext_relational_get_match - (unsigned int code) -{ - if ( code < N_ELEMENTS(rel_match_types) ) - return &rel_match_types[code]; - - return NULL; -} - const struct sieve_match_type_extension relational_match_extension = { &relational_extension, - NULL, - ext_relational_get_match + SIEVE_EXT_DEFINE_MATCH_TYPES(rel_match_types) }; /* Load extension into validator */ diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c index 180f0558acba440781e0f14990de7f360e9baaf0..2f24a38148bca46debefbd558907d8e739785fe0 100644 --- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c +++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c @@ -88,7 +88,6 @@ extern const struct sieve_address_part_extension subaddress_addrp_extension; const struct sieve_address_part user_address_part = { "user", - SIEVE_ADDRESS_PART_CUSTOM, &subaddress_addrp_extension, SUBADDRESS_USER, subaddress_user_extract_from @@ -96,31 +95,18 @@ const struct sieve_address_part user_address_part = { const struct sieve_address_part detail_address_part = { "detail", - SIEVE_ADDRESS_PART_CUSTOM, &subaddress_addrp_extension, SUBADDRESS_DETAIL, subaddress_detail_extract_from }; -static const struct sieve_address_part *ext_subaddress_get_part - (unsigned int code) -{ - switch ( code ) { - case SUBADDRESS_USER: - return &user_address_part; - case SUBADDRESS_DETAIL: - return &detail_address_part; - default: - break; - } - - return NULL; -} +const struct sieve_address_part *ext_subaddress_parts[] = { + &user_address_part, &detail_address_part +}; const struct sieve_address_part_extension subaddress_addrp_extension = { &subaddress_extension, - NULL, - ext_subaddress_get_part + SIEVE_EXT_DEFINE_ADDRESS_PARTS(ext_subaddress_parts) }; /* Load extension into validator */ diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index 0eeced2c3dcbbe279f804dc6d650229b9b9b2f56..c03fa2b536e12cad0fc718a66d6ee2a631b62024 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -27,8 +27,6 @@ */ static void opr_address_part_emit - (struct sieve_binary *sbin, const struct sieve_address_part *addrp); -static void opr_address_part_emit_ext (struct sieve_binary *sbin, const struct sieve_address_part *addrp, int ext_id); @@ -236,22 +234,20 @@ static bool tag_address_part_validate /* Code generation */ static void opr_address_part_emit -(struct sieve_binary *sbin, const struct sieve_address_part *addrp) -{ - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_ADDRESS_PART); - (void) sieve_binary_emit_byte(sbin, addrp->code); -} - -static void opr_address_part_emit_ext (struct sieve_binary *sbin, const struct sieve_address_part *addrp, int ext_id) { - unsigned char addrp_code = SIEVE_ADDRESS_PART_CUSTOM + - sieve_binary_extension_get_index(sbin, ext_id); - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_ADDRESS_PART); - (void) sieve_binary_emit_byte(sbin, addrp_code); - if ( addrp->extension->address_part == NULL ) - (void) sieve_binary_emit_byte(sbin, addrp->ext_code); + + if ( ext_id >= 0 ) { + sieve_size_t dummy; + + sieve_extension_emit_object + (addrp, address_parts, sbin, ext_id, SIEVE_ADDRESS_PART_CUSTOM, dummy); + + return; + } + + (void) sieve_binary_emit_byte(sbin, addrp->code); } /* FIXME: Duplicated */ @@ -271,26 +267,22 @@ const struct sieve_address_part *sieve_opr_address_part_read else return NULL; } else { - int ext_id = -1; - const struct sieve_address_part_extension *ap_ext; - - if ( sieve_binary_extension_get_by_index(sbin, - addrp_code - SIEVE_ADDRESS_PART_CUSTOM, &ext_id) == NULL ) - return NULL; + const struct sieve_address_part_extension *addrp_ext; + const struct sieve_address_part *addrp; + int ext_id = -1; + + if ( sieve_binary_extension_get_by_index + (sbin, addrp_code - SIEVE_ADDRESS_PART_CUSTOM, &ext_id) == NULL ) + return NULL; + + if ( (addrp_ext=sieve_address_part_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + sieve_extension_read_object + (addrp_ext, struct sieve_address_part, address_parts, sbin, address, + addrp) - ap_ext = sieve_address_part_extension_get(sbin, ext_id); - - if ( ap_ext != NULL ) { - unsigned int code; - if ( ap_ext->address_part != NULL ) - return ap_ext->address_part; - - if ( sieve_binary_read_byte(sbin, address, &code) && - ap_ext->get_part != NULL ) - return ap_ext->get_part(code); - } else { - i_info("Unknown address-part modifier %d.", addrp_code); - } + return addrp; } } @@ -324,11 +316,11 @@ static bool tag_address_part_generate if ( addrp->extension == NULL ) { if ( addrp->code < SIEVE_ADDRESS_PART_CUSTOM ) - opr_address_part_emit(sbin, addrp); + opr_address_part_emit(sbin, addrp, -1); else return FALSE; } else { - opr_address_part_emit_ext(sbin, addrp, adpctx->ext_id); + opr_address_part_emit(sbin, addrp, adpctx->ext_id); } return TRUE; @@ -477,25 +469,22 @@ static const char *addrp_localpart_extract_from const struct sieve_address_part all_address_part = { "all", - SIEVE_ADDRESS_PART_ALL, NULL, - 0, + SIEVE_ADDRESS_PART_ALL, addrp_all_extract_from }; const struct sieve_address_part local_address_part = { "localpart", - SIEVE_ADDRESS_PART_LOCAL, NULL, - 0, + SIEVE_ADDRESS_PART_LOCAL, addrp_localpart_extract_from }; const struct sieve_address_part domain_address_part = { "domain", - SIEVE_ADDRESS_PART_DOMAIN, NULL, - 0, + SIEVE_ADDRESS_PART_DOMAIN, addrp_domain_extract_from }; diff --git a/src/lib-sieve/sieve-address-parts.h b/src/lib-sieve/sieve-address-parts.h index 12368faf324439242f8563958e4b67613f9a4fd7..ff0365107d159b2e0e0b6cdbab397c690fcc304f 100644 --- a/src/lib-sieve/sieve-address-parts.h +++ b/src/lib-sieve/sieve-address-parts.h @@ -16,11 +16,9 @@ struct sieve_address_part_extension; struct sieve_address_part { const char *identifier; - - enum sieve_address_part_code code; - + const struct sieve_address_part_extension *extension; - unsigned int ext_code; + unsigned int code; const char *(*extract_from)(const struct message_address *address); }; @@ -28,14 +26,12 @@ struct sieve_address_part { struct sieve_address_part_extension { const struct sieve_extension *extension; - /* Either a single addr-part in this extension ... */ - const struct sieve_address_part *address_part; - - /* ... or multiple: then the extension must handle emit/read */ - const struct sieve_address_part *(*get_part) - (unsigned int code); + struct sieve_extension_obj_registry address_parts; }; +#define SIEVE_EXT_DEFINE_ADDRESS_PART(OP) SIEVE_EXT_DEFINE_OBJECT(OP) +#define SIEVE_EXT_DEFINE_ADDRESS_PARTS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) + struct sieve_address_part_context { struct sieve_command_context *command_ctx; const struct sieve_address_part *address_part; diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index b298ed1d8d6e44eb885be17503108c1ad2cb571e..e79e8acd9ea3fd9299863e9399250a88796f60c4 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -588,8 +588,16 @@ static struct sieve_coded_stringlist *opr_stringlist_read inline sieve_size_t sieve_operation_emit_code (struct sieve_binary *sbin, const struct sieve_operation *op, int ext_id) { - return sieve_extension_emit_operation - (op, sbin, ext_id, SIEVE_OPERATION_CUSTOM); + if ( ext_id >= 0 ) { + sieve_size_t address; + + sieve_extension_emit_object + (op, opcodes, sbin, ext_id, SIEVE_OPERATION_CUSTOM, address); + + return address; + } + + return sieve_binary_emit_byte(sbin, op->code); } const struct sieve_operation *sieve_operation_read @@ -604,8 +612,18 @@ const struct sieve_operation *sieve_operation_read else return NULL; } else { - return sieve_extension_read_operation - (opcode - SIEVE_OPERATION_CUSTOM, sbin, address); + struct sieve_operation *op; + int ext_id = -1; + const struct sieve_extension *ext; + + if ( (ext=sieve_binary_extension_get_by_index + (sbin, opcode - SIEVE_OPERATION_CUSTOM, &ext_id)) == NULL ) + return NULL; + + sieve_extension_read_object + (ext, struct sieve_operation, opcodes, sbin, address, op) + + return op; } } diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c index e1d33e37ebe54893a57e4e813e2d384b08f0deee..620d8c2fce55f503bfc950b39b0bb8cba6619602 100644 --- a/src/lib-sieve/sieve-comparators.c +++ b/src/lib-sieve/sieve-comparators.c @@ -26,8 +26,6 @@ extern const struct sieve_comparator *sieve_core_comparators[]; extern const unsigned int sieve_core_comparators_count; static void opr_comparator_emit - (struct sieve_binary *sbin, const struct sieve_comparator *cmp); -static void opr_comparator_emit_ext (struct sieve_binary *sbin, const struct sieve_comparator *cmp, int ext_id); static int cmp_i_octet_compare @@ -292,22 +290,20 @@ inline const struct sieve_comparator *sieve_comparator_tag_get /* Code generation */ static void opr_comparator_emit - (struct sieve_binary *sbin, const struct sieve_comparator *cmp) -{ - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_COMPARATOR); - (void) sieve_binary_emit_byte(sbin, cmp->code); -} - -static void opr_comparator_emit_ext (struct sieve_binary *sbin, const struct sieve_comparator *cmp, int ext_id) { - unsigned char cmp_code = SIEVE_COMPARATOR_CUSTOM + - sieve_binary_extension_get_index(sbin, ext_id); - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_COMPARATOR); - (void) sieve_binary_emit_byte(sbin, cmp_code); - if ( cmp->extension->comparator == NULL ) - (void) sieve_binary_emit_byte(sbin, cmp->ext_code); + + if ( ext_id >= 0 ) { + sieve_size_t dummy; + + sieve_extension_emit_object + (cmp, comparators, sbin, ext_id, SIEVE_COMPARATOR_CUSTOM, dummy); + + return; + } + + (void) sieve_binary_emit_byte(sbin, cmp->code); } const struct sieve_comparator *sieve_opr_comparator_read @@ -326,26 +322,21 @@ const struct sieve_comparator *sieve_opr_comparator_read else return NULL; } else { - int ext_id = -1; const struct sieve_comparator_extension *cmp_ext; + const struct sieve_comparator *cmp; + int ext_id = -1; + + if ( sieve_binary_extension_get_by_index + (sbin, cmp_code - SIEVE_COMPARATOR_CUSTOM, &ext_id) == NULL ) + return NULL; + + if ( (cmp_ext=sieve_comparator_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + sieve_extension_read_object + (cmp_ext, struct sieve_comparator, comparators, sbin, address, cmp) - if ( sieve_binary_extension_get_by_index(sbin, - cmp_code - SIEVE_COMPARATOR_CUSTOM, &ext_id) == NULL ) - return NULL; - - cmp_ext = sieve_comparator_extension_get(sbin, ext_id); - - if ( cmp_ext != NULL ) { - unsigned int code; - if ( cmp_ext->comparator != NULL ) - return cmp_ext->comparator; - - if ( sieve_binary_read_byte(sbin, address, &code) && - cmp_ext->get_comparator != NULL ) - return cmp_ext->get_comparator(code); - } else { - i_info("Unknown comparator %d.", cmp_code); - } + return cmp; } } @@ -379,11 +370,11 @@ static bool tag_comparator_generate if ( cmp->extension == NULL ) { if ( cmp->code < SIEVE_COMPARATOR_CUSTOM ) - opr_comparator_emit(sbin, cmp); + opr_comparator_emit(sbin, cmp, -1); else return FALSE; } else { - opr_comparator_emit_ext(sbin, cmp, cmpctx->ext_id); + opr_comparator_emit(sbin, cmp, cmpctx->ext_id); } return TRUE; @@ -395,11 +386,10 @@ static bool tag_comparator_generate const struct sieve_comparator i_octet_comparator = { "i;octet", - SIEVE_COMPARATOR_I_OCTET, SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY | SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH, NULL, - 0, + SIEVE_COMPARATOR_I_OCTET, cmp_i_octet_compare, cmp_i_octet_char_match, cmp_i_octet_char_skip @@ -407,11 +397,10 @@ const struct sieve_comparator i_octet_comparator = { const struct sieve_comparator i_ascii_casemap_comparator = { "i;ascii-casemap", - SIEVE_COMPARATOR_I_ASCII_CASEMAP, SIEVE_COMPARATOR_FLAG_ORDERING | SIEVE_COMPARATOR_FLAG_EQUALITY | SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH | SIEVE_COMPARATOR_FLAG_PREFIX_MATCH, NULL, - 0, + SIEVE_COMPARATOR_I_ASCII_CASEMAP, cmp_i_ascii_casemap_compare, cmp_i_ascii_casemap_char_match, cmp_i_octet_char_skip diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h index 61016ded7799299404edbd9865b7dae93fc63300..56bb5db5f386703cdfd678fde846665467f405ae 100644 --- a/src/lib-sieve/sieve-comparators.h +++ b/src/lib-sieve/sieve-comparators.h @@ -2,6 +2,7 @@ #define __SIEVE_COMPARATORS_H #include "sieve-common.h" +#include "sieve-extensions-private.h" enum sieve_comparator_code { SIEVE_COMPARATOR_I_OCTET, @@ -19,11 +20,10 @@ enum sieve_comparator_flags { struct sieve_comparator { const char *identifier; - enum sieve_comparator_code code; unsigned int flags; const struct sieve_comparator_extension *extension; - unsigned int ext_code; + unsigned int code; /* Equality and ordering */ @@ -43,14 +43,12 @@ struct sieve_comparator { struct sieve_comparator_extension { const struct sieve_extension *extension; - /* Either a single comparator in this extension ... */ - const struct sieve_comparator *comparator; - - /* ... or multiple: then the extension must handle emit/read */ - const struct sieve_comparator *(*get_comparator) - (unsigned int code); + struct sieve_extension_obj_registry comparators; }; +#define SIEVE_EXT_DEFINE_COMPARATOR(OP) SIEVE_EXT_DEFINE_OBJECT(OP) +#define SIEVE_EXT_DEFINE_COMPARATORS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) + struct sieve_comparator_context { struct sieve_command_context *command_ctx; const struct sieve_comparator *comparator; diff --git a/src/lib-sieve/sieve-extensions-private.h b/src/lib-sieve/sieve-extensions-private.h index 1e18dc3240a28945537512abcd8fd57ac25716dd..1fad34e71ae0239b8b659bb654098f6cce66549e 100644 --- a/src/lib-sieve/sieve-extensions-private.h +++ b/src/lib-sieve/sieve-extensions-private.h @@ -2,7 +2,6 @@ #define __SIEVE_EXTENSIONS_PRIVATE_H #include "sieve-common.h" -#include "sieve-code.h" #include "sieve-extensions.h" #include "sieve-binary.h" @@ -87,47 +86,13 @@ struct sieve_extension { }; /* - * Opcode access + * Opcodes and operands */ #define SIEVE_EXT_DEFINE_NO_OPERATIONS SIEVE_EXT_DEFINE_NO_OBJECTS #define SIEVE_EXT_DEFINE_OPERATION(OP) SIEVE_EXT_DEFINE_OBJECT(OP) #define SIEVE_EXT_DEFINE_OPERATIONS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) -static inline const struct sieve_operation *sieve_extension_read_operation -(unsigned int ext_code, struct sieve_binary *sbin, sieve_size_t *address) -{ - struct sieve_operation *op; - int ext_id = -1; - const struct sieve_extension *ext = sieve_binary_extension_get_by_index - (sbin, ext_code, &ext_id); - - sieve_extension_read_object - (ext, struct sieve_operation, opcodes, sbin, address, op) - - return op; -} - -static inline sieve_size_t sieve_extension_emit_operation -(const struct sieve_operation *op, struct sieve_binary *sbin, int ext_id, - unsigned int offset) -{ - if ( ext_id >= 0 ) { - sieve_size_t address; - - sieve_extension_emit_object - (op, opcodes, sbin, ext_id, offset, address); - - return address; - } - - return sieve_binary_emit_byte(sbin, op->code); -} - -/* - * Operand access - */ - #define SIEVE_EXT_DEFINE_NO_OPERANDS SIEVE_EXT_DEFINE_NO_OBJECTS /* diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index feece92ce49856baeb5237371d4f01f7d9b76533..732bce7b7e5a822f618e8ba43e35bfe5c391b7d0 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -25,8 +25,6 @@ */ static void opr_match_type_emit - (struct sieve_binary *sbin, const struct sieve_match_type *mtch); -static void opr_match_type_emit_ext (struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id); /* @@ -279,22 +277,21 @@ bool sieve_match_type_validate /* Code generation */ static void opr_match_type_emit - (struct sieve_binary *sbin, const struct sieve_match_type *mtch) -{ - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_MATCH_TYPE); - (void) sieve_binary_emit_byte(sbin, mtch->code); -} - -static void opr_match_type_emit_ext (struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id) { - unsigned char mtch_code = SIEVE_MATCH_TYPE_CUSTOM + - sieve_binary_extension_get_index(sbin, ext_id); - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_MATCH_TYPE); - (void) sieve_binary_emit_byte(sbin, mtch_code); - if ( mtch->extension->match_type == NULL ) - (void) sieve_binary_emit_byte(sbin, mtch->ext_code); + + if ( ext_id >= 0 ) { + sieve_size_t dummy; + + sieve_extension_emit_object + (mtch, match_types, sbin, ext_id, SIEVE_MATCH_TYPE_CUSTOM, dummy); + + return; + } + + (void) sieve_binary_emit_byte(sbin, mtch->code); + } const struct sieve_match_type *sieve_opr_match_type_read @@ -313,26 +310,21 @@ const struct sieve_match_type *sieve_opr_match_type_read else return NULL; } else { - int ext_id = -1; const struct sieve_match_type_extension *mtch_ext; + const struct sieve_match_type *mtch; + int ext_id = -1; + + if ( sieve_binary_extension_get_by_index + (sbin, mtch_code - SIEVE_MATCH_TYPE_CUSTOM, &ext_id) == NULL ) + return NULL; + + if ( (mtch_ext=sieve_match_type_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + sieve_extension_read_object + (mtch_ext, struct sieve_match_type, match_types, sbin, address, mtch) - if ( sieve_binary_extension_get_by_index(sbin, - mtch_code - SIEVE_MATCH_TYPE_CUSTOM, &ext_id) == NULL ) - return NULL; - - mtch_ext = sieve_match_type_extension_get(sbin, ext_id); - - if ( mtch_ext != NULL ) { - unsigned int code; - if ( mtch_ext->match_type != NULL ) - return mtch_ext->match_type; - - if ( sieve_binary_read_byte(sbin, address, &code) && - mtch_ext->get_match != NULL ) - return mtch_ext->get_match(code); - } else { - i_info("Unknown match-type modifier %d.", mtch_code); - } + return mtch; } } @@ -365,11 +357,11 @@ static bool tag_match_type_generate if ( mtctx->match_type->extension == NULL ) { if ( mtctx->match_type->code < SIEVE_MATCH_TYPE_CUSTOM ) - opr_match_type_emit(sbin, mtctx->match_type); + opr_match_type_emit(sbin, mtctx->match_type, -1); else return FALSE; } else { - opr_match_type_emit_ext(sbin, mtctx->match_type, mtctx->ext_id); + opr_match_type_emit(sbin, mtctx->match_type, mtctx->ext_id); } return TRUE; @@ -685,22 +677,18 @@ const struct sieve_argument match_type_tag = { }; const struct sieve_match_type is_match_type = { - "is", - SIEVE_MATCH_TYPE_IS, - TRUE, + "is", TRUE, NULL, - 0, + SIEVE_MATCH_TYPE_IS, NULL, NULL, NULL, mtch_is_match, NULL }; const struct sieve_match_type contains_match_type = { - "contains", - SIEVE_MATCH_TYPE_CONTAINS, - TRUE, + "contains", TRUE, NULL, - 0, + SIEVE_MATCH_TYPE_CONTAINS, NULL, mtch_contains_validate_context, NULL, @@ -709,11 +697,9 @@ const struct sieve_match_type contains_match_type = { }; const struct sieve_match_type matches_match_type = { - "matches", - SIEVE_MATCH_TYPE_MATCHES, - TRUE, + "matches", TRUE, NULL, - 0, + SIEVE_MATCH_TYPE_MATCHES, NULL, mtch_contains_validate_context, NULL, diff --git a/src/lib-sieve/sieve-match-types.h b/src/lib-sieve/sieve-match-types.h index 810992897e137bdb316b3221cc8a22d6b0b4639e..fc275f1188f969517e51466d2f5fe99ea18e534f 100644 --- a/src/lib-sieve/sieve-match-types.h +++ b/src/lib-sieve/sieve-match-types.h @@ -24,8 +24,6 @@ struct sieve_match_type_context; struct sieve_match_type { const char *identifier; - - enum sieve_match_type_code code; /* Match function called for every key value or should it be called once * for every tested value? (TRUE = first alternative) @@ -33,7 +31,7 @@ struct sieve_match_type { bool is_iterative; const struct sieve_match_type_extension *extension; - unsigned int ext_code; + unsigned int code; bool (*validate) (struct sieve_validator *validator, struct sieve_ast_argument **arg, @@ -52,14 +50,12 @@ struct sieve_match_type { struct sieve_match_type_extension { const struct sieve_extension *extension; - /* Either a single match-type in this extension ... */ - const struct sieve_match_type *match_type; - - /* ... or multiple: then the extension must handle emit/read */ - const struct sieve_match_type *(*get_match) - (unsigned int code); + struct sieve_extension_obj_registry match_types; }; +#define SIEVE_EXT_DEFINE_MATCH_TYPE(OP) SIEVE_EXT_DEFINE_OBJECT(OP) +#define SIEVE_EXT_DEFINE_MATCH_TYPES(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS) + struct sieve_match_type_context { struct sieve_command_context *command_ctx; const struct sieve_match_type *match_type;