Merged the other-tags branch into the trunk (this wasn't an rX:Y merge, since the branch wasn't branched directly from the head of the trunk)

This commit is contained in:
Jesse Beder
2010-10-19 06:46:55 +00:00
parent 18a805e46c
commit 51c84f1c02
8 changed files with 64 additions and 21 deletions

View File

@@ -78,6 +78,8 @@ namespace YAML
void EmitEndMap(); void EmitEndMap();
void EmitKey(); void EmitKey();
void EmitValue(); void EmitValue();
void EmitKindTag();
void EmitTag(bool verbatim, const _Tag& tag);
private: private:
ostream m_stream; ostream m_stream;

View File

@@ -11,6 +11,7 @@ namespace YAML
enum EMITTER_MANIP { enum EMITTER_MANIP {
// general manipulators // general manipulators
Auto, Auto,
TagByKind,
// output character set // output character set
EmitNonAscii, EmitNonAscii,
@@ -82,14 +83,24 @@ namespace YAML
} }
struct _Tag { struct _Tag {
_Tag(const std::string& content_): content(content_), verbatim(true) {} explicit _Tag(const std::string& content_)
: content(content_), verbatim(true)
{
}
std::string content; std::string content;
bool verbatim; bool verbatim;
}; };
inline _Tag VerbatimTag(const std::string& content) { typedef _Tag VerbatimTag;
return _Tag(content);
} struct LocalTag : public _Tag
{
explicit LocalTag(const std::string& content_)
: _Tag(content_)
{
verbatim = false;
}
};
struct _Comment { struct _Comment {
_Comment(const std::string& content_): content(content_) {} _Comment(const std::string& content_): content(content_) {}

View File

@@ -120,6 +120,9 @@ namespace YAML
case Value: case Value:
EmitValue(); EmitValue();
break; break;
case TagByKind:
EmitKindTag();
break;
default: default:
m_pState->SetLocalValue(value); m_pState->SetLocalValue(value);
break; break;
@@ -651,15 +654,26 @@ namespace YAML
if(!good()) if(!good())
return *this; return *this;
EmitTag(tag.verbatim, tag);
return *this;
}
void Emitter::EmitTag(bool verbatim, const _Tag& tag)
{
PreAtomicWrite(); PreAtomicWrite();
EmitSeparationIfNecessary(); EmitSeparationIfNecessary();
if(!Utils::WriteTag(m_stream, tag.content)) { if(!Utils::WriteTag(m_stream, tag.content, verbatim)) {
m_pState->SetError(ErrorMsg::INVALID_TAG); m_pState->SetError(ErrorMsg::INVALID_TAG);
return *this; return;
} }
m_pState->RequireSeparation(); m_pState->RequireSeparation();
// Note: no PostAtomicWrite() because we need another value for this node // Note: no PostAtomicWrite() because we need another value for this node
return *this; }
void Emitter::EmitKindTag()
{
_Tag tag("");
EmitTag(false, tag);
} }
Emitter& Emitter::Write(const _Comment& comment) Emitter& Emitter::Write(const _Comment& comment)

View File

@@ -294,12 +294,13 @@ namespace YAML
return WriteAliasName(out, str); return WriteAliasName(out, str);
} }
bool WriteTag(ostream& out, const std::string& str) bool WriteTag(ostream& out, const std::string& str, bool verbatim)
{ {
out << "!<"; out << (verbatim ? "!<" : "!");
StringCharSource buffer(str.c_str(), str.size()); StringCharSource buffer(str.c_str(), str.size());
const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag();
while(buffer) { while(buffer) {
int n = Exp::URI().Match(buffer); int n = reValid.Match(buffer);
if(n <= 0) if(n <= 0)
return false; return false;
@@ -308,7 +309,8 @@ namespace YAML
++buffer; ++buffer;
} }
} }
out << ">"; if (verbatim)
out << ">";
return true; return true;
} }
} }

View File

@@ -18,7 +18,7 @@ namespace YAML
bool WriteComment(ostream& out, const std::string& str, int postCommentIndent); bool WriteComment(ostream& out, const std::string& str, int postCommentIndent);
bool WriteAlias(ostream& out, const std::string& str); bool WriteAlias(ostream& out, const std::string& str);
bool WriteAnchor(ostream& out, const std::string& str); bool WriteAnchor(ostream& out, const std::string& str);
bool WriteTag(ostream& out, const std::string& str); bool WriteTag(ostream& out, const std::string& str, bool verbatim);
} }
} }

View File

@@ -276,7 +276,12 @@ namespace YAML
} else { } else {
bool canBeHandle; bool canBeHandle;
token.value = ScanTagHandle(INPUT, canBeHandle); token.value = ScanTagHandle(INPUT, canBeHandle);
token.data = (token.value.empty() ? Tag::SECONDARY_HANDLE : Tag::PRIMARY_HANDLE); if(!canBeHandle && token.value.empty())
token.data = Tag::NON_SPECIFIC;
else if(token.value.empty())
token.data = Tag::SECONDARY_HANDLE;
else
token.data = Tag::PRIMARY_HANDLE;
// is there a suffix? // is there a suffix?
if(canBeHandle && INPUT.peek() == Keys::Tag) { if(canBeHandle && INPUT.peek() == Keys::Tag) {
@@ -321,7 +326,7 @@ namespace YAML
//if(Exp::IllegalCharInScalar.Matches(INPUT)) //if(Exp::IllegalCharInScalar.Matches(INPUT))
// throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR);
Token token(Token::SCALAR, mark); Token token(Token::PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
@@ -360,7 +365,7 @@ namespace YAML
m_simpleKeyAllowed = false; m_simpleKeyAllowed = false;
m_canBeJSONFlow = true; m_canBeJSONFlow = true;
Token token(Token::SCALAR, mark); Token token(Token::NON_PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }
@@ -427,7 +432,7 @@ namespace YAML
m_simpleKeyAllowed = true; m_simpleKeyAllowed = true;
m_canBeJSONFlow = false; m_canBeJSONFlow = false;
Token token(Token::SCALAR, mark); Token token(Token::NON_PLAIN_SCALAR, mark);
token.value = scalar; token.value = scalar;
m_tokens.push(token); m_tokens.push(token);
} }

View File

@@ -8,6 +8,7 @@
#include "token.h" #include "token.h"
#include <sstream> #include <sstream>
#include <cstdio> #include <cstdio>
#include <algorithm>
namespace YAML namespace YAML
{ {
@@ -73,10 +74,17 @@ namespace YAML
anchor_t anchor; anchor_t anchor;
ParseProperties(tag, anchor); ParseProperties(tag, anchor);
const Token& token = m_scanner.peek();
// add non-specific tags
if(tag.empty())
tag = (token.type == Token::NON_PLAIN_SCALAR ? "!" : "?");
// now split based on what kind of node we should be // now split based on what kind of node we should be
switch(m_scanner.peek().type) { switch(token.type) {
case Token::SCALAR: case Token::PLAIN_SCALAR:
eventHandler.OnScalar(mark, tag, anchor, m_scanner.peek().value); case Token::NON_PLAIN_SCALAR:
eventHandler.OnScalar(mark, tag, anchor, token.value);
m_scanner.pop(); m_scanner.pop();
return; return;
case Token::FLOW_SEQ_START: case Token::FLOW_SEQ_START:

View File

@@ -57,9 +57,10 @@ namespace YAML
ANCHOR, ANCHOR,
ALIAS, ALIAS,
TAG, TAG,
SCALAR PLAIN_SCALAR,
NON_PLAIN_SCALAR
}; };
// data // data
Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {} Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {}