From 62cc5e9c87c4db5869aa81e1de964924aa494440 Mon Sep 17 00:00:00 2001 From: Abscissa Date: Tue, 27 Sep 2011 13:53:26 -0400 Subject: [PATCH 1/4] Add optional KeepTerminator param to splitLines. --- std/string.d | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/std/string.d b/std/string.d index b06a008238f..fa3aaba1721 100644 --- a/std/string.d +++ b/std/string.d @@ -1385,9 +1385,12 @@ S[] splitlines(S)(S s) /++ Split $(D s) into an array of lines using $(D '\r'), $(D '\n'), $(D "\r\n"), $(XREF uni, lineSep), and $(XREF uni, paraSep) as delimiters. - The delimiter is not included in the strings returned. + If $(D keepTerm) is set to $(D KeepTerminator.yes), then the delimiter + is included in the strings returned. +/ -S[] splitLines(S)(S s) +enum KeepTerminator : bool { no, yes } +/// ditto +S[] splitLines(S)(S s, KeepTerminator keepTerm=KeepTerminator.no) if(isSomeString!S) { size_t iStart = 0; @@ -1400,10 +1403,20 @@ S[] splitLines(S)(S s) if(c == '\r' || c == '\n' || c == lineSep || c == paraSep) { - retval.put(s[iStart .. i]); + auto isWinEOL = c == '\r' && i + 1 < s.length && s[i + 1] == '\n'; + auto iEnd = i; + + if(keepTerm == KeepTerminator.yes) + { + iEnd = nextI; + if(isWinEOL) + ++iEnd; + } + + retval.put(s[iStart .. iEnd]); iStart = nextI; - if(c == '\r' && i + 1 < s.length && s[i + 1] == '\n') + if(isWinEOL) { ++nextI; ++iStart; @@ -1437,10 +1450,26 @@ unittest assert(lines[7] == ""); assert(lines[8] == "sunday"); + lines = splitLines(s, KeepTerminator.yes); + assert(lines.length == 9); + assert(lines[0] == "\r"); + assert(lines[1] == "peter\n"); + assert(lines[2] == "\r"); + assert(lines[3] == "paul\r\n"); + assert(lines[4] == "jerry\u2028"); + assert(lines[5] == "ice\u2029"); + assert(lines[6] == "cream\n"); + assert(lines[7] == "\n"); + assert(lines[8] == "sunday\n"); + s.popBack(); // Lop-off trailing \n lines = splitLines(s); assert(lines.length == 9); assert(lines[8] == "sunday"); + + lines = splitLines(s, KeepTerminator.yes); + assert(lines.length == 9); + assert(lines[8] == "sunday"); } } From bb8ff2725658ec79bfbf5ac3ad6f0521f3149fb5 Mon Sep 17 00:00:00 2001 From: Abscissa Date: Tue, 27 Sep 2011 14:00:39 -0400 Subject: [PATCH 2/4] std.stdio.File.KeepTerminator and std.string.KeepTerminator should be the same type. --- std/stdio.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/std/stdio.d b/std/stdio.d index 3019a654e74..29c8ad1f8a5 100644 --- a/std/stdio.d +++ b/std/stdio.d @@ -907,7 +907,7 @@ Returns the file number corresponding to this object. /** Range that reads one line at a time. */ - enum KeepTerminator : bool { no, yes } + alias std.string.KeepTerminator KeepTerminator; /// ditto struct ByLine(Char, Terminator) { From 085f1fd3de661aaf3f2ba59ab20d670a48a659a8 Mon Sep 17 00:00:00 2001 From: Abscissa Date: Wed, 28 Sep 2011 05:43:41 -0400 Subject: [PATCH 3/4] splitLines cleanup suggestions. --- std/string.d | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/std/string.d b/std/string.d index fa3aaba1721..499d9061006 100644 --- a/std/string.d +++ b/std/string.d @@ -1390,7 +1390,7 @@ S[] splitlines(S)(S s) +/ enum KeepTerminator : bool { no, yes } /// ditto -S[] splitLines(S)(S s, KeepTerminator keepTerm=KeepTerminator.no) +S[] splitLines(S)(S s, KeepTerminator keepTerm = KeepTerminator.no) if(isSomeString!S) { size_t iStart = 0; @@ -1403,14 +1403,12 @@ S[] splitLines(S)(S s, KeepTerminator keepTerm=KeepTerminator.no) if(c == '\r' || c == '\n' || c == lineSep || c == paraSep) { - auto isWinEOL = c == '\r' && i + 1 < s.length && s[i + 1] == '\n'; + immutable isWinEOL = c == '\r' && i + 1 < s.length && s[i + 1] == '\n'; auto iEnd = i; if(keepTerm == KeepTerminator.yes) { - iEnd = nextI; - if(isWinEOL) - ++iEnd; + iEnd = isWinEOL? nextI + 1 : nextI; } retval.put(s[iStart .. iEnd]); From e63a66cd13b71feb345f3238bf79be2f30bf68a6 Mon Sep 17 00:00:00 2001 From: Abscissa Date: Wed, 28 Sep 2011 05:56:22 -0400 Subject: [PATCH 4/4] Kill some trailing whitespace. --- std/string.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/std/string.d b/std/string.d index 499d9061006..888bb000c95 100644 --- a/std/string.d +++ b/std/string.d @@ -1405,12 +1405,12 @@ S[] splitLines(S)(S s, KeepTerminator keepTerm = KeepTerminator.no) { immutable isWinEOL = c == '\r' && i + 1 < s.length && s[i + 1] == '\n'; auto iEnd = i; - + if(keepTerm == KeepTerminator.yes) { iEnd = isWinEOL? nextI + 1 : nextI; } - + retval.put(s[iStart .. iEnd]); iStart = nextI;