mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-02 15:40:55 -08:00
SXHASH does not produce the same key for two strings which only differ on the character type
This commit is contained in:
parent
788d6bb11a
commit
d715216ac2
2 changed files with 54 additions and 48 deletions
21
src/c/hash.d
21
src/c/hash.d
|
|
@ -167,8 +167,27 @@ _hash_equal(int depth, cl_hashkey h, cl_object x)
|
|||
return _hash_equal(depth, h, CDR(x));
|
||||
case t_symbol:
|
||||
x = x->symbol.name;
|
||||
#ifdef ECL_UNICODE
|
||||
case t_base_string: {
|
||||
cl_index i;
|
||||
for (i = 0; i < x->base_string.fillp; i++) {
|
||||
uint32_t w = x->base_string.self[i];
|
||||
h = hash_word(h, w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case t_string: {
|
||||
cl_index i;
|
||||
for (i = 0; i < x->string.fillp; i++) {
|
||||
uint32_t w = CHAR_CODE(x->string.self[i]);
|
||||
h = hash_word(h, w);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#else
|
||||
case t_base_string:
|
||||
return hash_string(h, x->base_string.self, x->base_string.fillp);
|
||||
#endif
|
||||
case t_pathname:
|
||||
h = _hash_equal(depth, h, x->pathname.host);
|
||||
h = _hash_equal(depth, h, x->pathname.device);
|
||||
|
|
@ -182,7 +201,7 @@ _hash_equal(int depth, cl_hashkey h, cl_object x)
|
|||
/* Notice that we may round out some bits. We must do this
|
||||
* because the fill pointer may be set in the middle of a byte.
|
||||
* If so, the extra bits _must_ _not_ take part in the hash,
|
||||
* because otherwise we two bit arrays which are EQUAL might
|
||||
* because otherwise two bit arrays which are EQUAL might
|
||||
* have different hash keys. */
|
||||
return hash_string(h, x->vector.self.ch, x->vector.fillp / 8);
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -408,55 +408,55 @@ BEGIN:
|
|||
case t_longfloat:
|
||||
#endif
|
||||
case t_complex:
|
||||
if (ECL_NUMBER_TYPE_P(ty))
|
||||
return number_equalp(x, y);
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return ECL_NUMBER_TYPE_P(ty) && number_equalp(x, y);
|
||||
case t_vector:
|
||||
#ifdef ECL_UNICODE
|
||||
case t_string:
|
||||
#endif
|
||||
case t_base_string:
|
||||
case t_bitvector:
|
||||
if (ty == t_vector || ty == t_base_string || ty == t_bitvector) {
|
||||
j = x->vector.fillp;
|
||||
if (j != y->vector.fillp)
|
||||
return FALSE;
|
||||
goto ARRAY;
|
||||
}
|
||||
else
|
||||
return(FALSE);
|
||||
#ifdef ECL_UNICODE
|
||||
case t_string:
|
||||
if (ty != t_vector && ty != t_base_string && ty != t_bitvector
|
||||
&& ty != t_string)
|
||||
return FALSE;
|
||||
#else
|
||||
if (ty != t_vector && ty != t_base_string && ty != t_bitvector)
|
||||
return FALSE;
|
||||
#endif
|
||||
|
||||
j = x->vector.fillp;
|
||||
if (j != y->vector.fillp)
|
||||
return FALSE;
|
||||
goto ARRAY;
|
||||
case t_array:
|
||||
if (ty == t_array && x->array.rank == y->array.rank) {
|
||||
if (x->array.rank > 1) {
|
||||
cl_index i = 0;
|
||||
for (i = 0; i < x->array.rank; i++)
|
||||
if (x->array.dims[i] != y->array.dims[i]) return(FALSE);
|
||||
}
|
||||
if (x->array.dim != y->array.dim)
|
||||
return(FALSE);
|
||||
j=x->array.dim;
|
||||
goto ARRAY;
|
||||
if (ty != t_array || x->array.rank != y->array.rank)
|
||||
return FALSE;
|
||||
if (x->array.rank > 1) {
|
||||
cl_index i = 0;
|
||||
for (i = 0; i < x->array.rank; i++)
|
||||
if (x->array.dims[i] != y->array.dims[i]) return(FALSE);
|
||||
}
|
||||
else
|
||||
if (x->array.dim != y->array.dim)
|
||||
return(FALSE);
|
||||
j=x->array.dim;
|
||||
ARRAY: {
|
||||
cl_index i;
|
||||
for (i = 0; i < j; i++)
|
||||
if (!equalp(aref(x, i), aref(y, i)))
|
||||
return(FALSE);
|
||||
return(TRUE);
|
||||
}
|
||||
default:;
|
||||
}
|
||||
if (tx != ty)
|
||||
return(FALSE);
|
||||
return FALSE;
|
||||
switch (tx) {
|
||||
case t_character:
|
||||
return(char_equal(x, y));
|
||||
|
||||
return char_equal(x, y);
|
||||
case t_cons:
|
||||
if (!equalp(CAR(x), CAR(y)))
|
||||
return(FALSE);
|
||||
x = CDR(x);
|
||||
y = CDR(y);
|
||||
goto BEGIN;
|
||||
|
||||
#ifdef CLOS
|
||||
case t_instance: {
|
||||
cl_index i;
|
||||
|
|
@ -480,10 +480,8 @@ BEGIN:
|
|||
return(TRUE);
|
||||
}
|
||||
#endif /* CLOS */
|
||||
|
||||
case t_pathname:
|
||||
return(equal(x, y));
|
||||
|
||||
return equal(x, y);
|
||||
case t_hashtable: {
|
||||
cl_index i;
|
||||
struct ecl_hashtable_entry *ex, *ey;
|
||||
|
|
@ -499,21 +497,10 @@ BEGIN:
|
|||
return(FALSE);
|
||||
}
|
||||
}
|
||||
return(TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
default:
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
ARRAY:
|
||||
{
|
||||
cl_index i;
|
||||
|
||||
for (i = 0; i < j; i++)
|
||||
if (!equalp(aref(x, i), aref(y, i)))
|
||||
return(FALSE);
|
||||
return(TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue