21 |
|
|
22 |
#include <stdio.h> |
#include <stdio.h> |
23 |
#include <stdlib.h> |
#include <stdlib.h> |
24 |
|
#include <stdarg.h> |
25 |
#include <sieve.h> |
#include <sieve.h> |
26 |
|
|
27 |
void * |
void * |
28 |
sieve_alloc (size_t size) |
sieve_alloc (size_t size) |
29 |
{ |
{ |
30 |
char *p = malloc (size); |
void *p = malloc (size); |
31 |
if (!p) |
if (!p) |
32 |
{ |
{ |
33 |
mu_error ("not enough memory"); |
mu_error ("not enough memory"); |
36 |
return p; |
return p; |
37 |
} |
} |
38 |
|
|
39 |
|
void * |
40 |
|
sieve_palloc (list_t *pool, size_t size) |
41 |
|
{ |
42 |
|
void *p = malloc (size); |
43 |
|
if (p) |
44 |
|
{ |
45 |
|
if (!*pool && list_create (pool)) |
46 |
|
{ |
47 |
|
free (p); |
48 |
|
return NULL; |
49 |
|
} |
50 |
|
list_append (*pool, p); |
51 |
|
} |
52 |
|
return p; |
53 |
|
} |
54 |
|
|
55 |
|
char * |
56 |
|
sieve_pstrdup (list_t *pool, const char *str) |
57 |
|
{ |
58 |
|
size_t len; |
59 |
|
char *p; |
60 |
|
|
61 |
|
if (!str) |
62 |
|
return NULL; |
63 |
|
len = strlen (str); |
64 |
|
p = sieve_palloc (pool, len + 1); |
65 |
|
if (p) |
66 |
|
{ |
67 |
|
memcpy (p, str, len); |
68 |
|
p[len] = 0; |
69 |
|
} |
70 |
|
return p; |
71 |
|
} |
72 |
|
|
73 |
|
void * |
74 |
|
sieve_prealloc (list_t *pool, void *ptr, size_t size) |
75 |
|
{ |
76 |
|
void *newptr; |
77 |
|
|
78 |
|
if (*pool) |
79 |
|
list_remove (*pool, ptr); |
80 |
|
|
81 |
|
newptr = realloc (ptr, size); |
82 |
|
if (newptr) |
83 |
|
{ |
84 |
|
if (!*pool && list_create (pool)) |
85 |
|
{ |
86 |
|
free (newptr); |
87 |
|
return NULL; |
88 |
|
} |
89 |
|
list_append (*pool, newptr); |
90 |
|
} |
91 |
|
return newptr; |
92 |
|
} |
93 |
|
|
94 |
|
void |
95 |
|
sieve_pfree (list_t *pool, void *ptr) |
96 |
|
{ |
97 |
|
|
98 |
|
if (*pool) |
99 |
|
list_remove (*pool, ptr); |
100 |
|
free (ptr); |
101 |
|
} |
102 |
|
|
103 |
void |
void |
104 |
sieve_slist_destroy (list_t *plist) |
sieve_slist_destroy (list_t *plist) |
105 |
{ |
{ |
150 |
return val; |
return val; |
151 |
} |
} |
152 |
|
|
153 |
|
void |
154 |
|
sieve_error (const char *fmt, ...) |
155 |
|
{ |
156 |
|
va_list ap; |
157 |
|
|
158 |
|
va_start (ap, fmt); |
159 |
|
sieve_error_count++; |
160 |
|
sieve_machine->error_printer (sieve_machine->data, fmt, ap); |
161 |
|
va_end (ap); |
162 |
|
} |
163 |
|
|
164 |
|
void |
165 |
|
sieve_debug_internal (sieve_printf_t printer, void *data, const char *fmt, ...) |
166 |
|
{ |
167 |
|
va_list ap; |
168 |
|
|
169 |
|
va_start (ap, fmt); |
170 |
|
printer (data, fmt, ap); |
171 |
|
va_end (ap); |
172 |
|
} |
173 |
|
|
174 |
|
void |
175 |
|
sieve_debug (sieve_machine_t *mach, const char *fmt, ...) |
176 |
|
{ |
177 |
|
va_list ap; |
178 |
|
|
179 |
|
va_start (ap, fmt); |
180 |
|
mach->debug_printer (mach->data, fmt, ap); |
181 |
|
va_end (ap); |
182 |
|
} |
183 |
|
|
184 |
|
int |
185 |
|
_sieve_default_error_printer (void *unused, const char *fmt, va_list ap) |
186 |
|
{ |
187 |
|
return mu_verror (fmt, ap); |
188 |
|
} |
189 |
|
|
190 |
|
char * |
191 |
|
sieve_type_str (sieve_data_type type) |
192 |
|
{ |
193 |
|
switch (type) |
194 |
|
{ |
195 |
|
case SVT_VOID: |
196 |
|
return "void"; |
197 |
|
|
198 |
|
case SVT_NUMBER: |
199 |
|
return "number"; |
200 |
|
|
201 |
|
case SVT_STRING: |
202 |
|
return "string"; |
203 |
|
|
204 |
|
case SVT_STRING_LIST: |
205 |
|
return "string-list"; |
206 |
|
|
207 |
|
case SVT_TAG: |
208 |
|
return "tag"; |
209 |
|
|
210 |
|
case SVT_IDENT: |
211 |
|
return "ident"; |
212 |
|
|
213 |
|
case SVT_VALUE_LIST: |
214 |
|
return "value-list"; |
215 |
|
} |
216 |
|
|
217 |
|
return "unknown"; |
218 |
|
} |
219 |
|
|
220 |
|
struct debug_data { |
221 |
|
sieve_printf_t printer; |
222 |
|
void *data; |
223 |
|
}; |
224 |
|
|
225 |
|
static int |
226 |
|
string_printer (char *s, struct debug_data *dbg) |
227 |
|
{ |
228 |
|
sieve_debug_internal (dbg->printer, dbg->data, "\"%s\" ", s); |
229 |
|
return 0; |
230 |
|
} |
231 |
|
|
232 |
|
static int |
233 |
|
value_printer (sieve_value_t *val, struct debug_data *dbg) |
234 |
|
{ |
235 |
|
sieve_print_value (val, dbg->printer, dbg->data); |
236 |
|
sieve_debug_internal (dbg->printer, dbg->data, " "); |
237 |
|
return 0; |
238 |
|
} |
239 |
|
|
240 |
|
void |
241 |
|
sieve_print_value (sieve_value_t *val, sieve_printf_t printer, void *data) |
242 |
|
{ |
243 |
|
struct debug_data dbg; |
244 |
|
|
245 |
|
dbg.printer = printer; |
246 |
|
dbg.data = data; |
247 |
|
|
248 |
|
sieve_debug_internal (printer, data, "%s(", sieve_type_str (val->type)); |
249 |
|
switch (val->type) |
250 |
|
{ |
251 |
|
case SVT_VOID: |
252 |
|
break; |
253 |
|
|
254 |
|
case SVT_NUMBER: |
255 |
|
sieve_debug_internal (printer, data, "%ld", val->v.number); |
256 |
|
break; |
257 |
|
|
258 |
|
case SVT_TAG: |
259 |
|
case SVT_IDENT: |
260 |
|
case SVT_STRING: |
261 |
|
sieve_debug_internal (printer, data, "%s", val->v.string); |
262 |
|
break; |
263 |
|
|
264 |
|
case SVT_STRING_LIST: |
265 |
|
list_do (val->v.list, (list_action_t*) string_printer, &dbg); |
266 |
|
break; |
267 |
|
|
268 |
|
case SVT_VALUE_LIST: |
269 |
|
list_do (val->v.list, (list_action_t*) value_printer, &dbg); |
270 |
|
} |
271 |
|
sieve_debug_internal (printer, data, ")"); |
272 |
|
} |
273 |
|
|
274 |
|
void |
275 |
|
sieve_print_value_list (list_t list, sieve_printf_t printer, void *data) |
276 |
|
{ |
277 |
|
sieve_value_t val; |
278 |
|
|
279 |
|
val.type = SVT_VALUE_LIST; |
280 |
|
val.v.list = list; |
281 |
|
sieve_print_value (&val, printer, data); |
282 |
|
} |
283 |
|
|
284 |
|
static int |
285 |
|
tag_printer (sieve_runtime_tag_t *val, struct debug_data *dbg) |
286 |
|
{ |
287 |
|
sieve_debug_internal (dbg->printer, dbg->data, "%d", val->tag); |
288 |
|
if (val->arg) |
289 |
|
{ |
290 |
|
sieve_debug_internal (dbg->printer, dbg->data, "("); |
291 |
|
sieve_print_value (val->arg, dbg->printer, dbg->data); |
292 |
|
sieve_debug_internal (dbg->printer, dbg->data, ")"); |
293 |
|
} |
294 |
|
sieve_debug_internal (dbg->printer, dbg->data, " "); |
295 |
|
} |
296 |
|
|
297 |
|
void |
298 |
|
sieve_print_tag_list (list_t list, sieve_printf_t printer, void *data) |
299 |
|
{ |
300 |
|
struct debug_data dbg; |
301 |
|
|
302 |
|
dbg.printer = printer; |
303 |
|
dbg.data = data; |
304 |
|
list_do (list, (list_action_t*) tag_printer, &dbg); |
305 |
|
} |
306 |
|
|
307 |
|
void |
308 |
|
sieve_set_debug (sieve_machine_t *mach, sieve_printf_t debug, int level) |
309 |
|
{ |
310 |
|
mach->debug_printer = debug; |
311 |
|
mach->debug_level = level; |
312 |
|
} |
313 |
|
|