summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-interpreter.h
blob: ec380293c58934bb330f34fae3a22bc6fca07efa (plain)
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#ifndef SIEVE_INTERPRETER_H
#define SIEVE_INTERPRETER_H

#include "lib.h"
#include "array.h"
#include "buffer.h"

#include "sieve-common.h"
#include "sieve-runtime.h"

/*
 * Interpreter
 */

struct sieve_interpreter *
sieve_interpreter_create(struct sieve_binary *sbin,
			 struct sieve_interpreter *parent,
			 const struct sieve_execute_env *eenv,
			 struct sieve_error_handler *ehandler) ATTR_NULL(2);
struct sieve_interpreter *
sieve_interpreter_create_for_block(struct sieve_binary_block *sblock,
				   struct sieve_script *script,
				   struct sieve_interpreter *parent,
				   const struct sieve_execute_env *eenv,
				   struct sieve_error_handler *ehandler)
				   ATTR_NULL(3);
void sieve_interpreter_free(struct sieve_interpreter **_interp);

/*
 * Accessors
 */

pool_t sieve_interpreter_pool(struct sieve_interpreter *interp);
struct sieve_interpreter *
sieve_interpreter_get_parent(struct sieve_interpreter *interp);
struct sieve_script *sieve_interpreter_script(struct sieve_interpreter *interp);
struct sieve_error_handler *
sieve_interpreter_get_error_handler(struct sieve_interpreter *interp);
struct sieve_instance *
sieve_interpreter_svinst(struct sieve_interpreter *interp);

/* Do not use this function for normal sieve extensions. This is intended for
 * the testsuite only.
 */
void sieve_interpreter_set_result(struct sieve_interpreter *interp,
				  struct sieve_result *result);

/*
 * Loop handling
 */

struct sieve_interpreter_loop;

int sieve_interpreter_loop_start(struct sieve_interpreter *interp,
				 sieve_size_t loop_end,
				 const struct sieve_extension_def *ext_def,
				 struct sieve_interpreter_loop **loop_r);
struct sieve_interpreter_loop *
sieve_interpreter_loop_get(struct sieve_interpreter *interp,
			   sieve_size_t loop_end,
			   const struct sieve_extension_def *ext_def);
int sieve_interpreter_loop_next(struct sieve_interpreter *interp,
				struct sieve_interpreter_loop *loop,
				sieve_size_t loop_begin);
int sieve_interpreter_loop_break(struct sieve_interpreter *interp,
				 struct sieve_interpreter_loop *loop);

struct sieve_interpreter_loop *
sieve_interpreter_loop_get_local(struct sieve_interpreter *interp,
				 struct sieve_interpreter_loop *loop,
				 const struct sieve_extension_def *ext_def)
				 ATTR_NULL(2, 3);
struct sieve_interpreter_loop *
sieve_interpreter_loop_get_global(struct sieve_interpreter *interp,
				  struct sieve_interpreter_loop *loop,
				  const struct sieve_extension_def *ext_def)
				  ATTR_NULL(2, 3);

pool_t sieve_interpreter_loop_get_pool(struct sieve_interpreter_loop *loop)
				       ATTR_PURE;
void *sieve_interpreter_loop_get_context(struct sieve_interpreter_loop *loop)
					 ATTR_PURE;
void sieve_interpreter_loop_set_context(struct sieve_interpreter_loop *loop,
					void *context);

/*
 * Program flow
 */

void sieve_interpreter_reset(struct sieve_interpreter *interp);
void sieve_interpreter_interrupt(struct sieve_interpreter *interp);
sieve_size_t
sieve_interpreter_program_counter(struct sieve_interpreter *interp);

int sieve_interpreter_program_jump_to(struct sieve_interpreter *interp,
				      sieve_size_t jmp_target,
				      bool break_loops);
int sieve_interpreter_program_jump(struct sieve_interpreter *interp, bool jump,
				   bool break_loops);

/*
 * Test results
 */

void sieve_interpreter_set_test_result(struct sieve_interpreter *interp,
				       bool result);
bool sieve_interpreter_get_test_result(struct sieve_interpreter *interp);

/*
 * Source location
 */

unsigned int
sieve_runtime_get_source_location(const struct sieve_runtime_env *renv,
				  sieve_size_t code_address);

unsigned int
sieve_runtime_get_command_location(const struct sieve_runtime_env *renv);
const char *
sieve_runtime_get_full_command_location(const struct sieve_runtime_env *renv);

/*
 * Extension support
 */

struct sieve_interpreter_extension {
	const struct sieve_extension_def *ext_def;

	int (*run)(const struct sieve_extension *ext,
		   const struct sieve_runtime_env *renv,
		   void *context, bool deferred);
	void (*free)(const struct sieve_extension *ext,
		     struct sieve_interpreter *interp, void *context);
};

void sieve_interpreter_extension_register(
	struct sieve_interpreter *interp, const struct sieve_extension *ext,
	const struct sieve_interpreter_extension *intext, void *context);
void sieve_interpreter_extension_set_context(
	struct sieve_interpreter *interp, const struct sieve_extension *ext,
	void *context);
void *sieve_interpreter_extension_get_context(
	struct sieve_interpreter *interp, const struct sieve_extension *ext);

int sieve_interpreter_extension_start(struct sieve_interpreter *interp,
				      const struct sieve_extension *ext);

/*
 * Opcodes and operands
 */

int sieve_interpreter_handle_optional_operands(
	const struct sieve_runtime_env *renv, sieve_size_t *address,
	struct sieve_side_effects_list **list);

/*
 * Code execute
 */

int sieve_interpreter_continue(struct sieve_interpreter *interp,
			       bool *interrupted);
int sieve_interpreter_start(struct sieve_interpreter *interp,
			    struct sieve_result *result, bool *interrupted);
int sieve_interpreter_run(struct sieve_interpreter *interp,
			  struct sieve_result *result);

/*
 * Error handling
 */

void sieve_runtime_error(const struct sieve_runtime_env *renv,
			 const char *csrc_filename, unsigned int csrc_linenum,
			 const char *location, const char *fmt, ...)
			 ATTR_FORMAT(5, 6);
#define sieve_runtime_error(renv, ...) \
	sieve_runtime_error(renv, __FILE__, __LINE__, __VA_ARGS__)
void sieve_runtime_warning(const struct sieve_runtime_env *renv,
			   const char *csrc_filename, unsigned int csrc_linenum,
			   const char *location, const char *fmt, ...)
			   ATTR_FORMAT(5, 6);
#define sieve_runtime_warning(renv, ...) \
	sieve_runtime_warning(renv, __FILE__, __LINE__, __VA_ARGS__)
void sieve_runtime_log(const struct sieve_runtime_env *renv,
		       const char *csrc_filename, unsigned int csrc_linenum,
		       const char *location, const char *fmt, ...)
		       ATTR_FORMAT(5, 6);
#define sieve_runtime_log(renv, ...) \
	sieve_runtime_log(renv, __FILE__, __LINE__, __VA_ARGS__)
void sieve_runtime_critical(const struct sieve_runtime_env *renv,
			    const char *csrc_filename,
			    unsigned int csrc_linenum,
			    const char *location, const char *user_prefix,
			    const char *fmt, ...) ATTR_FORMAT(6, 7);
#define sieve_runtime_critical(renv, ...) \
	sieve_runtime_critical(renv, __FILE__, __LINE__, __VA_ARGS__)
int sieve_runtime_mail_error(const struct sieve_runtime_env *renv,
			     struct mail *mail, 
			     const char *csrc_filename,
			     unsigned int csrc_linenum,
			     const char *fmt, ...) ATTR_FORMAT(5, 6);
#define sieve_runtime_mail_error(renv, mail, ...) \
	sieve_runtime_mail_error(renv, mail, __FILE__, __LINE__, __VA_ARGS__)

#endif