summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/testsuite/testsuite-result.c
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/src/testsuite/testsuite-result.c')
-rw-r--r--pigeonhole/src/testsuite/testsuite-result.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/pigeonhole/src/testsuite/testsuite-result.c b/pigeonhole/src/testsuite/testsuite-result.c
new file mode 100644
index 0000000..51be3ff
--- /dev/null
+++ b/pigeonhole/src/testsuite/testsuite-result.c
@@ -0,0 +1,206 @@
+/* Copyright (c) 2002-2018 Pigeonhole authors, see the included COPYING file
+ */
+
+#include "lib.h"
+#include "ostream.h"
+#include "str.h"
+
+#include "sieve-common.h"
+#include "sieve-error.h"
+#include "sieve-stringlist.h"
+#include "sieve-actions.h"
+#include "sieve-interpreter.h"
+#include "sieve-result.h"
+
+#include "testsuite-common.h"
+#include "testsuite-log.h"
+#include "testsuite-message.h"
+#include "testsuite-mailstore.h"
+
+#include "testsuite-result.h"
+
+struct sieve_execute_env testsuite_execute_env;
+
+static pool_t testsuite_execute_pool = NULL;
+static struct sieve_result *_testsuite_result = NULL;
+static struct sieve_result_execution *_testsuite_rexec = NULL;
+
+void testsuite_result_init(void)
+{
+ struct sieve_instance *svinst = testsuite_sieve_instance;
+
+ testsuite_execute_pool = pool_alloconly_create("sieve execution", 4096);
+
+ sieve_execute_init(&testsuite_execute_env, testsuite_sieve_instance,
+ testsuite_execute_pool, &testsuite_msgdata,
+ testsuite_scriptenv, 0);
+
+ _testsuite_result = sieve_result_create(svinst, testsuite_execute_pool,
+ &testsuite_execute_env);
+}
+
+void testsuite_result_deinit(void)
+{
+ sieve_result_execution_destroy(&_testsuite_rexec);
+ if (_testsuite_result != NULL)
+ sieve_result_unref(&_testsuite_result);
+ sieve_execute_deinit(&testsuite_execute_env);
+ pool_unref(&testsuite_execute_pool);
+}
+
+void testsuite_result_reset(const struct sieve_runtime_env *renv)
+{
+ struct sieve_instance *svinst = testsuite_sieve_instance;
+
+ if (_testsuite_result != NULL) {
+ sieve_result_execution_destroy(&_testsuite_rexec);
+ sieve_result_unref(&_testsuite_result);
+ pool_unref(&testsuite_execute_pool);
+ }
+
+ testsuite_message_flush();
+ testsuite_mailstore_flush();
+ i_zero(testsuite_execute_env.exec_status);
+
+ testsuite_execute_pool = pool_alloconly_create("sieve execution", 4096);
+ _testsuite_result = sieve_result_create(svinst, testsuite_execute_pool,
+ &testsuite_execute_env);
+ sieve_interpreter_set_result(renv->interp, _testsuite_result);
+}
+
+struct sieve_result *testsuite_result_get(void)
+{
+ return _testsuite_result;
+}
+
+struct sieve_result_iterate_context *testsuite_result_iterate_init(void)
+{
+ if (_testsuite_result == NULL)
+ return NULL;
+
+ return sieve_result_iterate_init(_testsuite_result);
+}
+
+bool testsuite_result_execute(const struct sieve_runtime_env *renv)
+{
+ int ret;
+
+ if (_testsuite_result == NULL) {
+ sieve_runtime_error(renv, NULL, "testsuite: "
+ "trying to execute result, "
+ "but no result evaluated yet");
+ return FALSE;
+ }
+
+ testsuite_log_clear_messages();
+
+ if (_testsuite_rexec == NULL) {
+ _testsuite_rexec = sieve_result_execution_create(
+ _testsuite_result, testsuite_execute_pool);
+ }
+
+ /* Execute the result */
+ ret = sieve_result_execute(_testsuite_rexec, SIEVE_EXEC_OK, TRUE,
+ testsuite_log_ehandler, NULL);
+
+ return (ret > 0);
+}
+
+void testsuite_result_print(const struct sieve_runtime_env *renv)
+{
+ const struct sieve_execute_env *eenv = renv->exec_env;
+ struct ostream *out;
+
+ out = o_stream_create_fd(1, 0);
+ o_stream_set_no_error_handling(out, TRUE);
+
+ o_stream_nsend_str(out, "\n--");
+ sieve_result_print(_testsuite_result, eenv->scriptenv, out, NULL);
+ o_stream_nsend_str(out, "--\n\n");
+
+ o_stream_destroy(&out);
+}
+
+/*
+ * Result stringlist
+ */
+
+/* Forward declarations */
+
+static int
+testsuite_result_stringlist_next_item(struct sieve_stringlist *_strlist,
+ string_t **str_r);
+static void
+testsuite_result_stringlist_reset(struct sieve_stringlist *_strlist);
+
+/* Stringlist object */
+
+struct testsuite_result_stringlist {
+ struct sieve_stringlist strlist;
+
+ struct sieve_result_iterate_context *result_iter;
+ int pos, index;
+};
+
+struct sieve_stringlist *
+testsuite_result_stringlist_create(const struct sieve_runtime_env *renv,
+ int index)
+{
+ struct testsuite_result_stringlist *strlist;
+
+ strlist = t_new(struct testsuite_result_stringlist, 1);
+ strlist->strlist.runenv = renv;
+ strlist->strlist.exec_status = SIEVE_EXEC_OK;
+ strlist->strlist.next_item = testsuite_result_stringlist_next_item;
+ strlist->strlist.reset = testsuite_result_stringlist_reset;
+
+ strlist->result_iter = testsuite_result_iterate_init();
+ strlist->index = index;
+ strlist->pos = 0;
+
+ return &strlist->strlist;
+}
+
+static int
+testsuite_result_stringlist_next_item(struct sieve_stringlist *_strlist,
+ string_t **str_r)
+{
+ struct testsuite_result_stringlist *strlist =
+ (struct testsuite_result_stringlist *)_strlist;
+ const struct sieve_action *action;
+ const char *act_name;
+ bool keep;
+
+ *str_r = NULL;
+
+ if (strlist->index > 0 && strlist->pos > 0)
+ return 0;
+
+ do {
+ if ((action = sieve_result_iterate_next(strlist->result_iter,
+ &keep)) == NULL)
+ return 0;
+
+ strlist->pos++;
+ } while (strlist->pos < strlist->index);
+
+ if (keep)
+ act_name = "keep";
+ else {
+ act_name = ((action == NULL || action->def == NULL ||
+ action->def->name == NULL) ?
+ "" : action->def->name);
+ }
+
+ *str_r = t_str_new_const(act_name, strlen(act_name));
+ return 1;
+}
+
+static void testsuite_result_stringlist_reset(struct sieve_stringlist *_strlist)
+{
+ struct testsuite_result_stringlist *strlist =
+ (struct testsuite_result_stringlist *)_strlist;
+
+ strlist->result_iter = testsuite_result_iterate_init();
+ strlist->pos = 0;
+}