Commit 1186b695 1186b695bc7c105b19e36bff4c7c9dc04fe30d8f by Sergey Poznyakoff

sieve: improve memory allocation

* include/mailutils/sieve.h (mu_sieve_alloc)
(mu_sieve_palloc,mu_sieve_prealloc)
(mu_sieve_pfree,mu_sieve_pstrdup):  Remove.
(mu_sieve_mstrdup,mu_sieve_mrealloc)
(mu_sieve_mfree): Remove.

(mu_sieve_reclaim_t): New typedef.
(mu_sieve_calloc,mu_sieve_strdup)
(mu_sieve_realloc)
(mu_sieve_reclaim_default,mu_sieve_reclaim_list)
(mu_sieve_reclaim_value,mu_sieve_reclaim_tag): New functions
(mu_sieve_value_create): Change prototype (take mu_sieve_machine_t
as first argument)
* libmu_sieve/mem.c: New file.
* libmu_sieve/Makefile.am: Add new file.

* libmu_sieve/comparator.c: Use new allocation functions.
* libmu_sieve/prog.c: Likewise.
* libmu_sieve/register.c: Likewise.
* libmu_sieve/sieve.l: Likewise.
* libmu_sieve/sieve.y: Likewise.
* libmu_sieve/util.c: Likewise.

* doc/texinfo/libmu_sieve.texi: Update (needs revision).
1 parent 7b6fe2ab
...@@ -609,27 +609,27 @@ freed upon the call to @code{mu_sieve_machine_destroy (@var{mach})}. ...@@ -609,27 +609,27 @@ freed upon the call to @code{mu_sieve_machine_destroy (@var{mach})}.
609 Allocates @var{size} bytes and returns a pointer to the allocated memory. 609 Allocates @var{size} bytes and returns a pointer to the allocated memory.
610 @end deftypefun 610 @end deftypefun
611 611
612 @deftypefun {char *} mu_sieve_mstrdup (mu_sieve_machine_t @var{mach}, const char *@var{str}) 612 @deftypefun {char *} mu_sieve_strdup (mu_sieve_machine_t @var{mach}, const char *@var{str})
613 This function returns a pointer to a new string which is a duplicate of the 613 This function returns a pointer to a new string which is a duplicate of the
614 string @var{str}. 614 string @var{str}.
615 @end deftypefun 615 @end deftypefun
616 616
617 @deftypefun {void *} mu_sieve_mrealloc (mu_sieve_machine_t @var{mach}, void *@var{ptr}, size_t @var{size}) 617 @deftypefun {void *} mu_sieve_realloc (mu_sieve_machine_t @var{mach}, void *@var{ptr}, size_t @var{size})
618 Changes the size of the memory block pointed to by @var{ptr} to 618 Changes the size of the memory block pointed to by @var{ptr} to
619 @var{size} bytes. The contents will be unchanged to the minimum of the 619 @var{size} bytes. The contents will be unchanged to the minimum of the
620 old and new sizes; newly allocated memory will be uninitialized. If 620 old and new sizes; newly allocated memory will be uninitialized. If
621 @var{ptr} is @code{NULL}, the call is equivalent to 621 @var{ptr} is @code{NULL}, the call is equivalent to
622 @code{mu_sieve_malloc(@var{mach}, @var{size})}; if @var{size} is equal to 622 @code{mu_sieve_malloc(@var{mach}, @var{size})}; if @var{size} is equal to
623 zero, the call is equivalent to @code{mu_sieve_mfree(@var{ptr})}. Unless 623 zero, the call is equivalent to @code{mu_sieve_free(@var{ptr})}. Unless
624 @var{ptr} is @code{NULL}, it must have been returned by an earlier 624 @var{ptr} is @code{NULL}, it must have been returned by an earlier
625 call to @code{mu_sieve_malloc()} or @code{mu_sieve_mrealloc()}. 625 call to @code{mu_sieve_malloc()} or @code{mu_sieve_realloc()}.
626 @end deftypefun 626 @end deftypefun
627 627
628 @deftypefun void mu_sieve_mfree (mu_sieve_machine_t @var{mach}, void *@var{ptr}) 628 @deftypefun void mu_sieve_free (mu_sieve_machine_t @var{mach}, void *@var{ptr})
629 @code{mu_sieve_mfree()} frees the memory space pointed to by @var{ptr} and 629 @code{mu_sieve_free()} frees the memory space pointed to by @var{ptr} and
630 detaches it from the destructor list of @var{mach}. The @var{ptr} must 630 detaches it from the destructor list of @var{mach}. The @var{ptr} must
631 have been returned by a previous call to @code{mu_sieve_malloc()} or 631 have been returned by a previous call to @code{mu_sieve_malloc()} or
632 @code{mu_sieve_mrealloc()}. Otherwise, or if @code{mu_sieve_mfree(@var{ptr})} 632 @code{mu_sieve_realloc()}. Otherwise, or if @code{mu_sieve_mfree(@var{ptr})}
633 has already been called before, undefined behaviour occurs. 633 has already been called before, undefined behaviour occurs.
634 634
635 If @var{ptr} is @code{NULL}, no operation is performed. 635 If @var{ptr} is @code{NULL}, no operation is performed.
......
...@@ -121,18 +121,24 @@ extern mu_list_t mu_sieve_library_path_prefix; ...@@ -121,18 +121,24 @@ extern mu_list_t mu_sieve_library_path_prefix;
121 void mu_sieve_debug_init (void); 121 void mu_sieve_debug_init (void);
122 122
123 /* Memory allocation functions */ 123 /* Memory allocation functions */
124 void *mu_sieve_alloc (size_t size); 124 typedef void (*mu_sieve_reclaim_t) (void *);
125 void *mu_sieve_palloc (mu_list_t *pool, size_t size); 125 void mu_sieve_register_memory (mu_sieve_machine_t mach, void *ptr,
126 void *mu_sieve_prealloc (mu_list_t *pool, void *ptr, size_t size); 126 mu_sieve_reclaim_t reclaim);
127 void mu_sieve_pfree (mu_list_t *pool, void *ptr); 127 void *mu_sieve_alloc_memory (mu_sieve_machine_t mach, size_t size,
128 char *mu_sieve_pstrdup (mu_list_t *pool, const char *str); 128 mu_sieve_reclaim_t recfun);
129 129 void mu_sieve_free (mu_sieve_machine_t mach, void *ptr);
130 void *mu_sieve_malloc (mu_sieve_machine_t mach, size_t size); 130 void *mu_sieve_malloc (mu_sieve_machine_t mach, size_t size);
131 char *mu_sieve_mstrdup (mu_sieve_machine_t mach, const char *str); 131 void *mu_sieve_calloc (mu_sieve_machine_t mach, size_t nmemb, size_t size);
132 void *mu_sieve_mrealloc (mu_sieve_machine_t mach, void *ptr, size_t size); 132 char *mu_sieve_strdup (mu_sieve_machine_t mach, char const *str);
133 void mu_sieve_mfree (mu_sieve_machine_t mach, void *ptr); 133 void *mu_sieve_realloc (mu_sieve_machine_t mach, void *ptr, size_t size);
134 134
135 mu_sieve_value_t *mu_sieve_value_create (mu_sieve_data_type type, void *data); 135 void mu_sieve_reclaim_default (void *p);
136 void mu_sieve_reclaim_list (void *p);
137 void mu_sieve_reclaim_value (void *p);
138 void mu_sieve_reclaim_tag (void *p);
139
140 mu_sieve_value_t *mu_sieve_value_create (mu_sieve_machine_t mach,
141 mu_sieve_data_type type, void *data);
136 void mu_sieve_slist_destroy (mu_list_t *plist); 142 void mu_sieve_slist_destroy (mu_list_t *plist);
137 143
138 /* Symbol space functions */ 144 /* Symbol space functions */
......
...@@ -32,6 +32,7 @@ libmu_sieve_la_SOURCES = \ ...@@ -32,6 +32,7 @@ libmu_sieve_la_SOURCES = \
32 comparator.c\ 32 comparator.c\
33 encoded.c\ 33 encoded.c\
34 load.c\ 34 load.c\
35 mem.c\
35 prog.c\ 36 prog.c\
36 register.c\ 37 register.c\
37 relational.c\ 38 relational.c\
......
...@@ -338,7 +338,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach, ...@@ -338,7 +338,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
338 338
339 tmp = mu_sieve_malloc (mach, sizeof (*tmp)); 339 tmp = mu_sieve_malloc (mach, sizeof (*tmp));
340 tmp->tag = TAG_COMPFUN; 340 tmp->tag = TAG_COMPFUN;
341 tmp->arg = mu_sieve_value_create (SVT_POINTER, compfun); 341 tmp->arg = mu_sieve_value_create (mach, SVT_POINTER, compfun);
342 mu_list_append (tags, tmp); 342 mu_list_append (tags, tmp);
343 343
344 if (matchtype == MU_SIEVE_MATCH_REGEX) 344 if (matchtype == MU_SIEVE_MATCH_REGEX)
...@@ -365,7 +365,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach, ...@@ -365,7 +365,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
365 365
366 if (rc) 366 if (rc)
367 return rc; 367 return rc;
368 newval = mu_sieve_value_create (SVT_STRING_LIST, rd.list); 368 newval = mu_sieve_value_create (rd.mach, SVT_STRING_LIST, rd.list);
369 mu_list_replace (args, val, newval); 369 mu_list_replace (args, val, newval);
370 } 370 }
371 #ifndef FNM_CASEFOLD 371 #ifndef FNM_CASEFOLD
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999-2002, 2005-2008, 2010-2012, 2014-2016 Free
3 Software Foundation, Inc.
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 3 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General
16 Public License along with this library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sieve-priv.h>
26
27 struct memory_cell
28 {
29 void *ptr;
30 void (*reclaim) (void *);
31 };
32
33 static void
34 memory_cell_destroy (void *item)
35 {
36 struct memory_cell *mcp = item;
37 if (!mcp->reclaim)
38 abort ();
39 else
40 mcp->reclaim (mcp->ptr);
41 free (mcp);
42 }
43
44 static int
45 memory_cell_cmp (const void *a, const void *b)
46 {
47 struct memory_cell const *ma = a;
48 struct memory_cell const *mb = b;
49 return ma->ptr != mb->ptr;
50 }
51
52 void
53 mu_sieve_register_memory (mu_sieve_machine_t mach, void *ptr,
54 mu_sieve_reclaim_t reclaim)
55 {
56 struct memory_cell *mcp;
57
58 if (!reclaim)
59 reclaim = mu_sieve_reclaim_default;
60
61 if (!mach->memory_pool)
62 {
63 if (mu_list_create (&mach->memory_pool))
64 mu_sieve_abort (mach);
65 mu_list_set_destroy_item (mach->memory_pool, memory_cell_destroy);
66 mu_list_set_comparator (mach->memory_pool, memory_cell_cmp);
67 }
68 mcp = malloc (sizeof (*mcp));
69 if (!mcp)
70 mu_sieve_abort (mach);
71 mcp->ptr = ptr;
72 mcp->reclaim = reclaim;
73 if (mu_list_append (mach->memory_pool, mcp))
74 {
75 memory_cell_destroy (mcp);
76 mu_sieve_abort (mach);
77 }
78 }
79
80 void
81 mu_sieve_free (mu_sieve_machine_t mach, void *ptr)
82 {
83 int rc;
84 struct memory_cell mcell;
85
86 mcell.ptr = ptr;
87 rc = mu_list_remove (mach->memory_pool, &mcell);
88 if (rc)
89 {
90 mu_sieve_error (mach, _("INTERNAL ERROR: trying to free unregistered memory pointer"));
91 abort ();
92 }
93 }
94
95 void *
96 mu_sieve_alloc_memory (mu_sieve_machine_t mach, size_t size,
97 mu_sieve_reclaim_t recfun)
98 {
99 char *p = malloc (size);
100 if (!p)
101 {
102 mu_sieve_error (mach, "%s", mu_strerror (errno));
103 mu_sieve_abort (mach);
104 }
105 mu_sieve_register_memory (mach, p, recfun);
106 return p;
107 }
108
109 void *
110 mu_sieve_malloc (mu_sieve_machine_t mach, size_t size)
111 {
112 return mu_sieve_alloc_memory (mach, size, mu_sieve_reclaim_default);
113 }
114
115 void *
116 mu_sieve_calloc (mu_sieve_machine_t mach, size_t nmemb, size_t size)
117 {
118 char *p = calloc (nmemb, size);
119 if (!p)
120 {
121 mu_sieve_error (mach, "%s", mu_strerror (errno));
122 mu_sieve_abort (mach);
123 }
124 mu_sieve_register_memory (mach, p, mu_sieve_reclaim_default);
125 return p;
126 }
127
128 char *
129 mu_sieve_strdup (mu_sieve_machine_t mach, char const *str)
130 {
131 size_t len;
132 char *p;
133
134 if (!str)
135 return NULL;
136 len = strlen (str);
137 p = mu_sieve_malloc (mach, len + 1);
138 memcpy (p, str, len);
139 p[len] = 0;
140 return p;
141 }
142
143 void *
144 mu_sieve_realloc (mu_sieve_machine_t mach, void *ptr, size_t size)
145 {
146 int rc;
147 struct memory_cell mcell, *mcp;
148
149 if (!ptr)
150 return mu_sieve_malloc (mach, size);
151
152 mcell.ptr = ptr;
153 rc = mu_list_locate (mach->memory_pool, &mcell, (void **)&mcp);
154 if (rc == MU_ERR_NOENT)
155 {
156 mu_sieve_error (mach, _("INTERNAL ERROR: trying to reallocate unregistered memory pointer"));
157 abort ();
158 }
159 else if (rc)
160 {
161 mu_sieve_error (mach, _("error reallocating memory: %s"),
162 mu_strerror (rc));
163 mu_sieve_abort (mach);
164 }
165
166 ptr = realloc (mcp->ptr, size);
167 if (!ptr)
168 {
169 mu_sieve_error (mach, _("error reallocating memory: %s"),
170 mu_strerror (errno));
171 mu_sieve_abort (mach);
172 }
173 mcp->ptr = ptr;
174
175 return ptr;
176 }
177
178 void
179 mu_sieve_reclaim_default (void *p)
180 {
181 free (p);
182 }
183
184 void
185 mu_sieve_reclaim_list (void *p)
186 {
187 mu_list_t list = p;
188 mu_list_destroy (&list);
189 }
190
191 void
192 mu_sieve_reclaim_value (void *p)
193 {
194 if (!p)
195 return;
196 /* For now, the same as _default. Will change in the future */
197 free (p);
198 }
199
200 void
201 mu_sieve_reclaim_tag (void *p)
202 {
203 mu_sieve_runtime_tag_t *tag = p;
204 mu_sieve_reclaim_value (tag->arg);
205 }
206
...@@ -31,7 +31,7 @@ mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op) ...@@ -31,7 +31,7 @@ mu_i_sv_code (struct mu_sieve_machine *mach, sieve_op_t op)
31 { 31 {
32 size_t newsize = mach->progsize + SIEVE_CODE_INCR; 32 size_t newsize = mach->progsize + SIEVE_CODE_INCR;
33 sieve_op_t *newprog = 33 sieve_op_t *newprog =
34 mu_sieve_mrealloc (mach, mach->prog, newsize * sizeof mach->prog[0]); 34 mu_sieve_realloc (mach, mach->prog, newsize * sizeof mach->prog[0]);
35 if (!newprog) 35 if (!newprog)
36 { 36 {
37 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, _("not enough memory")); 37 mu_diag_at_locus (MU_LOG_ERROR, &mach->locus, _("not enough memory"));
...@@ -261,8 +261,8 @@ sv_code_command (struct mu_sieve_machine *mach, ...@@ -261,8 +261,8 @@ sv_code_command (struct mu_sieve_machine *mach,
261 261
262 mu_list_create (&list); 262 mu_list_create (&list);
263 mu_list_append (list, val->v.string); 263 mu_list_append (list, val->v.string);
264 mu_sieve_mfree (mach, val); 264 mu_sieve_free (mach, val);
265 val = mu_sieve_value_create (SVT_STRING_LIST, list); 265 val = mu_sieve_value_create (mach, SVT_STRING_LIST, list);
266 } 266 }
267 else 267 else
268 { 268 {
......
...@@ -89,14 +89,14 @@ mu_sieve_require_test (mu_sieve_machine_t mach, const char *name) ...@@ -89,14 +89,14 @@ mu_sieve_require_test (mu_sieve_machine_t mach, const char *name)
89 89
90 90
91 static int 91 static int
92 sieve_register (mu_list_t *pool, 92 sieve_register (mu_sieve_machine_t mach,
93 mu_list_t *list, 93 mu_list_t *list,
94 const char *name, mu_sieve_handler_t handler, 94 const char *name, mu_sieve_handler_t handler,
95 mu_sieve_data_type *req_arg_types, 95 mu_sieve_data_type *req_arg_types,
96 mu_sieve_data_type *opt_arg_types, 96 mu_sieve_data_type *opt_arg_types,
97 mu_sieve_tag_group_t *tags, int required) 97 mu_sieve_tag_group_t *tags, int required)
98 { 98 {
99 mu_sieve_register_t *reg = mu_sieve_palloc (pool, sizeof (*reg)); 99 mu_sieve_register_t *reg = mu_sieve_malloc (mach, sizeof (*reg));
100 100
101 if (!reg) 101 if (!reg)
102 return ENOMEM; 102 return ENOMEM;
...@@ -129,7 +129,7 @@ mu_sieve_register_test_ext (mu_sieve_machine_t mach, ...@@ -129,7 +129,7 @@ mu_sieve_register_test_ext (mu_sieve_machine_t mach,
129 mu_sieve_data_type *opt_args, 129 mu_sieve_data_type *opt_args,
130 mu_sieve_tag_group_t *tags, int required) 130 mu_sieve_tag_group_t *tags, int required)
131 { 131 {
132 return sieve_register (&mach->memory_pool, 132 return sieve_register (mach,
133 &mach->test_list, name, handler, 133 &mach->test_list, name, handler,
134 req_args, opt_args, tags, required); 134 req_args, opt_args, tags, required);
135 } 135 }
...@@ -153,7 +153,7 @@ mu_sieve_register_action_ext (mu_sieve_machine_t mach, ...@@ -153,7 +153,7 @@ mu_sieve_register_action_ext (mu_sieve_machine_t mach,
153 mu_sieve_data_type *opt_args, 153 mu_sieve_data_type *opt_args,
154 mu_sieve_tag_group_t *tags, int required) 154 mu_sieve_tag_group_t *tags, int required)
155 { 155 {
156 return sieve_register (&mach->memory_pool, 156 return sieve_register (mach,
157 &mach->action_list, name, handler, 157 &mach->action_list, name, handler,
158 req_args, opt_args, tags, required); 158 req_args, opt_args, tags, required);
159 } 159 }
......
...@@ -226,7 +226,7 @@ push_source (const char *name) ...@@ -226,7 +226,7 @@ push_source (const char *name)
226 if (mu_sieve_locus.mu_file) 226 if (mu_sieve_locus.mu_file)
227 { 227 {
228 advance_locus (); 228 advance_locus ();
229 ctx = mu_sieve_alloc (sizeof (*ctx)); 229 ctx = mu_sieve_malloc (mu_sieve_machine, sizeof (*ctx));
230 ctx->locus = mu_sieve_locus; 230 ctx->locus = mu_sieve_locus;
231 ctx->i_node = sieve_source_inode; 231 ctx->i_node = sieve_source_inode;
232 ctx->input = input_stream; 232 ctx->input = input_stream;
...@@ -262,7 +262,7 @@ pop_source () ...@@ -262,7 +262,7 @@ pop_source ()
262 sieve_source_inode = context_stack->i_node; 262 sieve_source_inode = context_stack->i_node;
263 RESTORE_BUFFER_STATE (context_stack->state); 263 RESTORE_BUFFER_STATE (context_stack->state);
264 ctx = context_stack->prev; 264 ctx = context_stack->prev;
265 free (context_stack); 265 mu_sieve_free (mu_sieve_machine, context_stack);
266 context_stack = ctx; 266 context_stack = ctx;
267 267
268 return 0; 268 return 0;
...@@ -393,7 +393,7 @@ get_file_name (char *p, char *endp, int *usepath) ...@@ -393,7 +393,7 @@ get_file_name (char *p, char *endp, int *usepath)
393 } 393 }
394 394
395 n = p - startp; 395 n = p - startp;
396 name = mu_sieve_alloc (n + 1); 396 name = mu_sieve_malloc (mu_sieve_machine, n + 1);
397 memcpy (name, startp, n); 397 memcpy (name, startp, n);
398 name[n] = 0; 398 name[n] = 0;
399 return name; 399 return name;
...@@ -420,7 +420,7 @@ _try_include (void *item, void *data) ...@@ -420,7 +420,7 @@ _try_include (void *item, void *data)
420 } 420 }
421 421
422 static void 422 static void
423 sieve_include () 423 sieve_include (void)
424 { 424 {
425 char *p, *endp = yytext + yyleng, *name; 425 char *p, *endp = yytext + yyleng, *name;
426 int usepath; 426 int usepath;
...@@ -440,14 +440,14 @@ sieve_include () ...@@ -440,14 +440,14 @@ sieve_include ()
440 && mu_list_foreach (mu_sieve_include_path, _try_include, &p)) 440 && mu_list_foreach (mu_sieve_include_path, _try_include, &p))
441 { 441 {
442 push_source (p); 442 push_source (p);
443 free (name); 443 mu_sieve_free (mu_sieve_machine, name);
444 free (p); 444 free (p);
445 return; 445 return;
446 } 446 }
447 } 447 }
448 448
449 push_source (name); 449 push_source (name);
450 free (name); 450 mu_sieve_free (mu_sieve_machine, name);
451 } 451 }
452 452
453 static void 453 static void
...@@ -462,7 +462,7 @@ sieve_searchpath (void) ...@@ -462,7 +462,7 @@ sieve_searchpath (void)
462 if (name) 462 if (name)
463 { 463 {
464 mu_i_sv_load_add_dir (mu_sieve_machine, name); 464 mu_i_sv_load_add_dir (mu_sieve_machine, name);
465 free (name); 465 mu_sieve_free (mu_sieve_machine, name);
466 } 466 }
467 } 467 }
468 468
...@@ -597,7 +597,7 @@ multiline_begin (void) ...@@ -597,7 +597,7 @@ multiline_begin (void)
597 break; 597 break;
598 598
599 len = endp - p; 599 len = endp - p;
600 multiline_delimiter = mu_sieve_alloc (len + 1); 600 multiline_delimiter = mu_sieve_malloc (mu_sieve_machine, len + 1);
601 memcpy (multiline_delimiter, p, len); 601 memcpy (multiline_delimiter, p, len);
602 multiline_delimiter[len] = 0; 602 multiline_delimiter[len] = 0;
603 } 603 }
...@@ -635,7 +635,7 @@ ident (const char *text) ...@@ -635,7 +635,7 @@ ident (const char *text)
635 static char * 635 static char *
636 str_unescape (char *text, size_t len) 636 str_unescape (char *text, size_t len)
637 { 637 {
638 char *str = mu_sieve_alloc (len); 638 char *str = mu_sieve_malloc (mu_sieve_machine, len);
639 memcpy (str, text, len - 2); 639 memcpy (str, text, len - 2);
640 str[len - 2] = mu_wordsplit_c_unquote_char (text[len - 1]); 640 str[len - 2] = mu_wordsplit_c_unquote_char (text[len - 1]);
641 str[len - 1] = 0; 641 str[len - 1] = 0;
......
...@@ -333,23 +333,24 @@ arglist : arg ...@@ -333,23 +333,24 @@ arglist : arg
333 333
334 arg : stringlist 334 arg : stringlist
335 { 335 {
336 $$ = mu_sieve_value_create (SVT_STRING_LIST, $1); 336 $$ = mu_sieve_value_create (mu_sieve_machine,
337 SVT_STRING_LIST, $1);
337 } 338 }
338 | STRING 339 | STRING
339 { 340 {
340 $$ = mu_sieve_value_create (SVT_STRING, $1); 341 $$ = mu_sieve_value_create (mu_sieve_machine, SVT_STRING, $1);
341 } 342 }
342 | MULTILINE 343 | MULTILINE
343 { 344 {
344 $$ = mu_sieve_value_create (SVT_STRING, $1); 345 $$ = mu_sieve_value_create (mu_sieve_machine, SVT_STRING, $1);
345 } 346 }
346 | NUMBER 347 | NUMBER
347 { 348 {
348 $$ = mu_sieve_value_create (SVT_NUMBER, &$1); 349 $$ = mu_sieve_value_create (mu_sieve_machine, SVT_NUMBER, &$1);
349 } 350 }
350 | TAG 351 | TAG
351 { 352 {
352 $$ = mu_sieve_value_create (SVT_TAG, $1); 353 $$ = mu_sieve_value_create (mu_sieve_machine, SVT_TAG, $1);
353 } 354 }
354 ; 355 ;
355 356
...@@ -998,13 +999,7 @@ mu_sieve_machine_init (mu_sieve_machine_t *pmach) ...@@ -998,13 +999,7 @@ mu_sieve_machine_init (mu_sieve_machine_t *pmach)
998 if (!mach) 999 if (!mach)
999 return ENOMEM; 1000 return ENOMEM;
1000 memset (mach, 0, sizeof (*mach)); 1001 memset (mach, 0, sizeof (*mach));
1001 rc = mu_list_create (&mach->memory_pool); 1002 mach->memory_pool = NULL;
1002 if (rc)
1003 {
1004 free (mach);
1005 return rc;
1006 }
1007
1008 rc = mu_opool_create (&mach->string_pool, MU_OPOOL_DEFAULT); 1003 rc = mu_opool_create (&mach->string_pool, MU_OPOOL_DEFAULT);
1009 if (rc) 1004 if (rc)
1010 { 1005 {
...@@ -1217,8 +1212,8 @@ mu_sieve_get_daemon_email (mu_sieve_machine_t mach) ...@@ -1217,8 +1212,8 @@ mu_sieve_get_daemon_email (mu_sieve_machine_t mach)
1217 void 1212 void
1218 mu_sieve_set_daemon_email (mu_sieve_machine_t mach, const char *email) 1213 mu_sieve_set_daemon_email (mu_sieve_machine_t mach, const char *email)
1219 { 1214 {
1220 mu_sieve_mfree (mach, (void *)mach->daemon_email); 1215 mu_sieve_free (mach, (void *)mach->daemon_email);
1221 mach->daemon_email = mu_sieve_mstrdup (mach, email); 1216 mach->daemon_email = mu_sieve_strdup (mach, email);
1222 } 1217 }
1223 1218
1224 struct sieve_destr_record 1219 struct sieve_destr_record
...@@ -1267,7 +1262,7 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach) ...@@ -1267,7 +1262,7 @@ mu_sieve_machine_destroy (mu_sieve_machine_t *pmach)
1267 mu_list_destroy (&mach->comp_list); 1262 mu_list_destroy (&mach->comp_list);
1268 mu_list_destroy (&mach->source_list); 1263 mu_list_destroy (&mach->source_list);
1269 mu_opool_destroy (&mach->string_pool); 1264 mu_opool_destroy (&mach->string_pool);
1270 mu_sieve_slist_destroy (&mach->memory_pool); 1265 mu_list_destroy (&mach->memory_pool);
1271 free (mach); 1266 free (mach);
1272 *pmach = NULL; 1267 *pmach = NULL;
1273 } 1268 }
...@@ -1284,18 +1279,26 @@ with_machine (mu_sieve_machine_t mach, char const *name, ...@@ -1284,18 +1279,26 @@ with_machine (mu_sieve_machine_t mach, char const *name,
1284 mu_strerr = mach->errstream; 1279 mu_strerr = mach->errstream;
1285 mu_stream_ref (mu_strerr); 1280 mu_stream_ref (mu_strerr);
1286 1281
1287 mu_i_sv_register_standard_actions (mach);
1288 mu_i_sv_register_standard_tests (mach);
1289 mu_i_sv_register_standard_comparators (mach);
1290 mu_sieve_machine = mach; 1282 mu_sieve_machine = mach;
1283 rc = setjmp (mach->errbuf);
1291 1284
1292 mu_sieve_stream_save (mach); 1285 if (rc == 0)
1293 rc = thunk (data); 1286 {
1294 mu_sieve_stream_restore (mach); 1287 mach->state = mu_sieve_state_init;
1295 1288 mu_i_sv_register_standard_actions (mach);
1296 mu_stream_unref (save_errstr); 1289 mu_i_sv_register_standard_tests (mach);
1297 mu_strerr = save_errstr; 1290 mu_i_sv_register_standard_comparators (mach);
1298 mu_stream_unref (mu_strerr); 1291
1292 mu_sieve_stream_save (mach);
1293 rc = thunk (data);
1294 mu_sieve_stream_restore (mach);
1295
1296 mu_stream_unref (save_errstr);
1297 mu_strerr = save_errstr;
1298 mu_stream_unref (mu_strerr);
1299 }
1300 else
1301 mach->state = mu_sieve_state_error;
1299 1302
1300 return rc; 1303 return rc;
1301 } 1304 }
......
...@@ -25,112 +25,14 @@ ...@@ -25,112 +25,14 @@
25 #include <stdarg.h> 25 #include <stdarg.h>
26 #include <sieve-priv.h> 26 #include <sieve-priv.h>
27 27
28 void * 28
29 mu_sieve_alloc (size_t size)
30 {
31 void *p = malloc (size);
32 if (!p)
33 {
34 mu_error ("not enough memory");
35 abort ();
36 }
37 return p;
38 }
39
40 void *
41 mu_sieve_palloc (mu_list_t *pool, size_t size)
42 {
43 void *p = malloc (size);
44 if (p)
45 {
46 if (!*pool && mu_list_create (pool))
47 {
48 free (p);
49 return NULL;
50 }
51 mu_list_append (*pool, p);
52 }
53 return p;
54 }
55
56 char *
57 mu_sieve_pstrdup (mu_list_t *pool, const char *str)
58 {
59 size_t len;
60 char *p;
61
62 if (!str)
63 return NULL;
64 len = strlen (str);
65 p = mu_sieve_palloc (pool, len + 1);
66 if (p)
67 {
68 memcpy (p, str, len);
69 p[len] = 0;
70 }
71 return p;
72 }
73
74 void *
75 mu_sieve_prealloc (mu_list_t *pool, void *ptr, size_t size)
76 {
77 void *newptr;
78
79 if (*pool)
80 mu_list_remove (*pool, ptr);
81
82 newptr = realloc (ptr, size);
83 if (newptr)
84 {
85 if (!*pool && mu_list_create (pool))
86 {
87 free (newptr);
88 return NULL;
89 }
90 mu_list_append (*pool, newptr);
91 }
92 return newptr;
93 }
94
95 void
96 mu_sieve_pfree (mu_list_t *pool, void *ptr)
97 {
98 if (*pool)
99 mu_list_remove (*pool, ptr);
100 free (ptr);
101 }
102
103 void *
104 mu_sieve_malloc (mu_sieve_machine_t mach, size_t size)
105 {
106 return mu_sieve_palloc (&mach->memory_pool, size);
107 }
108
109 char *
110 mu_sieve_mstrdup (mu_sieve_machine_t mach, const char *str)
111 {
112 return mu_sieve_pstrdup (&mach->memory_pool, str);
113 }
114
115 void *
116 mu_sieve_mrealloc (mu_sieve_machine_t mach, void *ptr, size_t size)
117 {
118 return mu_sieve_prealloc (&mach->memory_pool, ptr, size);
119 }
120
121 void
122 mu_sieve_mfree (mu_sieve_machine_t mach, void *ptr)
123 {
124 mu_sieve_pfree (&mach->memory_pool, ptr);
125 }
126
127 static int 29 static int
128 _destroy_item (void *item, void *data) 30 _destroy_item (void *item, void *data)
129 { 31 {
130 free (item); 32 free (item);
131 return 0; 33 return 0;
132 } 34 }
133 35 /* FIXME: Not needed? */
134 void 36 void
135 mu_sieve_slist_destroy (mu_list_t *plist) 37 mu_sieve_slist_destroy (mu_list_t *plist)
136 { 38 {
...@@ -141,9 +43,11 @@ mu_sieve_slist_destroy (mu_list_t *plist) ...@@ -141,9 +43,11 @@ mu_sieve_slist_destroy (mu_list_t *plist)
141 } 43 }
142 44
143 mu_sieve_value_t * 45 mu_sieve_value_t *
144 mu_sieve_value_create (mu_sieve_data_type type, void *data) 46 mu_sieve_value_create (mu_sieve_machine_t mach, mu_sieve_data_type type,
47 void *data)
145 { 48 {
146 mu_sieve_value_t *val = mu_sieve_alloc (sizeof (*val)); 49 mu_sieve_value_t *val = mu_sieve_alloc_memory (mach, sizeof (*val),
50 mu_sieve_reclaim_value);
147 51
148 val->type = type; 52 val->type = type;
149 switch (type) 53 switch (type)
......