diff options
Diffstat (limited to 'pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c')
-rw-r--r-- | pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c b/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c new file mode 100644 index 0000000..26bd015 --- /dev/null +++ b/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c @@ -0,0 +1,137 @@ +/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file + */ + +#include "lib.h" +#include "str.h" + +#include "sieve-common.h" +#include "sieve-dump.h" +#include "sieve-binary.h" +#include "sieve-code.h" + +#include "ext-variables-common.h" +#include "ext-variables-dump.h" + +/* + * Code dumper extension + */ + +static void ext_variables_code_dumper_free + (struct sieve_code_dumper *dumper, void *context); + +static const struct sieve_code_dumper_extension +variables_dump_extension = { + &variables_extension, + ext_variables_code_dumper_free +}; + +/* + * Code dump context + */ + +struct ext_variables_dump_context { + struct sieve_variable_scope *local_scope; + ARRAY(struct sieve_variable_scope *) ext_scopes; +}; + +static void ext_variables_code_dumper_free +(struct sieve_code_dumper *dumper ATTR_UNUSED, void *context) +{ + struct ext_variables_dump_context *dctx = + (struct ext_variables_dump_context *) context; + + if ( dctx == NULL || dctx->local_scope == NULL ) + return; + + sieve_variable_scope_unref(&dctx->local_scope); +} + +static struct ext_variables_dump_context *ext_variables_dump_get_context +(const struct sieve_extension *this_ext, const struct sieve_dumptime_env *denv) +{ + struct sieve_code_dumper *dumper = denv->cdumper; + struct ext_variables_dump_context *dctx; + pool_t pool; + + i_assert( sieve_extension_is(this_ext, variables_extension) ); + dctx = sieve_dump_extension_get_context(dumper, this_ext); + + if ( dctx == NULL ) { + /* Create dumper context */ + pool = sieve_code_dumper_pool(dumper); + dctx = p_new(pool, struct ext_variables_dump_context, 1); + p_array_init(&dctx->ext_scopes, pool, + sieve_extensions_get_count(this_ext->svinst)); + + sieve_dump_extension_register + (dumper, this_ext, &variables_dump_extension, dctx); + } + + return dctx; +} + +bool ext_variables_code_dump +(const struct sieve_extension *ext, + const struct sieve_dumptime_env *denv, sieve_size_t *address) +{ + struct ext_variables_dump_context *dctx; + struct sieve_variable_scope *local_scope; + + local_scope = sieve_variable_scope_binary_dump + (ext->svinst, ext, NULL, denv, address); + + dctx = ext_variables_dump_get_context(ext, denv); + dctx->local_scope = local_scope; + + return TRUE; +} + +/* + * Scope registry + */ + +void sieve_ext_variables_dump_set_scope +(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, + const struct sieve_extension *ext, struct sieve_variable_scope *scope) +{ + struct ext_variables_dump_context *dctx = + ext_variables_dump_get_context(var_ext, denv); + + if ( ext->id < 0 ) return; + + array_idx_set(&dctx->ext_scopes, (unsigned int) ext->id, &scope); +} + +/* + * Variable identifier dump + */ + +const char *ext_variables_dump_get_identifier +(const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, + const struct sieve_extension *ext, unsigned int index) +{ + struct ext_variables_dump_context *dctx = + ext_variables_dump_get_context(var_ext, denv); + struct sieve_variable_scope *scope; + struct sieve_variable *var; + + if ( ext == NULL ) + scope = dctx->local_scope; + else { + struct sieve_variable_scope *const *ext_scope; + + if ( ext->id < 0 || ext->id >= (int) array_count(&dctx->ext_scopes) ) + return NULL; + + ext_scope = array_idx(&dctx->ext_scopes, (unsigned int) ext->id); + scope = *ext_scope; + } + + if ( scope == NULL ) + return NULL; + + var = sieve_variable_scope_get_indexed(scope, index); + + return var->identifier; +} + |