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->sblock, tsctx->tsub, tsctx->param);
139
139
(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd,
140
140
sieve_size_t *address);
141
141
static int opr_substitution_read_value
142
(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
142
(const struct sieve_runtime_env *renv, const struct sieve_operand *oprnd,
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, const struct sieve_operand *oprnd,
171
sieve_size_t *address)
170
(const struct sieve_dumptime_env *denv, const struct sieve_operand *oprnd,
171
sieve_size_t *address)
173
173
unsigned int code = 0;
174
174
const struct testsuite_substitution_def *tsub;
177
177
if ( !sieve_binary_read_unsigned(denv->sblock, address, &code) )
180
180
tsub = testsuite_substitution_get(code);
181
181
if ( tsub == NULL )
184
184
if ( !sieve_binary_read_string(denv->sblock, address, ¶m) )
187
if ( oprnd->field_name != NULL )
188
sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}",
187
if ( oprnd->field_name != NULL )
188
sieve_code_dumpf(denv, "%s: TEST_SUBS %%{%s:%s}",
189
189
oprnd->field_name, tsub->obj_def.identifier, str_c(param));
191
sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}",
191
sieve_code_dumpf(denv, "TEST_SUBS %%{%s:%s}",
192
192
tsub->obj_def.identifier, str_c(param));
196
196
static int opr_substitution_read_value
197
(const struct sieve_runtime_env *renv,
198
const struct sieve_operand *oprnd ATTR_UNUSED, sieve_size_t *address,
197
(const struct sieve_runtime_env *renv,
198
const struct sieve_operand *oprnd ATTR_UNUSED, sieve_size_t *address,
199
199
string_t **str_r)
201
201
const struct testsuite_substitution_def *tsub;
202
202
unsigned int code = 0;
205
205
if ( !sieve_binary_read_unsigned(renv->sblock, address, &code) )
206
206
return SIEVE_EXEC_BIN_CORRUPT;
208
208
tsub = testsuite_substitution_get(code);
209
209
if ( tsub == NULL )
210
return SIEVE_EXEC_FAILURE;
210
return SIEVE_EXEC_FAILURE;
212
/* Parameter str can be NULL if we are requested to only skip and not
212
/* Parameter str can be NULL if we are requested to only skip and not
213
213
* actually read the argument.
215
215
if ( str_r == NULL ) {
216
216
if ( !sieve_binary_read_string(renv->sblock, address, NULL) )
217
217
return SIEVE_EXEC_BIN_CORRUPT;
219
219
return SIEVE_EXEC_OK;
222
222
if ( !sieve_binary_read_string(renv->sblock, address, ¶m) )
223
223
return SIEVE_EXEC_BIN_CORRUPT;
225
225
if ( !tsub->get_value(str_c(param), str_r) )
226
226
return SIEVE_EXEC_FAILURE;
228
228
return SIEVE_EXEC_OK;
232
232
* Testsuite substitution definitions
235
235
static bool testsuite_file_substitution_get_value
236
(const char *param, string_t **result);
236
(const char *param, string_t **result);
238
238
static const struct testsuite_substitution_def testsuite_file_substitution = {
241
&testsuite_substitution_operand,
241
&testsuite_substitution_operand,
242
242
TESTSUITE_SUBSTITUTION_FILE
244
244
testsuite_file_substitution_get_value