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.
This commit is contained in:
Ferdinand Majerech 2011-10-22 11:18:57 +02:00
parent 1f2243190f
commit 3078262129
4 changed files with 30 additions and 23 deletions

View file

@ -277,22 +277,24 @@ struct Dumper
* Example: * Example:
* -------------------- * --------------------
* Dumper dumper = Dumper("file.yaml"); * Dumper dumper = Dumper("file.yaml");
* string[string] directives;
* directives["!short!"] = "tag:long.org,2011:";
* //This will emit tags starting with "tag:long.org,2011" * //This will emit tags starting with "tag:long.org,2011"
* //with a "!short!" prefix instead. * //with a "!short!" prefix instead.
* dumper.tags("short", "tag:long.org,2011:"); * dumper.tagDirectives(directives);
* dumper.dump(Node("foo")); * dumper.dump(Node("foo"));
* -------------------- * --------------------
*/ */
void tagDirectives(string[string] tags) void tagDirectives(string[string] tags)
{ {
Tuple!(string, string)[] t; tagDirective[] t;
foreach(handle, prefix; tags) foreach(handle, prefix; tags)
{ {
assert(handle.length >= 1 && handle[0] == '!' && handle[$ - 1] == '!', assert(handle.length >= 1 && handle[0] == '!' && handle[$ - 1] == '!',
"A tag handle is empty or does not start and end with a " "A tag handle is empty or does not start and end with a "
"'!' character : " ~ handle); "'!' character : " ~ handle);
assert(prefix.length >= 1, "A tag prefix is empty"); assert(prefix.length >= 1, "A tag prefix is empty");
t ~= tuple(handle, prefix); t ~= tagDirective(handle, prefix);
} }
tags_ = TagDirectives(t); tags_ = TagDirectives(t);
} }

View file

@ -65,12 +65,11 @@ align(4) struct ScalarAnalysis
struct Emitter struct Emitter
{ {
private: private:
alias dyaml.tagdirectives.tagDirective tagDirective;
///Default tag handle shortcuts and replacements. ///Default tag handle shortcuts and replacements.
static string[string] defaultTags_; static tagDirective[] defaultTagDirectives_ =
static this() [tagDirective("!", "!"), tagDirective("!!", "tag:yaml.org,2002:")];
{
defaultTags_ = ["!" : "!", "tag:yaml.org,2002:" : "!!"];
}
///Stream to write to. ///Stream to write to.
Stream stream_; Stream stream_;
@ -82,7 +81,6 @@ struct Emitter
///Current state. ///Current state.
void delegate() state_; void delegate() state_;
//TODO Should be replaced by a queue or linked list once Phobos has anything usable.
///Event queue. ///Event queue.
Queue!Event events_; Queue!Event events_;
///Event we're currently emitting. ///Event we're currently emitting.
@ -130,8 +128,8 @@ struct Emitter
///Best line break character/s. ///Best line break character/s.
LineBreak bestLineBreak_; LineBreak bestLineBreak_;
///Tag directive handles and prefixes. ///Tag directive handle - prefix pairs.
Tuple!(string, string)[] tagDirectives_; tagDirective[] tagDirectives_;
///Anchor/alias to process. ///Anchor/alias to process.
string preparedAnchor_ = null; string preparedAnchor_ = null;
@ -366,13 +364,18 @@ struct Emitter
foreach(ref pair; tagDirectives_) foreach(ref pair; tagDirectives_)
{ {
const handle = pair[0]; writeTagDirective(prepareTagHandle(pair.handle),
const prefix = pair[1]; prepareTagPrefix(pair.prefix));
writeTagDirective(prepareTagHandle(handle),
prepareTagPrefix(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_ && const implicit = first && !event_.explicitDocument && !canonical_ &&
YAMLVersion is null && tagDirectives.isNull() && YAMLVersion is null && tagDirectives.isNull() &&
!checkEmptyDocument(); !checkEmptyDocument();

View file

@ -106,10 +106,10 @@ final class Parser
{ {
private: private:
///Default tag handle shortcuts and replacements. ///Default tag handle shortcuts and replacements.
static Tuple!(string, string)[] defaultTags_; static tagDirective[] defaultTagDirectives_;
static this() static this()
{ {
defaultTags_ = [tuple("!", "!"), tuple("!!", "tag:yaml.org,2002:")]; defaultTagDirectives_ = [tagDirective("!", "!"), tagDirective("!!", "tag:yaml.org,2002:")];
} }
///Scanner providing YAML tokens. ///Scanner providing YAML tokens.
@ -121,7 +121,7 @@ final class Parser
///YAML version string. ///YAML version string.
string YAMLVersion_ = null; string YAMLVersion_ = null;
///Tag handle shortcuts and replacements. ///Tag handle shortcuts and replacements.
Tuple!(string, string)[] tagHandles_; tagDirective[] tagHandles_;
///Stack of states. ///Stack of states.
Event delegate()[] states_; Event delegate()[] states_;
@ -264,7 +264,7 @@ final class Parser
if(!scanner_.checkToken(TokenID.Directive, TokenID.DocumentStart, if(!scanner_.checkToken(TokenID.Directive, TokenID.DocumentStart,
TokenID.StreamEnd)) TokenID.StreamEnd))
{ {
tagHandles_ = defaultTags_; tagHandles_ = defaultTagDirectives_;
immutable token = scanner_.peekToken(); immutable token = scanner_.peekToken();
states_ ~= &parseDocumentEnd; states_ ~= &parseDocumentEnd;
@ -369,14 +369,14 @@ final class Parser
enforce(h != handle, new Error("Duplicate tag handle: " ~ handle, enforce(h != handle, new Error("Duplicate tag handle: " ~ handle,
token.startMark)); token.startMark));
} }
tagHandles_ ~= tuple(handle, parts[2]); tagHandles_ ~= tagDirective(handle, parts[2]);
} }
} }
TagDirectives value = tagHandles_.length == 0 ? TagDirectives() : TagDirectives(tagHandles_); TagDirectives value = tagHandles_.length == 0 ? TagDirectives() : TagDirectives(tagHandles_);
//Add any default tag handles that haven't been overridden. //Add any default tag handles that haven't been overridden.
foreach(ref defaultPair; defaultTags_) foreach(ref defaultPair; defaultTagDirectives_)
{ {
bool found = false; bool found = false;
foreach(ref pair; tagHandles_) foreach(ref pair; tagHandles_)

View file

@ -11,15 +11,17 @@ import std.typecons;
import dyaml.sharedobject; 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. ///Tag directives stored in Event.
struct TagDirectives struct TagDirectives
{ {
public: public:
mixin SharedObject!(Tuple!(string, string)[], TagDirectives); mixin SharedObject!(tagDirective[], TagDirectives);
///Construct a tags object from an array of tag directives. ///Construct a tags object from an array of tag directives.
this(Tuple!(string, string)[] tagDirectives) this(tagDirective[] tagDirectives)
{ {
add(tagDirectives); add(tagDirectives);
} }