diff --git a/doc/doctrees/environment.pickle b/doc/doctrees/environment.pickle index aab709c..4b69e2b 100644 Binary files a/doc/doctrees/environment.pickle and b/doc/doctrees/environment.pickle differ diff --git a/doc/html/api/dyaml.dumper.html b/doc/html/api/dyaml.dumper.html index 8113df9..df7a3a2 100644 --- a/doc/html/api/dyaml.dumper.html +++ b/doc/html/api/dyaml.dumper.html @@ -105,6 +105,11 @@

Construct a Dumper writing to a stream. This is useful to e.g. write to memory.

+
+
@property void name(string name); +
+

Set stream name. Used in debugging messages.

+
void resolver(Resolver resolver);
diff --git a/doc/html/api/dyaml.exception.html b/doc/html/api/dyaml.exception.html index dfaf5b7..997ada1 100644 --- a/doc/html/api/dyaml.exception.html +++ b/doc/html/api/dyaml.exception.html @@ -47,7 +47,7 @@
this(string msg, string file = __FILE__, int line = __LINE__);
-

Construct a YAMLException with specified message, and position where it was thrown.

+

Construct a YAMLException with specified message and position where it was thrown.

diff --git a/doc/html/api/dyaml.loader.html b/doc/html/api/dyaml.loader.html index 8be8ea2..572ea04 100644 --- a/doc/html/api/dyaml.loader.html +++ b/doc/html/api/dyaml.loader.html @@ -104,7 +104,7 @@ Parameters:
string 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(Stream stream); @@ -114,7 +114,7 @@ Parameters:
Stream 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.
@property void name(string name); @@ -136,7 +136,7 @@

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. @@ -153,7 +153,7 @@ 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.
int opApply(int delegate(ref Node) dg); diff --git a/doc/html/api/dyaml.representer.html b/doc/html/api/dyaml.representer.html index ec00226..bed446e 100644 --- a/doc/html/api/dyaml.representer.html +++ b/doc/html/api/dyaml.representer.html @@ -69,13 +69,13 @@

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.

diff --git a/doc/html/articles/spec_differences.html b/doc/html/articles/spec_differences.html index dd6c7fb..735a400 100644 --- a/doc/html/articles/spec_differences.html +++ b/doc/html/articles/spec_differences.html @@ -138,7 +138,7 @@ struct appears in Phobos.

diff --git a/doc/html/index.html b/doc/html/index.html index b18e041..677676e 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -104,7 +104,7 @@ diff --git a/doc/html/search.html b/doc/html/search.html index 15d9548..30abd00 100644 --- a/doc/html/search.html +++ b/doc/html/search.html @@ -87,7 +87,7 @@ diff --git a/doc/html/tutorials/custom_types.html b/doc/html/tutorials/custom_types.html index c7a0c4c..97e58fa 100644 --- a/doc/html/tutorials/custom_types.html +++ b/doc/html/tutorials/custom_types.html @@ -369,7 +369,7 @@ directory of the D:YAML package.

diff --git a/doc/html/tutorials/getting_started.html b/doc/html/tutorials/getting_started.html index 530bd27..bd8970a 100644 --- a/doc/html/tutorials/getting_started.html +++ b/doc/html/tutorials/getting_started.html @@ -237,7 +237,7 @@ example in the example/getting_st diff --git a/doc/html/tutorials/yaml_syntax.html b/doc/html/tutorials/yaml_syntax.html index f3d0827..f3c2235 100644 --- a/doc/html/tutorials/yaml_syntax.html +++ b/doc/html/tutorials/yaml_syntax.html @@ -330,7 +330,7 @@ Some of these might change in the future (especially !!map and !!set).

diff --git a/dyaml/composer.d b/dyaml/composer.d index 2283dc2..ce06730 100644 --- a/dyaml/composer.d +++ b/dyaml/composer.d @@ -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. + else if(root.isSequence) foreach(ref Node node; root) { - //Must be a sequence of mappings. - 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)); - merge(result, flatten(node, 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; diff --git a/dyaml/constructor.d b/dyaml/constructor.d index f19202a..a4427a6 100644 --- a/dyaml/constructor.d +++ b/dyaml/constructor.d @@ -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; diff --git a/dyaml/dumper.d b/dyaml/dumper.d index f0e9109..00ca9f9 100644 --- a/dyaml/dumper.d +++ b/dyaml/dumper.d @@ -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_ = ""; + 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); } } } diff --git a/dyaml/emitter.d b/dyaml/emitter.d index 566d289..43952d1 100644 --- a/dyaml/emitter.d +++ b/dyaml/emitter.d @@ -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,13 +859,13 @@ 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) ~ - " in tag handle " ~ handle)); + 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. diff --git a/dyaml/event.d b/dyaml/event.d index e94fe3e..37f8862 100644 --- a/dyaml/event.d +++ b/dyaml/event.d @@ -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);} } /** diff --git a/dyaml/exception.d b/dyaml/exception.d index 8a965c0..8d0f6d9 100644 --- a/dyaml/exception.d +++ b/dyaml/exception.d @@ -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__) - { - 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; - } + ///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); + } } ///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,11 +73,10 @@ 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__) - { - super(msg, file, line); - } + public this(string msg, string file = __FILE__, int line = __LINE__) + { + super(msg, file, line); + } } //Constructors of marked YAML exceptions are mostly the same, so we use a mixin. diff --git a/dyaml/loader.d b/dyaml/loader.d index bb9e9de..b173e19 100644 --- a/dyaml/loader.d +++ b/dyaml/loader.d @@ -104,23 +104,23 @@ struct Loader string name_ = ""; 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); } } } diff --git a/dyaml/node.d b/dyaml/node.d index 9e52261..8333353 100644 --- a/dyaml/node.d +++ b/dyaml/node.d @@ -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,8 +755,8 @@ 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", - startMark_)); + new Error("Trying to iterate over a node that is not a sequence", + startMark_)); int result = 0; foreach(ref node; get!(Node[])) @@ -815,8 +812,8 @@ 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", - startMark_)); + new Error("Trying to iterate over a node that is not a mapping", + startMark_)); int result = 0; foreach(ref pair; get!(Node.Pair[])) @@ -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_)); } } } diff --git a/dyaml/parser.d b/dyaml/parser.d index d9e71d3..52a0148 100644 --- a/dyaml/parser.d +++ b/dyaml/parser.d @@ -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,9 +288,9 @@ final class Parser auto tagDirectives = processDirectives(); enforce(scanner_.checkToken(TokenID.DocumentStart), - new ParserException("Expected document start but found " ~ - to!string(scanner_.peekToken().id), - scanner_.peekToken().startMark)); + new Error("Expected document start but found " ~ + scanner_.peekToken().idString, + scanner_.peekToken().startMark)); const endMark = scanner_.getToken().endMark; states_ ~= &parseDocumentEnd; @@ -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", - startMark, "expected the node content, but found: " - ~ to!string(token.id), token.startMark); + throw new Error("While parsing a " ~ (block ? "block" : "flow") ~ " node", + startMark, "expected the node content, but found: " + ~ token.idString, token.startMark); } /** @@ -549,8 +550,8 @@ final class Parser } //handle must be in tagHandles_ enforce(replacement !is null, - new ParserException("While parsing a node", startMark, - "found undefined tag handle: " ~ handle, tagMark)); + new Error("While parsing a node", startMark, + "found undefined tag handle: " ~ handle, tagMark)); return replacement ~ suffix; } return 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], - "expected ',' or ']', but got: " ~ - to!string(token.id), token.startMark); + throw new Error("While parsing a flow sequence", marks_[$ - 1], + "expected ',' or ']', but got: " ~ + 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], - "expected ',' or '}', but got: " ~ - to!string(token.id), token.startMark); + throw new Error("While parsing a flow mapping", marks_[$ - 1], + "expected ',' or '}', but got: " ~ + token.idString, token.startMark); } } diff --git a/dyaml/reader.d b/dyaml/reader.d index eda1d36..1f028d8 100644 --- a/dyaml/reader.d +++ b/dyaml/reader.d @@ -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 .. $]), diff --git a/dyaml/representer.d b/dyaml/representer.d index f6a3f71..c72eb70 100644 --- a/dyaml/representer.d +++ b/dyaml/representer.d @@ -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); } } diff --git a/dyaml/scanner.d b/dyaml/scanner.d index ab1a7f2..7ddcf52 100644 --- a/dyaml/scanner.d +++ b/dyaml/scanner.d @@ -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 " - "character \'", c, "\', index ",to!int(c), - " that cannot start " "any token"), reader_.mark); + throw new Error(format("While scanning for the next token, found " + "character \'", c, "\', index ",to!int(c), + " that cannot start any token"), reader_.mark); } @@ -303,9 +305,9 @@ final class Scanner if(key.line != reader_.line || reader_.charIndex - key.charIndex > 1024) { 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)); 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,8 +369,8 @@ final class Scanner //restrictive than what the specification requires. //if(pedantic_ && flowLevel_ > 0 && indent_ > column) //{ - // throw new ScannerException("Invalid intendation or unclosed '[' or '{'", - // reader_.mark) + // throw new Error("Invalid intendation or unclosed '[' or '{'", + // reader_.mark) //} return; } @@ -510,8 +510,8 @@ 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", - reader_.mark)); + 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,9 +855,9 @@ 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, - "expected alphanumeric, - or _, but found " - ~ to!string(reader_.peek()), reader_.mark)); + new Error("While scanning a directive", startMark, + "expected alphanumeric, - or _, but found " + ~ to!string(reader_.peek()), reader_.mark)); return name; } @@ -869,17 +868,17 @@ final class Scanner dstring result = scanYAMLDirectiveNumber(startMark); enforce(reader_.peek() == '.', - new ScannerException("While scanning a directive", startMark, - "expected a digit or '.', but found: " - ~ to!string(reader_.peek()), reader_.mark)); + new Error("While scanning a directive", startMark, + "expected a digit or '.', but found: " + ~ to!string(reader_.peek()), reader_.mark)); //Skip the '.'. reader_.forward(); result ~= '.' ~ scanYAMLDirectiveNumber(startMark); enforce(" \0\n\r\u0085\u2028\u2029".canFind(reader_.peek()), - new ScannerException("While scanning a directive", startMark, - "expected a digit or '.', but found: " - ~ to!string(reader_.peek()), reader_.mark)); + new Error("While scanning a directive", startMark, + "expected a digit or '.', but found: " + ~ to!string(reader_.peek()), reader_.mark)); return result; } @@ -887,9 +886,9 @@ final class Scanner dstring scanYAMLDirectiveNumber(in Mark startMark) { enforce(isDigit(reader_.peek()), - new ScannerException("While scanning a directive", startMark, - "expected a digit, but found: " ~ - to!string(reader_.peek()), reader_.mark)); + new Error("While scanning a directive", startMark, + "expected a digit, but found: " ~ + to!string(reader_.peek()), reader_.mark)); //Already found the first digit in the enforce(), so set length to 1. uint length = 1; @@ -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,9 +922,9 @@ 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, - "expected ' ', but found" ~ to!string(reader_.peek()), - reader_.mark)); + new Error("While scanning a directive prefix", startMark, + "expected ' ', but found" ~ to!string(reader_.peek()), + reader_.mark)); return value; } @@ -936,9 +935,9 @@ 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, - "expected comment or a line break, but found" - ~ to!string(reader_.peek()), reader_.mark)); + 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,9 +1167,9 @@ 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, - "expected a comment or a line break, but found " - ~ to!string(reader_.peek()), reader_.mark)); + 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,8 +1335,8 @@ final class Scanner dchar c = reader_.peek(); enforce(c != '\0', - new ScannerException("While scanning a quoted scalar", startMark, - "found unexpected end of stream", reader_.mark)); + new Error("While scanning a quoted scalar", startMark, + "found unexpected end of stream", reader_.mark)); auto appender = appender!dstring(); if("\n\r\u0085\u2028\u2029".canFind(c)) @@ -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,10 +1415,10 @@ final class Scanner !",[]{}".canFind(reader_.peek(length + 1))) { reader_.forward(length); - throw new ScannerException("While scanning a plain scalar", startMark, - "found unexpected ':' . Please check " - "http://pyyaml.org/wiki/YAMLColonInFlowContext " - "for details.", reader_.mark); + throw new Error("While scanning a plain scalar", startMark, + "found unexpected ':' . Please check " + "http://pyyaml.org/wiki/YAMLColonInFlowContext " + "for details.", reader_.mark); } if(length == 0){break;} @@ -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,9 +1507,9 @@ final class Scanner if(c != '!') { reader_.forward(length); - throw new ScannerException("While scanning a " ~ name, startMark, - "expected a '!', but found: " ~ to!string(c), - reader_.mark); + throw new Error("While scanning a " ~ name, startMark, + "expected a '!', but found: " ~ to!string(c), + reader_.mark); } ++length; } @@ -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,11 +1563,11 @@ final class Scanner foreach(k; 0 .. 2) { dchar c = reader_.peek(k); - enforce("0123456789ABCDEFabcdef".canFind(c), - new ScannerException("While scanning a " ~ name, startMark, - "expected URI escape sequence of " - "2 hexadecimal numbers, but found: " ~ - to!string(c), reader_.mark)); + 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)); uint digit; if(c - '0' < 10){digit = c - '0';} @@ -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); } } diff --git a/dyaml/token.d b/dyaml/token.d index ab135f8..618ce5d 100644 --- a/dyaml/token.d +++ b/dyaml/token.d @@ -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);} } /**