SXHASH does not produce the same key for two strings which only differ on the character type

This commit is contained in:
jgarcia 2006-11-10 18:41:47 +00:00
parent 788d6bb11a
commit d715216ac2
2 changed files with 54 additions and 48 deletions

View file

@ -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:

View file

@ -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;
}
}