From 51c84f1c02830841d3b24696d6ad4a7fee797ec5 Mon Sep 17 00:00:00 2001 From: Jesse Beder Date: Tue, 19 Oct 2010 06:46:55 +0000 Subject: [PATCH] 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) --- include/yaml-cpp/emitter.h | 2 ++ include/yaml-cpp/emittermanip.h | 19 +++++++++++++++---- src/emitter.cpp | 20 +++++++++++++++++--- src/emitterutils.cpp | 10 ++++++---- src/emitterutils.h | 2 +- src/scantoken.cpp | 13 +++++++++---- src/singledocparser.cpp | 14 +++++++++++--- src/token.h | 5 +++-- 8 files changed, 64 insertions(+), 21 deletions(-) diff --git a/include/yaml-cpp/emitter.h b/include/yaml-cpp/emitter.h index 305e8e6..12ade38 100644 --- a/include/yaml-cpp/emitter.h +++ b/include/yaml-cpp/emitter.h @@ -78,6 +78,8 @@ namespace YAML void EmitEndMap(); void EmitKey(); void EmitValue(); + void EmitKindTag(); + void EmitTag(bool verbatim, const _Tag& tag); private: ostream m_stream; diff --git a/include/yaml-cpp/emittermanip.h b/include/yaml-cpp/emittermanip.h index c88054f..bbf48c4 100644 --- a/include/yaml-cpp/emittermanip.h +++ b/include/yaml-cpp/emittermanip.h @@ -11,6 +11,7 @@ namespace YAML enum EMITTER_MANIP { // general manipulators Auto, + TagByKind, // output character set EmitNonAscii, @@ -82,14 +83,24 @@ namespace YAML } struct _Tag { - _Tag(const std::string& content_): content(content_), verbatim(true) {} + explicit _Tag(const std::string& content_) + : content(content_), verbatim(true) + { + } std::string content; bool verbatim; }; - inline _Tag VerbatimTag(const std::string& content) { - return _Tag(content); - } + typedef _Tag VerbatimTag; + + struct LocalTag : public _Tag + { + explicit LocalTag(const std::string& content_) + : _Tag(content_) + { + verbatim = false; + } + }; struct _Comment { _Comment(const std::string& content_): content(content_) {} diff --git a/src/emitter.cpp b/src/emitter.cpp index c036b8f..1e0d555 100644 --- a/src/emitter.cpp +++ b/src/emitter.cpp @@ -120,6 +120,9 @@ namespace YAML case Value: EmitValue(); break; + case TagByKind: + EmitKindTag(); + break; default: m_pState->SetLocalValue(value); break; @@ -651,15 +654,26 @@ namespace YAML if(!good()) return *this; + EmitTag(tag.verbatim, tag); + return *this; + } + + void Emitter::EmitTag(bool verbatim, const _Tag& tag) + { PreAtomicWrite(); EmitSeparationIfNecessary(); - if(!Utils::WriteTag(m_stream, tag.content)) { + if(!Utils::WriteTag(m_stream, tag.content, verbatim)) { m_pState->SetError(ErrorMsg::INVALID_TAG); - return *this; + return; } m_pState->RequireSeparation(); // 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) diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index c80b506..45e9f69 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -294,12 +294,13 @@ namespace YAML 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()); + const RegEx& reValid = verbatim ? Exp::URI() : Exp::Tag(); while(buffer) { - int n = Exp::URI().Match(buffer); + int n = reValid.Match(buffer); if(n <= 0) return false; @@ -308,7 +309,8 @@ namespace YAML ++buffer; } } - out << ">"; + if (verbatim) + out << ">"; return true; } } diff --git a/src/emitterutils.h b/src/emitterutils.h index 3438745..8e2356c 100644 --- a/src/emitterutils.h +++ b/src/emitterutils.h @@ -18,7 +18,7 @@ namespace YAML bool WriteComment(ostream& out, const std::string& str, int postCommentIndent); bool WriteAlias(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); } } diff --git a/src/scantoken.cpp b/src/scantoken.cpp index 768ed7f..82ea733 100644 --- a/src/scantoken.cpp +++ b/src/scantoken.cpp @@ -276,7 +276,12 @@ namespace YAML } else { bool 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? if(canBeHandle && INPUT.peek() == Keys::Tag) { @@ -321,7 +326,7 @@ namespace YAML //if(Exp::IllegalCharInScalar.Matches(INPUT)) // throw ParserException(INPUT.mark(), ErrorMsg::CHAR_IN_SCALAR); - Token token(Token::SCALAR, mark); + Token token(Token::PLAIN_SCALAR, mark); token.value = scalar; m_tokens.push(token); } @@ -360,7 +365,7 @@ namespace YAML m_simpleKeyAllowed = false; m_canBeJSONFlow = true; - Token token(Token::SCALAR, mark); + Token token(Token::NON_PLAIN_SCALAR, mark); token.value = scalar; m_tokens.push(token); } @@ -427,7 +432,7 @@ namespace YAML m_simpleKeyAllowed = true; m_canBeJSONFlow = false; - Token token(Token::SCALAR, mark); + Token token(Token::NON_PLAIN_SCALAR, mark); token.value = scalar; m_tokens.push(token); } diff --git a/src/singledocparser.cpp b/src/singledocparser.cpp index 85844a3..c67a0ff 100644 --- a/src/singledocparser.cpp +++ b/src/singledocparser.cpp @@ -8,6 +8,7 @@ #include "token.h" #include #include +#include namespace YAML { @@ -73,10 +74,17 @@ namespace YAML anchor_t 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 - switch(m_scanner.peek().type) { - case Token::SCALAR: - eventHandler.OnScalar(mark, tag, anchor, m_scanner.peek().value); + switch(token.type) { + case Token::PLAIN_SCALAR: + case Token::NON_PLAIN_SCALAR: + eventHandler.OnScalar(mark, tag, anchor, token.value); m_scanner.pop(); return; case Token::FLOW_SEQ_START: diff --git a/src/token.h b/src/token.h index ba2eb59..63093fc 100644 --- a/src/token.h +++ b/src/token.h @@ -57,9 +57,10 @@ namespace YAML ANCHOR, ALIAS, TAG, - SCALAR + PLAIN_SCALAR, + NON_PLAIN_SCALAR }; - + // data Token(TYPE type_, const Mark& mark_): status(VALID), type(type_), mark(mark_), data(0) {}