From 1caec277bfff3fe8df9769368d0d84601acd7944 Mon Sep 17 00:00:00 2001 From: Přemysl Janouch Date: Sun, 21 May 2017 09:03:57 +0200 Subject: set() can unset now Fixing two bugs with this commit. --- ell.c | 48 +++++++++++++++++++++++++++--------------------- 1 file 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); } -- cgit v1.2.3-70-g09d2