From 3078262129742c73d42fec8ebac7a2a821111e80 Mon Sep 17 00:00:00 2001 From: Ferdinand Majerech Date: Sat, 22 Oct 2011 11:18:57 +0200 Subject: [PATCH] Fixed an Emitter bug which caused tags to always be emitted in full format. Specified field names for the tag directive tuple to make code more readbvle. Fixed a bug in Dumpler.tagDirectives documentation example. --- dyaml/dumper.d | 8 +++++--- dyaml/emitter.d | 27 +++++++++++++++------------ dyaml/parser.d | 12 ++++++------ dyaml/tagdirectives.d | 6 ++++-- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/dyaml/dumper.d b/dyaml/dumper.d index 00ca9f9..735e7dc 100644 --- a/dyaml/dumper.d +++ b/dyaml/dumper.d @@ -277,22 +277,24 @@ struct Dumper * Example: * -------------------- * Dumper dumper = Dumper("file.yaml"); + * string[string] directives; + * directives["!short!"] = "tag:long.org,2011:"; * //This will emit tags starting with "tag:long.org,2011" * //with a "!short!" prefix instead. - * dumper.tags("short", "tag:long.org,2011:"); + * dumper.tagDirectives(directives); * dumper.dump(Node("foo")); * -------------------- */ void tagDirectives(string[string] tags) { - Tuple!(string, string)[] t; + tagDirective[] t; foreach(handle, prefix; tags) { assert(handle.length >= 1 && handle[0] == '!' && handle[$ - 1] == '!', "A tag handle is empty or does not start and end with a " "'!' character : " ~ handle); assert(prefix.length >= 1, "A tag prefix is empty"); - t ~= tuple(handle, prefix); + t ~= tagDirective(handle, prefix); } tags_ = TagDirectives(t); } diff --git a/dyaml/emitter.d b/dyaml/emitter.d index 3c2a8f9..cd319d9 100644 --- a/dyaml/emitter.d +++ b/dyaml/emitter.d @@ -65,12 +65,11 @@ align(4) struct ScalarAnalysis struct Emitter { private: + alias dyaml.tagdirectives.tagDirective tagDirective; + ///Default tag handle shortcuts and replacements. - static string[string] defaultTags_; - static this() - { - defaultTags_ = ["!" : "!", "tag:yaml.org,2002:" : "!!"]; - } + static tagDirective[] defaultTagDirectives_ = + [tagDirective("!", "!"), tagDirective("!!", "tag:yaml.org,2002:")]; ///Stream to write to. Stream stream_; @@ -82,7 +81,6 @@ struct Emitter ///Current state. void delegate() state_; - //TODO Should be replaced by a queue or linked list once Phobos has anything usable. ///Event queue. Queue!Event events_; ///Event we're currently emitting. @@ -130,8 +128,8 @@ struct Emitter ///Best line break character/s. LineBreak bestLineBreak_; - ///Tag directive handles and prefixes. - Tuple!(string, string)[] tagDirectives_; + ///Tag directive handle - prefix pairs. + tagDirective[] tagDirectives_; ///Anchor/alias to process. string preparedAnchor_ = null; @@ -366,13 +364,18 @@ struct Emitter foreach(ref pair; tagDirectives_) { - const handle = pair[0]; - const prefix = pair[1]; - writeTagDirective(prepareTagHandle(handle), - prepareTagPrefix(prefix)); + writeTagDirective(prepareTagHandle(pair.handle), + prepareTagPrefix(pair.prefix)); } } + bool eq(ref tagDirective a, ref tagDirective b){return a.handle == b.handle;} + //Add any default tag directives that have not been overriden. + foreach(ref def; defaultTagDirectives_) if(!canFind!eq(tagDirectives_, def)) + { + tagDirectives_ ~= def; + } + const implicit = first && !event_.explicitDocument && !canonical_ && YAMLVersion is null && tagDirectives.isNull() && !checkEmptyDocument(); diff --git a/dyaml/parser.d b/dyaml/parser.d index 00bef57..e175b3d 100644 --- a/dyaml/parser.d +++ b/dyaml/parser.d @@ -106,10 +106,10 @@ final class Parser { private: ///Default tag handle shortcuts and replacements. - static Tuple!(string, string)[] defaultTags_; + static tagDirective[] defaultTagDirectives_; static this() { - defaultTags_ = [tuple("!", "!"), tuple("!!", "tag:yaml.org,2002:")]; + defaultTagDirectives_ = [tagDirective("!", "!"), tagDirective("!!", "tag:yaml.org,2002:")]; } ///Scanner providing YAML tokens. @@ -121,7 +121,7 @@ final class Parser ///YAML version string. string YAMLVersion_ = null; ///Tag handle shortcuts and replacements. - Tuple!(string, string)[] tagHandles_; + tagDirective[] tagHandles_; ///Stack of states. Event delegate()[] states_; @@ -264,7 +264,7 @@ final class Parser if(!scanner_.checkToken(TokenID.Directive, TokenID.DocumentStart, TokenID.StreamEnd)) { - tagHandles_ = defaultTags_; + tagHandles_ = defaultTagDirectives_; immutable token = scanner_.peekToken(); states_ ~= &parseDocumentEnd; @@ -369,14 +369,14 @@ final class Parser enforce(h != handle, new Error("Duplicate tag handle: " ~ handle, token.startMark)); } - tagHandles_ ~= tuple(handle, parts[2]); + tagHandles_ ~= tagDirective(handle, parts[2]); } } TagDirectives value = tagHandles_.length == 0 ? TagDirectives() : TagDirectives(tagHandles_); //Add any default tag handles that haven't been overridden. - foreach(ref defaultPair; defaultTags_) + foreach(ref defaultPair; defaultTagDirectives_) { bool found = false; foreach(ref pair; tagHandles_) diff --git a/dyaml/tagdirectives.d b/dyaml/tagdirectives.d index 28e223d..5aa3e7c 100644 --- a/dyaml/tagdirectives.d +++ b/dyaml/tagdirectives.d @@ -11,15 +11,17 @@ import std.typecons; import dyaml.sharedobject; +///Single tag directive. handle is the shortcut, prefix is the prefix that replaces it. +alias Tuple!(string, "handle", string, "prefix") tagDirective; ///Tag directives stored in Event. struct TagDirectives { public: - mixin SharedObject!(Tuple!(string, string)[], TagDirectives); + mixin SharedObject!(tagDirective[], TagDirectives); ///Construct a tags object from an array of tag directives. - this(Tuple!(string, string)[] tagDirectives) + this(tagDirective[] tagDirectives) { add(tagDirectives); }