[augeas-devel] augeas: master - Handle allocation failures from define_native_intl
David Lutterkort
lutter at fedoraproject.org
Thu Oct 1 00:23:15 UTC 2009
Gitweb: http://git.fedorahosted.org/git/augeas.git?p=augeas.git;a=commitdiff;h=de5176539277cb7513cddf2ada51c9683555f29f
Commit: de5176539277cb7513cddf2ada51c9683555f29f
Parent: e5e7ee7ab6c88cb3e2a6ae4409f4ae4c1d5f4bd7
Author: David Lutterkort <lutter at redhat.com>
AuthorDate: Sun Feb 1 21:30:50 2009 -0800
Committer: David Lutterkort <lutter at redhat.com>
CommitterDate: Wed Sep 30 12:10:55 2009 -0700
Handle allocation failures from define_native_intl
---
src/builtin.c | 50 ++++++++++++++++++++++++++++++--------------------
src/syntax.c | 39 ++++++++++++++++++++++++++++++---------
src/syntax.h | 7 ++++---
3 files changed, 64 insertions(+), 32 deletions(-)
diff --git a/src/builtin.c b/src/builtin.c
index e066aba..c9698b0 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -429,39 +429,49 @@ static struct value *sys_read_file(struct info *info, struct value *n) {
struct module *builtin_init(void) {
struct module *modl = module_create("Builtin");
- define_native(modl, "gensym", 1, gensym, T_STRING, T_STRING);
+ int r;
+
+#define DEFINE_NATIVE(modl, name, nargs, impl, types ...) \
+ r = define_native(modl, name, nargs, impl, ##types); \
+ if (r < 0) goto error;
+
+ DEFINE_NATIVE(modl, "gensym", 1, gensym, T_STRING, T_STRING);
+
/* Primitive lenses */
- define_native(modl, "del", 2, lns_del, T_REGEXP, T_STRING, T_LENS);
- define_native(modl, "store", 1, lns_store, T_REGEXP, T_LENS);
- define_native(modl, "key", 1, lns_key, T_REGEXP, T_LENS);
- define_native(modl, "label", 1, lns_label, T_STRING, T_LENS);
- define_native(modl, "seq", 1, lns_seq, T_STRING, T_LENS);
- define_native(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
+ DEFINE_NATIVE(modl, "del", 2, lns_del, T_REGEXP, T_STRING, T_LENS);
+ DEFINE_NATIVE(modl, "store", 1, lns_store, T_REGEXP, T_LENS);
+ DEFINE_NATIVE(modl, "key", 1, lns_key, T_REGEXP, T_LENS);
+ DEFINE_NATIVE(modl, "label", 1, lns_label, T_STRING, T_LENS);
+ DEFINE_NATIVE(modl, "seq", 1, lns_seq, T_STRING, T_LENS);
+ DEFINE_NATIVE(modl, "counter", 1, lns_counter, T_STRING, T_LENS);
/* Applying lenses (mostly for tests) */
- define_native(modl, "get", 2, lens_get, T_LENS, T_STRING, T_TREE);
- define_native(modl, "put", 3, lens_put, T_LENS, T_TREE, T_STRING,
- T_STRING);
+ DEFINE_NATIVE(modl, "get", 2, lens_get, T_LENS, T_STRING, T_TREE);
+ DEFINE_NATIVE(modl, "put", 3, lens_put, T_LENS, T_TREE, T_STRING,
+ T_STRING);
/* Tree manipulation used by the PUT tests */
- define_native(modl, "set", 3, tree_set_glue, T_STRING, T_STRING, T_TREE,
+ DEFINE_NATIVE(modl, "set", 3, tree_set_glue, T_STRING, T_STRING, T_TREE,
T_TREE);
- define_native(modl, "clear", 2, tree_clear_glue, T_STRING, T_TREE,
+ DEFINE_NATIVE(modl, "clear", 2, tree_clear_glue, T_STRING, T_TREE,
T_TREE);
- define_native(modl, "rm", 2, tree_rm_glue, T_STRING, T_TREE, T_TREE);
- define_native(modl, "insa", 3, tree_insa_glue, T_STRING, T_STRING, T_TREE,
+ DEFINE_NATIVE(modl, "rm", 2, tree_rm_glue, T_STRING, T_TREE, T_TREE);
+ DEFINE_NATIVE(modl, "insa", 3, tree_insa_glue, T_STRING, T_STRING, T_TREE,
T_TREE);
- define_native(modl, "insb", 3, tree_insb_glue, T_STRING, T_STRING, T_TREE,
+ DEFINE_NATIVE(modl, "insb", 3, tree_insb_glue, T_STRING, T_STRING, T_TREE,
T_TREE);
/* Transforms and filters */
- define_native(modl, "incl", 1, xform_incl, T_STRING, T_FILTER);
- define_native(modl, "excl", 1, xform_excl, T_STRING, T_FILTER);
- define_native(modl, "transform", 2, xform_transform, T_LENS, T_FILTER,
+ DEFINE_NATIVE(modl, "incl", 1, xform_incl, T_STRING, T_FILTER);
+ DEFINE_NATIVE(modl, "excl", 1, xform_excl, T_STRING, T_FILTER);
+ DEFINE_NATIVE(modl, "transform", 2, xform_transform, T_LENS, T_FILTER,
T_TRANSFORM);
/* System functions */
struct module *sys = module_create("Sys");
modl->next = sys;
- define_native(sys, "getenv", 1, sys_getenv, T_STRING, T_STRING);
- define_native(sys, "read_file", 1, sys_read_file, T_STRING, T_STRING);
+ DEFINE_NATIVE(sys, "getenv", 1, sys_getenv, T_STRING, T_STRING);
+ DEFINE_NATIVE(sys, "read_file", 1, sys_read_file, T_STRING, T_STRING);
return modl;
+ error:
+ unref(modl, module);
+ return NULL;
}
/*
diff --git a/src/syntax.c b/src/syntax.c
index 3f06c05..a429c75 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -245,7 +245,8 @@ void free_value(struct value *v) {
unref(v->transform, transform);
break;
case V_NATIVE:
- unref(v->native->type, type);
+ if (v->native)
+ unref(v->native->type, type);
free(v->native);
break;
case V_CLOS:
@@ -1709,17 +1710,18 @@ static struct info *make_native_info(const char *fname, int line) {
return info;
}
-void define_native_intl(const char *file, int line,
- struct module *module, const char *name,
- int argc, void *impl, ...) {
+int define_native_intl(const char *file, int line,
+ struct module *module, const char *name,
+ int argc, void *impl, ...) {
assert(argc > 0); /* We have no unit type */
assert(argc <= 5);
va_list ap;
enum type_tag tag;
- struct term *params = NULL, *body;
+ struct term *params = NULL, *body = NULL, *func = NULL;
struct type *type;
- struct value *v;
+ struct value *v = NULL;
struct info *info = make_native_info(file, line);
+ struct ctx ctx;
va_start(ap, impl);
for (int i=0; i < argc; i++) {
@@ -1737,22 +1739,31 @@ void define_native_intl(const char *file, int line,
type = make_base_type(tag);
make_ref(v);
+ if (v == NULL)
+ goto error;
v->tag = V_NATIVE;
v->info = info;
- CALLOC(v->native, 1);
+ if (ALLOC(v->native) < 0)
+ goto error;
v->native->argc = argc;
v->native->type = type;
v->native->impl = impl;
make_ref(body);
+ if (body == NULL)
+ goto error;
body->info = ref(info);
body->type = ref(type);
body->tag = A_VALUE;
body->value = v;
+ v = NULL;
+
+ func = build_func(params, body);
+ if (func == NULL)
+ goto error;
+ body = NULL;
- struct term *func = build_func(params, body);
- struct ctx ctx;
ctx.aug = NULL;
ctx.local = ref(module->bindings);
ctx.name = module->name;
@@ -1762,12 +1773,22 @@ void define_native_intl(const char *file, int line,
abort();
}
v = make_closure(func, ctx.local);
+ if (v == NULL) {
+ unref(module->bindings, binding);
+ goto error;
+ }
bind(&ctx.local, name, func->type, v);
unref(v, value);
unref(func, term);
unref(module->bindings, binding);
module->bindings = ctx.local;
+ return 0;
+ error:
+ unref(v, value);
+ unref(body, term);
+ unref(func, term);
+ return -1;
}
diff --git a/src/syntax.h b/src/syntax.h
index f0c21a2..4d805ae 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -255,9 +255,10 @@ struct module *module_create(const char *name);
#define define_native(module, name, argc, impl, types ...) \
define_native_intl(__FILE__, __LINE__, module, name, argc, impl, ## types)
-void define_native_intl(const char *fname, int line,
- struct module *module, const char *name,
- int argc, void *impl, ...);
+ATTRIBUTE_RETURN_CHECK
+int define_native_intl(const char *fname, int line,
+ struct module *module, const char *name,
+ int argc, void *impl, ...);
struct module *builtin_init(void);
More information about the augeas-devel
mailing list