Skip to content

Commit

Permalink
splitLines: move to root/string.d
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored and dlang-bot committed Mar 30, 2024
1 parent e00869b commit 62e9d70
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 100 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dmd/errors.d
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ private void verrorPrint(const(char)* format, va_list ap, ref ErrorInfo info)
const fileName = FileName(loc.filename.toDString);
if (auto text = global.fileManager.getFileContents(fileName))
{
auto range = global.fileManager.splitLines(cast(const(char[])) text);
auto range = dmd.root.string.splitLines(cast(const(char[])) text);
size_t linnum;
foreach (line; range)
{
Expand Down
99 changes: 0 additions & 99 deletions compiler/src/dmd/file_manager.d
Original file line number Diff line number Diff line change
Expand Up @@ -317,105 +317,6 @@ nothrow:
return fb;
}

/**********************************
* Take `text` and turn it into an InputRange that emits
* slices into `text` for each line.
* Params:
* text = array of characters
* Returns:
* InputRange accessing `text` as a sequence of lines
* Reference:
* `std.string.splitLines()`
*/
auto splitLines(const char[] text)
{
struct Range
{
@safe:
@nogc:
nothrow:
pure:
private:

const char[] text;
size_t index; // index of start of line
size_t eolIndex; // index of end of line before newline characters
size_t nextIndex; // index past end of line

public this(const char[] text)
{
this.text = text;
}

public bool empty() { return index == text.length; }

public void popFront() { advance(); index = nextIndex; }

public const(char)[] front() { advance(); return text[index .. eolIndex]; }

private void advance()
{
if (index != nextIndex) // if already advanced
return;

for (size_t i = index; i < text.length; ++i)
{
switch (text[i])
{
case '\v', '\f', '\n':
eolIndex = i;
nextIndex = i + 1;
return;

case '\r':
if (i + 1 < text.length && text[i + 1] == '\n') // decode "\r\n"
{
eolIndex = i;
nextIndex = i + 2;
return;
}
eolIndex = i;
nextIndex = i + 1;
return;

/* Manually decode:
* NEL is C2 85
*/
case 0xC2:
if (i + 1 < text.length && text[i + 1] == 0x85)
{
eolIndex = i;
nextIndex = i + 2;
return;
}
break;

/* Manually decode:
* lineSep is E2 80 A8
* paraSep is E2 80 A9
*/
case 0xE2:
if (i + 2 < text.length &&
text[i + 1] == 0x80 &&
(text[i + 2] == 0xA8 || text[i + 2] == 0xA9)
)
{
eolIndex = i;
nextIndex = i + 3;
return;
}
break;

default:
break;
}
}
}
}

return Range(text);
}

/**
* Adds the contents of a file to the table.
* Params:
Expand Down
99 changes: 99 additions & 0 deletions compiler/src/dmd/root/string.d
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,102 @@ unittest
assert(ptr.startsWith("123"));
assert(!ptr.startsWith("1234"));
}

/**********************************
* Take `text` and turn it into an InputRange that emits
* slices into `text` for each line.
* Params:
* text = array of characters
* Returns:
* InputRange accessing `text` as a sequence of lines
* Reference:
* `std.string.splitLines()`
*/
auto splitLines(const char[] text)
{
struct Range
{
@safe:
@nogc:
nothrow:
pure:
private:

const char[] text;
size_t index; // index of start of line
size_t eolIndex; // index of end of line before newline characters
size_t nextIndex; // index past end of line

public this(const char[] text)
{
this.text = text;
}

public bool empty() { return index == text.length; }

public void popFront() { advance(); index = nextIndex; }

public const(char)[] front() { advance(); return text[index .. eolIndex]; }

private void advance()
{
if (index != nextIndex) // if already advanced
return;

for (size_t i = index; i < text.length; ++i)
{
switch (text[i])
{
case '\v', '\f', '\n':
eolIndex = i;
nextIndex = i + 1;
return;

case '\r':
if (i + 1 < text.length && text[i + 1] == '\n') // decode "\r\n"
{
eolIndex = i;
nextIndex = i + 2;
return;
}
eolIndex = i;
nextIndex = i + 1;
return;

/* Manually decode:
* NEL is C2 85
*/
case 0xC2:
if (i + 1 < text.length && text[i + 1] == 0x85)
{
eolIndex = i;
nextIndex = i + 2;
return;
}
break;

/* Manually decode:
* lineSep is E2 80 A8
* paraSep is E2 80 A9
*/
case 0xE2:
if (i + 2 < text.length &&
text[i + 1] == 0x80 &&
(text[i + 2] == 0xA8 || text[i + 2] == 0xA9)
)
{
eolIndex = i;
nextIndex = i + 3;
return;
}
break;

default:
break;
}
}
}
}

return Range(text);
}

0 comments on commit 62e9d70

Please sign in to comment.