diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-10-11 23:49:51 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-10-11 23:49:51 -0700 |
commit | 35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f (patch) | |
tree | 8c78ce4d12ce91ad4c60577009634c04f862f8be /hash.c | |
parent | e3ef5c56c8445b409ccb342c78aa79e7c2616582 (diff) | |
download | txr-35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f.tar.gz txr-35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f.tar.bz2 txr-35f3649a02f7edd0f69d3e1dcbed7fc2c435ce9f.zip |
hash: strengthen type mutual exclusion check.
* hash.c (equal_based_p): Take additional argument
eq indicating that :eq-based has been specified.
Check all three exclusive combinations.
(hashv): Call equal_based_p unconditionally, even when
:eq-based is specified and we don't use this function's
return value so we benefit from that function's exclusion
check. Pass the eq boolean, as required.
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 21 |
1 files changed, 13 insertions, 8 deletions
@@ -1267,15 +1267,21 @@ void hash_process_weak(void) do_iters(); } -static val equal_based_p(val equal, val eql, val wkeys) +static val equal_based_p(val equal, val eql, val eq, val wkeys) { + val mutex = lit("make-hash: mutually exclusive ~s and ~s"); + if (opt_compat && opt_compat <= 187) return equal; if (equal && eql) - uw_throwf(error_s, - lit("make-hash: mutually exclusive :equal-based and :eql-based"), - nao); + uw_throwf(error_s, mutex, equal_based_k, eql_based_k, nao); + + if (equal && eq) + uw_throwf(error_s, mutex, equal_based_k, eq_based_k, nao); + + if (eql && eq) + uw_throwf(error_s, mutex, eql_based_k, eq_based_k, nao); if (wkeys) { if (equal) @@ -1301,10 +1307,9 @@ val hashv(struct args *args) { eq_based_k, nil, &eq }, { userdata_k, t, &userdata } }; - val hash = (args_keys_extract(args, akv, sizeof akv / sizeof akv[0]), - if3(eq, - make_eq_hash(wkeys, wvals), - make_hash(wkeys, wvals, equal_based_p(equal, eql, wkeys)))); + val ebp = (args_keys_extract(args, akv, sizeof akv / sizeof akv[0]), + equal_based_p(equal, eql, eq, wkeys)); + val hash = if3(eq, make_eq_hash(wkeys, wvals), make_hash(wkeys, wvals, ebp)); if (userdata) set_hash_userdata(hash, userdata); return hash; |