Skip to content

Commit

Permalink
Merge pull request #278 from Abscissa/splitLinesKeepTerm
Browse files Browse the repository at this point in the history
Add optional KeepTerminator param to splitLines.
  • Loading branch information
jmdavis committed Sep 30, 2011
2 parents 8d97eb3 + e63a66c commit 9b41185
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 5 deletions.
2 changes: 1 addition & 1 deletion std/stdio.d
Expand Up @@ -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)
{
Expand Down
35 changes: 31 additions & 4 deletions std/string.d
Expand Up @@ -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;
Expand All @@ -1400,10 +1403,18 @@ S[] splitLines(S)(S s)

if(c == '\r' || c == '\n' || c == lineSep || c == paraSep)
{
retval.put(s[iStart .. i]);
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;

if(c == '\r' && i + 1 < s.length && s[i + 1] == '\n')
if(isWinEOL)
{
++nextI;
++iStart;
Expand Down Expand Up @@ -1437,10 +1448,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");
}
}

Expand Down

0 comments on commit 9b41185

Please sign in to comment.