1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
6
#include "str-sanitize.h"
9
#include "sieve-common.h"
10
#include "sieve-ast.h"
11
#include "sieve-commands.h"
12
#include "sieve-code.h"
13
#include "sieve-validator.h"
14
#include "sieve-generator.h"
15
#include "sieve-dump.h"
17
#include "testsuite-common.h"
18
#include "testsuite-substitutions.h"
19
#include "testsuite-arguments.h"
24
* Testsuite string argument
27
static bool arg_testsuite_string_validate
28
(struct sieve_validator *validator, struct sieve_ast_argument **arg,
29
struct sieve_command_context *context);
31
const struct sieve_argument testsuite_string_argument = {
34
arg_testsuite_string_validate,
36
sieve_arg_catenated_string_generate,
39
static bool arg_testsuite_string_validate
40
(struct sieve_validator *valdtr, struct sieve_ast_argument **arg,
41
struct sieve_command_context *cmd)
43
enum { ST_NONE, ST_OPEN, ST_SUBSTITUTION, ST_PARAM, ST_CLOSE } state =
45
pool_t pool = sieve_ast_pool((*arg)->ast);
46
struct sieve_arg_catenated_string *catstr = NULL;
47
string_t *str = sieve_ast_argument_str(*arg);
48
const char *p, *strstart, *substart = NULL;
49
const char *strval = (const char *) str_data(str);
50
const char *strend = strval + str_len(str);
52
string_t *subs_name = t_str_new(256);
53
string_t *subs_param = t_str_new(256);
56
/* Initialize substitution structure */
60
while ( result && p < strend ) {
63
/* Nothing found yet */
68
str_truncate(subs_name, 0);
69
str_truncate(subs_param, 0);
77
state = ST_SUBSTITUTION;
87
while ( *p != '}' && *p != ':' ) {
88
if ( !i_isalnum(*p) ) {
92
str_append_c(subs_name, *p);
101
while ( *p != '}' ) {
102
str_append_c(subs_param, *p);
109
/* Finished parsing param, expecting '}' */
112
struct sieve_ast_argument *strarg;
114
/* We now know that the substitution is valid */
116
if ( catstr == NULL ) {
117
catstr = sieve_arg_catenated_string_create(*arg);
120
/* Add the substring that is before the substitution to the
121
* variable-string AST.
123
if ( substart > strstart ) {
124
string_t *newstr = str_new(pool, substart - strstart);
125
str_append_n(newstr, strstart, substart - strstart);
127
strarg = sieve_ast_argument_string_create_raw
128
((*arg)->ast, newstr, (*arg)->source_line);
129
sieve_arg_catenated_string_add_element(catstr, strarg);
131
/* Give other substitution extensions a chance to do their work */
132
if ( !sieve_validator_argument_activate_super
133
(valdtr, cmd, strarg, FALSE) ) {
139
strarg = testsuite_substitution_argument_create
140
(valdtr, (*arg)->ast, (*arg)->source_line, str_c(subs_name),
143
if ( strarg != NULL )
144
sieve_arg_catenated_string_add_element(catstr, strarg);
146
sieve_argument_validate_error(valdtr, *arg,
147
"unknown testsuite substitution type '%s'", str_c(subs_name));
156
/* Finished, reset for the next substitution */
162
/* Bail out early if substitution is invalid */
163
if ( !result ) return FALSE;
165
/* Check whether any substitutions were found */
166
if ( catstr == NULL ) {
167
/* No substitutions in this string, pass it on to any other substution
170
return sieve_validator_argument_activate_super(valdtr, cmd, *arg, TRUE);
173
/* Add the final substring that comes after the last substitution to the
174
* variable-string AST.
176
if ( strend > strstart ) {
177
struct sieve_ast_argument *strarg;
178
string_t *newstr = str_new(pool, strend - strstart);
179
str_append_n(newstr, strstart, strend - strstart);
181
strarg = sieve_ast_argument_string_create_raw
182
((*arg)->ast, newstr, (*arg)->source_line);
183
sieve_arg_catenated_string_add_element(catstr, strarg);
185
/* Give other substitution extensions a chance to do their work */
186
if ( !sieve_validator_argument_activate_super
187
(valdtr, cmd, strarg, FALSE) )