From 4a8722ce9fcbb66abe2bd304e5a4bad03d842821 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Mon, 4 Dec 2017 06:31:19 -0800 Subject: args: redesign args extractor to just use array. * args.c (struct args_bool_key): Structure moved to header file. (struct args_bool_ctx): One more piece of context information, the array size. (args_check_key_store): Work with array of args_bool_key structs rather than linked list. Remove useless local variable "store". (args_key_extract_vl): Function removed. (args_key_extract): Takes array instead of va_list. * args.h (struct args_bool_key): Structure declared here. Loses the next pointer since not used for a linked list. (args_key_extract_vl): Function removed. (args_key_extract): Redeclared. * hash.c (hashv): Adapt to new args_key_extract function. --- args.c | 55 +++++++++++++------------------------------------------ args.h | 9 +++++++-- hash.c | 13 +++++++------ 3 files changed, 27 insertions(+), 50 deletions(-) diff --git a/args.c b/args.c index 3c222d18..8ce2f06e 100644 --- a/args.c +++ b/args.c @@ -138,23 +138,16 @@ void args_for_each(struct args *args, rplaca(iter, nil); } -struct args_bool_key { - struct args_bool_key *next; - val key; - val arg_p; - val *store; -}; - struct args_bool_ctx { - struct args_bool_key *akl; + struct args_bool_key *akv; + int n; val *next_arg_store; }; static int args_key_check_store(val arg, int ix, mem_t *ctx) { struct args_bool_ctx *acx = coerce(struct args_bool_ctx *, ctx); - struct args_bool_key **pakl, *akl; - val *store = 0; + int i, n = acx->n; if (acx->next_arg_store != 0) { *acx->next_arg_store = arg; @@ -162,49 +155,27 @@ static int args_key_check_store(val arg, int ix, mem_t *ctx) return 0; } - for (pakl = &acx->akl, akl = *pakl; - akl != 0; - pakl = &akl->next, akl = *pakl) - { - if (store != 0) - *store = arg; + for (i = 0; i < n; i++) { + struct args_bool_key *akl = &acx->akv[i]; if (akl->key == arg) { if (akl->arg_p) acx->next_arg_store = akl->store; else *akl->store = t; - *pakl = akl->next; + break; } } return 0; } -void args_keys_extract_vl(struct args *args, va_list vl) +void args_keys_extract(struct args *args, struct args_bool_key *akv, int n) { - struct args_bool_ctx acx = { 0 }; - - for (;;) { - val key; - struct args_bool_key *nakl; - if ((key = va_arg (vl, val)) == nil) - break; - nakl = coerce(struct args_bool_key *, alloca(sizeof *nakl)); - nakl->key = key; - nakl->arg_p = va_arg (vl, val); - nakl->store = va_arg (vl, val *); - nakl->next = acx.akl; - acx.akl = nakl; - } - - if (acx.akl != 0) + if (n > 0) { + struct args_bool_ctx acx; + acx.akv = akv; + acx.n = n; + acx.next_arg_store = 0; args_for_each(args, args_key_check_store, coerce(mem_t *, &acx)); -} - -void args_keys_extract(struct args *args, ...) -{ - va_list vl; - va_start (vl, args); - args_keys_extract_vl(args, vl); - va_end (vl); + } } diff --git a/args.h b/args.h index 6e0036c0..b3bb91db 100644 --- a/args.h +++ b/args.h @@ -41,6 +41,12 @@ typedef int arg_index; (coerce(struct args *, \ alloca(offsetof(struct args, arg) + (N)*sizeof (val)))) +struct args_bool_key { + val key; + val arg_p; + val *store; +}; + INLINE struct args *args_init_list(struct args *args, cnum argc, val list) { args->argc = argc; @@ -189,5 +195,4 @@ val args_copy_to_list(struct args *args); void args_for_each(struct args *args, int (*fn)(val arg, int ix, mem_t *ctx), mem_t *ctx); -void args_keys_extract_vl(struct args *args, va_list); -void args_keys_extract(struct args *args, ...); +void args_keys_extract(struct args *args, struct args_bool_key *, int n); diff --git a/hash.c b/hash.c index f6a79370..1720aa10 100644 --- a/hash.c +++ b/hash.c @@ -1062,12 +1062,13 @@ void hash_process_weak(void) val hashv(struct args *args) { val wkeys = nil, wvals = nil, equal = nil, userdata = nil; - val hash = (args_keys_extract(args, - weak_keys_k, nil, &wkeys, - weak_vals_k, nil, &wvals, - equal_based_k, nil, &equal, - userdata_k, t, &userdata, - nil), + struct args_bool_key akv[] = { + { weak_keys_k, nil, &wkeys }, + { weak_vals_k, nil, &wvals }, + { equal_based_k, nil, &equal }, + { userdata_k, t, &userdata } + }; + val hash = (args_keys_extract(args, akv, sizeof akv / sizeof akv[0]), make_hash(wkeys, wvals, equal)); if (userdata) set_hash_userdata(hash, userdata); -- cgit v1.2.3