[m-rev.] for review: fix MR_hash_string() bug
Simon Taylor
stayl at cs.mu.OZ.AU
Thu Nov 21 17:53:36 AEDT 2002
Estimated hours taken: 1
Branches: main, release
runtime/mercury_string.h:
Fix a bug which caused the results of MR_hash_string()
and string__hash to differ -- cast each character to
MR_UnsignedChar before combining it with the hash value.
tests/hard_coded/Mmakefile:
tests/hard_coded/string_hash.{m,exp}:
Test case.
Index: runtime/mercury_string.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_string.h,v
retrieving revision 1.27
diff -u -u -r1.27 mercury_string.h
--- runtime/mercury_string.h 30 Sep 2002 06:08:22 -0000 1.27
+++ runtime/mercury_string.h 21 Nov 2002 03:09:13 -0000
@@ -143,7 +143,7 @@
hash = 0; \
while(((MR_ConstString)(s))[len]) { \
hash ^= (hash << 5); \
- hash ^= ((MR_ConstString)(s))[len]; \
+ hash ^= (MR_UnsignedChar) ((MR_ConstString)(s))[len]; \
len++; \
} \
hash ^= len; \
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.173
diff -u -u -r1.173 Mmakefile
--- tests/hard_coded/Mmakefile 23 Oct 2002 13:41:52 -0000 1.173
+++ tests/hard_coded/Mmakefile 21 Nov 2002 03:29:17 -0000
@@ -263,8 +263,16 @@
endif
endif
+# string_hash tests features of the Mercury C runtime.
+ifeq "$(filter il% java%,$(GRADE))" ""
+ C_ONLY_PROGS=string_hash
+else
+ C_ONLY_PROGS=
+endif
+
PROGS = $(ORDINARY_PROGS) $(BROKEN_FOR_LCC_PROGS) $(CLOSURE_LAYOUT_PROGS) \
- $(EXCEPTION_PROGS) $(BACKEND_PROGS) $(NONDET_C_PROGS) $(CHAR_REP_PROGS)
+ $(EXCEPTION_PROGS) $(BACKEND_PROGS) $(NONDET_C_PROGS) \
+ $(C_ONLY_PROGS) $(CHAR_REP_PROGS)
# --split-c-files does not work in the hl* grades (e.g. hlc.gc),
# because it hasn't yet been implemented yet.
Index: tests/hard_coded/string_hash.exp
===================================================================
RCS file: tests/hard_coded/string_hash.exp
diff -N tests/hard_coded/string_hash.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/string_hash.exp 21 Nov 2002 03:24:40 -0000
@@ -0,0 +1 @@
+all tests succeeded
Index: tests/hard_coded/string_hash.m
===================================================================
RCS file: tests/hard_coded/string_hash.m
diff -N tests/hard_coded/string_hash.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/string_hash.m 21 Nov 2002 06:52:05 -0000
@@ -0,0 +1,78 @@
+% Test that string__hash and the MR_hash_string return the same value.
+:- module string_hash.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module bool, char, int, list, random, require, string.
+
+main(!IO) :-
+ MaxLength = 1024,
+ random__init(1, RS0),
+ test(MaxLength, yes, Succeeded, RS0, _, !IO),
+ ( Succeeded = yes ->
+ io__write_string("all tests succeeded\n", !IO)
+ ;
+ io__write_string("some tests failed\n", !IO)
+ ).
+
+:- pred test(int::in, bool::in, bool::out,
+ random__supply::mdi, random__supply::muo,
+ io__state::di, io__state::uo) is det.
+
+test(Length, !Succeeded, !RS, !IO) :-
+ ( Length = 0 ->
+ true
+ ;
+ make_char_list(Length, [], List, !RS),
+ string__from_char_list(List, String),
+ LibHash = string__hash(String),
+ RuntimeHash = runtime_string_hash(String),
+ ( LibHash = RuntimeHash ->
+ true
+ ;
+ !:Succeeded = no,
+ io__write_string("failed: runtime ", !IO),
+ io__write_int(RuntimeHash, !IO),
+ io__write_string(", library ", !IO),
+ io__write_int(LibHash, !IO),
+ io__write_string(": """, !IO),
+ io__write_string(String, !IO),
+ io__write_string("""\n", !IO)
+ ),
+ test(Length - 1, !Succeeded, !RS, !IO)
+ ).
+
+:- pred make_char_list(int::in, list(char)::in, list(char)::out,
+ random__supply::mdi, random__supply::muo) is det.
+
+make_char_list(Length, !List, !RS) :-
+ ( Length = 0 ->
+ true
+ ;
+ random__random(char__min_char_value,
+ (char__max_char_value - char__min_char_value + 1),
+ Int, !RS),
+ ( char__to_int(Char, Int) ->
+ !:List = [Char | !.List]
+ ;
+ error("char_to_int failed")
+ ),
+ make_char_list(Length - 1, !List, !RS)
+ ).
+
+:- pragma foreign_decl("C", "#include ""mercury_string.h""").
+
+:- func runtime_string_hash(string) = int.
+
+:- pragma foreign_proc("C", runtime_string_hash(String::in) = (Hash::out),
+ [promise_pure, will_not_call_mercury],
+"
+ Hash = MR_hash_string(String);
+").
+
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list