diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index 73e2b518312fb1e44e9812d4fb464b6583e2392a..02aef7fc393e3c43b4dfc94b49a2a11db4fcaf41 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -22,6 +22,13 @@ #include "sieve-interpreter.h" +/* Extensions to the interpreter */ + +struct sieve_interpreter_extension_reg { + const struct sieve_interpreter_extension *int_ext; + void *context; +}; + /* * Interpreter */ @@ -32,7 +39,7 @@ struct sieve_interpreter { struct sieve_error_handler *ehandler; /* Runtime data for extensions */ - ARRAY_DEFINE(ext_contexts, void *); + ARRAY_DEFINE(extensions, struct sieve_interpreter_extension_reg); /* Execution status */ @@ -72,7 +79,7 @@ struct sieve_interpreter *sieve_interpreter_create interp->pc = 0; - p_array_init(&interp->ext_contexts, pool, sieve_extensions_get_count()); + p_array_init(&interp->extensions, pool, sieve_extensions_get_count()); /* Pre-load core language features implemented as 'extensions' */ for ( i = 0; i < sieve_preloaded_extensions_count; i++ ) { @@ -211,25 +218,42 @@ void _sieve_runtime_trace_error /* Extension support */ +void sieve_interpreter_extension_register +(struct sieve_interpreter *interp, + const struct sieve_interpreter_extension *int_ext, void *context) +{ + struct sieve_interpreter_extension_reg reg = { int_ext, context }; + int ext_id = *int_ext->ext->id; + + if ( ext_id < 0 ) return; + + array_idx_set(&interp->extensions, (unsigned int) ext_id, ®); +} + void sieve_interpreter_extension_set_context -(struct sieve_interpreter *interpreter, const struct sieve_extension *ext, +(struct sieve_interpreter *interp, const struct sieve_extension *ext, void *context) { - array_idx_set(&interpreter->ext_contexts, (unsigned int) *ext->id, &context); + struct sieve_interpreter_extension_reg reg = { NULL, context }; + int ext_id = *ext->id; + + if ( ext_id < 0 ) return; + + array_idx_set(&interp->extensions, (unsigned int) ext_id, ®); } -const void *sieve_interpreter_extension_get_context -(struct sieve_interpreter *interpreter, const struct sieve_extension *ext) +void *sieve_interpreter_extension_get_context +(struct sieve_interpreter *interp, const struct sieve_extension *ext) { int ext_id = *ext->id; - void * const *ctx; + const struct sieve_interpreter_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&interpreter->ext_contexts) ) + if ( ext_id < 0 || ext_id >= (int) array_count(&interp->extensions) ) return NULL; - ctx = array_idx(&interpreter->ext_contexts, (unsigned int) ext_id); + reg = array_idx(&interp->extensions, (unsigned int) ext_id); - return *ctx; + return reg->context; } /* Program counter */ diff --git a/src/lib-sieve/sieve-interpreter.h b/src/lib-sieve/sieve-interpreter.h index 86ab5d446aada0a29ece50f4f0f413acae32fffd..eae9bdd17903f0dc4b6ff5f72aa8463b357aaa8f 100644 --- a/src/lib-sieve/sieve-interpreter.h +++ b/src/lib-sieve/sieve-interpreter.h @@ -97,11 +97,20 @@ void _sieve_runtime_trace_error /* Extension support */ +struct sieve_interpreter_extension { + const struct sieve_extension *ext; + + void (*free)(struct sieve_interpreter *interp, void *context); +}; + +void sieve_interpreter_extension_register + (struct sieve_interpreter *interp, + const struct sieve_interpreter_extension *int_ext, void *context); void sieve_interpreter_extension_set_context - (struct sieve_interpreter *interp, const struct sieve_extension *ext, + (struct sieve_interpreter *interp, const struct sieve_extension *ext, void *context); -const void *sieve_interpreter_extension_get_context - (struct sieve_interpreter *interp, const struct sieve_extension *ext); +void *sieve_interpreter_extension_get_context + (struct sieve_interpreter *interp, const struct sieve_extension *ext); /* Opcodes and operands */ diff --git a/src/lib-sieve/sieve-validator.c b/src/lib-sieve/sieve-validator.c index b48009e70f04b5f3ab408fa8ef718596204a17c7..e131dcfe227ff6879c86e6af6b591d7106b6d07e 100644 --- a/src/lib-sieve/sieve-validator.c +++ b/src/lib-sieve/sieve-validator.c @@ -19,6 +19,13 @@ struct sieve_default_argument { struct sieve_default_argument *overrides; }; +/* Extensions to the validator */ + +struct sieve_validator_extension_reg { + const struct sieve_validator_extension *val_ext; + void *context; +}; + /* * Context/Semantics checker implementation */ @@ -35,7 +42,7 @@ struct sieve_validator { struct hash_table *commands; - ARRAY_DEFINE(ext_contexts, void *); + ARRAY_DEFINE(extensions, struct sieve_validator_extension_reg); /* This is currently a wee bit ugly and needs more thought */ struct sieve_default_argument default_arguments[SAT_COUNT]; @@ -117,7 +124,7 @@ struct sieve_validator *sieve_validator_create argument = &string_list_argument; /* Setup storage for extension contexts */ - p_array_init(&validator->ext_contexts, pool, sieve_extensions_get_count()); + p_array_init(&validator->extensions, pool, sieve_extensions_get_count()); /* Setup command registry */ validator->commands = hash_create @@ -440,24 +447,42 @@ const struct sieve_extension *sieve_validator_extension_load return ext; } +void sieve_validator_extension_register +(struct sieve_validator *valdtr, + const struct sieve_validator_extension *val_ext, void *context) +{ + struct sieve_validator_extension_reg reg = { val_ext, context }; + int ext_id = *val_ext->ext->id; + + if ( ext_id < 0 ) return; + + array_idx_set(&valdtr->extensions, (unsigned int) ext_id, ®); +} + void sieve_validator_extension_set_context -(struct sieve_validator *validator, const struct sieve_extension *ext, void *context) +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + void *context) { - array_idx_set(&validator->ext_contexts, (unsigned int) *ext->id, &context); + struct sieve_validator_extension_reg reg = { NULL, context }; + int ext_id = *ext->id; + + if ( ext_id < 0 ) return; + + array_idx_set(&valdtr->extensions, (unsigned int) ext_id, ®); } -const void *sieve_validator_extension_get_context -(struct sieve_validator *validator, const struct sieve_extension *ext) +void *sieve_validator_extension_get_context +(struct sieve_validator *valdtr, const struct sieve_extension *ext) { int ext_id = *ext->id; - void * const *ctx; + const struct sieve_validator_extension_reg *reg; - if ( ext_id < 0 || ext_id >= (int) array_count(&validator->ext_contexts) ) + if ( ext_id < 0 || ext_id >= (int) array_count(&valdtr->extensions) ) return NULL; - ctx = array_idx(&validator->ext_contexts, (unsigned int) ext_id); + reg = array_idx(&valdtr->extensions, (unsigned int) ext_id); - return *ctx; + return reg->context; } /* Argument Validation API */ diff --git a/src/lib-sieve/sieve-validator.h b/src/lib-sieve/sieve-validator.h index 16b825f21c8dd4eb6b6e7fee44abaf1de77e756c..93ec9b80e4f44f6724739b11bedab78a112a9823 100644 --- a/src/lib-sieve/sieve-validator.h +++ b/src/lib-sieve/sieve-validator.h @@ -84,16 +84,28 @@ bool sieve_validator_argument_activate_super (struct sieve_validator *validator, struct sieve_command_context *cmd, struct sieve_ast_argument *arg, bool constant); -/* Extensions */ +/* + * Extension support + */ + +struct sieve_validator_extension { + const struct sieve_extension *ext; + + void (*free)(struct sieve_validator *valdtr, void *context); +}; + const struct sieve_extension *sieve_validator_extension_load (struct sieve_validator *validator, struct sieve_command_context *cmd, const char *ext_name); +void sieve_validator_extension_register + (struct sieve_validator *valdtr, + const struct sieve_validator_extension *val_ext, void *context); void sieve_validator_extension_set_context - (struct sieve_validator *validator, const struct sieve_extension *ext, - void *context); -const void *sieve_validator_extension_get_context - (struct sieve_validator *validator, const struct sieve_extension *ext); +(struct sieve_validator *valdtr, const struct sieve_extension *ext, + void *context); +void *sieve_validator_extension_get_context +(struct sieve_validator *valdtr, const struct sieve_extension *ext); /* * Validator object registry