Add Mark.name (#264)

Add `Mark.name`
merged-on-behalf-of: Cameron Ross <elpenguino@gmail.com>
This commit is contained in:
Tomoya Tanjo 2020-12-16 12:37:23 +09:00 committed by GitHub
parent 88eaf879ec
commit ecbd63edaf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 15 deletions

View file

@ -29,6 +29,8 @@ class YAMLException : Exception
struct Mark
{
package:
/// File name.
string name_;
/// Line number.
ushort line_;
/// Column number.
@ -36,14 +38,21 @@ struct Mark
public:
/// Construct a Mark with specified line and column in the file.
this(const uint line, const uint column) @safe pure nothrow @nogc
this(string name, const uint line, const uint column) @safe pure nothrow @nogc
{
name_ = name;
line_ = cast(ushort)min(ushort.max, line);
// This *will* overflow on extremely wide files but saves CPU time
// (mark ctor takes ~5% of time)
column_ = cast(ushort)column;
}
/// Get a file name.
@property string name() @safe pure nothrow @nogc const
{
return name_;
}
/// Get a line number.
@property ushort line() @safe pure nothrow @nogc const
{
@ -64,7 +73,7 @@ struct Mark
{
return text(v + 1, v == ushort.max ? " or higher" : "");
}
return "line " ~ clamped(line_) ~ ",column " ~ clamped(column_);
return "file " ~ name_ ~ ",line " ~ clamped(line_) ~ ",column " ~ clamped(column_);
}
}

View file

@ -64,8 +64,7 @@ struct Loader
{
try
{
auto loader = Loader(std.file.read(filename));
loader.name_ = filename;
auto loader = Loader(std.file.read(filename), filename);
return loader;
}
catch(FileException e)
@ -77,8 +76,7 @@ struct Loader
/// ditto
static Loader fromFile(File file) @system
{
auto loader = Loader(file.byChunk(4096).join);
loader.name_ = file.name;
auto loader = Loader(file.byChunk(4096).join, file.name);
return loader;
}
@ -140,17 +138,18 @@ struct Loader
return Loader(yamlData);
}
/// Ditto
private this(void[] yamlData) @system
private this(void[] yamlData, string name = "<unknown>") @system
{
this(cast(ubyte[])yamlData);
this(cast(ubyte[])yamlData, name);
}
/// Ditto
private this(ubyte[] yamlData) @safe
private this(ubyte[] yamlData, string name = "<unknown>") @safe
{
resolver_ = Resolver.withDefaultResolvers;
name_ = name;
try
{
auto reader_ = new Reader(yamlData);
auto reader_ = new Reader(yamlData, name);
scanner_ = Scanner(reader_);
parser_ = new Parser(scanner_);
}

View file

@ -57,6 +57,8 @@ final class Reader
// Number of characters (code points) in buffer_.
size_t characterCount_;
// File name
string name_;
// Current line in file.
uint line_;
// Current column in file.
@ -89,11 +91,14 @@ final class Reader
/// contents of a file or a string. $(B will) be modified by
/// the Reader and other parts of D:YAML (D:YAML tries to
/// reuse the buffer to minimize memory allocations)
/// name = File name if the buffer is the contents of a file or
/// `"<unknown>"` if the buffer is the contents of a string.
///
/// Throws: ReaderException on a UTF decoding error or if there are
/// nonprintable Unicode characters illegal in YAML.
this(ubyte[] buffer) @safe pure
this(ubyte[] buffer, string name = "<unknown>") @safe pure
{
name_ = name;
auto endianResult = fixUTFByteOrder(buffer);
if(endianResult.bytesStripped > 0)
{
@ -395,7 +400,10 @@ final class Reader
SliceBuilder sliceBuilder;
/// Get a string describing current buffer position, used for error messages.
Mark mark() const pure nothrow @nogc @safe { return Mark(line_, column_); }
Mark mark() const pure nothrow @nogc @safe { return Mark(name_, line_, column_); }
/// Get file name.
string name() const @safe pure nothrow @nogc { return name_; }
/// Get current line number.
uint line() const @safe pure nothrow @nogc { return line_; }

View file

@ -280,7 +280,7 @@ struct Scanner
{
enforce(!key.required,
new ScannerException("While scanning a simple key",
Mark(key.line, key.column),
Mark(reader_.name, key.line, key.column),
"could not find expected ':'", reader_.mark));
key.isNull = true;
}
@ -328,7 +328,7 @@ struct Scanner
const key = possibleSimpleKeys_[flowLevel_];
enforce(!key.required,
new ScannerException("While scanning a simple key",
Mark(key.line, key.column),
Mark(reader_.name, key.line, key.column),
"could not find expected ':'", reader_.mark));
possibleSimpleKeys_[flowLevel_].isNull = true;
}
@ -540,7 +540,7 @@ struct Scanner
{
const key = possibleSimpleKeys_[flowLevel_];
possibleSimpleKeys_[flowLevel_].isNull = true;
Mark keyMark = Mark(key.line, key.column);
Mark keyMark = Mark(reader_.name, key.line, key.column);
const idx = key.tokenIndex - tokensTaken_;
assert(idx >= 0);