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 struct Mark
{ {
package: package:
/// File name.
string name_;
/// Line number. /// Line number.
ushort line_; ushort line_;
/// Column number. /// Column number.
@ -36,14 +38,21 @@ struct Mark
public: public:
/// Construct a Mark with specified line and column in the file. /// 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); line_ = cast(ushort)min(ushort.max, line);
// This *will* overflow on extremely wide files but saves CPU time // This *will* overflow on extremely wide files but saves CPU time
// (mark ctor takes ~5% of time) // (mark ctor takes ~5% of time)
column_ = cast(ushort)column; column_ = cast(ushort)column;
} }
/// Get a file name.
@property string name() @safe pure nothrow @nogc const
{
return name_;
}
/// Get a line number. /// Get a line number.
@property ushort line() @safe pure nothrow @nogc const @property ushort line() @safe pure nothrow @nogc const
{ {
@ -64,7 +73,7 @@ struct Mark
{ {
return text(v + 1, v == ushort.max ? " or higher" : ""); 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 try
{ {
auto loader = Loader(std.file.read(filename)); auto loader = Loader(std.file.read(filename), filename);
loader.name_ = filename;
return loader; return loader;
} }
catch(FileException e) catch(FileException e)
@ -77,8 +76,7 @@ struct Loader
/// ditto /// ditto
static Loader fromFile(File file) @system static Loader fromFile(File file) @system
{ {
auto loader = Loader(file.byChunk(4096).join); auto loader = Loader(file.byChunk(4096).join, file.name);
loader.name_ = file.name;
return loader; return loader;
} }
@ -140,17 +138,18 @@ struct Loader
return Loader(yamlData); return Loader(yamlData);
} }
/// Ditto /// Ditto
private this(void[] yamlData) @system private this(void[] yamlData, string name = "<unknown>") @system
{ {
this(cast(ubyte[])yamlData); this(cast(ubyte[])yamlData, name);
} }
/// Ditto /// Ditto
private this(ubyte[] yamlData) @safe private this(ubyte[] yamlData, string name = "<unknown>") @safe
{ {
resolver_ = Resolver.withDefaultResolvers; resolver_ = Resolver.withDefaultResolvers;
name_ = name;
try try
{ {
auto reader_ = new Reader(yamlData); auto reader_ = new Reader(yamlData, name);
scanner_ = Scanner(reader_); scanner_ = Scanner(reader_);
parser_ = new Parser(scanner_); parser_ = new Parser(scanner_);
} }

View file

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

View file

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