File: mcht-count.c

package info (click to toggle)
dovecot 1:2.2.13-12~deb8u4
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 38,792 kB
  • sloc: ansic: 341,472; sh: 16,920; makefile: 5,393; cpp: 1,474; perl: 265; xml: 44; python: 34; pascal: 27
file content (121 lines) | stat: -rw-r--r-- 2,997 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* Copyright (c) 2002-2013 Pigeonhole authors, see the included COPYING file
 */

/* Match-type ':count'
 */

#include "lib.h"
#include "str.h"
#include "str-sanitize.h"

#include "sieve-common.h"
#include "sieve-ast.h"
#include "sieve-stringlist.h"
#include "sieve-code.h"
#include "sieve-extensions.h"
#include "sieve-commands.h"
#include "sieve-comparators.h"
#include "sieve-match-types.h"
#include "sieve-validator.h"
#include "sieve-generator.h"
#include "sieve-interpreter.h"
#include "sieve-runtime-trace.h"
#include "sieve-match.h"

#include "ext-relational-common.h"

/*
 * Forward declarations
 */

static int mcht_count_match
	(struct sieve_match_context *mctx, struct sieve_stringlist *value_list,
		struct sieve_stringlist *key_list);

/*
 * Match-type objects
 */

const struct sieve_match_type_def count_match_type = {
	SIEVE_OBJECT("count", &rel_match_type_operand, RELATIONAL_COUNT),
	mcht_relational_validate,
	NULL, NULL, NULL, NULL, NULL, NULL
};

#define COUNT_MATCH_TYPE(name, rel_match)                      \
const struct sieve_match_type_def rel_match_count_ ## name = { \
	SIEVE_OBJECT(                                                \
		"count-" #name, &rel_match_type_operand,                   \
		REL_MATCH_INDEX(RELATIONAL_COUNT, rel_match)),             \
	NULL, NULL,                                                  \
	mcht_count_match,                                            \
	NULL, NULL, NULL, NULL                                       \
}

COUNT_MATCH_TYPE(gt, REL_MATCH_GREATER);
COUNT_MATCH_TYPE(ge, REL_MATCH_GREATER_EQUAL);
COUNT_MATCH_TYPE(lt, REL_MATCH_LESS);
COUNT_MATCH_TYPE(le, REL_MATCH_LESS_EQUAL);
COUNT_MATCH_TYPE(eq, REL_MATCH_EQUAL);
COUNT_MATCH_TYPE(ne, REL_MATCH_NOT_EQUAL);

/*
 * Match-type implementation
 */

static int mcht_count_match
(struct sieve_match_context *mctx, struct sieve_stringlist *value_list,
	struct sieve_stringlist *key_list)
{
	const struct sieve_runtime_env *renv = mctx->runenv;
	bool trace = sieve_runtime_trace_active(renv, SIEVE_TRLVL_MATCHING);
	int count;
	string_t *key_item;
	int match, ret;

	if ( (count=sieve_stringlist_get_length(value_list)) < 0 ) {
		mctx->exec_status = value_list->exec_status;
		return -1;
	}

	sieve_stringlist_reset(key_list);

	string_t *value = t_str_new(20);
	str_printfa(value, "%d", count);

	if ( trace ) {
		sieve_runtime_trace(renv, 0,
			"matching count value `%s'", str_sanitize(str_c(value), 80));
	}

	sieve_runtime_trace_descend(renv);

  /* Match to all key values */
  key_item = NULL;
	match = 0;
  while ( match == 0 &&
		(ret=sieve_stringlist_next_item(key_list, &key_item)) > 0 )
  {
		match = mcht_value_match_key
			(mctx, str_c(value), str_len(value), str_c(key_item), str_len(key_item));

		if ( trace ) {
			sieve_runtime_trace(renv, 0,
				"with key `%s' => %d", str_sanitize(str_c(key_item), 80), ret);
		}
	}

	sieve_runtime_trace_ascend(renv);

	if ( ret < 0 ) {
		mctx->exec_status = key_list->exec_status;
		match = -1;
	}

	return match;
}