1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/* Copyright (c) 2002-2016 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, 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;
}
|