diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-12-04 06:31:19 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-12-04 06:31:19 -0800 |
commit | 4a8722ce9fcbb66abe2bd304e5a4bad03d842821 (patch) | |
tree | 85771680aa329b5436a3916d89bbdc34a9328c8b | |
parent | 507c6c1516233cb565142a71176bc0d3a246d5b4 (diff) | |
download | txr-4a8722ce9fcbb66abe2bd304e5a4bad03d842821.tar.gz txr-4a8722ce9fcbb66abe2bd304e5a4bad03d842821.tar.bz2 txr-4a8722ce9fcbb66abe2bd304e5a4bad03d842821.zip |
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.
-rw-r--r-- | args.c | 55 | ||||
-rw-r--r-- | args.h | 9 | ||||
-rw-r--r-- | hash.c | 13 |
3 files changed, 27 insertions, 50 deletions
@@ -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); + } } @@ -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); @@ -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); |