[m-rev.] for review: string__join_list
Zoltan Somogyi
zs at cs.mu.OZ.AU
Mon Jun 25 14:51:45 AEST 2001
For review by anyone. No test case is necessary, since my next change to the
deep profiler will use the new predicate.
library/string.m:
Add a function string__join_list(Separator, Strings), which is like
string__append_list, except it puts Separator between adjacent strings
in Strings.
Zoltan.
Index: string.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/string.m,v
retrieving revision 1.145
diff -u -b -r1.145 string.m
--- string.m 2001/05/31 06:00:08 1.145
+++ string.m 2001/06/25 01:17:54
@@ -363,6 +363,12 @@
:- mode string__append_list(in, out) is det.
% Append a list of strings together.
+:- func string__join_list(string, list(string)) = string.
+% string__join_list(Separator, Strings) = JoinedString:
+% Appends together the strings in Strings, putting Separator between
+% adjacent strings. If Strings is the empty list, returns the empty
+% string.
+
:- func string__hash(string) = int.
:- pred string__hash(string, int).
:- mode string__hash(in, out) is det.
@@ -934,15 +940,16 @@
string__append_list(Lists, string__append_list(Lists)).
- % Implementation of append_list that uses C as this minimises the
- % amount of garbage created.
+ % Implementation of string__append_list that uses C as this
+ % minimises the amount of garbage created.
:- pragma foreign_proc("C", string__append_list(Strs::in) = (Str::out),
[will_not_call_mercury, thread_safe], "{
MR_Word list = Strs;
MR_Word tmp;
- size_t len = 0;
+ size_t len;
/* Determine the total len of all strings */
+ len = 0;
while (!MR_list_is_empty(list)) {
len += strlen((MR_String) MR_list_head(list));
list = MR_list_tail(list);
@@ -964,11 +971,62 @@
Str[len] = '\\0';
}").
-:- pragma foreign_proc("MC++", string__append_list(_Strs::in) = (_Str::out),
+ % Implementation of string__join_list that uses C as this
+ % minimises the amount of garbage created.
+:- pragma foreign_proc("C", string__join_list(Sep::in, Strs::in) = (Str::out),
[will_not_call_mercury, thread_safe], "{
+ MR_Word list = Strs;
+ MR_Word tmp;
+ size_t len = 0;
+ size_t sep_len;
+ bool add_sep;
+
+ sep_len = strlen(Sep);
+
+ /* Determine the total len of all strings */
+ len = -sep_len; /* compensate for no separator before first string */
+ while (!MR_list_is_empty(list)) {
+ len += sep_len + strlen((MR_String) MR_list_head(list));
+ list = MR_list_tail(list);
+ }
+
+ /* Allocate enough word aligned memory for the string */
+ if (len <= 0) {
+ len = 0;
+ }
+ MR_allocate_aligned_string_msg(Str, len, MR_PROC_LABEL);
+
+ /* Copy the strings into the new memory */
+ len = 0;
+ list = Strs;
+ add_sep = FALSE;
+ while (!MR_list_is_empty(list)) {
+ if (add_sep) {
+ strcpy((MR_String) Str + len, Sep);
+ len += sep_len;
+ }
+
+ strcpy((MR_String) Str + len, (MR_String) MR_list_head(list));
+ len += strlen((MR_String) MR_list_head(list));
+ list = MR_list_tail(list);
+ add_sep = TRUE;
+ }
+
+ /* Set the last character to the null char */
+ Str[len] = '\\0';
+}").
+
+:- pragma foreign_proc("MC++",
+ string__append_list(_Strs::in) = (_Str::out),
+ [will_not_call_mercury, thread_safe], "{
mercury::runtime::Errors::SORRY(""c code for this function"");
}").
+:- pragma foreign_proc("MC++",
+ string__join_list(_Sep::in, _Strs::in) = (_Str::out),
+ [will_not_call_mercury, thread_safe], "{
+ mercury::runtime::Errors::SORRY(""c code for this function"");
+}").
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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