[m-rev.] for review: extend documentation of string.split_into_lines/1
Julien Fischer
jfischer at opturion.com
Sat Sep 26 16:05:56 AEST 2026
For review by anyone.
----------------------------
Extend documentation of string.split_into_lines/1.
library/string.m:
As above. In particular, mention that carriage returns do
not participate in line breaking as far as split_int_lines/1
is concerned.
tests/hard_coded/string_split_1.{m,exp}:
Test the examples added to the documentation.
Test strings containing other characters that are treated
line breaks in Unicode, or might be mistaken as such.
Julien.
diff --git a/library/string.m b/library/string.m
index 35b54d282..988332ab5 100644
--- a/library/string.m
+++ b/library/string.m
@@ -1094,11 +1094,29 @@
%
:- func split_at_string(string, string) = list(string).
- % split_into_lines(String) breaks String into a sequence of lines,
- % with each line consisting of a possibly empty sequence of non-newline
- % characters, followed either by a newline character, or by the end
- % of the string. The string returned for a line will not contain
- % the newline character.
+ % split_into_lines(String) breaks String into a list of lines,
+ % returning the text of each line without its terminating newline
+ % character, if it has one. A line is
+ %
+ % - a possibly empty sequence of non-newline characters terminated by
+ % a newline character, or
+ % - a non-empty sequence of non-newline characters terminated by the
+ % end of String.
+ %
+ % Only the newline character terminates a line; carriage returns and
+ % the other characters that Unicode treats as line breaks are ordinary
+ % text, and will appear in the returned strings.
+ %
+ % The empty string contains no lines, and a final newline character does
+ % not add an empty line at the end of the list.
+ %
+ % For example,
+ %
+ % split_into_lines("") = []
+ % split_into_lines("a") = ["a"]
+ % split_into_lines("a\n") = ["a"]
+ % split_into_lines("\n") = [""]
+ % split_into_lines("a\n\nb") = ["a", "", "b"]
%
:- func split_into_lines(string) = list(string).
diff --git a/tests/hard_coded/string_split_1.exp
b/tests/hard_coded/string_split_1.exp
index d791e97ec..d485e949f 100644
--- a/tests/hard_coded/string_split_1.exp
+++ b/tests/hard_coded/string_split_1.exp
@@ -16,3 +16,20 @@ col1<tab>col2:val2<tab>col3<tab>
"line2"
"line3"
"line4nonl"
+
+split_into_lines("") = []
+split_into_lines("a") = ["a"]
+split_into_lines("a\n") = ["a"]
+split_into_lines("\n") = [""]
+split_into_lines("a\n\nb") = ["a", "", "b"]
+split_into_lines(" ") = [" "]
+split_into_lines("\r") = ["\r"]
+split_into_lines("\r\n") = ["\r"]
+split_into_lines("a\r") = ["a\r"]
+split_into_lines("a\r\n") = ["a\r"]
+split_into_lines("\a\b\e\f\t\v\n") = ["\a\b\e\f\t\v"]
+split_into_lines("a\034\b") = ["a\034\b"]
+split_into_lines("a\035\b") = ["a\035\b"]
+split_into_lines("a\036\b") = ["a\036\b"]
+split_into_lines("a\205\b") = ["a\205\b"]
+
diff --git a/tests/hard_coded/string_split_1.m
b/tests/hard_coded/string_split_1.m
index bccae5d3d..27fd0bdec 100644
--- a/tests/hard_coded/string_split_1.m
+++ b/tests/hard_coded/string_split_1.m
@@ -54,4 +54,49 @@ main(!IO) :-
io.nl(!IO),
list.foldl(io.write_line,
split_into_lines("line1\nline2\nline3\nline4nonl"), !IO),
+ io.nl(!IO),
+
+ list.foldl(do_test_split_into_lines, split_into_line_tests, !IO),
+ io.nl(!IO),
+
true.
+
+:- pred do_test_split_into_lines(string::in, io::di, io::uo) is det.
+
+do_test_split_into_lines(Str, !IO) :-
+ io.format("split_into_lines(%s) = ", [s(string(Str))], !IO),
+ Lines = split_into_lines(Str),
+ io.write_line(Lines, !IO).
+
+:- func split_into_line_tests = list(string).
+
+split_into_line_tests = [
+ % Examples from the documentation comment for split_into_lines/1.
+ "",
+ "a",
+ "a\n",
+ "\n",
+ "a\n\nb",
+
+ " ",
+
+ % Examples containing carriage returns.
+ "\r",
+ "\r\n",
+ "a\r",
+ "a\r\n",
+
+ % Mercury backslash escapes
+ "\a\b\e\f\t\v\n",
+
+ % Other code points that are treated as line breaks
+ % in various contexts, but not by split_into_lines/1.
+ "a\u001Cb", % FILE SEPARATOR
+ "a\u001Db", % GROUP SEPARATOR
+ "a\u001Eb", % RECORD SEPARATOR
+ "a\u0085b" % NEXT LINE
+% XXX we should test these as well but string/1 does not currently
+% escape them.
+% "a\u2028b", % LINE SEPARATOR
+% "a\u2029b" % PARAGRAPH SEPARATOR
+].
More information about the reviews
mailing list