41
41
static const unsigned int substitutions_count = N_ELEMENTS(substitutions);
43
43
static inline const struct testsuite_substitution_def *
44
44
testsuite_substitution_get
45
45
(unsigned int code)
47
47
if ( code > substitutions_count )
50
50
return substitutions[code];
53
53
static const struct testsuite_substitution *testsuite_substitution_create
54
54
(struct sieve_ast *ast, const char *identifier)
58
58
for ( i = 0; i < substitutions_count; i++ ) {
59
59
if ( strcasecmp(substitutions[i]->obj_def.identifier, identifier) == 0 ) {
60
60
const struct testsuite_substitution_def *tsub_def = substitutions[i];
63
63
tsub = p_new(sieve_ast_pool(ast), struct testsuite_substitution, 1);
64
64
tsub->object.def = &tsub_def->obj_def;
65
65
tsub->object.ext = testsuite_ext;
76
76
* Substitution argument
79
79
static bool arg_testsuite_substitution_generate
80
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
80
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
81
81
struct sieve_command *context);
83
83
struct _testsuite_substitution_context {
88
const struct sieve_argument_def testsuite_substitution_argument = {
89
"@testsuite-substitution",
88
const struct sieve_argument_def testsuite_substitution_argument = {
89
"@testsuite-substitution",
90
90
NULL, NULL, NULL, NULL,
91
arg_testsuite_substitution_generate
91
arg_testsuite_substitution_generate
94
94
struct sieve_ast_argument *testsuite_substitution_argument_create
95
(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast *ast,
95
(struct sieve_validator *valdtr ATTR_UNUSED, struct sieve_ast *ast,
96
96
unsigned int source_line, const char *substitution, const char *param)
98
98
const struct testsuite_substitution *tsub;
99
99
struct _testsuite_substitution_context *tsctx;
100
100
struct sieve_ast_argument *arg;
103
103
tsub = testsuite_substitution_create(ast, substitution);
107
107
arg = sieve_ast_argument_create(ast, source_line);
108
108
arg->type = SAAT_STRING;
122
122
static bool arg_testsuite_substitution_generate
123
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
123
(const struct sieve_codegen_env *cgenv, struct sieve_ast_argument *arg,
124
124
struct sieve_command *context ATTR_UNUSED)
126
struct _testsuite_substitution_context *tsctx =
126
struct _testsuite_substitution_context *tsctx =
127
127
(struct _testsuite_substitution_context *) arg->argument->data;
129
129
testsuite_opr_substitution_emit(cgenv->sbin, tsctx->tsub, tsctx->param);
139
139
(const struct sieve_dumptime_env *denv, const struct sieve_operand *opr,
140
140
sieve_size_t *address, const char *field_name);
141
141
static bool opr_substitution_read_value
142
(const struct sieve_runtime_env *renv, const struct sieve_operand *opr,
142
(const struct sieve_runtime_env *renv, const struct sieve_operand *opr,
143
143
sieve_size_t *address, string_t **str);
145
const struct sieve_opr_string_interface testsuite_substitution_interface = {
145
const struct sieve_opr_string_interface testsuite_substitution_interface = {
146
146
opr_substitution_dump,
147
147
opr_substitution_read_value
150
const struct sieve_operand_def testsuite_substitution_operand = {
152
&testsuite_extension,
150
const struct sieve_operand_def testsuite_substitution_operand = {
152
&testsuite_extension,
153
153
TESTSUITE_OPERAND_SUBSTITUTION,
155
155
&testsuite_substitution_interface
169
169
static bool opr_substitution_dump
170
(const struct sieve_dumptime_env *denv,
170
(const struct sieve_dumptime_env *denv,
171
171
const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address,
172
const char *field_name)
172
const char *field_name)
174
174
unsigned int code = 0;
175
175
const struct testsuite_substitution_def *tsub;
178
178
if ( !sieve_binary_read_unsigned(denv->sbin, address, &code) )
181
181
tsub = testsuite_substitution_get(code);
182
182
if ( tsub == NULL )
185
185
if ( !sieve_binary_read_string(denv->sbin, address, ¶m) )
188
if ( field_name != NULL )
189
sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}",
188
if ( field_name != NULL )
189
sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}",
190
190
field_name, tsub->obj_def.identifier, str_c(param));
192
sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}",
192
sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}",
193
193
tsub->obj_def.identifier, str_c(param));
197
197
static bool opr_substitution_read_value
198
(const struct sieve_runtime_env *renv,
199
const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address,
198
(const struct sieve_runtime_env *renv,
199
const struct sieve_operand *opr ATTR_UNUSED, sieve_size_t *address,
202
202
const struct testsuite_substitution_def *tsub;
203
203
unsigned int code = 0;
206
206
if ( !sieve_binary_read_unsigned(renv->sbin, address, &code) )
209
209
tsub = testsuite_substitution_get(code);
210
210
if ( tsub == NULL )
213
/* Parameter str can be NULL if we are requested to only skip and not
213
/* Parameter str can be NULL if we are requested to only skip and not
214
214
* actually read the argument.
217
217
return sieve_binary_read_string(renv->sbin, address, NULL);
219
219
if ( !sieve_binary_read_string(renv->sbin, address, ¶m) )
222
222
return tsub->get_value(str_c(param), str);
226
226
* Testsuite substitution definitions
229
229
static bool testsuite_file_substitution_get_value
230
(const char *param, string_t **result);
230
(const char *param, string_t **result);
232
232
static const struct testsuite_substitution_def testsuite_file_substitution = {
235
&testsuite_substitution_operand,
235
&testsuite_substitution_operand,
236
236
TESTSUITE_SUBSTITUTION_FILE
238
238
testsuite_file_substitution_get_value