[m-rev.] diff: fix string_contains_char bug

Simon Taylor stayl at cs.mu.OZ.AU
Wed Aug 7 01:27:51 AEST 2002


Estimated hours taken: 0.5
Branches: main

library/string.m:
	Fix a bug in string__contains_char which broke
	Fergus's string quoting change, causing C compilation
	errors due to ill-formed char constants in the generated
	code. The C function strchr() considers the terminating
	'\0' to be part of the string, so searches for '\0' were
	always succeeded. In Mercury, the '\0' is just an
	implementation detail, so it shouldn't be considered
	to be part of the string.
	 
	Improve the efficiency of the Mercury version
	of string__contains_char by not recomputing the
	length of the string for each character.

tests/hard_coded/Mmakefile:
tests/hard_coded/contains_char.{m,exp}:
	Test case.	

Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.174
diff -u -u -r1.174 string.m
--- library/string.m	23 Jul 2002 08:26:28 -0000	1.174
+++ library/string.m	6 Aug 2002 15:24:10 -0000
@@ -1902,25 +1902,30 @@
 :- pred string__contains_char(string, char).
 :- mode string__contains_char(in, in) is semidet.
 */
+	% strchr always returns true when searching for '\0',
+	% but the '\0' is an implementation detail which really
+	% shouldn't be considered to be part of the string itself.
 :- pragma foreign_proc("C", string__contains_char(Str::in, Ch::in),
 		[will_not_call_mercury, promise_pure, thread_safe], "
-	SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);
+	SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL) && Ch != '\\0';
 ").
 :- pragma foreign_proc("MC++", string__contains_char(Str::in, Ch::in),
 		[will_not_call_mercury, promise_pure, thread_safe], "
 	SUCCESS_INDICATOR = (Str->IndexOf(Ch) != -1);
 ").
 string__contains_char(String, Char) :-
-	string__contains_char(String, Char, 0).
+	string__contains_char(String, Char, 0, string__length(Char)).
 
-:- pred string__contains_char(string::in, char::in, int::in) is semidet.
+:- pred string__contains_char(string::in, char::in,
+		int::in, int::in) is semidet.
 
-string__contains_char(Str, Char, Index) :-
-	string__index(Str, Index, IndexChar),
+string__contains_char(Str, Char, Index, Length) :-
+	Index < Length,
+	string__unsafe_index(Str, Index, IndexChar),
 	( IndexChar = Char ->
 		true
 	;
-		string__contains_char(Str, Char, Index + 1)
+		string__contains_char(Str, Char, Index + 1, Length)
 	).
 
 /*-----------------------------------------------------------------------*/
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.161
diff -u -u -r1.161 Mmakefile
--- tests/hard_coded/Mmakefile	6 Aug 2002 00:30:51 -0000	1.161
+++ tests/hard_coded/Mmakefile	6 Aug 2002 15:11:25 -0000
@@ -22,6 +22,7 @@
 	common_type_cast \
 	compare_spec \
 	comparison \
+	contains_char \
 	constraint \
 	constraint_order \
 	construct_test \
Index: tests/hard_coded/contains_char.exp
===================================================================
RCS file: tests/hard_coded/contains_char.exp
diff -N tests/hard_coded/contains_char.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/contains_char.exp	6 Aug 2002 15:21:41 -0000
@@ -0,0 +1 @@
+test succeeded
Index: tests/hard_coded/contains_char.m
===================================================================
RCS file: tests/hard_coded/contains_char.m
diff -N tests/hard_coded/contains_char.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/contains_char.m	6 Aug 2002 14:56:48 -0000
@@ -0,0 +1,22 @@
+:- module contains_char.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module char, string.
+
+main -->
+	(
+		{ char__to_int(Nul, 0) },
+		{ string__contains_char("", Nul) }
+	->
+		io__write_string("test failed\n")
+	;
+		io__write_string("test succeeded\n")
+	).
+
--------------------------------------------------------------------------
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