aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2001-01-25 10:03:10 +0800
committerMichael Zucci <zucchi@src.gnome.org>2001-01-25 10:03:10 +0800
commit7ad01f8ebef4b1e297a623c2015424d330da5958 (patch)
treef17ec843259e6595e32c5716ac24b755dd847e03
parent5bf4f88ae222d598431c5e5b7d54e2d67d742ab5 (diff)
downloadgsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.tar
gsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.tar.gz
gsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.tar.bz2
gsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.tar.lz
gsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.tar.xz
gsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.tar.zst
gsoc2013-evolution-7ad01f8ebef4b1e297a623c2015424d330da5958.zip
Add chunk allocators.
2001-01-24 Not Zed <NotZed@Ximian.com> * e-sexp.h (ESExp): Add chunk allocators. * e-sexp.c: Removed some redundant debug printfs. (e_sexp_term_eval): Dont allocate result till we have it. so we can have a fatal error, and not leak it. (term_eval_plus): If we have to abort, free our arguments. (term_eval_sub): Same. (parse_new_term): Renamed to parse_term_new for consistency. Fixed callers. (e_sexp_result_new): Add the esexp as an argument. Ouch, lots of code to change for this. Allocate blocks from an ememchunk. Fixed all callers. (e_sexp_result_free): Same as above, free blocks from the ememchunk. Fixed all callers. (parse_term_new): (parse_term_free): Similarly, add the esexp to the argument, and alloc/free from memchunks. Fixed all local callers. (e_sexp_init): Setup the memory chunk allocators. (e_sexp_finalise): Destroy memchunk allocators. svn path=/trunk/; revision=7795
-rw-r--r--e-util/ChangeLog12
-rw-r--r--e-util/e-sexp.c119
-rw-r--r--e-util/e-sexp.h9
3 files changed, 82 insertions, 58 deletions
diff --git a/e-util/ChangeLog b/e-util/ChangeLog
index 0019b44da9..96cd3815bb 100644
--- a/e-util/ChangeLog
+++ b/e-util/ChangeLog
@@ -1,5 +1,7 @@
2001-01-24 Not Zed <NotZed@Ximian.com>
+ * e-sexp.h (ESExp): Add chunk allocators.
+
* e-sexp.c: Removed some redundant debug printfs.
(e_sexp_term_eval): Dont allocate result till we have it. so we
can have a fatal error, and not leak it.
@@ -7,6 +9,16 @@
(term_eval_sub): Same.
(parse_new_term): Renamed to parse_term_new for consistency.
Fixed callers.
+ (e_sexp_result_new): Add the esexp as an argument. Ouch, lots of
+ code to change for this. Allocate blocks from an ememchunk.
+ Fixed all callers.
+ (e_sexp_result_free): Same as above, free blocks from the
+ ememchunk. Fixed all callers.
+ (parse_term_new):
+ (parse_term_free): Similarly, add the esexp to the argument, and
+ alloc/free from memchunks. Fixed all local callers.
+ (e_sexp_init): Setup the memory chunk allocators.
+ (e_sexp_finalise): Destroy memchunk allocators.
2001-01-23 Not Zed <NotZed@Ximian.com>
diff --git a/e-util/e-sexp.c b/e-util/e-sexp.c
index 1e250d8167..997eb441d8 100644
--- a/e-util/e-sexp.c
+++ b/e-util/e-sexp.c
@@ -73,6 +73,7 @@
#include <time.h>
#include <string.h>
+#include "e-memory.h"
#include "e-sexp.h"
#define p(x) /* parse debug */
@@ -149,15 +150,15 @@ e_sexp_error(struct _ESExp *f)
}
struct _ESExpResult *
-e_sexp_result_new(int type)
+e_sexp_result_new(struct _ESExp *f, int type)
{
- struct _ESExpResult *r = g_malloc0(sizeof(*r));
+ struct _ESExpResult *r = e_memchunk_alloc0(f->result_chunks);
r->type = type;
return r;
}
void
-e_sexp_result_free(struct _ESExpResult *t)
+e_sexp_result_free(struct _ESExp *f, struct _ESExpResult *t)
{
if (t == NULL)
return;
@@ -175,7 +176,7 @@ e_sexp_result_free(struct _ESExpResult *t)
case ESEXP_RES_UNDEFINED:
break;
}
- g_free(t);
+ e_memchunk_free(f->result_chunks, t);
}
/* used in normal functions if they have to abort, and free their arguments */
@@ -185,7 +186,7 @@ e_sexp_resultv_free(struct _ESExp *f, int argc, struct _ESExpResult **argv)
int i;
for (i=0;i<argc;i++) {
- e_sexp_result_free(argv[i]);
+ e_sexp_result_free(f, argv[i]);
}
}
@@ -226,15 +227,15 @@ term_eval_and(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
r(printf("( and\n"));
- r = e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ r = e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
for (i=0;bool && i<argc;i++) {
r1 = e_sexp_term_eval(f, argv[i]);
if (type == -1)
type = r1->type;
if (type != r1->type) {
- e_sexp_result_free(r);
- e_sexp_result_free(r1);
+ e_sexp_result_free(f, r);
+ e_sexp_result_free(f, r1);
g_hash_table_destroy(ht);
e_sexp_fatal_error(f, "Invalid types in AND");
} else if ( r1->type == ESEXP_RES_ARRAY_PTR ) {
@@ -251,7 +252,7 @@ term_eval_and(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
} else if ( r1->type == ESEXP_RES_BOOL ) {
bool &= r1->value.bool;
}
- e_sexp_result_free(r1);
+ e_sexp_result_free(f, r1);
}
if (type == ESEXP_RES_ARRAY_PTR) {
@@ -282,15 +283,15 @@ term_eval_or(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
r(printf("(or \n"));
- r = e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ r = e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
for (i=0;!bool && i<argc;i++) {
r1 = e_sexp_term_eval(f, argv[i]);
if (type == -1)
type = r1->type;
if (r1->type != type) {
- e_sexp_result_free(r);
- e_sexp_result_free(r1);
+ e_sexp_result_free(f, r);
+ e_sexp_result_free(f, r1);
g_hash_table_destroy(ht);
e_sexp_fatal_error(f, "Invalid types in OR");
} else if (r1->type == ESEXP_RES_ARRAY_PTR) {
@@ -305,7 +306,7 @@ term_eval_or(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
} else if (r1->type == ESEXP_RES_BOOL) {
bool |= r1->value.bool;
}
- e_sexp_result_free(r1);
+ e_sexp_result_free(f, r1);
}
if (type == ESEXP_RES_ARRAY_PTR) {
@@ -334,7 +335,7 @@ term_eval_not(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
&& argv[0]->value.bool)
res = FALSE;
}
- r = e_sexp_result_new(ESEXP_RES_BOOL);
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
r->value.bool = res;
return r;
}
@@ -345,15 +346,15 @@ term_eval_lt(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
{
struct _ESExpResult *r, *r1, *r2;
- r = e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ r = e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
if (argc == 2) {
r1 = e_sexp_term_eval(f, argv[0]);
r2 = e_sexp_term_eval(f, argv[1]);
if (r1->type != r2->type) {
- e_sexp_result_free(r1);
- e_sexp_result_free(r2);
- e_sexp_result_free(r);
+ e_sexp_result_free(f, r1);
+ e_sexp_result_free(f, r2);
+ e_sexp_result_free(f, r);
e_sexp_fatal_error(f, "Incompatible types in compare <");
} else if (r1->type == ESEXP_RES_INT) {
r->type = ESEXP_RES_BOOL;
@@ -362,8 +363,8 @@ term_eval_lt(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
r->type = ESEXP_RES_BOOL;
r->value.bool = strcmp(r1->value.string, r2->value.string) < 0;
}
- e_sexp_result_free(r1);
- e_sexp_result_free(r2);
+ e_sexp_result_free(f, r1);
+ e_sexp_result_free(f, r2);
}
return r;
}
@@ -374,15 +375,15 @@ term_eval_gt(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
{
struct _ESExpResult *r, *r1, *r2;
- r = e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ r = e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
if (argc == 2) {
r1 = e_sexp_term_eval(f, argv[0]);
r2 = e_sexp_term_eval(f, argv[1]);
if (r1->type != r2->type) {
- e_sexp_result_free(r1);
- e_sexp_result_free(r2);
- e_sexp_result_free(r);
+ e_sexp_result_free(f, r1);
+ e_sexp_result_free(f, r2);
+ e_sexp_result_free(f, r);
e_sexp_fatal_error(f, "Incompatible types in compare >");
} else if (r1->type == ESEXP_RES_INT) {
r->type = ESEXP_RES_BOOL;
@@ -391,8 +392,8 @@ term_eval_gt(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
r->type = ESEXP_RES_BOOL;
r->value.bool = strcmp(r1->value.string, r2->value.string) > 0;
}
- e_sexp_result_free(r1);
- e_sexp_result_free(r2);
+ e_sexp_result_free(f, r1);
+ e_sexp_result_free(f, r2);
}
return r;
}
@@ -403,7 +404,7 @@ term_eval_eq(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
{
struct _ESExpResult *r, *r1, *r2;
- r = e_sexp_result_new(ESEXP_RES_BOOL);
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
if (argc == 2) {
r1 = e_sexp_term_eval(f, argv[0]);
@@ -417,8 +418,8 @@ term_eval_eq(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
} else if (r1->type == ESEXP_RES_STRING) {
r->value.bool = strcmp(r1->value.string, r2->value.string) == 0;
}
- e_sexp_result_free(r1);
- e_sexp_result_free(r2);
+ e_sexp_result_free(f, r1);
+ e_sexp_result_free(f, r2);
}
return r;
}
@@ -442,7 +443,7 @@ term_eval_plus(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *dat
e_sexp_resultv_free(f, argc, argv);
e_sexp_fatal_error(f, "Invalid types in (+ ints)");
}
- r = e_sexp_result_new(ESEXP_RES_INT);
+ r = e_sexp_result_new(f, ESEXP_RES_INT);
r->value.number = total;
break; }
case ESEXP_RES_STRING: {
@@ -454,7 +455,7 @@ term_eval_plus(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *dat
e_sexp_resultv_free(f, argc, argv);
e_sexp_fatal_error(f, "Invalid types in (+ strings)");
}
- r = e_sexp_result_new(ESEXP_RES_STRING);
+ r = e_sexp_result_new(f, ESEXP_RES_STRING);
r->value.string = s->str;
g_string_free(s, FALSE);
break; }
@@ -463,7 +464,7 @@ term_eval_plus(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *dat
}
if (!r) {
- r = e_sexp_result_new(ESEXP_RES_INT);
+ r = e_sexp_result_new(f, ESEXP_RES_INT);
r->value.number = 0;
}
return r;
@@ -488,14 +489,14 @@ term_eval_sub(struct _ESExp *f, int argc, struct _ESExpResult **argv, void *data
e_sexp_resultv_free(f, argc, argv);
e_sexp_fatal_error(f, "Invalid types in -");
}
- r = e_sexp_result_new(ESEXP_RES_INT);
+ r = e_sexp_result_new(f, ESEXP_RES_INT);
r->value.number = total;
break; }
}
}
if (!r) {
- r = e_sexp_result_new(ESEXP_RES_INT);
+ r = e_sexp_result_new(f, ESEXP_RES_INT);
r->value.number = 0;
}
return r;
@@ -511,14 +512,14 @@ term_eval_if(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data)
if (argc >=2 && argc<=3) {
r = e_sexp_term_eval(f, argv[0]);
doit = (r->type == ESEXP_RES_BOOL && r->value.bool);
- e_sexp_result_free(r);
+ e_sexp_result_free(f, r);
if (doit) {
return e_sexp_term_eval(f, argv[1]);
} else if (argc>2) {
return e_sexp_term_eval(f, argv[2]);
}
}
- return e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ return e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
}
/* implements 'begin' statement */
@@ -530,13 +531,13 @@ term_eval_begin(struct _ESExp *f, int argc, struct _ESExpTerm **argv, void *data
for (i=0;i<argc;i++) {
if (r)
- e_sexp_result_free(r);
+ e_sexp_result_free(f, r);
r = e_sexp_term_eval(f, argv[i]);
}
if (r)
return r;
else
- return e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ return e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
}
@@ -556,18 +557,18 @@ e_sexp_term_eval(struct _ESExp *f, struct _ESExpTerm *t)
switch (t->type) {
case ESEXP_TERM_STRING:
r(printf(" (string \"%s\")\n", t->value.string));
- r = e_sexp_result_new(ESEXP_RES_STRING);
+ r = e_sexp_result_new(f, ESEXP_RES_STRING);
/* erk, this shoul;dn't need to strdup this ... */
r->value.string = g_strdup(t->value.string);
break;
case ESEXP_TERM_INT:
r(printf(" (int %d)\n", t->value.number));
- r = e_sexp_result_new(ESEXP_RES_INT);
+ r = e_sexp_result_new(f, ESEXP_RES_INT);
r->value.number = t->value.number;
break;
case ESEXP_TERM_BOOL:
r(printf(" (int %d)\n", t->value.number));
- r = e_sexp_result_new(ESEXP_RES_BOOL);
+ r = e_sexp_result_new(f, ESEXP_RES_BOOL);
r->value.bool = t->value.bool;
break;
case ESEXP_TERM_IFUNC:
@@ -591,7 +592,7 @@ e_sexp_term_eval(struct _ESExp *f, struct _ESExpTerm *t)
}
if (r==NULL)
- r = e_sexp_result_new(ESEXP_RES_UNDEFINED);
+ r = e_sexp_result_new(f, ESEXP_RES_UNDEFINED);
return r;
}
@@ -680,15 +681,15 @@ parse_dump_term(struct _ESExpTerm *t, int depth)
*/
static struct _ESExpTerm *
-parse_term_new(int type)
+parse_term_new(struct _ESExp *f, int type)
{
- struct _ESExpTerm *s = g_malloc0(sizeof(*s));
+ struct _ESExpTerm *s = e_memchunk_alloc0(f->term_chunks);
s->type = type;
return s;
}
static void
-parse_term_free(struct _ESExpTerm *t)
+parse_term_free(struct _ESExp *f, struct _ESExpTerm *t)
{
int i;
@@ -700,7 +701,7 @@ parse_term_free(struct _ESExpTerm *t)
case ESEXP_TERM_FUNC:
case ESEXP_TERM_IFUNC:
for (i=0;i<t->value.func.termcount;i++) {
- parse_term_free(t->value.func.terms[i]);
+ parse_term_free(f, t->value.func.terms[i]);
}
g_free(t->value.func.terms);
break;
@@ -714,7 +715,7 @@ parse_term_free(struct _ESExpTerm *t)
default:
printf("parse_term_free: unknown type: %d\n", t->type);
}
- g_free(t);
+ e_memchunk_free(f->term_chunks, t);
}
static struct _ESExpTerm **
@@ -760,18 +761,18 @@ parse_value(ESExp *f)
return parse_list(f, TRUE);
case G_TOKEN_STRING:
p(printf("got string\n"));
- t = parse_term_new(ESEXP_TERM_STRING);
+ t = parse_term_new(f, ESEXP_TERM_STRING);
t->value.string = g_strdup(g_scanner_cur_value(gs).v_string);
break;
case G_TOKEN_INT:
- t = parse_term_new(ESEXP_TERM_INT);
+ t = parse_term_new(f, ESEXP_TERM_INT);
t->value.number = g_scanner_cur_value(gs).v_int;
p(printf("got int\n"));
break;
case '#':
p(printf("got bool?\n"));
token = g_scanner_get_next_token(gs);
- t = parse_term_new(ESEXP_TERM_BOOL);
+ t = parse_term_new(f, ESEXP_TERM_BOOL);
t->value.bool = token=='t';
break;
case G_TOKEN_SYMBOL:
@@ -781,12 +782,12 @@ parse_value(ESExp *f)
case ESEXP_TERM_IFUNC:
/* this is basically invalid, since we can't use function
pointers, but let the runtime catch it ... */
- t = parse_term_new(s->type);
+ t = parse_term_new(f, s->type);
t->value.func.sym = s;
t->value.func.terms = parse_values(f, &t->value.func.termcount);
break;
case ESEXP_TERM_VAR:
- t = parse_term_new(s->type);
+ t = parse_term_new(f, s->type);
t->value.var = s;
break;
default:
@@ -824,7 +825,7 @@ parse_list(ESExp *f, int gotbrace)
s = g_scanner_cur_value(gs).v_symbol;
p(printf("got funciton: %s\n", s->name));
- t = parse_term_new(s->type);
+ t = parse_term_new(f, s->type);
p(printf("created new list %p\n", t));
/* if we have a variable, find out its base type */
while (s->type == ESEXP_TERM_VAR) {
@@ -835,7 +836,7 @@ parse_list(ESExp *f, int gotbrace)
t->value.func.sym = s;
t->value.func.terms = parse_values(f, &t->value.func.termcount);
} else {
- parse_term_free(t);
+ parse_term_free(f, t);
e_sexp_fatal_error(f, "Trying to call variable as function: %s", s->name);
}
break; }
@@ -907,10 +908,13 @@ e_sexp_finalise(void *o)
ESExp *s = (ESExp *)o;
if (s->tree) {
- parse_term_free(s->tree);
+ parse_term_free(s, s->tree);
s->tree = NULL;
}
+ e_memchunk_destroy(s->term_chunks);
+ e_memchunk_destroy(s->result_chunks);
+
g_scanner_scope_foreach_symbol(s->scanner, 0, free_symbol, 0);
g_scanner_destroy(s->scanner);
@@ -925,6 +929,8 @@ e_sexp_init (ESExp *s)
int i;
s->scanner = g_scanner_new(&scanner_config);
+ s->term_chunks = e_memchunk_new(16, sizeof(struct _ESExpTerm));
+ s->result_chunks = e_memchunk_new(16, sizeof(struct _ESExpResult));
/* load in builtin symbols? */
for(i=0;i<sizeof(symbols)/sizeof(symbols[0]);i++) {
@@ -973,6 +979,7 @@ e_sexp_new (void)
ESExp *f = g_malloc0(sizeof(*f));
e_sexp_init(f);
#endif
+
return f;
}
@@ -1095,7 +1102,7 @@ e_sexp_parse(ESExp *f)
}
if (f->tree)
- parse_term_free(f->tree);
+ parse_term_free(f, f->tree);
f->tree = parse_list(f, FALSE);
diff --git a/e-util/e-sexp.h b/e-util/e-sexp.h
index 3584abcaf5..9299fdb61a 100644
--- a/e-util/e-sexp.h
+++ b/e-util/e-sexp.h
@@ -103,6 +103,11 @@ struct _ESExp {
/* private stuff */
jmp_buf failenv;
char *error;
+
+ /* TODO: may also need a pool allocator for term strings, so we dont lose them
+ in error conditions? */
+ struct _EMemChunk *term_chunks;
+ struct _EMemChunk *result_chunks;
};
struct _ESExpClass {
@@ -133,8 +138,8 @@ int e_sexp_parse (ESExp *f);
ESExpResult *e_sexp_eval (ESExp *f);
ESExpResult *e_sexp_term_eval (struct _ESExp *f, struct _ESExpTerm *t);
-ESExpResult *e_sexp_result_new (int type);
-void e_sexp_result_free (struct _ESExpResult *t);
+ESExpResult *e_sexp_result_new (struct _ESExp *f, int type);
+void e_sexp_result_free (struct _ESExp *f, struct _ESExpResult *t);
/* used in normal functions if they have to abort, to free their arguments */
void e_sexp_resultv_free (struct _ESExp *f, int argc, struct _ESExpResult **argv);