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 | 9466c7755b265baba149d8478d28e25265d0e080 (patch) | |
tree | 8c78ce4d12ce91ad4c60577009634c04f862f8be | |
parent | 36a4980ee384acf3f590b028a7e417300ece6b5b (diff) | |
download | txr-9466c7755b265baba149d8478d28e25265d0e080.tar.gz txr-9466c7755b265baba149d8478d28e25265d0e080.tar.bz2 txr-9466c7755b265baba149d8478d28e25265d0e080.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.
-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; |