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-validator.h"
7
#include "sieve-generator.h"
8
#include "sieve-binary.h"
9
#include "sieve-code.h"
10
#include "sieve-binary.h"
16
* allof <tests: test-list>
19
static bool tst_allof_generate
20
(const struct sieve_codegen_env *cgenv,
21
struct sieve_command_context *ctx,
22
struct sieve_jumplist *jumps, bool jump_true);
24
const struct sieve_command tst_allof = {
28
NULL, NULL, NULL, NULL,
36
static bool tst_allof_generate
37
(const struct sieve_codegen_env *cgenv,
38
struct sieve_command_context *ctx,
39
struct sieve_jumplist *jumps, bool jump_true)
41
struct sieve_binary *sbin = cgenv->sbin;
42
struct sieve_ast_node *test;
43
struct sieve_jumplist false_jumps;
45
if ( sieve_ast_test_count(ctx->ast_node) > 1 ) {
47
/* Prepare jumplist */
48
sieve_jumplist_init_temp(&false_jumps, sbin);
51
test = sieve_ast_test_first(ctx->ast_node);
52
while ( test != NULL ) {
55
/* If this test list must jump on false, all sub-tests can simply add their jumps
56
* to the caller's jump list, otherwise this test redirects all false jumps to the
57
* end of the currently generated code. This is just after a final jump to the true
61
result = sieve_generate_test(cgenv, test, &false_jumps, FALSE);
63
result = sieve_generate_test(cgenv, test, jumps, FALSE);
65
if ( !result ) return FALSE;
67
test = sieve_ast_test_next(test);
71
/* All tests succeeded, jump to case TRUE */
72
sieve_operation_emit_code(cgenv->sbin, &sieve_jmp_operation);
73
sieve_jumplist_add(jumps, sieve_binary_emit_offset(sbin, 0));
75
/* All false exits jump here */
76
sieve_jumplist_resolve(&false_jumps);
79
/* Script author is being inefficient; we can optimize the allof test away */
80
test = sieve_ast_test_first(ctx->ast_node);
81
sieve_generate_test(cgenv, test, jumps, jump_true);