diff --git a/CMakeLists.txt b/CMakeLists.txt index e03eed9..3f47f27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,10 +34,11 @@ endif() set(build-shared $) set(build-windows-dll $,${build-shared}>) set(not-msvc $>) +set(msvc-shared_rt $) if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) set(CMAKE_MSVC_RUNTIME_LIBRARY - MultiThreaded$<$:Debug>$<${build-shared}:DLL>) + MultiThreaded$<$:Debug>$<${msvc-shared_rt}:DLL>) endif() set(contrib-pattern "src/contrib/*.cpp") @@ -108,7 +109,7 @@ target_sources(yaml-cpp PRIVATE $<$:${yaml-cpp-contrib-sources}> ${yaml-cpp-sources}) - + if (NOT DEFINED CMAKE_DEBUG_POSTFIX) set(CMAKE_DEBUG_POSTFIX "d") endif() diff --git a/docs/Breaking-Changes.md b/docs/Breaking-Changes.md index 3b23127..959adea 100644 --- a/docs/Breaking-Changes.md +++ b/docs/Breaking-Changes.md @@ -5,6 +5,7 @@ ## HEAD ## * Throws an exception when trying to parse a negative number as an unsigned integer. + * Supports the `as`/`as`, which throws an exception when the value exceeds the range of `int8_t`/`uint8_t`. ## 0.6.0 ## diff --git a/docs/Strings.md b/docs/Strings.md index 8ecfa64..f2328a1 100644 --- a/docs/Strings.md +++ b/docs/Strings.md @@ -1,6 +1,6 @@ # Encodings and `yaml-cpp` # -`yaml-cpp` will parse any file as specificed by the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html#id2570322). Internally, it stores all strings in UTF-8, and representation is done with UTF-8. This means that in +`yaml-cpp` will parse any file as specified by the [YAML 1.2 spec](http://www.yaml.org/spec/1.2/spec.html#id2570322). Internally, it stores all strings in UTF-8, and representation is done with UTF-8. This means that in ``` std::string str; diff --git a/include/yaml-cpp/node/convert.h b/include/yaml-cpp/node/convert.h index db7e44d..bbe0b7d 100644 --- a/include/yaml-cpp/node/convert.h +++ b/include/yaml-cpp/node/convert.h @@ -15,7 +15,6 @@ #include #include #include -#include #include "yaml-cpp/binary.h" #include "yaml-cpp/node/impl.h" @@ -114,6 +113,31 @@ typename std::enable_if::value, void>::type inner_encode(const T& rhs, std::stringstream& stream){ stream << rhs; } + +template +typename std::enable_if<(std::is_same::value || + std::is_same::value), bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + int num; + if ((stream >> std::noskipws >> num) && (stream >> std::ws).eof()) { + if (num >= std::numeric_limits::min() && + num <= std::numeric_limits::max()) { + rhs = num; + return true; + } + } + return false; +} + +template +typename std::enable_if::value || + std::is_same::value), bool>::type +ConvertStreamTo(std::stringstream& stream, T& rhs) { + if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { + return true; + } + return false; +} } #define YAML_DEFINE_CONVERT_STREAMABLE(type, negative_op) \ @@ -137,7 +161,7 @@ inner_encode(const T& rhs, std::stringstream& stream){ if ((stream.peek() == '-') && std::is_unsigned::value) { \ return false; \ } \ - if ((stream >> std::noskipws >> rhs) && (stream >> std::ws).eof()) { \ + if (conversion::ConvertStreamTo(stream, rhs)) { \ return true; \ } \ if (std::numeric_limits::has_infinity) { \ @@ -201,9 +225,8 @@ template struct convert> { static Node encode(const std::map& rhs) { Node node(NodeType::Map); - for (typename std::map::const_iterator it = rhs.begin(); - it != rhs.end(); ++it) - node.force_insert(it->first, it->second); + for (const auto& element : rhs) + node.force_insert(element.first, element.second); return node; } @@ -212,12 +235,12 @@ struct convert> { return false; rhs.clear(); - for (const_iterator it = node.begin(); it != node.end(); ++it) + for (const auto& element : node) #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: - rhs[it->first.template as()] = it->second.template as(); + rhs[element.first.template as()] = element.second.template as(); #else - rhs[it->first.as()] = it->second.as(); + rhs[element.first.as()] = element.second.as(); #endif return true; } @@ -228,9 +251,8 @@ template struct convert> { static Node encode(const std::vector& rhs) { Node node(NodeType::Sequence); - for (typename std::vector::const_iterator it = rhs.begin(); - it != rhs.end(); ++it) - node.push_back(*it); + for (const auto& element : rhs) + node.push_back(element); return node; } @@ -239,12 +261,12 @@ struct convert> { return false; rhs.clear(); - for (const_iterator it = node.begin(); it != node.end(); ++it) + for (const auto& element : node) #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: - rhs.push_back(it->template as()); + rhs.push_back(element.template as()); #else - rhs.push_back(it->as()); + rhs.push_back(element.as()); #endif return true; } @@ -255,9 +277,8 @@ template struct convert> { static Node encode(const std::list& rhs) { Node node(NodeType::Sequence); - for (typename std::list::const_iterator it = rhs.begin(); - it != rhs.end(); ++it) - node.push_back(*it); + for (const auto& element : rhs) + node.push_back(element); return node; } @@ -266,12 +287,12 @@ struct convert> { return false; rhs.clear(); - for (const_iterator it = node.begin(); it != node.end(); ++it) + for (const auto& element : node) #if defined(__GNUC__) && __GNUC__ < 4 // workaround for GCC 3: - rhs.push_back(it->template as()); + rhs.push_back(element.template as()); #else - rhs.push_back(it->as()); + rhs.push_back(element.as()); #endif return true; } diff --git a/include/yaml-cpp/node/detail/impl.h b/include/yaml-cpp/node/detail/impl.h index bbefd59..a94c7bc 100644 --- a/include/yaml-cpp/node/detail/impl.h +++ b/include/yaml-cpp/node/detail/impl.h @@ -9,6 +9,8 @@ #include "yaml-cpp/node/detail/node.h" #include "yaml-cpp/node/detail/node_data.h" + +#include #include namespace YAML { @@ -125,13 +127,11 @@ inline node* node_data::get(const Key& key, throw BadSubscript(m_mark, key); } - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->equals(key, pMemory)) { - return it->second; - } - } + auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { + return m.first->equals(key, pMemory); + }); - return nullptr; + return it != m_map.end() ? it->second : nullptr; } template @@ -153,10 +153,12 @@ inline node& node_data::get(const Key& key, shared_memory_holder pMemory) { throw BadSubscript(m_mark, key); } - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->equals(key, pMemory)) { - return *it->second; - } + auto it = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { + return m.first->equals(key, pMemory); + }); + + if (it != m_map.end()) { + return *it->second; } node& k = convert_to_node(key, pMemory); @@ -169,7 +171,9 @@ template inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { if (m_type == NodeType::Sequence) { return remove_idx::remove(m_sequence, key, m_seqSize); - } else if (m_type == NodeType::Map) { + } + + if (m_type == NodeType::Map) { kv_pairs::iterator it = m_undefinedPairs.begin(); while (it != m_undefinedPairs.end()) { kv_pairs::iterator jt = std::next(it); @@ -179,11 +183,13 @@ inline bool node_data::remove(const Key& key, shared_memory_holder pMemory) { it = jt; } - for (node_map::iterator iter = m_map.begin(); iter != m_map.end(); ++iter) { - if (iter->first->equals(key, pMemory)) { - m_map.erase(iter); - return true; - } + auto iter = std::find_if(m_map.begin(), m_map.end(), [&](const kv_pair m) { + return m.first->equals(key, pMemory); + }); + + if (iter != m_map.end()) { + m_map.erase(iter); + return true; } } diff --git a/include/yaml-cpp/node/detail/node_data.h b/include/yaml-cpp/node/detail/node_data.h index 065df4b..07cf81a 100644 --- a/include/yaml-cpp/node/detail/node_data.h +++ b/include/yaml-cpp/node/detail/node_data.h @@ -60,8 +60,8 @@ class YAML_CPP_API node_data { node_iterator end(); // sequence - void push_back(node& node, shared_memory_holder pMemory); - void insert(node& key, node& value, shared_memory_holder pMemory); + void push_back(node& node, const shared_memory_holder& pMemory); + void insert(node& key, node& value, const shared_memory_holder& pMemory); // indexing template @@ -71,9 +71,9 @@ class YAML_CPP_API node_data { template bool remove(const Key& key, shared_memory_holder pMemory); - node* get(node& key, shared_memory_holder pMemory) const; - node& get(node& key, shared_memory_holder pMemory); - bool remove(node& key, shared_memory_holder pMemory); + node* get(node& key, const shared_memory_holder& pMemory) const; + node& get(node& key, const shared_memory_holder& pMemory); + bool remove(node& key, const shared_memory_holder& pMemory); // map template @@ -91,8 +91,8 @@ class YAML_CPP_API node_data { void reset_map(); void insert_map_pair(node& key, node& value); - void convert_to_map(shared_memory_holder pMemory); - void convert_sequence_to_map(shared_memory_holder pMemory); + void convert_to_map(const shared_memory_holder& pMemory); + void convert_sequence_to_map(const shared_memory_holder& pMemory); template static node& convert_to_node(const T& rhs, shared_memory_holder pMemory); diff --git a/include/yaml-cpp/stlemitter.h b/include/yaml-cpp/stlemitter.h index 06780c8..8dacf97 100644 --- a/include/yaml-cpp/stlemitter.h +++ b/include/yaml-cpp/stlemitter.h @@ -16,8 +16,8 @@ namespace YAML { template inline Emitter& EmitSeq(Emitter& emitter, const Seq& seq) { emitter << BeginSeq; - for (typename Seq::const_iterator it = seq.begin(); it != seq.end(); ++it) - emitter << *it; + for (const auto& emit : seq) + emitter << emit; emitter << EndSeq; return emitter; } @@ -41,8 +41,8 @@ template inline Emitter& operator<<(Emitter& emitter, const std::map& m) { typedef typename std::map map; emitter << BeginMap; - for (typename map::const_iterator it = m.begin(); it != m.end(); ++it) - emitter << Key << it->first << Value << it->second; + for (const auto& emit : m) + emitter << Key << emit.first << Value << emit.second; emitter << EndMap; return emitter; } diff --git a/src/contrib/graphbuilder.cpp b/src/contrib/graphbuilder.cpp index 7032dc4..0352054 100644 --- a/src/contrib/graphbuilder.cpp +++ b/src/contrib/graphbuilder.cpp @@ -10,8 +10,7 @@ void* BuildGraphOfNextDocument(Parser& parser, GraphBuilderAdapter eventHandler(graphBuilder); if (parser.HandleNextDocument(eventHandler)) { return eventHandler.RootNode(); - } else { - return nullptr; } + return nullptr; } } // namespace YAML diff --git a/src/convert.cpp b/src/convert.cpp index 0ab12b1..9658b36 100644 --- a/src/convert.cpp +++ b/src/convert.cpp @@ -16,11 +16,7 @@ std::string tolower(const std::string& str) { template bool IsEntirely(const std::string& str, T func) { - for (char ch : str) - if (!func(ch)) - return false; - - return true; + return std::all_of(str.begin(), str.end(), [=](char ch) { return func(ch); }); } // IsFlexibleCase diff --git a/src/emitterstate.cpp b/src/emitterstate.cpp index 5c76226..d50106c 100644 --- a/src/emitterstate.cpp +++ b/src/emitterstate.cpp @@ -94,15 +94,13 @@ EmitterNodeType::value EmitterState::NextGroupType( if (type == GroupType::Seq) { if (GetFlowType(type) == Block) return EmitterNodeType::BlockSeq; - else - return EmitterNodeType::FlowSeq; - } else { - if (GetFlowType(type) == Block) - return EmitterNodeType::BlockMap; - else - return EmitterNodeType::FlowMap; + return EmitterNodeType::FlowSeq; } + if (GetFlowType(type) == Block) + return EmitterNodeType::BlockMap; + return EmitterNodeType::FlowMap; + // can't happen assert(false); return EmitterNodeType::NoType; @@ -156,9 +154,8 @@ void EmitterState::EndedGroup(GroupType::value type) { if (m_groups.empty()) { if (type == GroupType::Seq) { return SetError(ErrorMsg::UNEXPECTED_END_SEQ); - } else { - return SetError(ErrorMsg::UNEXPECTED_END_MAP); } + return SetError(ErrorMsg::UNEXPECTED_END_MAP); } // get rid of the current group diff --git a/src/emitterutils.cpp b/src/emitterutils.cpp index 3764c2b..0410f93 100644 --- a/src/emitterutils.cpp +++ b/src/emitterutils.cpp @@ -1,3 +1,4 @@ +#include #include #include @@ -199,15 +200,10 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType, bool IsValidSingleQuotedScalar(const std::string& str, bool escapeNonAscii) { // TODO: check for non-printable characters? - for (char ch : str) { - if (escapeNonAscii && (0x80 <= static_cast(ch))) { - return false; - } - if (ch == '\n') { - return false; - } - } - return true; + return std::none_of(str.begin(), str.end(), [=](char ch) { + return (escapeNonAscii && (0x80 <= static_cast(ch))) || + (ch == '\n'); + }); } bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, @@ -217,12 +213,9 @@ bool IsValidLiteralScalar(const std::string& str, FlowType::value flowType, } // TODO: check for non-printable characters? - for (char ch : str) { - if (escapeNonAscii && (0x80 <= static_cast(ch))) { - return false; - } - } - return true; + return std::none_of(str.begin(), str.end(), [=](char ch) { + return (escapeNonAscii && (0x80 <= static_cast(ch))); + }); } void WriteDoubleQuoteEscapeSequence(ostream_wrapper& out, int codePoint) { @@ -373,15 +366,15 @@ bool WriteChar(ostream_wrapper& out, char ch) { if (('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z')) { out << ch; } else if (ch == '\"') { - out << "\"\\\"\""; + out << R"("\"")"; } else if (ch == '\t') { - out << "\"\\t\""; + out << R"("\t")"; } else if (ch == '\n') { - out << "\"\\n\""; + out << R"("\n")"; } else if (ch == '\b') { - out << "\"\\b\""; + out << R"("\b")"; } else if (ch == '\\') { - out << "\"\\\\\""; + out << R"("\\")"; } else if (0x20 <= ch && ch <= 0x7e) { out << "\"" << ch << "\""; } else { diff --git a/src/exp.cpp b/src/exp.cpp index 5c3d471..992620f 100644 --- a/src/exp.cpp +++ b/src/exp.cpp @@ -54,14 +54,16 @@ std::string Escape(Stream& in, int codeLength) { // now break it up into chars if (value <= 0x7F) return Str(value); - else if (value <= 0x7FF) + + if (value <= 0x7FF) return Str(0xC0 + (value >> 6)) + Str(0x80 + (value & 0x3F)); - else if (value <= 0xFFFF) + + if (value <= 0xFFFF) return Str(0xE0 + (value >> 12)) + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); - else - return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + - Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); + + return Str(0xF0 + (value >> 18)) + Str(0x80 + ((value >> 12) & 0x3F)) + + Str(0x80 + ((value >> 6) & 0x3F)) + Str(0x80 + (value & 0x3F)); } // Escape @@ -103,7 +105,7 @@ std::string Escape(Stream& in) { case 'e': return "\x1B"; case ' ': - return "\x20"; + return R"( )"; case '\"': return "\""; case '\'': diff --git a/src/exp.h b/src/exp.h index fe36535..33c4b7b 100644 --- a/src/exp.h +++ b/src/exp.h @@ -155,7 +155,7 @@ inline const RegEx& PlainScalar() { inline const RegEx& PlainScalarInFlow() { static const RegEx e = !(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) | - (RegEx("-:", REGEX_OR) + Blank())); + (RegEx("-:", REGEX_OR) + (Blank() | RegEx()))); return e; } inline const RegEx& EndScalar() { diff --git a/src/node_data.cpp b/src/node_data.cpp index cc45f21..8eb286c 100644 --- a/src/node_data.cpp +++ b/src/node_data.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -120,7 +121,7 @@ void node_data::compute_map_size() const { const_node_iterator node_data::begin() const { if (!m_isDefined) - return const_node_iterator(); + return {}; switch (m_type) { case NodeType::Sequence: @@ -128,13 +129,13 @@ const_node_iterator node_data::begin() const { case NodeType::Map: return const_node_iterator(m_map.begin(), m_map.end()); default: - return const_node_iterator(); + return {}; } } node_iterator node_data::begin() { if (!m_isDefined) - return node_iterator(); + return {}; switch (m_type) { case NodeType::Sequence: @@ -142,13 +143,13 @@ node_iterator node_data::begin() { case NodeType::Map: return node_iterator(m_map.begin(), m_map.end()); default: - return node_iterator(); + return {}; } } const_node_iterator node_data::end() const { if (!m_isDefined) - return const_node_iterator(); + return {}; switch (m_type) { case NodeType::Sequence: @@ -156,13 +157,13 @@ const_node_iterator node_data::end() const { case NodeType::Map: return const_node_iterator(m_map.end(), m_map.end()); default: - return const_node_iterator(); + return {}; } } node_iterator node_data::end() { if (!m_isDefined) - return node_iterator(); + return {}; switch (m_type) { case NodeType::Sequence: @@ -170,12 +171,13 @@ node_iterator node_data::end() { case NodeType::Map: return node_iterator(m_map.end(), m_map.end()); default: - return node_iterator(); + return {}; } } // sequence -void node_data::push_back(node& node, shared_memory_holder /* pMemory */) { +void node_data::push_back(node& node, + const shared_memory_holder& /* pMemory */) { if (m_type == NodeType::Undefined || m_type == NodeType::Null) { m_type = NodeType::Sequence; reset_sequence(); @@ -187,7 +189,8 @@ void node_data::push_back(node& node, shared_memory_holder /* pMemory */) { m_sequence.push_back(&node); } -void node_data::insert(node& key, node& value, shared_memory_holder pMemory) { +void node_data::insert(node& key, node& value, + const shared_memory_holder& pMemory) { switch (m_type) { case NodeType::Map: break; @@ -204,20 +207,21 @@ void node_data::insert(node& key, node& value, shared_memory_holder pMemory) { } // indexing -node* node_data::get(node& key, shared_memory_holder /* pMemory */) const { +node* node_data::get(node& key, + const shared_memory_holder& /* pMemory */) const { if (m_type != NodeType::Map) { return nullptr; } - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->is(key)) - return it->second; + for (const auto& it : m_map) { + if (it.first->is(key)) + return it.second; } return nullptr; } -node& node_data::get(node& key, shared_memory_holder pMemory) { +node& node_data::get(node& key, const shared_memory_holder& pMemory) { switch (m_type) { case NodeType::Map: break; @@ -230,9 +234,9 @@ node& node_data::get(node& key, shared_memory_holder pMemory) { throw BadSubscript(m_mark, key); } - for (node_map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->is(key)) - return *it->second; + for (const auto& it : m_map) { + if (it.first->is(key)) + return *it.second; } node& value = pMemory->create_node(); @@ -240,7 +244,7 @@ node& node_data::get(node& key, shared_memory_holder pMemory) { return value; } -bool node_data::remove(node& key, shared_memory_holder /* pMemory */) { +bool node_data::remove(node& key, const shared_memory_holder& /* pMemory */) { if (m_type != NodeType::Map) return false; @@ -252,11 +256,15 @@ bool node_data::remove(node& key, shared_memory_holder /* pMemory */) { it = jt; } - for (node_map::iterator it = m_map.begin(); it != m_map.end(); ++it) { - if (it->first->is(key)) { - m_map.erase(it); - return true; - } + auto it = + std::find_if(m_map.begin(), m_map.end(), + [&](std::pair j) { + return (j.first->is(key)); + }); + + if (it != m_map.end()) { + m_map.erase(it); + return true; } return false; @@ -279,7 +287,7 @@ void node_data::insert_map_pair(node& key, node& value) { m_undefinedPairs.emplace_back(&key, &value); } -void node_data::convert_to_map(shared_memory_holder pMemory) { +void node_data::convert_to_map(const shared_memory_holder& pMemory) { switch (m_type) { case NodeType::Undefined: case NodeType::Null: @@ -297,7 +305,7 @@ void node_data::convert_to_map(shared_memory_holder pMemory) { } } -void node_data::convert_sequence_to_map(shared_memory_holder pMemory) { +void node_data::convert_sequence_to_map(const shared_memory_holder& pMemory) { assert(m_type == NodeType::Sequence); reset_map(); diff --git a/src/nodebuilder.cpp b/src/nodebuilder.cpp index 8dac0c5..bbaefac 100644 --- a/src/nodebuilder.cpp +++ b/src/nodebuilder.cpp @@ -92,7 +92,7 @@ void NodeBuilder::Push(detail::node& node) { m_stack.push_back(&node); if (needsKey) - m_keys.push_back(PushedKey(&node, false)); + m_keys.emplace_back(&node, false); } void NodeBuilder::Pop() { diff --git a/src/nodeevents.cpp b/src/nodeevents.cpp index b7222e0..51fbe55 100644 --- a/src/nodeevents.cpp +++ b/src/nodeevents.cpp @@ -32,13 +32,12 @@ void NodeEvents::Setup(const detail::node& node) { return; if (node.type() == NodeType::Sequence) { - for (detail::const_node_iterator it = node.begin(); it != node.end(); ++it) - Setup(**it); + for (auto element : node) + Setup(*element); } else if (node.type() == NodeType::Map) { - for (detail::const_node_iterator it = node.begin(); it != node.end(); - ++it) { - Setup(*it->first); - Setup(*it->second); + for (auto element : node) { + Setup(*element.first); + Setup(*element.second); } } } @@ -77,17 +76,15 @@ void NodeEvents::Emit(const detail::node& node, EventHandler& handler, break; case NodeType::Sequence: handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style()); - for (detail::const_node_iterator it = node.begin(); it != node.end(); - ++it) - Emit(**it, handler, am); + for (auto element : node) + Emit(*element, handler, am); handler.OnSequenceEnd(); break; case NodeType::Map: handler.OnMapStart(Mark(), node.tag(), anchor, node.style()); - for (detail::const_node_iterator it = node.begin(); it != node.end(); - ++it) { - Emit(*it->first, handler, am); - Emit(*it->second, handler, am); + for (auto element : node) { + Emit(*element.first, handler, am); + Emit(*element.second, handler, am); } handler.OnMapEnd(); break; diff --git a/src/parse.cpp b/src/parse.cpp index 7600a91..262536b 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -51,7 +51,7 @@ std::vector LoadAll(std::istream& input) { std::vector docs; Parser parser(input); - while (1) { + while (true) { NodeBuilder builder; if (!parser.HandleNextDocument(builder)) { break; diff --git a/src/scanner.cpp b/src/scanner.cpp index 3a466b3..ea5511a 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -51,7 +51,7 @@ Token& Scanner::peek() { Mark Scanner::mark() const { return INPUT.mark(); } void Scanner::EnsureTokensInQueue() { - while (1) { + while (true) { if (!m_tokens.empty()) { Token& token = m_tokens.front(); @@ -88,7 +88,7 @@ void Scanner::ScanNextToken() { return StartStream(); } - // get rid of whitespace, etc. (in between tokens it should be irrelevent) + // get rid of whitespace, etc. (in between tokens it should be irrelevant) ScanToNextToken(); // maybe need to end some blocks @@ -174,7 +174,7 @@ void Scanner::ScanNextToken() { } void Scanner::ScanToNextToken() { - while (1) { + while (true) { // first eat whitespace while (INPUT && IsWhitespaceToBeEaten(INPUT.peek())) { if (InBlockContext() && Exp::Tab().Matches(INPUT)) { diff --git a/src/scanscalar.cpp b/src/scanscalar.cpp index c97d136..0a47a46 100644 --- a/src/scanscalar.cpp +++ b/src/scanscalar.cpp @@ -47,7 +47,8 @@ std::string ScanScalar(Stream& INPUT, ScanScalarParams& params) { if (INPUT.column() == 0 && Exp::DocIndicator().Matches(INPUT)) { if (params.onDocIndicator == BREAK) { break; - } else if (params.onDocIndicator == THROW) { + } + if (params.onDocIndicator == THROW) { throw ParserException(INPUT.mark(), ErrorMsg::DOC_IN_SCALAR); } } diff --git a/src/scanscalar.h b/src/scanscalar.h index c3a574a..296b885 100644 --- a/src/scanscalar.h +++ b/src/scanscalar.h @@ -57,7 +57,7 @@ struct ScanScalarParams { bool leadingSpaces; }; -std::string ScanScalar(Stream& INPUT, ScanScalarParams& info); +std::string ScanScalar(Stream& INPUT, ScanScalarParams& params); } #endif // SCANSCALAR_H_62B23520_7C8E_11DE_8A39_0800200C9A66 diff --git a/src/scantoken.cpp b/src/scantoken.cpp index 325de57..1a94ab1 100644 --- a/src/scantoken.cpp +++ b/src/scantoken.cpp @@ -37,7 +37,7 @@ void Scanner::ScanDirective() { token.value += INPUT.get(); // read parameters - while (1) { + while (true) { // first get rid of whitespace while (Exp::Blank().Matches(INPUT)) INPUT.eat(1); @@ -171,7 +171,7 @@ void Scanner::ScanBlockEntry() { // Key void Scanner::ScanKey() { - // handle keys diffently in the block context (and manage indents) + // handle keys differently in the block context (and manage indents) if (InBlockContext()) { if (!m_simpleKeyAllowed) throw ParserException(INPUT.mark(), ErrorMsg::MAP_KEY); @@ -199,7 +199,7 @@ void Scanner::ScanValue() { // seems fine) m_simpleKeyAllowed = false; } else { - // handle values diffently in the block context (and manage indents) + // handle values differently in the block context (and manage indents) if (InBlockContext()) { if (!m_simpleKeyAllowed) throw ParserException(INPUT.mark(), ErrorMsg::MAP_VALUE); diff --git a/src/setting.h b/src/setting.h index 1bd3cfe..4960bbf 100644 --- a/src/setting.h +++ b/src/setting.h @@ -83,9 +83,8 @@ class SettingChanges { } void restore() YAML_CPP_NOEXCEPT { - for (setting_changes::const_iterator it = m_settingChanges.begin(); - it != m_settingChanges.end(); ++it) - (*it)->pop(); + for (const auto& setting : m_settingChanges) + setting->pop(); } void push(std::unique_ptr pSettingChange) { diff --git a/src/singledocparser.cpp b/src/singledocparser.cpp index 65602af..7e281ec 100644 --- a/src/singledocparser.cpp +++ b/src/singledocparser.cpp @@ -167,7 +167,7 @@ void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) { m_scanner.pop(); m_pCollectionStack->PushCollectionType(CollectionType::BlockSeq); - while (1) { + while (true) { if (m_scanner.empty()) throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ); @@ -200,7 +200,7 @@ void SingleDocParser::HandleFlowSequence(EventHandler& eventHandler) { m_scanner.pop(); m_pCollectionStack->PushCollectionType(CollectionType::FlowSeq); - while (1) { + while (true) { if (m_scanner.empty()) throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_SEQ_FLOW); @@ -253,7 +253,7 @@ void SingleDocParser::HandleBlockMap(EventHandler& eventHandler) { m_scanner.pop(); m_pCollectionStack->PushCollectionType(CollectionType::BlockMap); - while (1) { + while (true) { if (m_scanner.empty()) throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP); @@ -292,7 +292,7 @@ void SingleDocParser::HandleFlowMap(EventHandler& eventHandler) { m_scanner.pop(); m_pCollectionStack->PushCollectionType(CollectionType::FlowMap); - while (1) { + while (true) { if (m_scanner.empty()) throw ParserException(m_scanner.mark(), ErrorMsg::END_OF_MAP_FLOW); @@ -377,7 +377,7 @@ void SingleDocParser::ParseProperties(std::string& tag, anchor_t& anchor, anchor_name.clear(); anchor = NullAnchor; - while (1) { + while (true) { if (m_scanner.empty()) return; diff --git a/src/stream.cpp b/src/stream.cpp index 8fa6ab7..b1aa092 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -350,7 +350,9 @@ void Stream::StreamInUtf16() const { // Trailing (low) surrogate...ugh, wrong order QueueUnicodeCodepoint(m_readahead, CP_REPLACEMENT_CHARACTER); return; - } else if (ch >= 0xD800 && ch < 0xDC00) { + } + + if (ch >= 0xD800 && ch < 0xDC00) { // ch is a leading (high) surrogate // Four byte UTF-8 code point @@ -375,11 +377,10 @@ void Stream::StreamInUtf16() const { // Easiest case: queue the codepoint and return QueueUnicodeCodepoint(m_readahead, ch); return; - } else { - // Start the loop over with the new high surrogate - ch = chLow; - continue; } + // Start the loop over with the new high surrogate + ch = chLow; + continue; } // Select the payload bits from the high surrogate diff --git a/test/integration/emitter_test.cpp b/test/integration/emitter_test.cpp index 3a5783b..30607aa 100644 --- a/test/integration/emitter_test.cpp +++ b/test/integration/emitter_test.cpp @@ -52,6 +52,63 @@ TEST_F(EmitterTest, SimpleQuotedScalar) { ExpectEmit("test"); } +TEST_F(EmitterTest, DumpAndSize) { + Node n(Load("test")); + EXPECT_EQ("test", Dump(n)); + out << n; + EXPECT_EQ(4, out.size()); +} + +TEST_F(EmitterTest, NullScalar) { + Node n(Load("null")); + out << n; + ExpectEmit("~"); +} + +TEST_F(EmitterTest, AliasScalar) { + Node n(Load("[&a str, *a]")); + out << n; + ExpectEmit("[&1 str, *1]"); +} + +TEST_F(EmitterTest, StringFormat) { + out << BeginSeq; + out.SetStringFormat(SingleQuoted); + out << "string"; + out.SetStringFormat(DoubleQuoted); + out << "string"; + out.SetStringFormat(Literal); + out << "string"; + out << EndSeq; + + ExpectEmit("- 'string'\n- \"string\"\n- |\n string"); +} + +TEST_F(EmitterTest, IntBase) { + out << BeginSeq; + out.SetIntBase(Dec); + out << 1024; + out.SetIntBase(Hex); + out << 1024; + out.SetIntBase(Oct); + out << 1024; + out << EndSeq; + + ExpectEmit("- 1024\n- 0x400\n- 02000"); +} + +TEST_F(EmitterTest, NumberPrecision) { + out.SetFloatPrecision(3); + out.SetDoublePrecision(2); + out << BeginSeq; + out << 3.1425926f; + out << 53.5893; + out << 2384626.4338; + out << EndSeq; + + ExpectEmit("- 3.14\n- 54\n- 2.4e+06"); +} + TEST_F(EmitterTest, SimpleSeq) { out << BeginSeq; out << "eggs"; @@ -429,6 +486,12 @@ TEST_F(EmitterTest, ByKindTagWithScalar) { ExpectEmit("- \"12\"\n- 12\n- ! 12"); } +TEST_F(EmitterTest, LocalTagInNameHandle) { + out << LocalTag("a", "foo") << "bar"; + + ExpectEmit("!a!foo bar"); +} + TEST_F(EmitterTest, LocalTagWithScalar) { out << LocalTag("foo") << "bar"; @@ -516,6 +579,17 @@ TEST_F(EmitterTest, STLContainers) { ExpectEmit("- [2, 3, 5, 7, 11, 13]\n- Daniel: 26\n Jesse: 24"); } +TEST_F(EmitterTest, CommentStyle) { + out.SetPreCommentIndent(1); + out.SetPostCommentIndent(2); + out << BeginMap; + out << Key << "method"; + out << Value << "least squares" << Comment("should we change this method?"); + out << EndMap; + + ExpectEmit("method: least squares # should we change this method?"); +} + TEST_F(EmitterTest, SimpleComment) { out << BeginMap; out << Key << "method"; @@ -644,6 +718,17 @@ TEST_F(EmitterTest, Null) { ExpectEmit("- ~\n- null value: ~\n ~: null key"); } +TEST_F(EmitterTest, OutputCharset) { + out << BeginSeq; + out.SetOutputCharset(EmitNonAscii); + out << "\x24 \xC2\xA2 \xE2\x82\xAC"; + out.SetOutputCharset(EscapeNonAscii); + out << "\x24 \xC2\xA2 \xE2\x82\xAC"; + out << EndSeq; + + ExpectEmit("- $ ¢ €\n- \"$ \\xa2 \\u20ac\""); +} + TEST_F(EmitterTest, EscapedUnicode) { out << EscapeNonAscii << "\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2"; @@ -660,6 +745,11 @@ TEST_F(EmitterTest, DoubleQuotedUnicode) { ExpectEmit("\"\x24 \xC2\xA2 \xE2\x82\xAC \xF0\xA4\xAD\xA2\""); } +TEST_F(EmitterTest, DoubleQuotedString) { + out << DoubleQuoted << "\" \\ \n \t \r \b \x15 \xEF\xBB\xBF \x24"; + ExpectEmit("\"\\\" \\\\ \\n \\t \\r \\b \\x15 \\ufeff $\""); +} + struct Foo { Foo() : x(0) {} Foo(int x_, const std::string& bar_) : x(x_), bar(bar_) {} @@ -826,6 +916,57 @@ TEST_F(EmitterTest, ColonAtEndOfScalarInFlow) { ExpectEmit("{\"C:\": \"C:\"}"); } +TEST_F(EmitterTest, GlobalBoolFormatting) { + out << BeginSeq; + out.SetBoolFormat(UpperCase); + out.SetBoolFormat(YesNoBool); + out << true; + out << false; + out.SetBoolFormat(TrueFalseBool); + out << true; + out << false; + out.SetBoolFormat(OnOffBool); + out << true; + out << false; + out.SetBoolFormat(LowerCase); + out.SetBoolFormat(YesNoBool); + out << true; + out << false; + out.SetBoolFormat(TrueFalseBool); + out << true; + out << false; + out.SetBoolFormat(OnOffBool); + out << true; + out << false; + out.SetBoolFormat(CamelCase); + out.SetBoolFormat(YesNoBool); + out << true; + out << false; + out.SetBoolFormat(TrueFalseBool); + out << true; + out << false; + out.SetBoolFormat(OnOffBool); + out << true; + out << false; + out.SetBoolFormat(ShortBool); + out.SetBoolFormat(UpperCase); + out.SetBoolFormat(YesNoBool); + out << true; + out << false; + out.SetBoolFormat(TrueFalseBool); + out << true; + out << false; + out.SetBoolFormat(OnOffBool); + out << true; + out << false; + out << EndSeq; + ExpectEmit( + "- YES\n- NO\n- TRUE\n- FALSE\n- ON\n- OFF\n" + "- yes\n- no\n- true\n- false\n- on\n- off\n" + "- Yes\n- No\n- True\n- False\n- On\n- Off\n" + "- Y\n- N\n- Y\n- N\n- Y\n- N"); +} + TEST_F(EmitterTest, BoolFormatting) { out << BeginSeq; out << TrueFalseBool << UpperCase << true; diff --git a/test/integration/load_node_test.cpp b/test/integration/load_node_test.cpp index 9a93a68..b28cd37 100644 --- a/test/integration/load_node_test.cpp +++ b/test/integration/load_node_test.cpp @@ -21,22 +21,35 @@ TEST(LoadNodeTest, FallbackValues) { } TEST(LoadNodeTest, NumericConversion) { - Node node = Load("[1.5, 1, .nan, .inf, -.inf, 0x15, 015]"); - EXPECT_EQ(1.5f, node[0].as()); - EXPECT_EQ(1.5, node[0].as()); - EXPECT_THROW(node[0].as(), TypedBadConversion); - EXPECT_EQ(1, node[1].as()); - EXPECT_EQ(1.0f, node[1].as()); - EXPECT_NE(node[2].as(), node[2].as()); - EXPECT_EQ(std::numeric_limits::infinity(), node[3].as()); - EXPECT_EQ(-std::numeric_limits::infinity(), node[4].as()); - EXPECT_EQ(21, node[5].as()); - EXPECT_EQ(13, node[6].as()); + EXPECT_EQ(1.5f, Load("1.5").as()); + EXPECT_EQ(1.5, Load("1.5").as()); + EXPECT_THROW(Load("1.5").as(), TypedBadConversion); + EXPECT_EQ(1, Load("1").as()); + EXPECT_EQ(1.0f, Load("1").as()); + EXPECT_NE(Load(".nan").as(), Load(".nan").as()); + EXPECT_EQ(std::numeric_limits::infinity(), Load(".inf").as()); + EXPECT_EQ(-std::numeric_limits::infinity(), Load("-.inf").as()); + EXPECT_EQ(21, Load("0x15").as()); + EXPECT_EQ(13, Load("015").as()); + EXPECT_EQ(-128, +Load("-128").as()); + EXPECT_EQ(127, +Load("127").as()); + EXPECT_THROW(Load("128").as(), TypedBadConversion); + EXPECT_EQ(255, +Load("255").as()); + EXPECT_THROW(Load("256").as(), TypedBadConversion); + // test as/as with ‘a’,"ab",'1',"127" + EXPECT_EQ('a', Load("a").as()); + EXPECT_THROW(Load("ab").as(), TypedBadConversion); + EXPECT_EQ('1', Load("1").as()); + EXPECT_THROW(Load("127").as(), TypedBadConversion); + EXPECT_THROW(Load("a").as(), TypedBadConversion); + EXPECT_THROW(Load("ab").as(), TypedBadConversion); + EXPECT_EQ(1, +Load("1").as()); // Throw exception: convert a negative number to an unsigned number. - EXPECT_THROW(node[7].as(), TypedBadConversion); - EXPECT_THROW(node[7].as(), TypedBadConversion); - EXPECT_THROW(node[7].as(), TypedBadConversion); - EXPECT_THROW(node[7].as(), TypedBadConversion); + EXPECT_THROW(Load("-128").as(), TypedBadConversion); + EXPECT_THROW(Load("-128").as(), TypedBadConversion); + EXPECT_THROW(Load("-128").as(), TypedBadConversion); + EXPECT_THROW(Load("-128").as(), TypedBadConversion); + EXPECT_THROW(Load("-128").as(), TypedBadConversion); } TEST(LoadNodeTest, Binary) { @@ -241,7 +254,7 @@ TEST(NodeTest, IncompleteJson) { {"JSON map without end brace", "{\"access\":\"abc\"", ErrorMsg::END_OF_MAP_FLOW}, }; - for (const ParserExceptionTestCase test : tests) { + for (const ParserExceptionTestCase& test : tests) { try { Load(test.input); FAIL() << "Expected exception " << test.expected_exception << " for " @@ -256,7 +269,18 @@ TEST(NodeTest, LoadTildeAsNull) { Node node = Load("~"); ASSERT_TRUE(node.IsNull()); } - + +TEST(NodeTest, LoadNullWithStrTag) { + Node node = Load("!!str null"); + EXPECT_EQ(node.Tag(), "tag:yaml.org,2002:str"); + EXPECT_EQ(node.as(), "null"); +} + +TEST(NodeTest, LoadQuotedNull) { + Node node = Load("\"null\""); + EXPECT_EQ(node.as(), "null"); +} + TEST(NodeTest, LoadTagWithParenthesis) { Node node = Load("!Complex(Tag) foo"); EXPECT_EQ(node.Tag(), "!Complex(Tag)"); diff --git a/test/integration/node_spec_test.cpp b/test/integration/node_spec_test.cpp index aedf38b..bfc8578 100644 --- a/test/integration/node_spec_test.cpp +++ b/test/integration/node_spec_test.cpp @@ -1127,5 +1127,10 @@ TEST(NodeSpecTest, Ex8_22_BlockCollectionNodes) { EXPECT_EQ(1, doc["mapping"].size()); EXPECT_EQ("bar", doc["mapping"]["foo"].as()); } + +TEST(NodeSpecTest, FlowMapNotClosed) { + EXPECT_THROW_PARSER_EXCEPTION(Load("{x:"), ErrorMsg::UNKNOWN_TOKEN); +} + } } diff --git a/util/read.cpp b/util/read.cpp index fc88f1f..3455ea3 100644 --- a/util/read.cpp +++ b/util/read.cpp @@ -8,23 +8,23 @@ class NullEventHandler : public YAML::EventHandler { public: - typedef YAML::Mark Mark; - typedef YAML::anchor_t anchor_t; + using Mark = YAML::Mark; + using anchor_t = YAML::anchor_t; - NullEventHandler() {} + NullEventHandler() = default; - virtual void OnDocumentStart(const Mark&) {} - virtual void OnDocumentEnd() {} - virtual void OnNull(const Mark&, anchor_t) {} - virtual void OnAlias(const Mark&, anchor_t) {} - virtual void OnScalar(const Mark&, const std::string&, anchor_t, - const std::string&) {} - virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) {} - virtual void OnSequenceEnd() {} - virtual void OnMapStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) {} - virtual void OnMapEnd() {} + void OnDocumentStart(const Mark&) override {} + void OnDocumentEnd() override {} + void OnNull(const Mark&, anchor_t) override {} + void OnAlias(const Mark&, anchor_t) override {} + void OnScalar(const Mark&, const std::string&, anchor_t, + const std::string&) override {} + void OnSequenceStart(const Mark&, const std::string&, anchor_t, + YAML::EmitterStyle::value style) override {} + void OnSequenceEnd() override {} + void OnMapStart(const Mark&, const std::string&, anchor_t, + YAML::EmitterStyle::value style) override {} + void OnMapEnd() override {} }; void run(std::istream& in) { @@ -68,14 +68,14 @@ int main(int argc, char** argv) { } } - if (N > 1 && !cache && filename == "") { + if (N > 1 && !cache && filename.empty()) { usage(); return -1; } if (cache) { std::string input; - if (filename != "") { + if (!filename.empty()) { std::ifstream in(filename); input = read_stream(in); } else { @@ -87,7 +87,7 @@ int main(int argc, char** argv) { run(in); } } else { - if (filename != "") { + if (!filename.empty()) { std::ifstream in(filename); for (int i = 0; i < N; i++) { in.seekg(std::ios_base::beg); diff --git a/util/sandbox.cpp b/util/sandbox.cpp index 1df25bb..f21490e 100644 --- a/util/sandbox.cpp +++ b/util/sandbox.cpp @@ -6,23 +6,23 @@ class NullEventHandler : public YAML::EventHandler { public: - typedef YAML::Mark Mark; - typedef YAML::anchor_t anchor_t; + using Mark = YAML::Mark; + using anchor_t = YAML::anchor_t; - NullEventHandler() {} + NullEventHandler() = default; - virtual void OnDocumentStart(const Mark&) {} - virtual void OnDocumentEnd() {} - virtual void OnNull(const Mark&, anchor_t) {} - virtual void OnAlias(const Mark&, anchor_t) {} - virtual void OnScalar(const Mark&, const std::string&, anchor_t, - const std::string&) {} - virtual void OnSequenceStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) {} - virtual void OnSequenceEnd() {} - virtual void OnMapStart(const Mark&, const std::string&, anchor_t, - YAML::EmitterStyle::value style) {} - virtual void OnMapEnd() {} + void OnDocumentStart(const Mark&) override {} + void OnDocumentEnd() override {} + void OnNull(const Mark&, anchor_t) override {} + void OnAlias(const Mark&, anchor_t) override {} + void OnScalar(const Mark&, const std::string&, anchor_t, + const std::string&) override {} + void OnSequenceStart(const Mark&, const std::string&, anchor_t, + YAML::EmitterStyle::value style) override {} + void OnSequenceEnd() override {} + void OnMapStart(const Mark&, const std::string&, anchor_t, + YAML::EmitterStyle::value style) override {} + void OnMapEnd() override {} }; int main() {