summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c
diff options
context:
space:
mode:
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.c137
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;
+}
+