Coverage Report

Created: 2026-08-08 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pigeonhole/src/testsuite/testsuite-result.c
Line
Count
Source
1
/* Copyright (c) Pigeonhole authors, see top-level COPYING file */
2
3
#include "lib.h"
4
#include "ostream.h"
5
#include "str.h"
6
7
#include "sieve-common.h"
8
#include "sieve-error.h"
9
#include "sieve-stringlist.h"
10
#include "sieve-actions.h"
11
#include "sieve-interpreter.h"
12
#include "sieve-result.h"
13
14
#include "testsuite-common.h"
15
#include "testsuite-log.h"
16
#include "testsuite-message.h"
17
#include "testsuite-mailstore.h"
18
19
#include "testsuite-result.h"
20
21
struct sieve_execute_env testsuite_execute_env;
22
23
static pool_t testsuite_execute_pool = NULL;
24
static struct sieve_result *_testsuite_result = NULL;
25
static struct sieve_result_execution *_testsuite_rexec = NULL;
26
27
void testsuite_result_init(void)
28
0
{
29
0
  struct sieve_instance *svinst = testsuite_sieve_instance;
30
31
0
  testsuite_execute_pool = pool_alloconly_create("sieve execution", 4096);
32
33
0
  sieve_execute_init(&testsuite_execute_env, testsuite_sieve_instance,
34
0
         testsuite_execute_pool, &testsuite_msgdata,
35
0
         testsuite_scriptenv, 0);
36
37
0
  _testsuite_result = sieve_result_create(svinst, testsuite_execute_pool,
38
0
            &testsuite_execute_env);
39
0
}
40
41
void testsuite_result_deinit(void)
42
0
{
43
0
  sieve_result_execution_destroy(&_testsuite_rexec);
44
0
  sieve_result_unref(&_testsuite_result);
45
0
  sieve_execute_deinit(&testsuite_execute_env);
46
0
  pool_unref(&testsuite_execute_pool);
47
0
}
48
49
void testsuite_result_reset(const struct sieve_runtime_env *renv)
50
0
{
51
0
  struct sieve_instance *svinst = testsuite_sieve_instance;
52
53
0
  if (_testsuite_result != NULL) {
54
0
    sieve_result_execution_destroy(&_testsuite_rexec);
55
0
    sieve_result_unref(&_testsuite_result);
56
0
    pool_unref(&testsuite_execute_pool);
57
0
  }
58
59
0
  testsuite_message_flush();
60
0
  testsuite_mailstore_flush();
61
0
  i_zero(testsuite_execute_env.exec_status);
62
63
0
  testsuite_execute_pool = pool_alloconly_create("sieve execution", 4096);
64
0
  _testsuite_result = sieve_result_create(svinst, testsuite_execute_pool,
65
0
            &testsuite_execute_env);
66
0
  sieve_interpreter_set_result(renv->interp, _testsuite_result);
67
0
}
68
69
struct sieve_result *testsuite_result_get(void)
70
0
{
71
0
  return _testsuite_result;
72
0
}
73
74
struct sieve_result_iterate_context *testsuite_result_iterate_init(void)
75
0
{
76
0
  if (_testsuite_result == NULL)
77
0
    return NULL;
78
79
0
  return sieve_result_iterate_init(_testsuite_result);
80
0
}
81
82
bool testsuite_result_execute(const struct sieve_runtime_env *renv)
83
0
{
84
0
  int ret;
85
86
0
  if (_testsuite_result == NULL) {
87
0
    sieve_runtime_error(renv, NULL,  "testsuite: "
88
0
            "trying to execute result, "
89
0
            "but no result evaluated yet");
90
0
    return FALSE;
91
0
  }
92
93
0
  testsuite_log_clear_messages();
94
95
0
  if (_testsuite_rexec == NULL) {
96
0
    _testsuite_rexec = sieve_result_execution_create(
97
0
      _testsuite_result, testsuite_execute_pool);
98
0
  }
99
100
  /* Execute the result */
101
0
  ret = sieve_result_execute(_testsuite_rexec, SIEVE_EXEC_OK, TRUE,
102
0
           testsuite_log_ehandler, NULL);
103
104
0
  return (ret > 0);
105
0
}
106
107
void testsuite_result_print(const struct sieve_runtime_env *renv)
108
0
{
109
0
  const struct sieve_execute_env *eenv = renv->exec_env;
110
0
  struct ostream *out;
111
112
0
  out = o_stream_create_fd(1, 0);
113
0
  o_stream_set_no_error_handling(out, TRUE);
114
115
0
  o_stream_nsend_str(out, "\n--");
116
0
  sieve_result_print(_testsuite_result, eenv->scriptenv, out, NULL);
117
0
  o_stream_nsend_str(out, "--\n\n");
118
119
0
  o_stream_destroy(&out);
120
0
}
121
122
/*
123
 * Result stringlist
124
 */
125
126
/* Forward declarations */
127
128
static int
129
testsuite_result_stringlist_next_item(struct sieve_stringlist *_strlist,
130
              string_t **str_r);
131
static void
132
testsuite_result_stringlist_reset(struct sieve_stringlist *_strlist);
133
134
/* Stringlist object */
135
136
struct testsuite_result_stringlist {
137
  struct sieve_stringlist strlist;
138
139
  struct sieve_result_iterate_context *result_iter;
140
  int pos, index;
141
};
142
143
struct sieve_stringlist *
144
testsuite_result_stringlist_create(const struct sieve_runtime_env *renv,
145
           int index)
146
0
{
147
0
  struct testsuite_result_stringlist *strlist;
148
149
0
  strlist = t_new(struct testsuite_result_stringlist, 1);
150
0
  strlist->strlist.runenv = renv;
151
0
  strlist->strlist.exec_status = SIEVE_EXEC_OK;
152
0
  strlist->strlist.next_item = testsuite_result_stringlist_next_item;
153
0
  strlist->strlist.reset = testsuite_result_stringlist_reset;
154
155
0
  strlist->result_iter = testsuite_result_iterate_init();
156
0
  strlist->index = index;
157
0
  strlist->pos = 0;
158
159
0
  return &strlist->strlist;
160
0
}
161
162
static int
163
testsuite_result_stringlist_next_item(struct sieve_stringlist *_strlist,
164
              string_t **str_r)
165
0
{
166
0
  struct testsuite_result_stringlist *strlist =
167
0
    (struct testsuite_result_stringlist *)_strlist;
168
0
  const struct sieve_action *action;
169
0
  const char *act_name;
170
0
  bool keep;
171
172
0
  *str_r = NULL;
173
174
0
  if (strlist->index > 0 && strlist->pos > 0)
175
0
    return 0;
176
177
0
  do {
178
0
    action = sieve_result_iterate_next(strlist->result_iter, &keep);
179
0
    if (action == NULL)
180
0
      return 0;
181
182
0
    strlist->pos++;
183
0
  } while (strlist->pos < strlist->index);
184
185
0
  if (keep)
186
0
    act_name = "keep";
187
0
  else {
188
0
    act_name = ((action == NULL || action->def == NULL ||
189
0
           action->def->name == NULL) ?
190
0
          "" : action->def->name);
191
0
  }
192
193
0
  *str_r = t_str_new_const(act_name, strlen(act_name));
194
0
  return 1;
195
0
}
196
197
static void testsuite_result_stringlist_reset(struct sieve_stringlist *_strlist)
198
0
{
199
0
  struct testsuite_result_stringlist *strlist =
200
0
    (struct testsuite_result_stringlist *)_strlist;
201
202
0
  strlist->result_iter = testsuite_result_iterate_init();
203
0
  strlist->pos = 0;
204
0
}