aboutsummaryrefslogtreecommitdiff
path: root/ell.c
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2017-05-21 09:03:57 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2017-05-21 13:19:48 +0200
commit1caec277bfff3fe8df9769368d0d84601acd7944 (patch)
treee0ad6e668234a458727c75a62521466b79ad0d13 /ell.c
parent706f452d9ddc180cf2fdaf9814778ee818661ee4 (diff)
downloadell-1caec277bfff3fe8df9769368d0d84601acd7944.tar.gz
ell-1caec277bfff3fe8df9769368d0d84601acd7944.tar.xz
ell-1caec277bfff3fe8df9769368d0d84601acd7944.zip
set() can unset now
Fixing two bugs with this commit.
Diffstat (limited to 'ell.c')
-rwxr-xr-xell.c48
1 files changed, 27 insertions, 21 deletions
diff --git a/ell.c b/ell.c
index bdbc6fb..f5b1924 100755
--- a/ell.c
+++ b/ell.c
@@ -694,21 +694,24 @@ get (struct context *ctx, const char *name) {
static bool
set (struct context *ctx, const char *name, struct item *value) {
- struct item *iter, *key, *pair;
- for (iter = ctx->variables; iter; iter = iter->next)
- if (!strcmp (iter->head->value, name))
+ struct item **p;
+ for (p = &ctx->variables; *p; p = &(*p)->next)
+ if (!strcmp ((*p)->head->value, name)) {
+ struct item *tmp = *p;
+ *p = (*p)->next;
+ item_free (tmp);
break;
- if (iter) {
- item_free (iter->head->next);
- return check (ctx, (iter->head->next = new_clone (value)));
- }
+ }
+ if (!value)
+ return true;
+
+ struct item *key, *pair;
if (!check (ctx, (key = new_string (name, strlen (name))))
- || !check (ctx, (pair = new_list (key))))
- return false;
- if (!check (ctx, (key->next = new_clone (value)))) {
- item_free (pair);
+ || !check (ctx, (pair = new_list (key)))) {
+ item_free_list (value);
return false;
}
+ key->next = value;
pair->next = ctx->variables;
ctx->variables = pair;
return true;
@@ -731,16 +734,14 @@ static bool
rename_arguments (struct context *ctx, struct item *names) {
size_t i = 0;
for (; names; names = names->next) {
+ if (names->type != ITEM_STRING)
+ return set_error (ctx, "argument names must be strings");
+
char buf[64];
(void) snprintf (buf, sizeof buf, "%zu", i++);
struct item *value = get (ctx, buf);
-
- // TODO: set to some sort of nil value?
- if (!value)
- return true;
-
- if (names->type != ITEM_STRING)
- return set_error (ctx, "argument names must be strings");
+ if (value && !check (ctx, (value = new_clone (value))))
+ return false;
if (!set (ctx, names->value, value))
return false;
}
@@ -770,7 +771,8 @@ static bool
set_arg (struct context *ctx, size_t arg, struct item *value) {
char buf[64];
(void) snprintf (buf, sizeof buf, "%zu", arg);
- return set (ctx, buf, value);
+ return check (ctx, (value = new_clone (value)))
+ && set (ctx, buf, value);
}
// TODO: we should probably maintain arguments in a separate list,
@@ -896,7 +898,8 @@ defn (fn_set) {
struct item *value;
if ((value = name->next))
- return set (ctx, name->value, value);
+ return check (ctx, (value = new_clone (value)))
+ && set (ctx, name->value, value);
// We return an empty list for a nil value
if (!(value = get (ctx, name->value)))
@@ -1091,8 +1094,11 @@ init_runtime_library (struct context *ctx) {
printf ("error parsing internal function `%s': %s\n",
functions[i].name, e);
ok = false;
+ } else if (!check (ctx, (body = new_list (body)))
+ || !set (ctx, functions[i].name, body)) {
+ ok = false;
} else
- ok &= set (ctx, functions[i].name, body);
+ body = NULL;
item_free_list (body);
parser_free (&parser);
}