diff --git a/sieve/tests/address-part.sieve b/sieve/tests/address-part.sieve index fbe58b6b5bae85af03065f7778835d16ce60ba2b..1bc36eb8ba56e8eaa03faa2ddf71b7011503aedc 100644 --- a/sieve/tests/address-part.sieve +++ b/sieve/tests/address-part.sieve @@ -1,7 +1,7 @@ if address :comparator "i;octet" :domain "from" "STEPHAN" { discard; - if address :domain :comparator "i;octet" "from" "drunksnipers.com" { + if address :localpart :comparator "i;octet" "from" "drunksnipers.com" { keep; } stop; diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c index 8733ec93abf6a4db4a987d22cbc362702dc930b1..23608ea468187dc2b36b96107c82c7271a10cc9f 100644 --- a/src/lib-sieve/ext-encoded-character.c +++ b/src/lib-sieve/ext-encoded-character.c @@ -11,7 +11,7 @@ #include "lib.h" #include "unichar.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 641eeaccb3d894c2ca0270c3dd370f50dc60a4c8..00bc1457a7adc4374560d5cf23759053923427ff 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -13,7 +13,7 @@ #include "lib.h" #include "array.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-comparators.h" diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index e4e3c5b76335fe356b094d4f9ee75bc626bb445d..8dcc093fb129e41ef98e9abfd52e4b4c456c1c4a 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -10,7 +10,7 @@ #include <stdio.h> -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-actions.h" diff --git a/src/lib-sieve/ext-reject.c b/src/lib-sieve/ext-reject.c index 88765aa37fa114dec6e761946ffc21746f554e0f..41a38aef13fcf3e855fb0986db9c23831ca594e0 100644 --- a/src/lib-sieve/ext-reject.c +++ b/src/lib-sieve/ext-reject.c @@ -16,7 +16,7 @@ #include "istream.h" #include "istream-header-filter.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-code.h" #include "sieve-actions.h" diff --git a/src/lib-sieve/plugins/body/ext-body.c b/src/lib-sieve/plugins/body/ext-body.c index 8fba4e08b81ba7aa0420979b1389581317fec118..0a3218d5033b10a25fda5d6a9fff55d3d79a4480 100644 --- a/src/lib-sieve/plugins/body/ext-body.c +++ b/src/lib-sieve/plugins/body/ext-body.c @@ -27,7 +27,7 @@ #include "lib.h" #include "array.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" 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 650330e47a3d963eb1979a4a719bdfb358c59a85..99f7b89e45378ee3e983353c7373df1124514a83 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 @@ -11,7 +11,7 @@ #include "sieve-common.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-comparators.h" #include "sieve-validator.h" #include "sieve-generator.h" diff --git a/src/lib-sieve/plugins/copy/ext-copy.c b/src/lib-sieve/plugins/copy/ext-copy.c index f25cf894afcf15cdd0ea0689095328e2a75a4698..a674bf151daecd9913617430ce3f7861c73c62f6 100644 --- a/src/lib-sieve/plugins/copy/ext-copy.c +++ b/src/lib-sieve/plugins/copy/ext-copy.c @@ -13,7 +13,7 @@ #include "sieve-common.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-actions.h" #include "sieve-commands.h" #include "sieve-validator.h" diff --git a/src/lib-sieve/plugins/imapflags/tag-flags.c b/src/lib-sieve/plugins/imapflags/tag-flags.c index b1f061a8a05427afc0228d9445d1b4c8d1904cb7..989902bee02f0b7ebacff14ae1bc23a3f8a5ca42 100644 --- a/src/lib-sieve/plugins/imapflags/tag-flags.c +++ b/src/lib-sieve/plugins/imapflags/tag-flags.c @@ -3,7 +3,7 @@ #include "mail-storage.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-result.h" #include "sieve-validator.h" diff --git a/src/lib-sieve/plugins/include/ext-include.c b/src/lib-sieve/plugins/include/ext-include.c index 622ba1d2bc5d6da5061ef5fd599b3551978dcda5..b914869e75c7d67cf16b2e569a4374dc1f94d089 100644 --- a/src/lib-sieve/plugins/include/ext-include.c +++ b/src/lib-sieve/plugins/include/ext-include.c @@ -21,7 +21,7 @@ #include "sieve-common.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-validator.h" #include "sieve-generator.h" #include "sieve-interpreter.h" diff --git a/src/lib-sieve/plugins/regex/ext-regex.c b/src/lib-sieve/plugins/regex/ext-regex.c index 12b31e37330cb40e24b5fb7445d234abd4e2f3fc..b5270c3a16c4b9920c993a42c5e826c412a5c235 100644 --- a/src/lib-sieve/plugins/regex/ext-regex.c +++ b/src/lib-sieve/plugins/regex/ext-regex.c @@ -21,7 +21,7 @@ #include "sieve-common.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" diff --git a/src/lib-sieve/plugins/relational/ext-relational.c b/src/lib-sieve/plugins/relational/ext-relational.c index 0d03d7ae44eb7405e7a9c24f263092d6a7bdb172..1a886ef2f4ac91849e26d4ec64999eb7be9c2101 100644 --- a/src/lib-sieve/plugins/relational/ext-relational.c +++ b/src/lib-sieve/plugins/relational/ext-relational.c @@ -23,7 +23,7 @@ #include "sieve-ast.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-comparators.h" #include "sieve-match-types.h" diff --git a/src/lib-sieve/plugins/subaddress/ext-subaddress.c b/src/lib-sieve/plugins/subaddress/ext-subaddress.c index 2f24a38148bca46debefbd558907d8e739785fe0..c2b409789ba4685fb02a180dcb3c4d897b9e8940 100644 --- a/src/lib-sieve/plugins/subaddress/ext-subaddress.c +++ b/src/lib-sieve/plugins/subaddress/ext-subaddress.c @@ -14,7 +14,7 @@ #include "sieve-common.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-address-parts.h" #include "sieve-validator.h" diff --git a/src/lib-sieve/plugins/vacation/ext-vacation.c b/src/lib-sieve/plugins/vacation/ext-vacation.c index 236004509217971d29831f1f507ddadbf52471d8..47f70b81740daccdfe0bc2df3bef5454706f7ade 100644 --- a/src/lib-sieve/plugins/vacation/ext-vacation.c +++ b/src/lib-sieve/plugins/vacation/ext-vacation.c @@ -20,7 +20,7 @@ #include "sieve-common.h" #include "sieve-code.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-actions.h" #include "sieve-validator.h" diff --git a/src/lib-sieve/plugins/variables/ext-variables.c b/src/lib-sieve/plugins/variables/ext-variables.c index 367be81297772bb303d8a5eede5f8d326705840e..e25fa996ef5297dc3300d65853e79009f300b6c3 100644 --- a/src/lib-sieve/plugins/variables/ext-variables.c +++ b/src/lib-sieve/plugins/variables/ext-variables.c @@ -11,7 +11,7 @@ #include "lib.h" #include "unichar.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands.h" #include "sieve-validator.h" diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index bdccc318acb073b47962a0b53f9a051e5461eb4b..9b7d389e332f16b554d30661582808cebeb15759 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -14,6 +14,9 @@ #include <ctype.h> +static struct sieve_extension_obj_registry seff_default_reg = + SIEVE_EXT_DEFINE_NO_SIDE_EFFECTS; + /* * Message transmission (FIXME: place this somewhere more appropriate) */ @@ -93,12 +96,40 @@ void sieve_opr_side_effect_emit (struct sieve_binary *sbin, const struct sieve_side_effect *seffect, int ext_id) { - sieve_size_t address; - (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_SIDE_EFFECT); - sieve_extension_emit_object - (seffect, side_effects, sbin, ext_id, 0, address); + (void) sieve_extension_emit_obj + (sbin, &seff_default_reg, seffect, side_effects, ext_id); +} + +static const struct sieve_extension_obj_registry * + sieve_side_effect_registry_get +(struct sieve_binary *sbin, unsigned int ext_index) +{ + int ext_id = -1; + const struct sieve_side_effect_extension *ext; + + if ( sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id) == NULL ) + return NULL; + + if ( (ext=sieve_side_effect_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + return &(ext->side_effects); +} + +const struct sieve_side_effect *sieve_opr_side_effect_read +(struct sieve_binary *sbin, sieve_size_t *address) +{ + unsigned int seffect_code; + const struct sieve_operand *operand = sieve_operand_read(sbin, address); + + if ( operand == NULL || operand->class != &side_effect_class ) + return NULL; + + return sieve_extension_read_obj + (struct sieve_side_effect, sbin, address, &seff_default_reg, + sieve_side_effect_registry_get); } bool sieve_opr_side_effect_dump @@ -106,13 +137,13 @@ bool sieve_opr_side_effect_dump { const struct sieve_side_effect *seffect; - sieve_code_mark(denv); + sieve_code_mark(denv); seffect = sieve_opr_side_effect_read(denv->sbin, address); if ( seffect == NULL ) return FALSE; - sieve_code_dumpf(denv, "SIDE-EFFECT: %s", seffect->name); + sieve_code_dumpf(denv, "SIDE-EFFECT: %s", seffect->name); if ( seffect->dump_context != NULL ) { sieve_code_descend(denv); @@ -121,39 +152,7 @@ bool sieve_opr_side_effect_dump sieve_code_ascend(denv); } - return TRUE; -} - -/* FIXME: Duplicated */ -const struct sieve_side_effect *sieve_opr_side_effect_read -(struct sieve_binary *sbin, sieve_size_t *address) -{ - unsigned int seffect_code; - const struct sieve_operand *operand = sieve_operand_read(sbin, address); - - if ( operand == NULL || operand->class != &side_effect_class ) - return NULL; - - - if ( sieve_binary_read_byte(sbin, address, &seffect_code) ) { - int ext_id = -1; - const struct sieve_side_effect_extension *se_ext; - const struct sieve_side_effect *seffect; - - if ( sieve_binary_extension_get_by_index(sbin, - seffect_code, &ext_id) == NULL ) - return NULL; - - se_ext = sieve_side_effect_extension_get(sbin, ext_id); - - sieve_extension_read_object - (se_ext, struct sieve_side_effect, side_effects, sbin, - address, seffect) - - return seffect; - } - - return NULL; + return TRUE; } /* diff --git a/src/lib-sieve/sieve-actions.h b/src/lib-sieve/sieve-actions.h index 2d879769f7dde51c55f67e67609f22cb164590e4..7806872f3f522ca76d6ba3189b8f9b2b393f5425 100644 --- a/src/lib-sieve/sieve-actions.h +++ b/src/lib-sieve/sieve-actions.h @@ -5,7 +5,7 @@ #include "mail-storage.h" #include "sieve-common.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" /* Sieve action */ @@ -98,6 +98,7 @@ struct sieve_side_effect_extension { struct sieve_extension_obj_registry side_effects; }; +#define SIEVE_EXT_DEFINE_NO_SIDE_EFFECTS SIEVE_EXT_DEFINE_NO_OBJECTS #define SIEVE_EXT_DEFINE_SIDE_EFFECT(SEF) SIEVE_EXT_DEFINE_OBJECT(SEF) #define SIEVE_EXT_DEFINE_SIDE_EFFECTS(SEFS) SIEVE_EXT_DEFINE_OBJECTS(SEFS) diff --git a/src/lib-sieve/sieve-address-parts.c b/src/lib-sieve/sieve-address-parts.c index c03fa2b536e12cad0fc718a66d6ee2a631b62024..bf6f70dddfa28b57b8ffbc461651b64713e0f2c9 100644 --- a/src/lib-sieve/sieve-address-parts.c +++ b/src/lib-sieve/sieve-address-parts.c @@ -23,9 +23,23 @@ #include <string.h> /* - * Predeclarations + * Default address parts */ - + +const struct sieve_address_part *sieve_core_address_parts[] = { + &all_address_part, &local_address_part, &domain_address_part +}; + +const unsigned int sieve_core_address_parts_count = + N_ELEMENTS(sieve_core_address_parts); + +static struct sieve_extension_obj_registry addrp_default_reg = + SIEVE_EXT_DEFINE_ADDRESS_PARTS(sieve_core_address_parts); + +/* + * Forward declarations + */ + static void opr_address_part_emit (struct sieve_binary *sbin, const struct sieve_address_part *addrp, int ext_id); @@ -231,62 +245,46 @@ static bool tag_address_part_validate return TRUE; } -/* Code generation */ +/* + * Code generation + */ static void opr_address_part_emit (struct sieve_binary *sbin, const struct sieve_address_part *addrp, int ext_id) -{ +{ (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_ADDRESS_PART); - 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_extension_emit_obj + (sbin, &addrp_default_reg, addrp, address_parts, ext_id); +} + +static const struct sieve_extension_obj_registry * + sieve_address_part_registry_get +(struct sieve_binary *sbin, unsigned int ext_index) +{ + int ext_id = -1; + const struct sieve_address_part_extension *ext; - (void) sieve_binary_emit_byte(sbin, addrp->code); + if ( sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id) == NULL ) + return NULL; + + if ( (ext=sieve_address_part_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + return &(ext->address_parts); } -/* FIXME: Duplicated */ const struct sieve_address_part *sieve_opr_address_part_read (struct sieve_binary *sbin, sieve_size_t *address) { - unsigned int addrp_code; const struct sieve_operand *operand = sieve_operand_read(sbin, address); if ( operand == NULL || operand->class != &address_part_class ) return NULL; - - if ( sieve_binary_read_byte(sbin, address, &addrp_code) ) { - if ( addrp_code < SIEVE_ADDRESS_PART_CUSTOM ) { - if ( addrp_code < sieve_core_address_parts_count ) - return sieve_core_address_parts[addrp_code]; - else - return NULL; - } else { - 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) - return addrp; - } - } - - return NULL; + return sieve_extension_read_obj + (struct sieve_address_part, sbin, address, &addrp_default_reg, + sieve_address_part_registry_get); } bool sieve_opr_address_part_dump @@ -488,11 +486,3 @@ const struct sieve_address_part domain_address_part = { addrp_domain_extract_from }; -const struct sieve_address_part *sieve_core_address_parts[] = { - &all_address_part, &local_address_part, &domain_address_part -}; - -const unsigned int sieve_core_address_parts_count = - N_ELEMENTS(sieve_core_address_parts); - - diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c index 35c11d74a5ab73161d5fb0199db8adbae034c3e5..be358a8589ff3ff92d3993c03f6ba12eb4a96829 100644 --- a/src/lib-sieve/sieve-binary.c +++ b/src/lib-sieve/sieve-binary.c @@ -6,7 +6,7 @@ #include "array.h" #include "ostream.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-code.h" #include "sieve-script.h" diff --git a/src/lib-sieve/sieve-code.c b/src/lib-sieve/sieve-code.c index e79e8acd9ea3fd9299863e9399250a88796f60c4..9a95cf19bafe20ba15c8e3df38a318d28cd86c39 100644 --- a/src/lib-sieve/sieve-code.c +++ b/src/lib-sieve/sieve-code.c @@ -3,7 +3,7 @@ #include "str-sanitize.h" #include "sieve-common.h" -#include "sieve-extensions.h" +#include "sieve-extensions-private.h" #include "sieve-actions.h" #include "sieve-binary.h" #include "sieve-generator.h" @@ -582,54 +582,7 @@ static struct sieve_coded_stringlist *opr_stringlist_read /* * Operations */ - -/* Operation functions */ - -inline sieve_size_t sieve_operation_emit_code - (struct sieve_binary *sbin, const struct sieve_operation *op, int ext_id) -{ - 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 - (struct sieve_binary *sbin, sieve_size_t *address) -{ - unsigned int opcode; - - if ( sieve_binary_read_byte(sbin, address, &opcode) ) { - if ( opcode < SIEVE_OPERATION_CUSTOM ) { - if ( opcode < sieve_operations_count ) - return sieve_operations[opcode]; - else - return NULL; - } else { - 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; - } - } - - return NULL; -} - + /* Declaration of opcodes defined in this file */ static bool opc_jmp_dump @@ -703,6 +656,67 @@ const struct sieve_operation *sieve_operations[] = { const unsigned int sieve_operations_count = N_ELEMENTS(sieve_operations); +static struct sieve_extension_obj_registry oprt_default_reg = + SIEVE_EXT_DEFINE_OPERATIONS(sieve_operations); + +/* Operation functions */ + +inline sieve_size_t sieve_operation_emit_code + (struct sieve_binary *sbin, const struct sieve_operation *op, int ext_id) +{ + return sieve_extension_emit_obj + (sbin, &oprt_default_reg, op, operations, ext_id); +} + +static const struct sieve_extension_obj_registry * + sieve_operation_registry_get +(struct sieve_binary *sbin, unsigned int ext_index) +{ + int ext_id = -1; + const struct sieve_extension *ext; + + if ( (ext=sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id)) + == NULL ) + return NULL; + + return &(ext->operations); +} + +const struct sieve_operation *sieve_operation_read + (struct sieve_binary *sbin, sieve_size_t *address) +{ + return sieve_extension_read_obj + (struct sieve_operation, sbin, address, &oprt_default_reg, + sieve_operation_registry_get); + +/* unsigned int opcode; + + if ( sieve_binary_read_byte(sbin, address, &opcode) ) { + if ( opcode < SIEVE_OPERATION_CUSTOM ) { + if ( opcode < sieve_operations_count ) + return sieve_operations[opcode]; + else + return NULL; + } else { + 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; + } + } + + return NULL;*/ +} + + /* Code dump for core commands */ static bool opc_jmp_dump diff --git a/src/lib-sieve/sieve-comparators.c b/src/lib-sieve/sieve-comparators.c index 620d8c2fce55f503bfc950b39b0bb8cba6619602..644247f2db61ffff7743a27f53e3bc1814fb5ead 100644 --- a/src/lib-sieve/sieve-comparators.c +++ b/src/lib-sieve/sieve-comparators.c @@ -19,12 +19,23 @@ #include <ctype.h> /* - * Predeclarations + * Default comparators */ -extern const struct sieve_comparator *sieve_core_comparators[]; -extern const unsigned int sieve_core_comparators_count; +const struct sieve_comparator *sieve_core_comparators[] = { + &i_octet_comparator, &i_ascii_casemap_comparator +}; + +const unsigned int sieve_core_comparators_count = + N_ELEMENTS(sieve_core_comparators); +static struct sieve_extension_obj_registry cmp_default_reg = + SIEVE_EXT_DEFINE_COMPARATORS(sieve_core_comparators); + +/* + * Forward declarations + */ + static void opr_comparator_emit (struct sieve_binary *sbin, const struct sieve_comparator *cmp, int ext_id); @@ -188,8 +199,10 @@ static bool cmp_binary_load(struct sieve_binary *sbin) * Comparator operand */ -struct sieve_operand_class comparator_class = { "comparator", NULL }; -struct sieve_operand comparator_operand = { "comparator", &comparator_class, FALSE }; +struct sieve_operand_class comparator_class = + { "comparator", NULL }; +struct sieve_operand comparator_operand = + { "comparator", &comparator_class, FALSE }; /* * Comparator tag @@ -294,53 +307,37 @@ static void opr_comparator_emit { (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_COMPARATOR); - if ( ext_id >= 0 ) { - sieve_size_t dummy; - - sieve_extension_emit_object - (cmp, comparators, sbin, ext_id, SIEVE_COMPARATOR_CUSTOM, dummy); - - return; - } + (void) sieve_extension_emit_obj + (sbin, &cmp_default_reg, cmp, comparators, ext_id); +} + +static const struct sieve_extension_obj_registry * + sieve_comparator_registry_get +(struct sieve_binary *sbin, unsigned int ext_index) +{ + int ext_id = -1; + const struct sieve_comparator_extension *ext; - (void) sieve_binary_emit_byte(sbin, cmp->code); + if ( sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id) == NULL ) + return NULL; + + if ( (ext=sieve_comparator_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + return &(ext->comparators); } const struct sieve_comparator *sieve_opr_comparator_read (struct sieve_binary *sbin, sieve_size_t *address) { - unsigned int cmp_code; const struct sieve_operand *operand = sieve_operand_read(sbin, address); if ( operand == NULL || operand->class != &comparator_class ) return NULL; - if ( sieve_binary_read_byte(sbin, address, &cmp_code) ) { - if ( cmp_code < SIEVE_COMPARATOR_CUSTOM ) { - if ( cmp_code < sieve_core_comparators_count ) - return sieve_core_comparators[cmp_code]; - else - return NULL; - } else { - 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) - - return cmp; - } - } - - return NULL; + return sieve_extension_read_obj + (struct sieve_comparator, sbin, address, &cmp_default_reg, + sieve_comparator_registry_get); } bool sieve_opr_comparator_dump @@ -406,13 +403,6 @@ const struct sieve_comparator i_ascii_casemap_comparator = { cmp_i_octet_char_skip }; -const struct sieve_comparator *sieve_core_comparators[] = { - &i_octet_comparator, &i_ascii_casemap_comparator -}; - -const unsigned int sieve_core_comparators_count = - N_ELEMENTS(sieve_core_comparators); - static int cmp_i_octet_compare( const struct sieve_comparator *cmp ATTR_UNUSED, const char *val1, size_t val1_size, const char *val2, size_t val2_size) diff --git a/src/lib-sieve/sieve-comparators.h b/src/lib-sieve/sieve-comparators.h index 56bb5db5f386703cdfd678fde846665467f405ae..b082870033fa8bd76da8f3cea6af1e1664dcf8b4 100644 --- a/src/lib-sieve/sieve-comparators.h +++ b/src/lib-sieve/sieve-comparators.h @@ -2,7 +2,7 @@ #define __SIEVE_COMPARATORS_H #include "sieve-common.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" enum sieve_comparator_code { SIEVE_COMPARATOR_I_OCTET, diff --git a/src/lib-sieve/sieve-extensions-private.h b/src/lib-sieve/sieve-extensions-private.h index 1fad34e71ae0239b8b659bb654098f6cce66549e..16c694c727309c18e76dd12d543936ef057fa368 100644 --- a/src/lib-sieve/sieve-extensions-private.h +++ b/src/lib-sieve/sieve-extensions-private.h @@ -9,37 +9,31 @@ * Per-extension object declaration */ -struct sieve_extension_obj_registry { - const void *objects; - unsigned int count; -}; - -#define SIEVE_EXT_DEFINE_NO_OBJECTS \ - { NULL, 0 } -#define SIEVE_EXT_DEFINE_OBJECT(OBJ) \ - { &OBJ, 1 } -#define SIEVE_EXT_DEFINE_OBJECTS(OBJS) \ - { OBJS, N_ELEMENTS(OBJS) } - -#define SIEVE_EXT_GET_OBJECTS_COUNT(ext, field) \ - ext->field->count; - -static inline const void *_sieve_extension_read_object -(const struct sieve_extension_obj_registry *reg, struct sieve_binary *sbin, - sieve_size_t *address) +static inline const void *_sieve_extension_get_object +(const struct sieve_extension_obj_registry *reg, unsigned int code) { - unsigned int code; - if ( reg->count == 1 ) return reg->objects; - if ( sieve_binary_read_byte(sbin, address, &code) && code < reg->count ) { + if ( code < reg->count ) { const void * const *objects = (const void * const *) reg->objects; return objects[code]; } return NULL; } +static inline const void *_sieve_extension_read_object +(const struct sieve_extension_obj_registry *reg, struct sieve_binary *sbin, + sieve_size_t *address) +{ + unsigned int code = 0; + + if ( reg->count > 1) + sieve_binary_read_byte(sbin, address, &code); + + return _sieve_extension_get_object(reg, code); +} + #define sieve_extension_read_object\ (ext, type, field, sbin, address, result) \ { \ @@ -71,35 +65,57 @@ static inline sieve_size_t _sieve_extension_emit_object * Extension object */ -struct sieve_extension { - const char *name; +static inline sieve_size_t _sieve_extension_emit_obj +(struct sieve_binary *sbin, + const struct sieve_extension_obj_registry *defreg, + const struct sieve_extension_obj_registry *reg, + unsigned int obj_code, int ext_id) +{ + if ( ext_id >= 0 ) { + sieve_size_t address; + unsigned char code = defreg->count + + sieve_binary_extension_get_index(sbin, ext_id); + + address = sieve_binary_emit_byte(sbin, code); + + if ( reg->count > 1 ) + (void) sieve_binary_emit_byte(sbin, obj_code); - bool (*load)(int ext_id); - - bool (*validator_load)(struct sieve_validator *validator); - bool (*generator_load)(struct sieve_generator *generator); - bool (*binary_load)(struct sieve_binary *binary); - bool (*interpreter_load)(struct sieve_interpreter *interpreter); - - struct sieve_extension_obj_registry opcodes; - struct sieve_extension_obj_registry operands; -}; - -/* - * 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) - -#define SIEVE_EXT_DEFINE_NO_OPERANDS SIEVE_EXT_DEFINE_NO_OBJECTS - -/* - * Pre-loaded extensions - */ - -extern const struct sieve_extension *sieve_preloaded_extensions[]; -extern const unsigned int sieve_preloaded_extensions_count; + return address; + } + + return sieve_binary_emit_byte(sbin, obj_code); +} +#define sieve_extension_emit_obj(sbin, defreg, obj, reg, ext_id)\ + _sieve_extension_emit_obj\ + (sbin, defreg, &obj->extension->reg, obj->code, ext_id) + +static inline const void *_sieve_extension_read_obj +(struct sieve_binary *sbin, sieve_size_t *address, + const struct sieve_extension_obj_registry *defreg, + const struct sieve_extension_obj_registry *(*get_reg_func) + (struct sieve_binary *sbin, unsigned int index)) +{ + unsigned int obj_code; + + if ( sieve_binary_read_byte(sbin, address, &obj_code) ) { + if ( obj_code < defreg->count ) { + return _sieve_extension_get_object(defreg, obj_code); + } else { + const struct sieve_extension_obj_registry *reg; + + if ( (reg=get_reg_func(sbin, obj_code - defreg->count)) == NULL || + reg->count == 0 ) + return NULL; + + return _sieve_extension_read_object(reg, sbin, address); + } + } + + return NULL; +} +#define sieve_extension_read_obj(type, sbin, address, defreg, get_reg_func) \ + ((const type *) _sieve_extension_read_obj \ + (sbin, address, defreg, get_reg_func)) #endif /* __SIEVE_EXTENSIONS_PRIVATE_H */ diff --git a/src/lib-sieve/sieve-extensions.h b/src/lib-sieve/sieve-extensions.h index e1327af3ebedca78a5626d6eb6a3776b40df4ade..1db54d10f4b2ebf097ee7e5d15c53954caba3964 100644 --- a/src/lib-sieve/sieve-extensions.h +++ b/src/lib-sieve/sieve-extensions.h @@ -4,7 +4,52 @@ #include "lib.h" #include "sieve-common.h" -struct sieve_extension; +/* Per-extension object registry */ + +struct sieve_extension_obj_registry { + const void *objects; + unsigned int count; +}; + +/* Extension object */ + +struct sieve_extension { + const char *name; + + bool (*load)(int ext_id); + + bool (*validator_load)(struct sieve_validator *validator); + bool (*generator_load)(struct sieve_generator *generator); + bool (*binary_load)(struct sieve_binary *binary); + bool (*interpreter_load)(struct sieve_interpreter *interpreter); + + struct sieve_extension_obj_registry operations; + struct sieve_extension_obj_registry operands; +}; + +#define SIEVE_EXT_DEFINE_NO_OBJECTS \ + { NULL, 0 } +#define SIEVE_EXT_DEFINE_OBJECT(OBJ) \ + { &OBJ, 1 } +#define SIEVE_EXT_DEFINE_OBJECTS(OBJS) \ + { OBJS, N_ELEMENTS(OBJS) } + +#define SIEVE_EXT_GET_OBJECTS_COUNT(ext, field) \ + ext->field->count; + +/* 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) + +#define SIEVE_EXT_DEFINE_NO_OPERANDS SIEVE_EXT_DEFINE_NO_OBJECTS + +/* Pre-loaded extensions */ + +extern const struct sieve_extension *sieve_preloaded_extensions[]; +extern const unsigned int sieve_preloaded_extensions_count; + const struct sieve_extension *sieve_extension_acquire(const char *extension); diff --git a/src/lib-sieve/sieve-generator.c b/src/lib-sieve/sieve-generator.c index 447ff2d1e26df946378a6b621d1a42d851b606ff..88e026a482a702a0d7a819d6aea3bc0e065da354 100644 --- a/src/lib-sieve/sieve-generator.c +++ b/src/lib-sieve/sieve-generator.c @@ -4,7 +4,7 @@ #include "mempool.h" #include "sieve-common.h" -#include "sieve-extensions-private.h" +#include "sieve-extensions.h" #include "sieve-commands-private.h" #include "sieve-code.h" #include "sieve-binary.h" diff --git a/src/lib-sieve/sieve-match-types.c b/src/lib-sieve/sieve-match-types.c index 732bce7b7e5a822f618e8ba43e35bfe5c391b7d0..edd79cfbafdfb61e7425029b5ca759ef4e51d88c 100644 --- a/src/lib-sieve/sieve-match-types.c +++ b/src/lib-sieve/sieve-match-types.c @@ -21,9 +21,23 @@ #include <string.h> /* - * Predeclarations + * Default match types + */ + +const struct sieve_match_type *sieve_core_match_types[] = { + &is_match_type, &contains_match_type, &matches_match_type +}; + +const unsigned int sieve_core_match_types_count = + N_ELEMENTS(sieve_core_match_types); + +static struct sieve_extension_obj_registry mtch_default_reg = + SIEVE_EXT_DEFINE_MATCH_TYPES(sieve_core_match_types); + +/* + * Forward declarations */ - + static void opr_match_type_emit (struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id); @@ -274,61 +288,46 @@ bool sieve_match_type_validate return TRUE; } -/* Code generation */ +/* + * Code generation + */ static void opr_match_type_emit (struct sieve_binary *sbin, const struct sieve_match_type *mtch, int ext_id) { (void) sieve_operand_emit_code(sbin, SIEVE_OPERAND_MATCH_TYPE); + + (void) sieve_extension_emit_obj + (sbin, &mtch_default_reg, mtch, match_types, ext_id); +} - if ( ext_id >= 0 ) { - sieve_size_t dummy; - - sieve_extension_emit_object - (mtch, match_types, sbin, ext_id, SIEVE_MATCH_TYPE_CUSTOM, dummy); - - return; - } +static const struct sieve_extension_obj_registry * + sieve_match_type_registry_get +(struct sieve_binary *sbin, unsigned int ext_index) +{ + int ext_id = -1; + const struct sieve_match_type_extension *ext; - (void) sieve_binary_emit_byte(sbin, mtch->code); + if ( sieve_binary_extension_get_by_index(sbin, ext_index, &ext_id) == NULL ) + return NULL; + if ( (ext=sieve_match_type_extension_get(sbin, ext_id)) == NULL ) + return NULL; + + return &(ext->match_types); } const struct sieve_match_type *sieve_opr_match_type_read (struct sieve_binary *sbin, sieve_size_t *address) { - unsigned int mtch_code; const struct sieve_operand *operand = sieve_operand_read(sbin, address); if ( operand == NULL || operand->class != &match_type_class ) return NULL; - - if ( sieve_binary_read_byte(sbin, address, &mtch_code) ) { - if ( mtch_code < SIEVE_MATCH_TYPE_CUSTOM ) { - if ( mtch_code < sieve_core_match_types_count ) - return sieve_core_match_types[mtch_code]; - else - return NULL; - } else { - 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) - return mtch; - } - } - - return NULL; + return sieve_extension_read_obj + (struct sieve_match_type, sbin, address, &mtch_default_reg, + sieve_match_type_registry_get); } bool sieve_opr_match_type_dump @@ -706,10 +705,3 @@ const struct sieve_match_type matches_match_type = { mtch_matches_match, NULL }; - -const struct sieve_match_type *sieve_core_match_types[] = { - &is_match_type, &contains_match_type, &matches_match_type -}; - -const unsigned int sieve_core_match_types_count = - N_ELEMENTS(sieve_core_match_types); diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index a1c679e80bfbe945897d3b0aaf1ee9bce664212a..87a9107d9f36024cce2c8cb4acb392af0cd37434 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -4,12 +4,12 @@ #include "mempool.h" #include "hash.h" +#include "sieve-extensions.h" #include "sieve-script.h" #include "sieve-ast.h" #include "sieve-commands.h" #include "sieve-commands-private.h" #include "sieve-validator.h" -#include "sieve-extensions-private.h" #include "sieve-comparators.h" #include "sieve-address-parts.h"