Cleaned up exceptions and their messages.

Some minor dog fixes.
This commit is contained in:
Ferdinand Majerech 2011-10-18 16:12:22 +02:00
parent 009017eef0
commit 8ad650e089
24 changed files with 284 additions and 298 deletions

Binary file not shown.

View file

@ -105,6 +105,11 @@
</dt>
<dd><p>Construct a Dumper writing to a stream. This is useful to e.g. write to memory.</p>
</dd>
<dt class="d_decl">@property void <a name="name"></a><span class="ddoc_psymbol">name</span>(string <a name="name"></a><span class="ddoc_psymbol">name</span>);
</dt>
<dd><p>Set stream name. Used in debugging messages.</p>
</dd>
<dt class="d_decl">void <a name="resolver"></a><span class="ddoc_psymbol">resolver</span>(Resolver <a name="resolver"></a><span class="ddoc_psymbol">resolver</span>);
</dt>

View file

@ -47,7 +47,7 @@
<dl><dt class="d_decl">this(string <b>msg</b>, string <b>file</b> = __FILE__, int <b>line</b> = __LINE__);
</dt>
<dd><p>Construct a YAMLException with specified message, and position where it was thrown.</p>
<dd><p>Construct a YAMLException with specified message and position where it was thrown.</p>
</dd>
</dl>

View file

@ -104,7 +104,7 @@
<b>Parameters:</b><div class="pbr"><table class=parms><tr><td valign=top>string <b>filename</b></td>
<td valign=top>Name of the file to load from.</td></tr>
</table></div>
<b>Throws:</b><div class="pbr">YAMLException if the file could not be opened or read from.</div>
<b>Throws:</b><div class="pbr">YAMLException if the file could not be opened or read.</div>
</dd>
<dt class="d_decl">this(Stream <b>stream</b>);
@ -114,7 +114,7 @@
<b>Parameters:</b><div class="pbr"><table class=parms><tr><td valign=top>Stream <b>stream</b></td>
<td valign=top>Stream to read from. Must be readable.</td></tr>
</table></div>
<b>Throws:</b><div class="pbr">YAMLException if <b>stream</b> could not be read from.</div>
<b>Throws:</b><div class="pbr">YAMLException if <b>stream</b> could not be read.</div>
</dd>
<dt class="d_decl">@property void <a name="name"></a><span class="ddoc_psymbol">name</span>(string <a name="name"></a><span class="ddoc_psymbol">name</span>);
@ -136,7 +136,7 @@
</dt>
<dd><p>Load single YAML document.
</p>
<p>If none or more than one YAML document is found, this will throw a YAMLException.
<p>If none or more than one YAML document is found, this throws a YAMLException.
</p>
<b>Returns:</b><div class="pbr">Root node of the document.
@ -153,7 +153,7 @@
<b>Returns:</b><div class="pbr">Array of root nodes of all documents in the file/stream.
</div>
<b>Throws:</b><div class="pbr">YAMLException on a YAML parsing error.</div>
<b>Throws:</b><div class="pbr">YAMLException on a parsing error.</div>
</dd>
<dt class="d_decl">int <a name="opApply"></a><span class="ddoc_psymbol">opApply</span>(int delegate(ref Node) <b>dg</b>);

View file

@ -69,13 +69,13 @@
</dt>
<dd><p>Add a function to represent nodes with a specific data type.
</p>
<p>The representer function takes a reference to a Node storing the data
<p>The representer function takes references to a Node storing the data
type and to the Representer. It returns the represented node and may
throw a RepresenterException. See the example for more information.
<br>
Only one function may be specified for one data type. Default data
types already have representer functions unless disabled in these
types already have representer functions unless disabled in the
Representer constructor.
</p>

View file

@ -138,7 +138,7 @@ struct appears in Phobos.</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Oct 17, 2011.
Last updated on Oct 18, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -104,7 +104,7 @@
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Oct 17, 2011.
Last updated on Oct 18, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -87,7 +87,7 @@
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Oct 17, 2011.
Last updated on Oct 18, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -369,7 +369,7 @@ directory of the D:YAML package.</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Oct 17, 2011.
Last updated on Oct 18, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -237,7 +237,7 @@ example in the <tt class="docutils literal"><span class="pre">example/getting_st
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Oct 17, 2011.
Last updated on Oct 18, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -330,7 +330,7 @@ Some of these might change in the future (especially !!map and !!set).</p>
</div>
<div class="footer">
&copy; Copyright 2011, Ferdinand Majerech. Based on PyYAML http://www.pyyaml.org by Kirill Simonov.
Last updated on Oct 17, 2011.
Last updated on Oct 18, 2011.
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.0.7.
</div>
</body>

View file

@ -26,7 +26,7 @@ import dyaml.resolver;
package:
/**
* Marked exception thrown at composer errors.
* Exception thrown at composer errors.
*
* See_Also: MarkedYAMLException
*/
@ -113,7 +113,7 @@ final class Composer
//Ensure that the stream contains no more documents.
enforce(parser_.checkEvent(EventID.StreamEnd),
new ComposerException("Expected single document in the stream, "
"but found another document: ",
"but found another document.",
parser_.getEvent().startMark));
//Drop the STREAM-END event.
@ -246,6 +246,18 @@ final class Composer
{
Node.Pair[] result;
void error(Node node)
{
//this is Composer, but the code is related to Constructor.
throw new ConstructorException("While constructing a mapping, "
"expected a mapping or a list of "
"mappings for merging, but found: "
~ node.type.toString ~
" NOTE: line/column shows topmost parent "
"to which the content is being merged",
startMark, endMark);
}
if(root.isMapping)
{
Node[] toMerge;
@ -259,32 +271,15 @@ final class Composer
merge(result, flatten(node, startMark, endMark));
}
}
else if(root.isSequence)
{
//Must be a sequence of mappings.
foreach(ref Node node; root)
else if(root.isSequence) foreach(ref Node node; root)
{
//this is Composer, but the code is related to constructor
enforce(node.isType!(Node.Pair[]),
new ConstructorException("While constructing a mapping, " ~
"expected a mapping for merging, but found"
~ node.type.toString ~
"NOTE: line/column shows topmost parent "
"to which the content is being merged",
startMark, endMark));
if(!node.isType!(Node.Pair[])){error(node);}
merge(result, flatten(node, startMark, endMark));
}
}
else
{
//this is Composer, but the code is related to constructor
throw new ConstructorException("While constructing a mapping, " ~
"expected a mapping or a list of mappings for "
"merging, but found: "
~ root.type.toString ~
"NOTE: line/column shows topmost parent "
"to which the content is being merged",
startMark, endMark);
error(root);
}
return result;

View file

@ -45,11 +45,13 @@ class ConstructorException : YAMLException
*/
this(string msg, Mark start, Mark end, string file = __FILE__, int line = __LINE__)
{
super(msg ~ "\nstart:" ~ start.toString() ~ "\nend:" ~ end.toString(),
super(msg ~ "\nstart: " ~ start.toString() ~ "\nend: " ~ end.toString(),
file, line);
}
}
private alias ConstructorException Error;
/**
* Constructs YAML values.
*
@ -177,8 +179,7 @@ final class Constructor
if(is(T : string) || is(T == Node[]) || is(T == Node.Pair[]))
{
enforce((tag in *delegates!T) !is null,
new ConstructorException("Could not determine a constructor for tag "
~ tag.get(), start, end));
new Error("No constructor function for tag " ~ tag.get(), start, end));
Node node = Node(value);
return Node.rawNode((*delegates!T)[tag](start, end, node), start, tag);
}
@ -234,7 +235,7 @@ bool constructBool(Mark start, Mark end, ref Node node)
string value = node.get!string().toLower();
if(["yes", "true", "on"].canFind(value)) {return true;}
if(["no", "false", "off"].canFind(value)){return false;}
throw new ConstructorException("Unable to parse boolean value: " ~ value, start, end);
throw new Error("Unable to parse boolean value: " ~ value, start, end);
}
///Construct an integer (long) node.
@ -248,8 +249,7 @@ long constructLong(Mark start, Mark end, ref Node node)
value = value[1 .. $];
}
enforce(value != "", new ConstructorException("Unable to parse float value: " ~ value,
start, end));
enforce(value != "", new Error("Unable to parse float value: " ~ value, start, end));
long result;
try
@ -279,7 +279,7 @@ long constructLong(Mark start, Mark end, ref Node node)
}
catch(ConvException e)
{
throw new ConstructorException("Unable to parse integer value: " ~ value, start, end);
throw new Error("Unable to parse integer value: " ~ value, start, end);
}
return result;
@ -318,7 +318,7 @@ real constructReal(Mark start, Mark end, ref Node node)
}
enforce(value != "" && value != "nan" && value != "inf" && value != "-inf",
new ConstructorException("Unable to parse float value: " ~ value, start, end));
new Error("Unable to parse float value: " ~ value, start, end));
real result;
try
@ -344,7 +344,7 @@ real constructReal(Mark start, Mark end, ref Node node)
}
catch(ConvException e)
{
throw new ConstructorException("Unable to parse float value: " ~ value, start, end);
throw new Error("Unable to parse float value: " ~ value, start, end);
}
return result;
@ -386,13 +386,13 @@ ubyte[] constructBinary(Mark start, Mark end, ref Node node)
try{return Base64.decode(value.removechars("\n"));}
catch(Exception e)
{
throw new ConstructorException("Unable to decode base64 value: " ~ e.msg, start,
end);
throw new Error("Unable to decode base64 value: " ~ e.msg,
start, end);
}
}
catch(UtfException e)
{
throw new ConstructorException("Unable to decode base64 value: " ~ e.msg, start, end);
throw new Error("Unable to decode base64 value: " ~ e.msg, start, end);
}
}
unittest
@ -419,8 +419,8 @@ SysTime constructTimestamp(Mark start, Mark end, ref Node node)
//First, get year, month and day.
auto matches = match(value, YMDRegexp);
enforce(!matches.empty, new ConstructorException("Unable to parse timestamp value: "
~ value, start, end));
enforce(!matches.empty,
new Error("Unable to parse timestamp value: " ~ value, start, end));
auto captures = matches.front.captures;
const year = to!int(captures[1]);
@ -467,13 +467,11 @@ SysTime constructTimestamp(Mark start, Mark end, ref Node node)
}
catch(ConvException e)
{
throw new ConstructorException("Unable to parse timestamp value: " ~ value ~
" Reason: " ~ e.msg, start, end);
throw new Error("Unable to parse timestamp value " ~ value ~ " : " ~ e.msg, start, end);
}
catch(DateTimeException e)
{
throw new ConstructorException("Invalid timestamp value: " ~ value ~
" Reason: " ~ e.msg, start, end);
throw new Error("Invalid timestamp value " ~ value ~ " : " ~ e.msg, start, end);
}
assert(false, "This code should never be reached");
@ -520,9 +518,8 @@ Node.Pair[] getPairs(string type, Mark start, Mark end, Node[] nodes)
foreach(ref node; nodes)
{
enforce(node.isMapping && node.length == 1,
new ConstructorException("While constructing " ~ type ~
", expected a mapping with single element,", start,
end));
new Error("While constructing " ~ type ~
", expected a mapping with single element", start, end));
pairs ~= node.get!(Node.Pair[]);
}
@ -542,8 +539,7 @@ Node.Pair[] constructOrderedMap(Mark start, Mark end, ref Node node)
foreach(ref pair; pairs)
{
enforce((pair.key in map) is null,
new ConstructorException("Found a duplicate entry in an ordered map",
start, end));
new Error("Duplicate entry in an ordered map", start, end));
map[pair.key] = true;
}
clear(map);
@ -611,7 +607,7 @@ Node[] constructSet(Mark start, Mark end, ref Node node)
foreach(ref pair; pairs)
{
enforce((pair.key in map) is null,
new ConstructorException("Found a duplicate entry in a set", start, end));
new Error("Duplicate entry in a set", start, end));
map[pair.key] = 0;
nodes ~= pair.key;
}
@ -679,7 +675,7 @@ Node.Pair[] constructMap(Mark start, Mark end, ref Node node)
foreach(ref pair; pairs)
{
enforce((pair.key in map) is null,
new ConstructorException("Found a duplicate entry in a map", start, end));
new Error("Duplicate entry in a map", start, end));
map[pair.key] = true;
}
return pairs;

View file

@ -140,6 +140,9 @@ struct Dumper
///Always write document end?
bool explicitEnd_ = false;
///Name of the output file or stream, used in error messages.
string name_ = "<unknown>";
public:
@disable this();
@ -152,10 +155,12 @@ struct Dumper
*/
this(string filename)
{
name_ = filename;
try{this(new File(filename, FileMode.OutNew));}
catch(StreamException e)
{
throw new YAMLException("Unable to use file for YAML dumping " ~ filename ~ " : " ~ e.msg);
throw new YAMLException("Unable to open file " ~ filename ~
" for YAML dumping: " ~ e.msg);
}
}
@ -177,6 +182,12 @@ struct Dumper
YAMLVersion_ = null;
}
///Set stream _name. Used in debugging messages.
@property void name(string name)
{
name_ = name;
}
///Specify custom Resolver to use.
void resolver(Resolver resolver)
{
@ -312,7 +323,8 @@ struct Dumper
}
catch(YAMLException e)
{
throw new YAMLException("Unable to dump YAML: " ~ e.msg);
throw new YAMLException("Unable to dump YAML to stream "
~ name_ ~ " : " ~ e.msg);
}
}
@ -336,7 +348,8 @@ struct Dumper
}
catch(YAMLException e)
{
throw new YAMLException("Unable to emit YAML: " ~ e.msg);
throw new YAMLException("Unable to emit YAML to stream "
~ name_ ~ " : " ~ e.msg);
}
}
}

View file

@ -47,6 +47,8 @@ class EmitterException : YAMLException
mixin ExceptionCtors;
}
private alias EmitterException Error;
//Stores results of analysis of a scalar, determining e.g. what scalar style to use.
align(4) struct ScalarAnalysis
{
@ -230,7 +232,7 @@ struct Emitter
}
catch(WriteException e)
{
throw new EmitterException("Unable to write to stream");
throw new Error("Unable to write to stream: " ~ e.msg);
}
}
@ -293,7 +295,7 @@ struct Emitter
bool eventTypeIs(in EventID id) const
{
enforce(!event_.isNull,
new EmitterException("Expected an event, but no event is available."));
new Error("Expected an event, but no event is available."));
return event_.id == id;
}
@ -307,8 +309,7 @@ struct Emitter
void expectStreamStart()
{
enforce(eventTypeIs(EventID.StreamStart),
new EmitterException("Expected StreamStart, but got "
~ to!string(event_.id)));
new Error("Expected StreamStart, but got " ~ event_.idString));
encoding_ = event_.encoding;
writeStreamStart();
@ -318,7 +319,7 @@ struct Emitter
///Expect nothing, throwing if we still have something.
void expectNothing()
{
throw new EmitterException("Expected nothing, but got " ~ to!string(event_.id));
throw new Error("Expected nothing, but got " ~ event_.idString);
}
//Document handlers.
@ -327,8 +328,8 @@ struct Emitter
void expectDocumentStart(bool first)()
{
enforce(eventTypeIs(EventID.DocumentStart) || eventTypeIs(EventID.StreamEnd),
new EmitterException("Expected DocumentStart or StreamEnd, but got "
~ to!string(event_.id)));
new Error("Expected DocumentStart or StreamEnd, but got "
~ event_.idString));
if(event_.id == EventID.DocumentStart)
{
@ -386,8 +387,7 @@ struct Emitter
void expectDocumentEnd()
{
enforce(eventTypeIs(EventID.DocumentEnd),
new EmitterException("Expected DocumentEnd, but got "
~ to!string(event_.id)));
new Error("Expected DocumentEnd, but got " ~ event_.idString));
writeIndent();
if(event_.explicitDocument)
@ -450,17 +450,15 @@ struct Emitter
}
break;
default:
throw new EmitterException("Expected Alias, Scalar, SequenceStart "
"or MappingStart, but got: "
~ to!string(event_.id));
throw new Error("Expected Alias, Scalar, SequenceStart or "
"MappingStart, but got: " ~ event_.idString);
}
}
///Handle an alias.
void expectAlias()
{
enforce(!event_.anchor.isNull(),
new EmitterException("Anchor is not specified for alias"));
enforce(!event_.anchor.isNull(), new Error("Anchor is not specified for alias"));
processAnchor("*");
state_ = popState();
}
@ -785,7 +783,7 @@ struct Emitter
return;
}
enforce(!tag.isNull(), new EmitterException("Tag is not specified"));
enforce(!tag.isNull(), new Error("Tag is not specified"));
if(preparedTag_ is null){preparedTag_ = prepareTag(tag);}
if(preparedTag_ !is null && preparedTag_ != "")
{
@ -841,7 +839,7 @@ struct Emitter
static string prepareVersion(in string YAMLVersion)
{
enforce(YAMLVersion.split(".")[0] == "1",
new EmitterException("Unsupported YAML version: " ~ YAMLVersion));
new Error("Unsupported YAML version: " ~ YAMLVersion));
return YAMLVersion;
}
@ -861,12 +859,12 @@ struct Emitter
static string prepareTagHandle(in string handle)
{
enforce(handle !is null && handle != "",
new EmitterException("Tag handle must not be empty"));
new Error("Tag handle must not be empty"));
if(handle.length > 1) foreach(const dchar c; handle[1 .. $ - 1])
{
enforce(isAlphaNum(c) || "-_".canFind(c),
new EmitterException("Invalid character: " ~ to!string(c) ~
new Error("Invalid character: " ~ to!string(c) ~
" in tag handle " ~ handle));
}
return handle;
@ -876,7 +874,7 @@ struct Emitter
static string prepareTagPrefix(in string prefix)
{
enforce(prefix !is null && prefix != "",
new EmitterException("Tag prefix must not be empty"));
new Error("Tag prefix must not be empty"));
auto appender = appender!string();
const offset = prefix[0] == '!' ? 1 : 0;
@ -906,7 +904,7 @@ struct Emitter
///Prepare tag for output.
string prepareTag(in Tag tag)
{
enforce(!tag.isNull(), new EmitterException("Tag must not be empty"));
enforce(!tag.isNull(), new Error("Tag must not be empty"));
string tagString = tag.get;
if(tagString == "!"){return tagString;}
@ -954,13 +952,12 @@ struct Emitter
static string prepareAnchor(in Anchor anchor)
{
enforce(!anchor.isNull() && anchor.get != "",
new EmitterException("Anchor must not be empty"));
new Error("Anchor must not be empty"));
const str = anchor.get;
foreach(const dchar c; str)
{
enforce(isAlphaNum(c) || "-_".canFind(c),
new EmitterException("Invalid character: " ~ to!string(c) ~
" in anchor: " ~ str));
new Error("Invalid character: " ~ to!string(c) ~ " in anchor: " ~ str));
}
return str;
}
@ -1150,8 +1147,7 @@ struct Emitter
break;
}
enforce(stream_.write(bom) == bom.length,
new EmitterException("Unable to write to stream"));
enforce(stream_.write(bom) == bom.length, new Error("Unable to write to stream"));
}
///End the YAML stream.

View file

@ -83,6 +83,9 @@ struct Event
{
return id == EventID.Invalid;
}
///Get string representation of the token ID.
@property string idString() const {return to!string(id);}
}
/**

View file

@ -16,19 +16,11 @@ import std.string;
///Base class for all exceptions thrown by D:YAML.
class YAMLException : Exception
{
public:
///Construct a YAMLException with specified message, and position where it was thrown.
this(string msg, string file = __FILE__, int line = __LINE__)
///Construct a YAMLException with specified message and position where it was thrown.
public this(string msg, string file = __FILE__, int line = __LINE__)
{
super(msg, file, line);
}
package:
//Set name of the file that was being processed when this exception was thrown.
@property name(in string name)
{
msg = name ~ ":\n" ~ msg;
}
}
///Position in a YAML stream, used for error messages.
@ -65,9 +57,9 @@ abstract class MarkedYAMLException : YAMLException
this(string context, Mark contextMark, string problem, Mark problemMark,
string file = __FILE__, int line = __LINE__)
{
string msg = context ~ '\n';
if(contextMark != problemMark){msg ~= contextMark.toString() ~ '\n';}
msg ~= problem ~ '\n' ~ problemMark.toString() ~ '\n';
const msg = context ~ '\n' ~
(contextMark != problemMark ? contextMark.toString() ~ '\n' : "") ~
problem ~ '\n' ~ problemMark.toString() ~ '\n';
super(msg, file, line);
}
@ -81,8 +73,7 @@ abstract class MarkedYAMLException : YAMLException
//Constructors of YAML exceptions are mostly the same, so we use a mixin.
template ExceptionCtors()
{
public:
this(string msg, string file = __FILE__, int line = __LINE__)
public this(string msg, string file = __FILE__, int line = __LINE__)
{
super(msg, file, line);
}

View file

@ -104,23 +104,23 @@ struct Loader
string name_ = "<unknown>";
public:
@disable this();
/**
* Construct a Loader to load YAML from a file.
*
* Params: filename = Name of the file to load from.
*
* Throws: YAMLException if the file could not be opened or read from.
* Throws: YAMLException if the file could not be opened or read.
*/
this(in string filename)
{
try
{
name = filename;
this(new File(filename));
}
name_ = filename;
try{this(new File(filename));}
catch(StreamException e)
{
throw new YAMLException("Unable to load YAML file " ~ filename ~ " : " ~ e.msg);
throw new YAMLException("Unable to open file " ~ filename ~
" for YAML loading: " ~ e.msg);
}
}
@ -129,7 +129,7 @@ struct Loader
*
* Params: stream = Stream to read from. Must be readable.
*
* Throws: YAMLException if stream could not be read from.
* Throws: YAMLException if stream could not be read.
*/
this(Stream stream)
{
@ -145,8 +145,8 @@ struct Loader
}
catch(YAMLException e)
{
e.name = name_;
throw e;
throw new YAMLException("Unable to open stream " ~ name_ ~
" for YAML loading: " ~ e.msg);
}
}
@ -181,7 +181,7 @@ struct Loader
/**
* Load single YAML document.
*
* If none or more than one YAML document is found, this will throw a YAMLException.
* If none or more than one YAML document is found, this throws a YAMLException.
*
* Returns: Root node of the document.
*
@ -198,8 +198,8 @@ struct Loader
}
catch(YAMLException e)
{
e.name = name_;
throw e;
throw new YAMLException("Unable to load YAML from stream " ~
name_ ~ " : " ~ e.msg);
}
}
@ -208,15 +208,12 @@ struct Loader
*
* Returns: Array of root nodes of all documents in the file/stream.
*
* Throws: YAMLException on a YAML parsing error.
* Throws: YAMLException on a parsing error.
*/
Node[] loadAll()
{
Node[] nodes;
foreach(ref node; this)
{
nodes ~= node;
}
foreach(ref node; this){nodes ~= node;}
return nodes;
}
@ -245,8 +242,8 @@ struct Loader
}
catch(YAMLException e)
{
e.name = name_;
throw e;
throw new YAMLException("Unable to load YAML from stream " ~
name_ ~ " : " ~ e.msg);
}
}
@ -262,8 +259,8 @@ struct Loader
}
catch(YAMLException e)
{
e.name = name_;
throw e;
throw new YAMLException("Unable to scan YAML from stream " ~
name_ ~ " : " ~ e.msg);
}
}
@ -278,8 +275,8 @@ struct Loader
}
catch(YAMLException e)
{
e.name = name_;
throw e;
throw new YAMLException("Unable to parse YAML from stream " ~
name_ ~ " : " ~ e.msg);
}
}
}

View file

@ -39,10 +39,12 @@ class NodeException : YAMLException
*/
this(string msg, Mark start, string file = __FILE__, int line = __LINE__)
{
super(msg ~ "\nNode at:" ~ start.toString(), file, line);
super(msg ~ "\nNode at: " ~ start.toString(), file, line);
}
}
private alias NodeException Error;
//Node kinds.
package enum NodeID : ubyte
{
@ -532,8 +534,8 @@ struct Node
void throwUnexpectedType()
{
//Can't get the value.
throw new NodeException("Node has unexpected type " ~ type.toString ~
". Expected " ~ typeid(T).toString, startMark_);
throw new Error("Node has unexpected type: " ~ type.toString ~
". Expected: " ~ typeid(T).toString, startMark_);
}
static if(isSomeString!T)
@ -546,8 +548,7 @@ struct Node
}
catch(VariantException e)
{
throw new NodeException("Unable to convert node value to a string",
startMark_);
throw new Error("Unable to convert node value to string", startMark_);
}
}
else static if(isFloatingPoint!T)
@ -571,9 +572,9 @@ struct Node
long temp = value_.get!long;
if(temp < T.min || temp > T.max)
{
throw new NodeException("Integer value out of range of type " ~
typeid(T).toString ~ "Value: " ~
to!string(temp), startMark_);
throw new Error("Integer value out of range of type " ~
typeid(T).toString ~ "Value: " ~ to!string(temp),
startMark_);
}
target = to!T(temp);
return;
@ -602,8 +603,7 @@ struct Node
{
if(isSequence) {return get!(Node[]).length;}
else if(isMapping){return get!(Pair[]).length;}
throw new NodeException("Trying to get length of a node that is not a collection",
startMark_);
throw new Error("Trying to get length of a scalar node", startMark_);
}
/**
@ -637,12 +637,10 @@ struct Node
auto idx = findPair(index);
if(idx >= 0){return get!(Pair[])[idx].value;}
throw new NodeException("Mapping index not found" ~
isSomeString!T ? ": " ~ to!string(index) : "",
startMark_);
throw new Error("Mapping index not found" ~
isSomeString!T ? ": " ~ to!string(index) : "", startMark_);
}
throw new NodeException("Trying to index node that does not support indexing",
startMark_);
throw new Error("Trying to index node that does not support indexing", startMark_);
}
unittest
{
@ -723,8 +721,7 @@ struct Node
return;
}
throw new NodeException("Trying to index a YAML node that is not a collection.",
startMark_);
throw new Error("Trying to index a scalar node.", startMark_);
}
unittest
{
@ -758,7 +755,7 @@ struct Node
int opApply(T)(int delegate(ref T) dg)
{
enforce(isSequence,
new NodeException("Trying to iterate over a node that is not a sequence",
new Error("Trying to iterate over a node that is not a sequence",
startMark_));
int result = 0;
@ -815,7 +812,7 @@ struct Node
int opApply(K, V)(int delegate(ref K, ref V) dg)
{
enforce(isMapping,
new NodeException("Trying to iterate over a node that is not a mapping",
new Error("Trying to iterate over a node that is not a mapping",
startMark_));
int result = 0;
@ -915,8 +912,7 @@ struct Node
void add(T)(T value)
{
enforce(isSequence(),
new NodeException("Trying to add an element to a "
"non-sequence YAML node", startMark_));
new Error("Trying to add an element to a non-sequence node", startMark_));
auto nodes = get!(Node[])();
static if(is(T == Node)){nodes ~= value;}
@ -953,8 +949,8 @@ struct Node
void add(K, V)(K key, V value)
{
enforce(isMapping(),
new NodeException("Trying to add a key-value pair to a "
"non-mapping YAML node", startMark_));
new Error("Trying to add a key-value pair to a non-mapping node",
startMark_));
auto pairs = get!(Node.Pair[])();
pairs ~= Pair(key, value);
@ -1010,8 +1006,7 @@ struct Node
}
return;
}
throw new NodeException("Trying to remove an element from a YAML node that "
"is not a collection.", startMark_);
throw new Error("Trying to remove an element from a scalar node", startMark_);
}
unittest
{
@ -1077,8 +1072,7 @@ struct Node
}
return;
}
throw new NodeException("Trying to remove an element from a YAML node that "
"is not a collection.", startMark_);
throw new Error("Trying to remove an element from a scalar node", startMark_);
}
unittest
{
@ -1334,14 +1328,13 @@ struct Node
{
static if(!isIntegral!T)
{
throw new NodeException("Indexing a YAML sequence with a non-integral type.",
startMark_);
throw new Error("Indexing a sequence with a non-integral type.", startMark_);
}
else
{
enforce(index >= 0 && index < value_.get!(Node[]).length,
new NodeException("Index to a YAML sequence out of range: "
~ to!string(index), startMark_));
new Error("Sequence index out of range: " ~ to!string(index),
startMark_));
}
}
}

View file

@ -99,6 +99,8 @@ class ParserException : MarkedYAMLException
mixin MarkedExceptionCtors;
}
private alias ParserException Error;
///Generates events from tokens provided by a Scanner.
final class Parser
{
@ -225,7 +227,7 @@ final class Parser
Event delegate() popState()
{
enforce(states_.length > 0,
new YAMLException("Parser: Need to pop a state but there are no states left"));
new YAMLException("Parser: Need to pop state but no states left to pop"));
const result = states_.back();
states_.popBack;
return result;
@ -235,7 +237,7 @@ final class Parser
Mark popMark()
{
enforce(marks_.length > 0,
new YAMLException("Parser: Need to pop a mark but there are no marks left"));
new YAMLException("Parser: Need to pop mark but no marks left to pop"));
const result = marks_.back();
marks_.popBack;
return result;
@ -286,8 +288,8 @@ final class Parser
auto tagDirectives = processDirectives();
enforce(scanner_.checkToken(TokenID.DocumentStart),
new ParserException("Expected document start but found " ~
to!string(scanner_.peekToken().id),
new Error("Expected document start but found " ~
scanner_.peekToken().idString,
scanner_.peekToken().startMark));
const endMark = scanner_.getToken().endMark;
@ -347,12 +349,11 @@ final class Parser
if(name == "YAML")
{
enforce(YAMLVersion_ is null,
new ParserException("Found duplicate YAML directive",
token.startMark));
new Error("Duplicate YAML directive", token.startMark));
const minor = parts[1].split(".")[0];
enforce(to!int(minor) == 1,
new ParserException("Found incompatible YAML document (version "
"1.* is required)", token.startMark));
new Error("Incompatible document (version 1.x is required)",
token.startMark));
YAMLVersion_ = parts[1];
}
else if(name == "TAG")
@ -365,8 +366,8 @@ final class Parser
//handle
auto h = pair[0];
auto replacement = pair[1];
enforce(h != handle, new ParserException("Duplicate tag handle: " ~
handle, token.startMark));
enforce(h != handle, new Error("Duplicate tag handle: " ~ handle,
token.startMark));
}
tagHandles_ ~= tuple(handle, parts[2]);
}
@ -515,9 +516,9 @@ final class Parser
}
Token token = scanner_.peekToken();
throw new ParserException("While parsing a " ~ (block ? "block" : "flow") ~ " node",
throw new Error("While parsing a " ~ (block ? "block" : "flow") ~ " node",
startMark, "expected the node content, but found: "
~ to!string(token.id), token.startMark);
~ token.idString, token.startMark);
}
/**
@ -549,7 +550,7 @@ final class Parser
}
//handle must be in tagHandles_
enforce(replacement !is null,
new ParserException("While parsing a node", startMark,
new Error("While parsing a node", startMark,
"found undefined tag handle: " ~ handle, tagMark));
return replacement ~ suffix;
}
@ -584,9 +585,9 @@ final class Parser
if(!scanner_.checkToken(TokenID.BlockEnd))
{
Token token = scanner_.peekToken();
throw new ParserException("While parsing a block collection", marks_[$ - 1],
"expected block end, but found "
~ to!string(token.id), token.startMark);
throw new Error("While parsing a block collection", marks_[$ - 1],
"expected block end, but found " ~ token.idString,
token.startMark);
}
state_ = popState();
@ -649,9 +650,9 @@ final class Parser
if(!scanner_.checkToken(TokenID.BlockEnd))
{
Token token = scanner_.peekToken();
throw new ParserException("While parsing a block mapping", marks_[$ - 1],
"expected block end, but found: "
~ to!string(token.id), token.startMark);
throw new Error("While parsing a block mapping", marks_[$ - 1],
"expected block end, but found: " ~ token.idString,
token.startMark);
}
state_ = popState();
@ -710,10 +711,9 @@ final class Parser
else
{
Token token = scanner_.peekToken;
throw new ParserException("While parsing a flow sequence",
marks_[$ - 1],
throw new Error("While parsing a flow sequence", marks_[$ - 1],
"expected ',' or ']', but got: " ~
to!string(token.id), token.startMark);
token.idString, token.startMark);
}
}
@ -818,10 +818,9 @@ final class Parser
else
{
Token token = scanner_.peekToken;
throw new ParserException("While parsing a flow mapping",
marks_[$ - 1],
throw new Error("While parsing a flow mapping", marks_[$ - 1],
"expected ',' or '}', but got: " ~
to!string(token.id), token.startMark);
token.idString, token.startMark);
}
}

View file

@ -29,7 +29,7 @@ class ReaderException : YAMLException
{
this(string msg, string file = __FILE__, int line = __LINE__)
{
super("Error reading YAML stream: " ~ msg, file, line);
super("Error reading stream: " ~ msg, file, line);
}
}
@ -105,11 +105,11 @@ final class Reader
rawBuffer16_[0] = stream_.getcw();
rawUsed_ = 1;
enforce(stream_.available % 2 == 0,
new ReaderException("Odd number of bytes in an UTF-16 stream"));
new ReaderException("Odd byte count in an UTF-16 stream"));
break;
case 3, 4:
enforce(stream_.available % 4 == 0,
new ReaderException("Number of bytes in an UTF-32 stream not divisible by 4"));
new ReaderException("Byte count in an UTF-32 stream not divisible by 4"));
encoding_ = Encoding.UTF_32;
break;
default: assert(false, "Unknown UTF BOM");
@ -286,7 +286,7 @@ final class Reader
*
* Params: chars = Maximum number of characters to load.
*
* Throws: ReaderException on unicode decoding error,
* Throws: ReaderException on Unicode decoding error,
* if nonprintable characters are detected, or
* if there is an error reading from the stream.
*/
@ -382,13 +382,12 @@ final class Reader
catch(UtfException e)
{
const position = stream_.position;
throw new ReaderException("Unicode decoding error between bytes " ~
to!string(oldPosition) ~ " and " ~
to!string(position) ~ " " ~ e.msg);
throw new ReaderException(format("Unicode decoding error between bytes ",
oldPosition, " and ", position, " : ", e.msg));
}
catch(ReadException e)
{
throw new ReaderException("Error reading from the stream: " ~ e.msg);
throw new ReaderException(e.msg);
}
enforce(printable(buffer_[oldLength .. $]),

View file

@ -73,12 +73,12 @@ final class Representer
/**
* Add a function to represent nodes with a specific data type.
*
* The representer function takes a reference to a Node storing the data
* The representer function takes references to a Node storing the data
* type and to the Representer. It returns the represented node and may
* throw a RepresenterException. See the example for more information.
*
* Only one function may be specified for one data type. Default data
* types already have representer functions unless disabled in these
* types already have representer functions unless disabled in the
* Representer constructor.
*
* Params: representer = Representer function to add.
@ -297,8 +297,8 @@ final class Representer
auto type = data.isUserType ? data.get!YAMLObject.type : data.type;
enforce((type in representers_) !is null,
new RepresenterException("No YAML representer function for type "
~ type.toString() ~ " cannot represent."));
new RepresenterException("No representer function for type "
~ type.toString() ~ " , cannot represent."));
Node result = representers_[type](data, this);
if(!data.tag.isNull()){result.tag = data.tag;}
return result;
@ -426,8 +426,7 @@ Node representPairs(ref Node node, Representer representer)
if(node.tag == Tag("tag:yaml.org,2002:omap"))
{
enforce(!hasDuplicates(pairs),
new RepresenterException("Found a duplicate entry "
"in an ordered map"));
new RepresenterException("Duplicate entry in an ordered map"));
return representer.representSequence(node.tag.get, mapToSequence(pairs));
}
else if(node.tag == Tag("tag:yaml.org,2002:pairs"))
@ -437,8 +436,7 @@ Node representPairs(ref Node node, Representer representer)
else
{
enforce(!hasDuplicates(pairs),
new RepresenterException("Found a duplicate entry "
"in an unordered map"));
new RepresenterException("Duplicate entry in an unordered map"));
return representer.representMapping("tag:yaml.org,2002:map", pairs);
}
}

View file

@ -63,6 +63,8 @@ class ScannerException : MarkedYAMLException
mixin MarkedExceptionCtors;
}
private alias ScannerException Error;
///Generates tokens from data provided by a Reader.
final class Scanner
{
@ -269,9 +271,9 @@ final class Scanner
if(c == '\"') {return fetchDouble();}
if(checkPlain()) {return fetchPlain();}
throw new ScannerException(format("While scanning for the next token, found "
throw new Error(format("While scanning for the next token, found "
"character \'", c, "\', index ",to!int(c),
" that cannot start " "any token"), reader_.mark);
" that cannot start any token"), reader_.mark);
}
@ -303,7 +305,7 @@ final class Scanner
if(key.line != reader_.line || reader_.charIndex - key.charIndex > 1024)
{
enforce(!key.required,
new ScannerException("While scanning a simple key",
new Error("While scanning a simple key",
Mark(key.line, key.column),
"could not find expected ':'", reader_.mark));
levelsToRemove ~= level;
@ -341,10 +343,8 @@ final class Scanner
{
auto key = possibleSimpleKeys_[flowLevel_];
enforce(!key.required,
new ScannerException("While scanning a simple key",
Mark(key.line, key.column),
"could not find expected ':'",
reader_.mark));
new Error("While scanning a simple key", Mark(key.line, key.column),
"could not find expected ':'", reader_.mark));
possibleSimpleKeys_.remove(flowLevel_);
}
}
@ -369,7 +369,7 @@ final class Scanner
//restrictive than what the specification requires.
//if(pedantic_ && flowLevel_ > 0 && indent_ > column)
//{
// throw new ScannerException("Invalid intendation or unclosed '[' or '{'",
// throw new Error("Invalid intendation or unclosed '[' or '{'",
// reader_.mark)
//}
return;
@ -510,7 +510,7 @@ final class Scanner
void blockChecks(string type, TokenID id)()
{
//Are we allowed to start a key (not neccesarily a simple one)?
enforce(allowSimpleKey_, new ScannerException(type ~ " keys are not allowed here",
enforce(allowSimpleKey_, new Error(type ~ " keys are not allowed here",
reader_.mark));
if(addIndent(reader_.column))
@ -585,8 +585,7 @@ final class Scanner
{
//We can start a complex value if and only if we can start a simple key.
enforce(flowLevel_ > 0 || allowSimpleKey_,
new ScannerException("Mapping values are not allowed here",
reader_.mark));
new Error("Mapping values are not allowed here", reader_.mark));
//If this value starts a new block mapping, we need to add
//BLOCK-MAPPING-START. It'll be detected as an error later by the parser.
@ -777,9 +776,9 @@ final class Scanner
}
enforce(length > 0,
new ScannerException("While scanning " ~ name, startMark,
"expected alphanumeric, - or _, but found "
~ to!string(c), reader_.mark));
new Error("While scanning " ~ name, startMark,
"expected alphanumeric, - or _, but found " ~ to!string(c),
reader_.mark));
return reader_.get(length);
}
@ -856,7 +855,7 @@ final class Scanner
const name = scanAlphaNumeric!"a directive"(startMark);
enforce(" \0\n\r\u0085\u2028\u2029".canFind(reader_.peek()),
new ScannerException("While scanning a directive", startMark,
new Error("While scanning a directive", startMark,
"expected alphanumeric, - or _, but found "
~ to!string(reader_.peek()), reader_.mark));
return name;
@ -869,7 +868,7 @@ final class Scanner
dstring result = scanYAMLDirectiveNumber(startMark);
enforce(reader_.peek() == '.',
new ScannerException("While scanning a directive", startMark,
new Error("While scanning a directive", startMark,
"expected a digit or '.', but found: "
~ to!string(reader_.peek()), reader_.mark));
//Skip the '.'.
@ -877,7 +876,7 @@ final class Scanner
result ~= '.' ~ scanYAMLDirectiveNumber(startMark);
enforce(" \0\n\r\u0085\u2028\u2029".canFind(reader_.peek()),
new ScannerException("While scanning a directive", startMark,
new Error("While scanning a directive", startMark,
"expected a digit or '.', but found: "
~ to!string(reader_.peek()), reader_.mark));
return result;
@ -887,7 +886,7 @@ final class Scanner
dstring scanYAMLDirectiveNumber(in Mark startMark)
{
enforce(isDigit(reader_.peek()),
new ScannerException("While scanning a directive", startMark,
new Error("While scanning a directive", startMark,
"expected a digit, but found: " ~
to!string(reader_.peek()), reader_.mark));
@ -912,9 +911,9 @@ final class Scanner
{
const value = scanTagHandle("directive", startMark);
enforce(reader_.peek() == ' ',
new ScannerException("While scanning a directive handle", startMark,
"expected ' ', but found: " ~
to!string(reader_.peek()), reader_.mark));
new Error("While scanning a directive handle", startMark,
"expected ' ', but found: " ~ to!string(reader_.peek()),
reader_.mark));
return value;
}
@ -923,7 +922,7 @@ final class Scanner
{
const value = scanTagURI("directive", startMark);
enforce(" \0\n\r\u0085\u2028\u2029".canFind(reader_.peek()),
new ScannerException("While scanning a directive prefix", startMark,
new Error("While scanning a directive prefix", startMark,
"expected ' ', but found" ~ to!string(reader_.peek()),
reader_.mark));
@ -936,7 +935,7 @@ final class Scanner
findNextNonSpace();
if(reader_.peek() == '#'){scanToNextBreak();}
enforce("\0\n\r\u0085\u2028\u2029".canFind(reader_.peek()),
new ScannerException("While scanning a directive", startMark,
new Error("While scanning a directive", startMark,
"expected comment or a line break, but found"
~ to!string(reader_.peek()), reader_.mark));
scanLineBreak();
@ -966,7 +965,7 @@ final class Scanner
enforce((" \t\0\n\r\u0085\u2028\u2029".canFind(reader_.peek()) ||
("?:,]}%@").canFind(reader_.peek())),
new ScannerException("While scanning an " ~ (i == '*') ? "alias" : "anchor",
new Error("While scanning an " ~ (i == '*') ? "alias" : "anchor",
startMark, "expected alphanumeric, - or _, but found "~
to!string(reader_.peek()), reader_.mark));
@ -994,9 +993,9 @@ final class Scanner
reader_.forward(2);
suffix = scanTagURI("tag", startMark);
enforce(reader_.peek() == '>',
new ScannerException("While scanning a tag", startMark,
"expected '>' but found" ~
to!string(reader_.peek()), reader_.mark));
new Error("While scanning a tag", startMark,
"expected '>' but found" ~ to!string(reader_.peek()),
reader_.mark));
reader_.forward();
}
else if(" \t\0\n\r\u0085\u2028\u2029".canFind(c))
@ -1031,9 +1030,9 @@ final class Scanner
}
enforce(" \0\n\r\u0085\u2028\u2029".canFind(reader_.peek()),
new ScannerException("While scanning a tag", startMark,
"expected ' ' but found" ~
to!string(reader_.peek()), reader_.mark));
new Error("While scanning a tag", startMark,
"expected ' ' but found" ~ to!string(reader_.peek()),
reader_.mark));
return tagToken(startMark, reader_.mark, to!string(handle ~ '\0' ~ suffix));
}
@ -1141,9 +1140,9 @@ final class Scanner
if(!isDigit(c)){return false;}
increment = to!int(""d ~ c);
enforce(increment != 0,
new ScannerException("While scanning a block scalar", startMark,
"expected indentation indicator in range 1-9, "
"but found 0", reader_.mark));
new Error("While scanning a block scalar", startMark,
"expected indentation indicator in range 1-9, but found 0",
reader_.mark));
reader_.forward();
c = reader_.peek();
return true;
@ -1154,9 +1153,9 @@ final class Scanner
else if(getIncrement()){getChomping();}
enforce(" \0\n\r\u0085\u2028\u2029".canFind(c),
new ScannerException("While scanning a block scalar", startMark,
"expected chomping or indentation indicator, "
"but found " ~ to!string(c), reader_.mark));
new Error("While scanning a block scalar", startMark,
"expected chomping or indentation indicator, but found "
~ to!string(c), reader_.mark));
return tuple(chomping, increment);
}
@ -1168,7 +1167,7 @@ final class Scanner
if(reader_.peek == '#'){scanToNextBreak();}
enforce("\0\n\r\u0085\u2028\u2029".canFind(reader_.peek()),
new ScannerException("While scanning a block scalar", startMark,
new Error("While scanning a block scalar", startMark,
"expected a comment or a line break, but found "
~ to!string(reader_.peek()), reader_.mark));
scanLineBreak();
@ -1300,7 +1299,7 @@ final class Scanner
foreach(i; 0 .. length)
{
enforce(isHexDigit(reader_.peek(i)),
new ScannerException(
new Error(
"While scanning a double qouted scalar", startMark,
"expected escape sequence of " ~ to!string(length) ~
" hexadecimal numbers, but found " ~
@ -1317,7 +1316,7 @@ final class Scanner
}
else
{
throw new ScannerException("While scanning a double quoted scalar",
throw new Error("While scanning a double quoted scalar",
startMark,
"found unknown escape character: " ~
to!string(c), reader_.mark);
@ -1336,7 +1335,7 @@ final class Scanner
dchar c = reader_.peek();
enforce(c != '\0',
new ScannerException("While scanning a quoted scalar", startMark,
new Error("While scanning a quoted scalar", startMark,
"found unexpected end of stream", reader_.mark));
auto appender = appender!dstring();
@ -1364,9 +1363,8 @@ final class Scanner
if((prefix == "---" || prefix == "...") &&
" \t\0\n\r\u0085\u2028\u2029".canFind(reader_.peek(3)))
{
throw new ScannerException("While scanning a quoted scalar", startMark,
"found unexpected document separator",
reader_.mark);
throw new Error("While scanning a quoted scalar", startMark,
"found unexpected document separator", reader_.mark);
}
while(" \t".canFind(reader_.peek())){reader_.forward();}
@ -1417,7 +1415,7 @@ final class Scanner
!",[]{}".canFind(reader_.peek(length + 1)))
{
reader_.forward(length);
throw new ScannerException("While scanning a plain scalar", startMark,
throw new Error("While scanning a plain scalar", startMark,
"found unexpected ':' . Please check "
"http://pyyaml.org/wiki/YAMLColonInFlowContext "
"for details.", reader_.mark);
@ -1494,9 +1492,8 @@ final class Scanner
{
dchar c = reader_.peek();
enforce(c == '!',
new ScannerException("While scanning a " ~ name, startMark,
"expected a '!', but found: " ~ to!string(c),
reader_.mark));
new Error("While scanning a " ~ name, startMark,
"expected a '!', but found: " ~ to!string(c), reader_.mark));
uint length = 1;
c = reader_.peek(length);
@ -1510,7 +1507,7 @@ final class Scanner
if(c != '!')
{
reader_.forward(length);
throw new ScannerException("While scanning a " ~ name, startMark,
throw new Error("While scanning a " ~ name, startMark,
"expected a '!', but found: " ~ to!string(c),
reader_.mark);
}
@ -1544,9 +1541,8 @@ final class Scanner
length = 0;
}
enforce(appender.data.length > 0,
new ScannerException("While parsing a " ~ name, startMark,
"expected URI, but found: " ~ to!string(c),
reader_.mark));
new Error("While parsing a " ~ name, startMark,
"expected URI, but found: " ~ to!string(c), reader_.mark));
return appender.data;
}
@ -1567,8 +1563,8 @@ final class Scanner
foreach(k; 0 .. 2)
{
dchar c = reader_.peek(k);
enforce("0123456789ABCDEFabcdef".canFind(c),
new ScannerException("While scanning a " ~ name, startMark,
enforce(isHexDigit(c),
new Error("While scanning a " ~ name, startMark,
"expected URI escape sequence of "
"2 hexadecimal numbers, but found: " ~
to!string(c), reader_.mark));
@ -1589,11 +1585,11 @@ final class Scanner
try{return to!dstring(cast(string)bytes);}
catch(ConvException e)
{
throw new ScannerException("While scanning a " ~ name, startMark, e.msg, mark);
throw new Error("While scanning a " ~ name, startMark, e.msg, mark);
}
catch(UtfException e)
{
throw new ScannerException("While scanning a " ~ name, startMark, e.msg, mark);
throw new Error("While scanning a " ~ name, startMark, e.msg, mark);
}
}

View file

@ -11,6 +11,8 @@
module dyaml.token;
import std.conv;
import dyaml.encoding;
import dyaml.exception;
import dyaml.reader;
@ -81,6 +83,9 @@ immutable struct Token
ScalarStyle style;
///Encoding, if this is a stream start token.
Encoding encoding;
///Get string representation of the token ID.
@property string idString() const {return to!string(id);}
}
/**