diff options
author | Přemysl Janouch <p.janouch@gmail.com> | 2017-05-21 09:03:57 +0200 |
---|---|---|
committer | Přemysl Janouch <p.janouch@gmail.com> | 2017-05-21 13:19:48 +0200 |
commit | 1caec277bfff3fe8df9769368d0d84601acd7944 (patch) | |
tree | e0ad6e668234a458727c75a62521466b79ad0d13 | |
parent | 706f452d9ddc180cf2fdaf9814778ee818661ee4 (diff) | |
download | ell-1caec277bfff3fe8df9769368d0d84601acd7944.tar.gz ell-1caec277bfff3fe8df9769368d0d84601acd7944.tar.xz ell-1caec277bfff3fe8df9769368d0d84601acd7944.zip |
set() can unset now
Fixing two bugs with this commit.
-rwxr-xr-x | ell.c | 48 |
1 files changed, 27 insertions, 21 deletions
@@ -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); } |