[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