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