1
/* Copyright (c) 2002-2009 Dovecot Sieve authors, see the included COPYING file
4
#include "sieve-common.h"
5
#include "sieve-commands.h"
6
#include "sieve-generator.h"
7
#include "sieve-validator.h"
8
#include "sieve-binary.h"
9
#include "sieve-code.h"
10
#include "sieve-binary.h"
16
* anyof <tests: test-list>
19
static bool tst_anyof_generate
20
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
21
struct sieve_jumplist *jumps, bool jump_true);
23
const struct sieve_command tst_anyof = {
27
NULL, NULL, NULL, NULL,
35
static bool tst_anyof_generate
36
(const struct sieve_codegen_env *cgenv, struct sieve_command_context *ctx,
37
struct sieve_jumplist *jumps, bool jump_true)
39
struct sieve_binary *sbin = cgenv->sbin;
40
struct sieve_ast_node *test;
41
struct sieve_jumplist true_jumps;
43
if ( sieve_ast_test_count(ctx->ast_node) > 1 ) {
45
/* Prepare jumplist */
46
sieve_jumplist_init_temp(&true_jumps, sbin);
49
test = sieve_ast_test_first(ctx->ast_node);
50
while ( test != NULL ) {
53
/* If this test list must jump on true, all sub-tests can simply add their jumps
54
* to the caller's jump list, otherwise this test redirects all true jumps to the
55
* end of the currently generated code. This is just after a final jump to the false
59
result = sieve_generate_test(cgenv, test, &true_jumps, TRUE);
61
result = sieve_generate_test(cgenv, test, jumps, TRUE);
63
if ( !result ) return FALSE;
65
test = sieve_ast_test_next(test);
69
/* All tests failed, jump to case FALSE */
70
sieve_operation_emit_code(sbin, &sieve_jmp_operation);
71
sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0));
73
/* All true exits jump here */
74
sieve_jumplist_resolve(&true_jumps);
77
/* Script author is being inefficient; we can optimize the allof test away */
78
test = sieve_ast_test_first(ctx->ast_node);
79
sieve_generate_test(cgenv, test, jumps, jump_true);