diff --git a/src/testsuite/Makefile.am b/src/testsuite/Makefile.am index 3e2ddb4e4082845cb418e9f92603963037c9bc04..061606cc4f29c2b44c430f7d2bf74c0e4819ad0e 100644 --- a/src/testsuite/Makefile.am +++ b/src/testsuite/Makefile.am @@ -44,11 +44,13 @@ testsuite_SOURCES = \ namespaces.c \ mail-raw.c \ testsuite-common.c \ + testsuite-objects.c \ $(cmds) \ ext-testsuite.c \ testsuite.c noinst_HEADERS = \ testsuite-common.h \ + testsuite-objects.h \ namespaces.h \ mail-raw.h diff --git a/src/testsuite/cmd-test-set.c b/src/testsuite/cmd-test-set.c index 925592c00918ac662b8fae4b74705a331674a614..8dc5a952993337b2f9de2e1714f321c81a79e78c 100644 --- a/src/testsuite/cmd-test-set.c +++ b/src/testsuite/cmd-test-set.c @@ -15,6 +15,7 @@ #include "sieve-result.h" #include "testsuite-common.h" +#include "testsuite-objects.h" #include <stdio.h> diff --git a/src/testsuite/testsuite-common.c b/src/testsuite/testsuite-common.c index bc253964f62bbbe3a7a994b2ee177f66a9c6cfdc..ff3e2317aabfb883d585edce6e03e4f7554c3dd2 100644 --- a/src/testsuite/testsuite-common.c +++ b/src/testsuite/testsuite-common.c @@ -14,38 +14,9 @@ #include "sieve-generator.h" #include "sieve-dump.h" +#include "testsuite-objects.h" #include "testsuite-common.h" -/* - * Types - */ - -struct testsuite_object_registration { - int ext_id; - const struct testsuite_object *object; -}; - -struct testsuite_validator_context { - struct hash_table *object_registrations; -}; - -/* - * Testsuite core objects - */ - -enum testsuite_object_code { - TESTSUITE_OBJECT_MESSAGE, - TESTSUITE_OBJECT_ENVELOPE -}; - -const struct testsuite_object *testsuite_core_objects[] = { - &message_testsuite_object, &envelope_testsuite_object -}; - -const unsigned int testsuite_core_objects_count = - N_ELEMENTS(testsuite_core_objects); - - /* * Global data */ @@ -54,14 +25,6 @@ const unsigned int testsuite_core_objects_count = struct sieve_message_data testsuite_msgdata; -/* - * Forward declarations - */ - -static void _testsuite_object_register - (pool_t pool, struct testsuite_validator_context *ctx, - const struct testsuite_object *obj, int ext_id); - /* * Testsuite message environment */ @@ -143,16 +106,8 @@ void testsuite_message_deinit(void) * Validator context */ -static inline struct testsuite_validator_context * - get_validator_context(struct sieve_validator *valdtr) -{ - return (struct testsuite_validator_context *) - sieve_validator_extension_get_context(valdtr, ext_testsuite_my_id); -} - bool testsuite_validator_context_initialize(struct sieve_validator *valdtr) { - unsigned int i; pool_t pool = sieve_validator_pool(valdtr); struct testsuite_validator_context *ctx = p_new(pool, struct testsuite_validator_context, 1); @@ -161,202 +116,9 @@ bool testsuite_validator_context_initialize(struct sieve_validator *valdtr) ctx->object_registrations = hash_create (pool, pool, 0, str_hash, (hash_cmp_callback_t *) strcmp); - /* Register core testsuite objects */ - for ( i = 0; i < testsuite_core_objects_count; i++ ) { - const struct testsuite_object *object = testsuite_core_objects[i]; - - _testsuite_object_register(pool, ctx, object, ext_testsuite_my_id); - } - - sieve_validator_extension_set_context(valdtr, ext_testsuite_my_id, ctx); - - return TRUE; -} - -/* - * Testsuite object registry - */ - -static void _testsuite_object_register -(pool_t pool, struct testsuite_validator_context *ctx, - const struct testsuite_object *obj, int ext_id) -{ - struct testsuite_object_registration *reg; - - reg = p_new(pool, struct testsuite_object_registration, 1); - reg->object = obj; - reg->ext_id = ext_id; - - hash_insert(ctx->object_registrations, (void *) obj->identifier, (void *) reg); -} - -void testsuite_object_register -(struct sieve_validator *valdtr, const struct testsuite_object *obj, int ext_id) -{ - pool_t pool = sieve_validator_pool(valdtr); - struct testsuite_validator_context *ctx = get_validator_context(valdtr); - - _testsuite_object_register(pool, ctx, obj, ext_id); -} - -const struct testsuite_object *testsuite_object_find -(struct sieve_validator *valdtr, const char *identifier, int *ext_id) -{ - struct testsuite_validator_context *ctx = get_validator_context(valdtr); - struct testsuite_object_registration *reg = - (struct testsuite_object_registration *) - hash_lookup(ctx->object_registrations, identifier); - - if ( reg == NULL ) return NULL; - - if ( ext_id != NULL ) *ext_id = reg->ext_id; - - return reg->object; -} - -/* - * Testsuite object code - */ - -const struct sieve_operand_class testsuite_object_oprclass = - { "testsuite-object" }; - -const struct testsuite_object_operand_interface testsuite_object_oprint = { - SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects) -}; - -const struct sieve_operand testsuite_object_operand = { - "testsuite-object", - &testsuite_extension, - TESTSUITE_OPERAND_OBJECT, - &testsuite_object_oprclass, - &testsuite_object_oprint -}; - -static void testsuite_object_emit - (struct sieve_binary *sbin, const struct testsuite_object *obj, int ext_id) -{ - (void) sieve_operand_emit_code(sbin, obj->operand, ext_id); - (void) sieve_binary_emit_byte(sbin, obj->code); -} - -const struct testsuite_object *testsuite_object_read -(struct sieve_binary *sbin, sieve_size_t *address) -{ - const struct sieve_operand *operand; - const struct testsuite_object_operand_interface *intf; - unsigned int obj_code; - - operand = sieve_operand_read(sbin, address); - if ( operand == NULL || operand->class != &testsuite_object_oprclass ) - return NULL; - - intf = operand->interface; - if ( intf == NULL ) - return NULL; - - if ( !sieve_binary_read_byte(sbin, address, &obj_code) ) - return NULL; - - return sieve_extension_get_object - (struct testsuite_object, intf->testsuite_objects, obj_code); -} - -bool testsuite_object_dump -(const struct sieve_dumptime_env *denv, sieve_size_t *address) -{ - const struct testsuite_object *object; - - sieve_code_mark(denv); - - if ( (object = testsuite_object_read(denv->sbin, address)) == NULL ) - return FALSE; - - sieve_code_dumpf(denv, "TESTSUITE_OBJECT: %s", object->identifier); - - return TRUE; -} - -/* - * Testsuite object argument - */ - -static bool arg_testsuite_object_generate - (struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); - -const struct sieve_argument testsuite_object_argument = - { "testsuite-object", NULL, NULL, NULL, arg_testsuite_object_generate }; - -struct testsuite_object_argctx { - const struct testsuite_object *object; - int ext_id; -}; - -bool testsuite_object_argument_activate -(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd) -{ - const char *objname = sieve_ast_argument_strc(arg); - const struct testsuite_object *object; - int ext_id; - struct testsuite_object_argctx *ctx; - - object = testsuite_object_find(valdtr, objname, &ext_id); - if ( object == NULL ) { - sieve_command_validate_error(valdtr, cmd, - "unknown testsuite object '%s'", objname); - return FALSE; - } + testsuite_register_core_objects(pool, ctx); - ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1); - ctx->object = object; - ctx->ext_id = ext_id; - - arg->argument = &testsuite_object_argument; - arg->context = (void *) ctx; - - return TRUE; -} - -static bool arg_testsuite_object_generate - (struct sieve_generator *generator, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd ATTR_UNUSED) -{ - struct sieve_binary *sbin = sieve_generator_get_binary(generator); - struct testsuite_object_argctx *ctx = - (struct testsuite_object_argctx *) arg->context; - - testsuite_object_emit(sbin, ctx->object, ctx->ext_id); - - return TRUE; -} - -/* - * Testsuite core object implementation - */ - -static bool tsto_message_set_member(int id, string_t *value); - -const struct testsuite_object message_testsuite_object = { - "message", - TESTSUITE_OBJECT_MESSAGE, - &testsuite_object_operand, - NULL, tsto_message_set_member, NULL -}; - -const struct testsuite_object envelope_testsuite_object = { - "envelope", - TESTSUITE_OBJECT_ENVELOPE, - &testsuite_object_operand, - NULL, NULL, NULL -}; + sieve_validator_extension_set_context(valdtr, ext_testsuite_my_id, ctx); -static bool tsto_message_set_member(int id, string_t *value) -{ - if ( id != -1 ) return FALSE; - - testsuite_message_set(value); - return TRUE; } diff --git a/src/testsuite/testsuite-common.h b/src/testsuite/testsuite-common.h index 2d878b3152ee61920e233452d5db089a7249ee4a..0cac40c8b6d5b034b5a7a8d6e632360228790d93 100644 --- a/src/testsuite/testsuite-common.h +++ b/src/testsuite/testsuite-common.h @@ -1,5 +1,5 @@ -#ifndef __EXT_TESTSUITE_COMMON_H -#define __EXT_TESTSUITE_COMMON_H +#ifndef __TESTSUITE_COMMON_H +#define __TESTSUITE_COMMON_H extern const struct sieve_extension testsuite_extension; @@ -16,51 +16,18 @@ void testsuite_message_set(string_t *message); /* Testsuite validator context */ +struct testsuite_validator_context { + struct hash_table *object_registrations; +}; + bool testsuite_validator_context_initialize(struct sieve_validator *valdtr); /* Testsuite operands */ -struct testsuite_object_operand_interface { - struct sieve_extension_obj_registry testsuite_objects; -}; - -extern const struct sieve_operand_class testsuite_object_oprclass; extern const struct sieve_operand testsuite_object_operand; enum testsuite_operand_code { TESTSUITE_OPERAND_OBJECT }; -/* Testsuite object access */ - -struct testsuite_object { - const char *identifier; - unsigned int code; - const struct sieve_operand *operand; - - int (*get_member_id)(const char *identifier); - bool (*set_member)(int id, string_t *value); - string_t *(*get_member)(int id); -}; - -const struct testsuite_object *testsuite_object_find - (struct sieve_validator *valdtr, const char *identifier, int *ext_id); -void testsuite_object_register - (struct sieve_validator *valdtr, const struct testsuite_object *obj, - int ext_id); - -const struct testsuite_object *testsuite_object_read - (struct sieve_binary *sbin, sieve_size_t *address); -bool testsuite_object_dump - (const struct sieve_dumptime_env *denv, sieve_size_t *address); - -bool testsuite_object_argument_activate - (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, - struct sieve_command_context *cmd); - -/* Testsuite core objects */ - -extern const struct testsuite_object message_testsuite_object; -extern const struct testsuite_object envelope_testsuite_object; - -#endif +#endif /* __TESTSUITE_COMMON_H */ diff --git a/src/testsuite/testsuite-objects.c b/src/testsuite/testsuite-objects.c new file mode 100644 index 0000000000000000000000000000000000000000..5ddf0fda4b11848629c55bdd9efd1726524bca22 --- /dev/null +++ b/src/testsuite/testsuite-objects.c @@ -0,0 +1,259 @@ +#include "lib.h" +#include "string.h" +#include "ostream.h" +#include "hash.h" +#include "mail-storage.h" + +#include "mail-raw.h" +#include "namespaces.h" +#include "sieve.h" +#include "sieve-code.h" +#include "sieve-commands.h" +#include "sieve-extensions-private.h" +#include "sieve-validator.h" +#include "sieve-generator.h" +#include "sieve-dump.h" + +#include "testsuite-common.h" +#include "testsuite-objects.h" + +/* + * Types + */ + +struct testsuite_object_registration { + int ext_id; + const struct testsuite_object *object; +}; + +/* + * Testsuite core objects + */ + +enum testsuite_object_code { + TESTSUITE_OBJECT_MESSAGE, + TESTSUITE_OBJECT_ENVELOPE +}; + +const struct testsuite_object *testsuite_core_objects[] = { + &message_testsuite_object, &envelope_testsuite_object +}; + +const unsigned int testsuite_core_objects_count = + N_ELEMENTS(testsuite_core_objects); + +/* + * Forward declarations + */ + +static void _testsuite_object_register + (pool_t pool, struct testsuite_validator_context *ctx, + const struct testsuite_object *obj, int ext_id); + +/* + * Testsuite object registry + */ + +static inline struct testsuite_validator_context * + _get_validator_context(struct sieve_validator *valdtr) +{ + return (struct testsuite_validator_context *) + sieve_validator_extension_get_context(valdtr, ext_testsuite_my_id); +} + +static void _testsuite_object_register +(pool_t pool, struct testsuite_validator_context *ctx, + const struct testsuite_object *obj, int ext_id) +{ + struct testsuite_object_registration *reg; + + reg = p_new(pool, struct testsuite_object_registration, 1); + reg->object = obj; + reg->ext_id = ext_id; + + hash_insert(ctx->object_registrations, (void *) obj->identifier, (void *) reg); +} + +void testsuite_object_register +(struct sieve_validator *valdtr, const struct testsuite_object *obj, int ext_id) +{ + pool_t pool = sieve_validator_pool(valdtr); + struct testsuite_validator_context *ctx = _get_validator_context(valdtr); + + _testsuite_object_register(pool, ctx, obj, ext_id); +} + +const struct testsuite_object *testsuite_object_find +(struct sieve_validator *valdtr, const char *identifier, int *ext_id) +{ + struct testsuite_validator_context *ctx = _get_validator_context(valdtr); + struct testsuite_object_registration *reg = + (struct testsuite_object_registration *) + hash_lookup(ctx->object_registrations, identifier); + + if ( reg == NULL ) return NULL; + + if ( ext_id != NULL ) *ext_id = reg->ext_id; + + return reg->object; +} + +void testsuite_register_core_objects + (pool_t pool, struct testsuite_validator_context *ctx) +{ + unsigned int i; + + /* Register core testsuite objects */ + for ( i = 0; i < testsuite_core_objects_count; i++ ) { + const struct testsuite_object *object = testsuite_core_objects[i]; + + _testsuite_object_register(pool, ctx, object, ext_testsuite_my_id); + } +} + +/* + * Testsuite object code + */ + +const struct sieve_operand_class testsuite_object_oprclass = + { "testsuite-object" }; + +const struct testsuite_object_operand_interface testsuite_object_oprint = { + SIEVE_EXT_DEFINE_OBJECTS(testsuite_core_objects) +}; + +const struct sieve_operand testsuite_object_operand = { + "testsuite-object", + &testsuite_extension, + TESTSUITE_OPERAND_OBJECT, + &testsuite_object_oprclass, + &testsuite_object_oprint +}; + +static void testsuite_object_emit + (struct sieve_binary *sbin, const struct testsuite_object *obj, int ext_id) +{ + (void) sieve_operand_emit_code(sbin, obj->operand, ext_id); + (void) sieve_binary_emit_byte(sbin, obj->code); +} + +const struct testsuite_object *testsuite_object_read +(struct sieve_binary *sbin, sieve_size_t *address) +{ + const struct sieve_operand *operand; + const struct testsuite_object_operand_interface *intf; + unsigned int obj_code; + + operand = sieve_operand_read(sbin, address); + if ( operand == NULL || operand->class != &testsuite_object_oprclass ) + return NULL; + + intf = operand->interface; + if ( intf == NULL ) + return NULL; + + if ( !sieve_binary_read_byte(sbin, address, &obj_code) ) + return NULL; + + return sieve_extension_get_object + (struct testsuite_object, intf->testsuite_objects, obj_code); +} + +bool testsuite_object_dump +(const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + const struct testsuite_object *object; + + sieve_code_mark(denv); + + if ( (object = testsuite_object_read(denv->sbin, address)) == NULL ) + return FALSE; + + sieve_code_dumpf(denv, "TESTSUITE_OBJECT: %s", object->identifier); + + return TRUE; +} + +/* + * Testsuite object argument + */ + +static bool arg_testsuite_object_generate + (struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd); + +const struct sieve_argument testsuite_object_argument = + { "testsuite-object", NULL, NULL, NULL, arg_testsuite_object_generate }; + +struct testsuite_object_argctx { + const struct testsuite_object *object; + int ext_id; +}; + +bool testsuite_object_argument_activate +(struct sieve_validator *valdtr, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd) +{ + const char *objname = sieve_ast_argument_strc(arg); + const struct testsuite_object *object; + int ext_id; + struct testsuite_object_argctx *ctx; + + object = testsuite_object_find(valdtr, objname, &ext_id); + if ( object == NULL ) { + sieve_command_validate_error(valdtr, cmd, + "unknown testsuite object '%s'", objname); + return FALSE; + } + + ctx = p_new(sieve_command_pool(cmd), struct testsuite_object_argctx, 1); + ctx->object = object; + ctx->ext_id = ext_id; + + arg->argument = &testsuite_object_argument; + arg->context = (void *) ctx; + + return TRUE; +} + +static bool arg_testsuite_object_generate + (struct sieve_generator *generator, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd ATTR_UNUSED) +{ + struct sieve_binary *sbin = sieve_generator_get_binary(generator); + struct testsuite_object_argctx *ctx = + (struct testsuite_object_argctx *) arg->context; + + testsuite_object_emit(sbin, ctx->object, ctx->ext_id); + + return TRUE; +} + +/* + * Testsuite core object implementation + */ + +static bool tsto_message_set_member(int id, string_t *value); + +const struct testsuite_object message_testsuite_object = { + "message", + TESTSUITE_OBJECT_MESSAGE, + &testsuite_object_operand, + NULL, tsto_message_set_member, NULL +}; + +const struct testsuite_object envelope_testsuite_object = { + "envelope", + TESTSUITE_OBJECT_ENVELOPE, + &testsuite_object_operand, + NULL, NULL, NULL +}; + +static bool tsto_message_set_member(int id, string_t *value) +{ + if ( id != -1 ) return FALSE; + + testsuite_message_set(value); + + return TRUE; +} diff --git a/src/testsuite/testsuite-objects.h b/src/testsuite/testsuite-objects.h new file mode 100644 index 0000000000000000000000000000000000000000..a8e2b97d1af8e281aaa6adc1d64915949976cef3 --- /dev/null +++ b/src/testsuite/testsuite-objects.h @@ -0,0 +1,54 @@ +#ifndef __TESTSUITE_OBJECTS_H +#define __TESTSUITE_OBJECTS_H + +#include "testsuite-common.h" + +/* Testsuite object operand */ + +struct testsuite_object_operand_interface { + struct sieve_extension_obj_registry testsuite_objects; +}; + +extern const struct sieve_operand_class testsuite_object_oprclass; + +/* Testsuite object access */ + +struct testsuite_object { + const char *identifier; + unsigned int code; + const struct sieve_operand *operand; + + int (*get_member_id)(const char *identifier); + bool (*set_member)(int id, string_t *value); + string_t *(*get_member)(int id); +}; + +/* Testsuite object registration */ + +const struct testsuite_object *testsuite_object_find + (struct sieve_validator *valdtr, const char *identifier, int *ext_id); +void testsuite_object_register + (struct sieve_validator *valdtr, const struct testsuite_object *obj, + int ext_id); +void testsuite_register_core_objects + (pool_t pool, struct testsuite_validator_context *ctx); + +/* Testsuite object argument */ + +bool testsuite_object_argument_activate + (struct sieve_validator *valdtr, struct sieve_ast_argument *arg, + struct sieve_command_context *cmd); + +/* Testsuite object code */ + +const struct testsuite_object *testsuite_object_read + (struct sieve_binary *sbin, sieve_size_t *address); +bool testsuite_object_dump + (const struct sieve_dumptime_env *denv, sieve_size_t *address); + +/* Testsuite core objects */ + +extern const struct testsuite_object message_testsuite_object; +extern const struct testsuite_object envelope_testsuite_object; + +#endif /* __TESTSUITE_OBJECTS_H */