/src/pigeonhole/src/lib-sieve/plugins/variables/ext-variables-dump.c
Line | Count | Source |
1 | | /* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file |
2 | | */ |
3 | | |
4 | | #include "lib.h" |
5 | | #include "str.h" |
6 | | |
7 | | #include "sieve-common.h" |
8 | | #include "sieve-dump.h" |
9 | | #include "sieve-binary.h" |
10 | | #include "sieve-code.h" |
11 | | |
12 | | #include "ext-variables-common.h" |
13 | | #include "ext-variables-dump.h" |
14 | | |
15 | | /* |
16 | | * Code dumper extension |
17 | | */ |
18 | | |
19 | | static void ext_variables_code_dumper_free |
20 | | (struct sieve_code_dumper *dumper, void *context); |
21 | | |
22 | | static const struct sieve_code_dumper_extension |
23 | | variables_dump_extension = { |
24 | | &variables_extension, |
25 | | ext_variables_code_dumper_free |
26 | | }; |
27 | | |
28 | | /* |
29 | | * Code dump context |
30 | | */ |
31 | | |
32 | | struct ext_variables_dump_context { |
33 | | struct sieve_variable_scope *local_scope; |
34 | | ARRAY(struct sieve_variable_scope *) ext_scopes; |
35 | | }; |
36 | | |
37 | | static void ext_variables_code_dumper_free |
38 | | (struct sieve_code_dumper *dumper ATTR_UNUSED, void *context) |
39 | 0 | { |
40 | 0 | struct ext_variables_dump_context *dctx = |
41 | 0 | (struct ext_variables_dump_context *) context; |
42 | |
|
43 | 0 | if ( dctx == NULL || dctx->local_scope == NULL ) |
44 | 0 | return; |
45 | | |
46 | 0 | sieve_variable_scope_unref(&dctx->local_scope); |
47 | 0 | } |
48 | | |
49 | | static struct ext_variables_dump_context *ext_variables_dump_get_context |
50 | | (const struct sieve_extension *this_ext, const struct sieve_dumptime_env *denv) |
51 | 0 | { |
52 | 0 | struct sieve_code_dumper *dumper = denv->cdumper; |
53 | 0 | struct ext_variables_dump_context *dctx; |
54 | 0 | pool_t pool; |
55 | |
|
56 | 0 | i_assert( sieve_extension_is(this_ext, variables_extension) ); |
57 | 0 | dctx = sieve_dump_extension_get_context(dumper, this_ext); |
58 | |
|
59 | 0 | if ( dctx == NULL ) { |
60 | | /* Create dumper context */ |
61 | 0 | pool = sieve_code_dumper_pool(dumper); |
62 | 0 | dctx = p_new(pool, struct ext_variables_dump_context, 1); |
63 | 0 | p_array_init(&dctx->ext_scopes, pool, |
64 | 0 | sieve_extensions_get_count(this_ext->svinst)); |
65 | |
|
66 | 0 | sieve_dump_extension_register |
67 | 0 | (dumper, this_ext, &variables_dump_extension, dctx); |
68 | 0 | } |
69 | |
|
70 | 0 | return dctx; |
71 | 0 | } |
72 | | |
73 | | bool ext_variables_code_dump |
74 | | (const struct sieve_extension *ext, |
75 | | const struct sieve_dumptime_env *denv, sieve_size_t *address) |
76 | 0 | { |
77 | 0 | struct ext_variables_dump_context *dctx; |
78 | 0 | struct sieve_variable_scope *local_scope; |
79 | |
|
80 | 0 | local_scope = sieve_variable_scope_binary_dump |
81 | 0 | (ext->svinst, ext, NULL, denv, address); |
82 | |
|
83 | 0 | dctx = ext_variables_dump_get_context(ext, denv); |
84 | 0 | dctx->local_scope = local_scope; |
85 | |
|
86 | 0 | return TRUE; |
87 | 0 | } |
88 | | |
89 | | /* |
90 | | * Scope registry |
91 | | */ |
92 | | |
93 | | void sieve_ext_variables_dump_set_scope |
94 | | (const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, |
95 | | const struct sieve_extension *ext, struct sieve_variable_scope *scope) |
96 | 0 | { |
97 | 0 | struct ext_variables_dump_context *dctx = |
98 | 0 | ext_variables_dump_get_context(var_ext, denv); |
99 | |
|
100 | 0 | if ( ext->id < 0 ) return; |
101 | | |
102 | 0 | array_idx_set(&dctx->ext_scopes, (unsigned int) ext->id, &scope); |
103 | 0 | } |
104 | | |
105 | | /* |
106 | | * Variable identifier dump |
107 | | */ |
108 | | |
109 | | const char *ext_variables_dump_get_identifier |
110 | | (const struct sieve_extension *var_ext, const struct sieve_dumptime_env *denv, |
111 | | const struct sieve_extension *ext, unsigned int index) |
112 | 0 | { |
113 | 0 | struct ext_variables_dump_context *dctx = |
114 | 0 | ext_variables_dump_get_context(var_ext, denv); |
115 | 0 | struct sieve_variable_scope *scope; |
116 | 0 | struct sieve_variable *var; |
117 | |
|
118 | 0 | if ( ext == NULL ) |
119 | 0 | scope = dctx->local_scope; |
120 | 0 | else { |
121 | 0 | struct sieve_variable_scope *const *ext_scope; |
122 | |
|
123 | 0 | if ( ext->id < 0 || ext->id >= (int) array_count(&dctx->ext_scopes) ) |
124 | 0 | return NULL; |
125 | | |
126 | 0 | ext_scope = array_idx(&dctx->ext_scopes, (unsigned int) ext->id); |
127 | 0 | scope = *ext_scope; |
128 | 0 | } |
129 | | |
130 | 0 | if ( scope == NULL ) |
131 | 0 | return NULL; |
132 | | |
133 | 0 | var = sieve_variable_scope_get_indexed(scope, index); |
134 | |
|
135 | 0 | return var->identifier; |
136 | 0 | } |
137 | | |