[m-rev.] Minor addition to string.m

Ralph Becket rafe at cs.mu.OZ.AU
Thu Jan 30 14:59:28 AEDT 2003


Having taken various comments on board, this is now a slightly larger
change.  I'll add some test cases once people have had a chance to
comment on the new functions.

Estimated hours taken: 2
Branches: main

Added some new utility functions to the string module.

library/string.m:
	Added functions elem/2, unsafe_elem/2, chomp/1,
	strip_whitespace_prefix/1, strip_whitespace_suffix/1,
	strip_surrounding_whitespace/1, strip_prefix/2, strip_suffix/2,
	prefix_length/2, and suffix_length/2.

Index: library/string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.190
diff -u -r1.190 string.m
--- library/string.m	29 Nov 2002 13:25:56 -0000	1.190
+++ library/string.m	30 Jan 2003 03:51:06 -0000
@@ -263,6 +263,10 @@
 %	Calls error/1 if `Index' is out of range (negative, or greater than or
 %	equal to the length of `String').
 
+:- func string ^ elem(int) = char.
+%	A synonym for index_dex/2:
+%	String ^ elem(Index) = string__index_det(String, Index).
+
 :- func string__unsafe_index(string, int) = char.
 :- pred string__unsafe_index(string, int, char).
 :- mode string__unsafe_index(in, in, out) is det.
@@ -274,6 +278,51 @@
 %	may be linear in the length of the string.
 %	Use with care!
 
+:- func string ^ unsafe_elem(int) = char.
+%	A synonym for index_dex/2:
+%	String ^ unsafe_elem(Index) = string__unsafe_index(String, Index).
+
+:- func string__chomp(string) = string.
+%	string__chomp(String):
+%	`String' minus any trailing newline characters; equivalent
+%	to string__strip__suffix(pred('\n'::in) is semidet, String).
+
+:- func string__strip_whitespace_prefix(string) = string.
+%	string__strip_whitespace_prefix(String):
+%	`String' minus any initial whitespace characters.
+
+:- func string__strip_whitespace_suffix(string) = string.
+%	string__strip_whitespace_suffix(String):
+%	`String' minus any trailing whitespace characters.
+
+:- func string__strip_surrounding_whitespace(string) = string.
+%	string__strip_surrounding_whitespace(String):
+%	`String' minus any whitespace prefix and suffix characters.
+
+:- func string__strip_prefix(pred(char),          string) = string.
+:- mode string__strip_prefix(pred(in) is semidet, in    ) = out is det.
+%	string__strip_prefix(Pred, String):
+%	`String' minus the maximal prefix consisting entirely of
+%	chars satisfying `Pred'.
+
+:- func string__strip_suffix(pred(char),          string) = string.
+:- mode string__strip_suffix(pred(in) is semidet, in    ) = out is det.
+%	string__strip_suffix(Pred, String):
+%	`String' minus the maximal suffix consisting entirely of
+%	chars satisfying `Pred'.
+
+:- func string__prefix_length(pred(char),            string) = int.
+:- mode string__prefix_length(pred(in  ) is semidet, in)     = out is det.
+% string__prefix_length(Pred, String):
+% The length of the maximal prefix of `String' consisting entirely of
+% chars satisfying Pred.
+
+:- func suffix_length(pred(char),            string) = int.
+:- mode suffix_length(pred(in  ) is semidet, in)     = out is det.
+% string__suffix_length(Pred, String):
+% The length of the maximal suffix of `String' consisting entirely of
+% chars satisfying Pred.
+
 :- pred string__set_char(char, int, string, string).
 :- mode string__set_char(in, in, in, out) is semidet.
 % XXX This mode is disabled because the compiler puts constant
@@ -653,6 +702,8 @@
 		error("string__index_det: index out of range")
 	).
 
+String ^ elem(Index) = index_det(String, Index).
+
 string__set_char_det(Char, Int, String0, String) :-
 	( string__set_char(Char, Int, String0, String1) ->
 		String = String1
@@ -3009,6 +3060,8 @@
 		error("string__unsafe_index: out of bounds")
 	).
 
+String ^ unsafe_elem(Index) = unsafe_index(String, Index).
+
 /*-----------------------------------------------------------------------*/
 
 :- pragma c_header_code("
@@ -3799,6 +3852,60 @@
 	  else
 	  	error("string__det_base_string_to_int/2: conversion failed")
 	).
+
+%-----------------------------------------------------------------------------%
+
+chomp(S) = strip_suffix(pred('\n'::in) is semidet, S).
+
+%-----------------------------------------------------------------------------%
+
+strip_whitespace_suffix(S) = strip_suffix(is_whitespace, S).
+
+%-----------------------------------------------------------------------------%
+
+strip_whitespace_prefix(S) = strip_prefix(is_whitespace, S).
+
+%-----------------------------------------------------------------------------%
+
+strip_surrounding_whitespace(S0) = S :-
+	L = prefix_length(is_whitespace, S0),
+	R = suffix_length(is_whitespace, S0),
+	S = substring(S0, L, length(S0) - L - R).
+
+%-----------------------------------------------------------------------------%
+
+strip_suffix(P, S) = substring(S, 0, length(S) - suffix_length(P, S)).
+
+%-----------------------------------------------------------------------------%
+
+strip_prefix(P, S)  = substring(S, 0, prefix_length(P, S)).
+
+%-----------------------------------------------------------------------------%
+
+prefix_length(P, S) = prefix_length_2(0, length(S), P, S).
+
+
+:- func prefix_length_2(int, int, pred(char),            string) = int.
+:- mode prefix_length_2(in,  in,  pred(in  ) is semidet, in)     = out is det.
+
+prefix_length_2(I, N, P, S) =
+	( if I < N, P(S ^ elem(I)) then prefix_length_2(I + 1, N, P, S)
+				   else I
+	).
+
+%-----------------------------------------------------------------------------%
+
+suffix_length(P, S) = suffix_length_2(length(S) - 1, length(S), P, S).
+
+
+:- func suffix_length_2(int, int, pred(char),            string) = int.
+:- mode suffix_length_2(in,  in,  pred(in  ) is semidet, in)     = out is det.
+
+suffix_length_2(I, N, P, S) =
+	( if 0 =< I, P(S ^ elem(I)) then suffix_length_2(I - 1, N, P, S)
+				    else N - (I + 1)
+	).
+
 
 %------------------------------------------------------------------------------%
 
--------------------------------------------------------------------------
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