Add more compile time diagnostics for g++ and clang++

Add compilation flags: -Wshadow -Weffc++ -pedantic -pedantic-errors

* Delete implicit copy & move constructors & assignment operators
  in classes with pointer data members.
* An exception to the above: Add default copy & move constructors &
  assignment operators for the Binary class.
* Convert boolean RegEx operators to binary operators.
* Initialize all members in all classes in ctors.
* Let default ctor delegate to the converting ctor in
  Binary and RegEx
* Don't change any tests except regex_test (as a result of the change
  to binary operators).

Note: https://bugzilla.redhat.com/show_bug.cgi?id=1544675 makes
-Weffc++ report a false positive in "include/yaml-cpp/node/impl.h".
This commit is contained in:
Ted Lyngmo 2019-03-07 22:41:33 +01:00
parent a2a113c6ff
commit 5ab904311f
36 changed files with 187 additions and 128 deletions

View File

@ -165,7 +165,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} -fPIC")
endif()
#
set(FLAG_TESTED "-Wextra")
set(FLAG_TESTED "-Wextra -Wshadow -Weffc++ -pedantic -pedantic-errors")
check_cxx_compiler_flag(${FLAG_TESTED} FLAG_WEXTRA)
if(FLAG_WEXTRA)
set(GCC_EXTRA_OPTIONS "${GCC_EXTRA_OPTIONS} ${FLAG_TESTED}")

View File

@ -19,9 +19,13 @@ YAML_CPP_API std::vector<unsigned char> DecodeBase64(const std::string &input);
class YAML_CPP_API Binary {
public:
Binary() : m_unownedData(0), m_unownedSize(0) {}
Binary(const unsigned char *data_, std::size_t size_)
: m_unownedData(data_), m_unownedSize(size_) {}
: m_data{}, m_unownedData(data_), m_unownedSize(size_) {}
Binary() : Binary(nullptr, 0) {}
Binary(const Binary&) = default;
Binary(Binary&&) = default;
Binary& operator=(const Binary&) = default;
Binary& operator=(Binary&&) = default;
bool owned() const { return !m_unownedData; }
std::size_t size() const { return owned() ? m_data.size() : m_unownedSize; }

View File

@ -32,7 +32,7 @@ class AnchorDict {
T Get(anchor_t anchor) const { return m_data[anchor - 1]; }
private:
std::vector<T> m_data;
std::vector<T> m_data{};
};
}

View File

@ -27,7 +27,7 @@ class YAML_CPP_API memory {
private:
typedef std::set<shared_node> Nodes;
Nodes m_nodes;
Nodes m_nodes{};
};
class YAML_CPP_API memory_holder {

View File

@ -18,7 +18,7 @@ namespace YAML {
namespace detail {
class node {
public:
node() : m_pRef(new node_ref) {}
node() : m_pRef(new node_ref), m_dependencies{} {}
node(const node&) = delete;
node& operator=(const node&) = delete;

View File

@ -15,7 +15,7 @@
#include <string>
namespace YAML {
inline Node::Node() : m_isValid(true), m_pNode(NULL) {}
inline Node::Node() : m_isValid(true), m_pMemory(nullptr), m_pNode(NULL) {}
inline Node::Node(NodeType::value type)
: m_isValid(true),
@ -42,7 +42,7 @@ inline Node::Node(const Node& rhs)
m_pMemory(rhs.m_pMemory),
m_pNode(rhs.m_pNode) {}
inline Node::Node(Zombie) : m_isValid(false), m_pNode(NULL) {}
inline Node::Node(Zombie) : m_isValid(false), m_pMemory{}, m_pNode(NULL) {}
inline Node::Node(detail::node& node, detail::shared_memory_holder pMemory)
: m_isValid(true), m_pMemory(pMemory), m_pNode(&node) {}
@ -202,6 +202,15 @@ inline Node& Node::operator=(const T& rhs) {
return *this;
}
inline Node& Node::operator=(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
if (is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::reset(const YAML::Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
@ -238,15 +247,6 @@ inline void Node::Assign(char* rhs) {
m_pNode->set_scalar(rhs);
}
inline Node& Node::operator=(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();
if (is(rhs))
return *this;
AssignNode(rhs);
return *this;
}
inline void Node::AssignData(const Node& rhs) {
if (!m_isValid || !rhs.m_isValid)
throw InvalidNode();

View File

@ -13,12 +13,10 @@ namespace YAML {
// this is basically boost::noncopyable
class YAML_CPP_API noncopyable {
protected:
noncopyable() {}
~noncopyable() {}
private:
noncopyable(const noncopyable&);
const noncopyable& operator=(const noncopyable&);
noncopyable() = default;
~noncopyable() = default;
noncopyable(const noncopyable&) = delete;
noncopyable& operator=(const noncopyable&) = delete;
};
}

View File

@ -17,6 +17,10 @@ class YAML_CPP_API ostream_wrapper {
public:
ostream_wrapper();
explicit ostream_wrapper(std::ostream& stream);
ostream_wrapper(const ostream_wrapper&) = delete;
ostream_wrapper(ostream_wrapper&&) = delete;
ostream_wrapper& operator=(const ostream_wrapper&) = delete;
ostream_wrapper& operator=(ostream_wrapper&&) = delete;
~ostream_wrapper();
void write(const std::string& str);

View File

@ -33,7 +33,7 @@ class CollectionStack {
}
private:
std::stack<CollectionType::value> collectionStack;
std::stack<CollectionType::value> collectionStack{};
};
}

View File

@ -26,7 +26,11 @@ namespace YAML {
class GraphBuilderAdapter : public EventHandler {
public:
GraphBuilderAdapter(GraphBuilderInterface& builder)
: m_builder(builder), m_pRootNode(nullptr), m_pKeyNode(nullptr) {}
: m_builder(builder), m_containers{}, m_anchors{}, m_pRootNode(nullptr), m_pKeyNode(nullptr) {}
GraphBuilderAdapter(const GraphBuilderAdapter&) = delete;
GraphBuilderAdapter(GraphBuilderAdapter&&) = delete;
GraphBuilderAdapter& operator=(const GraphBuilderAdapter&) = delete;
GraphBuilderAdapter& operator=(GraphBuilderAdapter&&) = delete;
virtual void OnDocumentStart(const Mark& mark) { (void)mark; }
virtual void OnDocumentEnd() {}
@ -50,8 +54,8 @@ class GraphBuilderAdapter : public EventHandler {
struct ContainerFrame {
ContainerFrame(void* pSequence)
: pContainer(pSequence), pPrevKeyNode(&sequenceMarker) {}
ContainerFrame(void* pMap, void* pPrevKeyNode)
: pContainer(pMap), pPrevKeyNode(pPrevKeyNode) {}
ContainerFrame(void* pMap, void* PrevKeyNode)
: pContainer(pMap), pPrevKeyNode(PrevKeyNode) {}
void* pContainer;
void* pPrevKeyNode;

View File

@ -1,11 +1,11 @@
#include "directives.h"
namespace YAML {
Directives::Directives() {
// version
version.isDefault = true;
version.major = 1;
version.minor = 2;
Directives::Directives() : version{true, 1, 2}, tags{} {
/* Version:
** bool isDefault;
** int major, minor;
*/
}
const std::string Directives::TranslateTagHandle(

View File

@ -19,7 +19,7 @@ std::string ToString(YAML::anchor_t anchor) {
}
namespace YAML {
EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter) {}
EmitFromEvents::EmitFromEvents(Emitter& emitter) : m_emitter(emitter), m_stateStack{} {}
void EmitFromEvents::OnDocumentStart(const Mark&) {}

View File

@ -11,7 +11,7 @@ namespace YAML {
class Binary;
struct _Null;
Emitter::Emitter() : m_pState(new EmitterState) {}
Emitter::Emitter() : m_pState(new EmitterState), m_stream{} {}
Emitter::Emitter(std::ostream& stream)
: m_pState(new EmitterState), m_stream(stream) {}

View File

@ -6,27 +6,32 @@
namespace YAML {
EmitterState::EmitterState()
: m_isGood(true),
m_lastError{},
// default global manipulators
m_charset(EmitNonAscii),
m_strFmt(Auto),
m_boolFmt(TrueFalseBool),
m_boolLengthFmt(LongBool),
m_boolCaseFmt(LowerCase),
m_intFmt(Dec),
m_indent(2),
m_preCommentIndent(2),
m_postCommentIndent(1),
m_seqFmt(Block),
m_mapFmt(Block),
m_mapKeyFmt(Auto),
m_floatPrecision(std::numeric_limits<float>::max_digits10),
m_doublePrecision(std::numeric_limits<double>::max_digits10),
//
m_modifiedSettings{},
m_globalModifiedSettings{},
m_groups{},
m_curIndent(0),
m_hasAnchor(false),
m_hasTag(false),
m_hasNonContent(false),
m_docCount(0) {
// set default global manipulators
m_charset.set(EmitNonAscii);
m_strFmt.set(Auto);
m_boolFmt.set(TrueFalseBool);
m_boolLengthFmt.set(LongBool);
m_boolCaseFmt.set(LowerCase);
m_intFmt.set(Dec);
m_indent.set(2);
m_preCommentIndent.set(2);
m_postCommentIndent.set(1);
m_seqFmt.set(Block);
m_mapFmt.set(Block);
m_mapKeyFmt.set(Auto);
m_floatPrecision.set(std::numeric_limits<float>::max_digits10);
m_doublePrecision.set(std::numeric_limits<double>::max_digits10);
}
m_docCount(0)
{}
EmitterState::~EmitterState() {}

View File

@ -145,7 +145,7 @@ class EmitterState {
struct Group {
explicit Group(GroupType::value type_)
: type(type_), indent(0), childCount(0), longKey(false) {}
: type(type_), flowType{}, indent(0), childCount(0), longKey(false), modifiedSettings{} {}
GroupType::value type;
FlowType::value flowType;

View File

@ -173,12 +173,12 @@ bool IsValidPlainScalar(const std::string& str, FlowType::value flowType,
// then check until something is disallowed
static const RegEx& disallowed_flow =
Exp::EndScalarInFlow() || (Exp::BlankOrBreak() + Exp::Comment()) ||
Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
Exp::EndScalarInFlow() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab();
static const RegEx& disallowed_block =
Exp::EndScalar() || (Exp::BlankOrBreak() + Exp::Comment()) ||
Exp::NotPrintable() || Exp::Utf8_ByteOrderMark() || Exp::Break() ||
Exp::EndScalar() | (Exp::BlankOrBreak() + Exp::Comment()) |
Exp::NotPrintable() | Exp::Utf8_ByteOrderMark() | Exp::Break() |
Exp::Tab();
const RegEx& disallowed =
flowType == FlowType::Flow ? disallowed_flow : disallowed_block;

View File

@ -33,15 +33,15 @@ inline const RegEx& Tab() {
return e;
}
inline const RegEx& Blank() {
static const RegEx e = Space() || Tab();
static const RegEx e = Space() | Tab();
return e;
}
inline const RegEx& Break() {
static const RegEx e = RegEx('\n') || RegEx("\r\n");
static const RegEx e = RegEx('\n') | RegEx("\r\n");
return e;
}
inline const RegEx& BlankOrBreak() {
static const RegEx e = Blank() || Break();
static const RegEx e = Blank() | Break();
return e;
}
inline const RegEx& Digit() {
@ -49,29 +49,29 @@ inline const RegEx& Digit() {
return e;
}
inline const RegEx& Alpha() {
static const RegEx e = RegEx('a', 'z') || RegEx('A', 'Z');
static const RegEx e = RegEx('a', 'z') | RegEx('A', 'Z');
return e;
}
inline const RegEx& AlphaNumeric() {
static const RegEx e = Alpha() || Digit();
static const RegEx e = Alpha() | Digit();
return e;
}
inline const RegEx& Word() {
static const RegEx e = AlphaNumeric() || RegEx('-');
static const RegEx e = AlphaNumeric() | RegEx('-');
return e;
}
inline const RegEx& Hex() {
static const RegEx e = Digit() || RegEx('A', 'F') || RegEx('a', 'f');
static const RegEx e = Digit() | RegEx('A', 'F') | RegEx('a', 'f');
return e;
}
// Valid Unicode code points that are not part of c-printable (YAML 1.2, sec.
// 5.1)
inline const RegEx& NotPrintable() {
static const RegEx e =
RegEx(0) ||
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) ||
RegEx(0x0E, 0x1F) ||
(RegEx('\xC2') + (RegEx('\x80', '\x84') || RegEx('\x86', '\x9F')));
RegEx(0) |
RegEx("\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C\x7F", REGEX_OR) |
RegEx(0x0E, 0x1F) |
(RegEx('\xC2') + (RegEx('\x80', '\x84') | RegEx('\x86', '\x9F')));
return e;
}
inline const RegEx& Utf8_ByteOrderMark() {
@ -82,19 +82,19 @@ inline const RegEx& Utf8_ByteOrderMark() {
// actual tags
inline const RegEx& DocStart() {
static const RegEx e = RegEx("---") + (BlankOrBreak() || RegEx());
static const RegEx e = RegEx("---") + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& DocEnd() {
static const RegEx e = RegEx("...") + (BlankOrBreak() || RegEx());
static const RegEx e = RegEx("...") + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& DocIndicator() {
static const RegEx e = DocStart() || DocEnd();
static const RegEx e = DocStart() | DocEnd();
return e;
}
inline const RegEx& BlockEntry() {
static const RegEx e = RegEx('-') + (BlankOrBreak() || RegEx());
static const RegEx e = RegEx('-') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& Key() {
@ -106,11 +106,11 @@ inline const RegEx& KeyInFlow() {
return e;
}
inline const RegEx& Value() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& ValueInFlow() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx(",}", REGEX_OR));
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx(",}", REGEX_OR));
return e;
}
inline const RegEx& ValueInJSONFlow() {
@ -122,20 +122,20 @@ inline const RegEx Comment() {
return e;
}
inline const RegEx& Anchor() {
static const RegEx e = !(RegEx("[]{},", REGEX_OR) || BlankOrBreak());
static const RegEx e = !(RegEx("[]{},", REGEX_OR) | BlankOrBreak());
return e;
}
inline const RegEx& AnchorEnd() {
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) || BlankOrBreak();
static const RegEx e = RegEx("?:,]}%@`", REGEX_OR) | BlankOrBreak();
return e;
}
inline const RegEx& URI() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) ||
static const RegEx e = Word() | RegEx("#;/?:@&=+$,_.!~*'()[]", REGEX_OR) |
(RegEx('%') + Hex() + Hex());
return e;
}
inline const RegEx& Tag() {
static const RegEx e = Word() || RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) ||
static const RegEx e = Word() | RegEx("#;/?:@&=+$_.~*'()", REGEX_OR) |
(RegEx('%') + Hex() + Hex());
return e;
}
@ -148,34 +148,34 @@ inline const RegEx& Tag() {
// space.
inline const RegEx& PlainScalar() {
static const RegEx e =
!(BlankOrBreak() || RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) ||
(RegEx("-?:", REGEX_OR) + (BlankOrBreak() || RegEx())));
!(BlankOrBreak() | RegEx(",[]{}#&*!|>\'\"%@`", REGEX_OR) |
(RegEx("-?:", REGEX_OR) + (BlankOrBreak() | RegEx())));
return e;
}
inline const RegEx& PlainScalarInFlow() {
static const RegEx e =
!(BlankOrBreak() || RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) ||
!(BlankOrBreak() | RegEx("?,[]{}#&*!|>\'\"%@`", REGEX_OR) |
(RegEx("-:", REGEX_OR) + Blank()));
return e;
}
inline const RegEx& EndScalar() {
static const RegEx e = RegEx(':') + (BlankOrBreak() || RegEx());
static const RegEx e = RegEx(':') + (BlankOrBreak() | RegEx());
return e;
}
inline const RegEx& EndScalarInFlow() {
static const RegEx e =
(RegEx(':') + (BlankOrBreak() || RegEx() || RegEx(",]}", REGEX_OR))) ||
(RegEx(':') + (BlankOrBreak() | RegEx() | RegEx(",]}", REGEX_OR))) |
RegEx(",?[]{}", REGEX_OR);
return e;
}
inline const RegEx& ScanScalarEndInFlow() {
static const RegEx e = (EndScalarInFlow() || (BlankOrBreak() + Comment()));
static const RegEx e = (EndScalarInFlow() | (BlankOrBreak() + Comment()));
return e;
}
inline const RegEx& ScanScalarEnd() {
static const RegEx e = EndScalar() || (BlankOrBreak() + Comment());
static const RegEx e = EndScalar() | (BlankOrBreak() + Comment());
return e;
}
inline const RegEx& EscSingleQuote() {
@ -192,8 +192,8 @@ inline const RegEx& ChompIndicator() {
return e;
}
inline const RegEx& Chomp() {
static const RegEx e = (ChompIndicator() + Digit()) ||
(Digit() + ChompIndicator()) || ChompIndicator() ||
static const RegEx e = (ChompIndicator() + Digit()) |
(Digit() + ChompIndicator()) | ChompIndicator() |
Digit();
return e;
}

View File

@ -22,8 +22,14 @@ node_data::node_data()
: m_isDefined(false),
m_mark(Mark::null_mark()),
m_type(NodeType::Null),
m_tag{},
m_style(EmitterStyle::Default),
m_seqSize(0) {}
m_scalar{},
m_sequence{},
m_seqSize(0),
m_map{},
m_undefinedPairs{}
{}
void node_data::mark_defined() {
if (m_type == NodeType::Undefined)
@ -238,8 +244,7 @@ bool node_data::remove(node& key, shared_memory_holder /* pMemory */) {
if (m_type != NodeType::Map)
return false;
kv_pairs::iterator it = m_undefinedPairs.begin();
while (it != m_undefinedPairs.end()) {
for(kv_pairs::iterator it = m_undefinedPairs.begin(); it != m_undefinedPairs.end();) {
kv_pairs::iterator jt = std::next(it);
if (it->first->is(key))
m_undefinedPairs.erase(it);

View File

@ -11,7 +11,13 @@ namespace YAML {
struct Mark;
NodeBuilder::NodeBuilder()
: m_pMemory(new detail::memory_holder), m_pRoot(nullptr), m_mapDepth(0) {
: m_pMemory(new detail::memory_holder),
m_pRoot(nullptr),
m_stack{},
m_anchors{},
m_keys{},
m_mapDepth(0)
{
m_anchors.push_back(nullptr); // since the anchors start at 1
}

View File

@ -27,6 +27,10 @@ class Node;
class NodeBuilder : public EventHandler {
public:
NodeBuilder();
NodeBuilder(const NodeBuilder&) = delete;
NodeBuilder(NodeBuilder&&) = delete;
NodeBuilder& operator=(const NodeBuilder&) = delete;
NodeBuilder& operator=(NodeBuilder&&) = delete;
virtual ~NodeBuilder();
Node Root();

View File

@ -20,7 +20,7 @@ anchor_t NodeEvents::AliasManager::LookupAnchor(
}
NodeEvents::NodeEvents(const Node& node)
: m_pMemory(node.m_pMemory), m_root(node.m_pNode) {
: m_pMemory(node.m_pMemory), m_root(node.m_pNode), m_refCount{} {
if (m_root)
Setup(*m_root);
}

View File

@ -26,13 +26,17 @@ class Node;
class NodeEvents {
public:
explicit NodeEvents(const Node& node);
NodeEvents(const NodeEvents&) = delete;
NodeEvents(NodeEvents&&) = delete;
NodeEvents& operator=(const NodeEvents&) = delete;
NodeEvents& operator=(NodeEvents&&) = delete;
void Emit(EventHandler& handler);
private:
class AliasManager {
public:
AliasManager() : m_curAnchor(0) {}
AliasManager() : m_anchorByIdentity{}, m_curAnchor(0) {}
void RegisterReference(const detail::node& node);
anchor_t LookupAnchor(const detail::node& node) const;

View File

@ -14,7 +14,7 @@ ostream_wrapper::ostream_wrapper()
m_comment(false) {}
ostream_wrapper::ostream_wrapper(std::ostream& stream)
: m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {}
: m_buffer{}, m_pStream(&stream), m_pos(0), m_row(0), m_col(0), m_comment(false) {}
ostream_wrapper::~ostream_wrapper() {}

View File

@ -11,9 +11,9 @@
namespace YAML {
class EventHandler;
Parser::Parser() {}
Parser::Parser() : m_pScanner{}, m_pDirectives{} {}
Parser::Parser(std::istream& in) { Load(in); }
Parser::Parser(std::istream& in) : Parser() { Load(in); }
Parser::~Parser() {}

View File

@ -20,7 +20,7 @@ namespace YAML {
template <typename T>
class ptr_vector : private YAML::noncopyable {
public:
ptr_vector() {}
ptr_vector() : m_data{} {}
void clear() { m_data.clear(); }

View File

@ -2,17 +2,19 @@
namespace YAML {
// constructors
RegEx::RegEx() : m_op(REGEX_EMPTY) {}
RegEx::RegEx(REGEX_OP op) : m_op(op) {}
RegEx::RegEx(REGEX_OP op) : m_op(op), m_a(0), m_z(0), m_params{} {}
RegEx::RegEx() : RegEx(REGEX_EMPTY) {}
RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch) {}
RegEx::RegEx(char ch) : m_op(REGEX_MATCH), m_a(ch), m_z(0), m_params{} {}
RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z) {}
RegEx::RegEx(char a, char z) : m_op(REGEX_RANGE), m_a(a), m_z(z), m_params{} {}
RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op) {
RegEx::RegEx(const std::string& str, REGEX_OP op) : m_op(op), m_a(0), m_z(0), m_params(str.begin(), str.end()) {
/*
for (std::size_t i = 0; i < str.size(); i++)
m_params.push_back(RegEx(str[i]));
*/
}
// combination constructors
@ -22,14 +24,14 @@ RegEx operator!(const RegEx& ex) {
return ret;
}
RegEx operator||(const RegEx& ex1, const RegEx& ex2) {
RegEx operator|(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_OR);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);
return ret;
}
RegEx operator&&(const RegEx& ex1, const RegEx& ex2) {
RegEx operator&(const RegEx& ex1, const RegEx& ex2) {
RegEx ret(REGEX_AND);
ret.m_params.push_back(ex1);
ret.m_params.push_back(ex2);

View File

@ -37,8 +37,8 @@ class YAML_CPP_API RegEx {
~RegEx() {}
friend YAML_CPP_API RegEx operator!(const RegEx& ex);
friend YAML_CPP_API RegEx operator||(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator&&(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator|(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator&(const RegEx& ex1, const RegEx& ex2);
friend YAML_CPP_API RegEx operator+(const RegEx& ex1, const RegEx& ex2);
bool Matches(char ch) const;

View File

@ -9,10 +9,16 @@
namespace YAML {
Scanner::Scanner(std::istream& in)
: INPUT(in),
m_tokens{},
m_startedStream(false),
m_endedStream(false),
m_simpleKeyAllowed(false),
m_canBeJSONFlow(false) {}
m_canBeJSONFlow(false),
m_simpleKeys{},
m_indents{},
m_indentRefs{},
m_flows{}
{}
Scanner::~Scanner() {}

View File

@ -338,7 +338,7 @@ void Scanner::ScanQuotedScalar() {
// setup the scanning parameters
ScanScalarParams params;
RegEx end = (single ? RegEx(quote) && !Exp::EscSingleQuote() : RegEx(quote));
RegEx end = (single ? RegEx(quote) & !Exp::EscSingleQuote() : RegEx(quote));
params.end = &end;
params.eatEnd = true;
params.escape = (single ? '\'' : '\\');

View File

@ -18,6 +18,9 @@ template <typename T>
class Setting {
public:
Setting() : m_value() {}
Setting(const T& value) : m_value() {
set(value);
}
const T get() const { return m_value; }
std::unique_ptr<SettingChangeBase> set(const T& value);
@ -34,12 +37,16 @@ class SettingChangeBase {
};
template <typename T>
class SettingChange : public SettingChangeBase {
class SettingChange : public SettingChangeBase, private noncopyable {
public:
SettingChange(Setting<T>* pSetting) : m_pCurSetting(pSetting) {
// copy old setting to save its state
m_oldSetting = *pSetting;
}
SettingChange(Setting<T>* pSetting) :
m_pCurSetting(pSetting),
m_oldSetting(*pSetting) // copy old setting to save its state
{}
SettingChange(const SettingChange&) = delete;
SettingChange(SettingChange&&) = delete;
SettingChange& operator=(const SettingChange&) = delete;
SettingChange& operator=(SettingChange&&) = delete;
virtual void pop() { m_pCurSetting->restore(m_oldSetting); }
@ -57,7 +64,7 @@ inline std::unique_ptr<SettingChangeBase> Setting<T>::set(const T& value) {
class SettingChanges : private noncopyable {
public:
SettingChanges() {}
SettingChanges() : m_settingChanges{} {}
~SettingChanges() { clear(); }
void clear() {

View File

@ -18,7 +18,9 @@ SingleDocParser::SingleDocParser(Scanner& scanner, const Directives& directives)
: m_scanner(scanner),
m_directives(directives),
m_pCollectionStack(new CollectionStack),
m_curAnchor(0) {}
m_anchors{},
m_curAnchor(0)
{}
SingleDocParser::~SingleDocParser() {}
@ -166,10 +168,10 @@ void SingleDocParser::HandleBlockSequence(EventHandler& eventHandler) {
// check for null
if (!m_scanner.empty()) {
const Token& token = m_scanner.peek();
if (token.type == Token::BLOCK_ENTRY ||
token.type == Token::BLOCK_SEQ_END) {
eventHandler.OnNull(token.mark, NullAnchor);
const Token& tnullcheck = m_scanner.peek();
if (tnullcheck.type == Token::BLOCK_ENTRY ||
tnullcheck.type == Token::BLOCK_SEQ_END) {
eventHandler.OnNull(tnullcheck.mark, NullAnchor);
continue;
}
}

View File

@ -192,9 +192,13 @@ inline void QueueUnicodeCodepoint(std::deque<char>& q, unsigned long ch) {
Stream::Stream(std::istream& input)
: m_input(input),
m_mark{},
m_charSet{},
m_readahead{},
m_pPrefetched(new unsigned char[YAML_PREFETCH_SIZE]),
m_nPrefetchedAvailable(0),
m_nPrefetchedUsed(0) {
m_nPrefetchedUsed(0)
{
typedef std::istream::traits_type char_traits;
if (!input)

View File

@ -22,6 +22,10 @@ class Stream : private noncopyable {
friend class StreamCharSource;
Stream(std::istream& input);
Stream(const Stream&) = delete;
Stream(Stream&&) = delete;
Stream& operator=(const Stream&) = delete;
Stream& operator=(Stream&&) = delete;
~Stream();
operator bool() const;

View File

@ -6,7 +6,7 @@
#include "token.h"
namespace YAML {
Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)) {
Tag::Tag(const Token& token) : type(static_cast<TYPE>(token.data)), handle{}, value{} {
switch (type) {
case VERBATIM:
value = token.value;

View File

@ -48,7 +48,7 @@ struct Token {
// data
Token(TYPE type_, const Mark& mark_)
: status(VALID), type(type_), mark(mark_), data(0) {}
: status(VALID), type(type_), mark(mark_), value{}, params{}, data(0) {}
friend std::ostream& operator<<(std::ostream& out, const Token& token) {
out << TokenNames[token.type] << std::string(": ") << token.value;

View File

@ -106,8 +106,8 @@ TEST(RegExTest, OperatorOr) {
for (int j = i + 1; j < 128; ++j) {
auto iStr = std::string(1, char(i));
auto jStr = std::string(1, char(j));
RegEx ex1 = RegEx(iStr) || RegEx(jStr);
RegEx ex2 = RegEx(jStr) || RegEx(iStr);
RegEx ex1 = RegEx(iStr) | RegEx(jStr);
RegEx ex2 = RegEx(jStr) | RegEx(iStr);
for (int k = MIN_CHAR; k < 128; ++k) {
auto str = std::string(1, char(k));
@ -128,8 +128,8 @@ TEST(RegExTest, OperatorOr) {
}
TEST(RegExTest, OperatorOrShortCircuits) {
RegEx ex1 = RegEx(std::string("aaaa")) || RegEx(std::string("aa"));
RegEx ex2 = RegEx(std::string("aa")) || RegEx(std::string("aaaa"));
RegEx ex1 = RegEx(std::string("aaaa")) | RegEx(std::string("aa"));
RegEx ex2 = RegEx(std::string("aa")) | RegEx(std::string("aaaa"));
EXPECT_TRUE(ex1.Matches(std::string("aaaaa")));
EXPECT_EQ(4, ex1.Match(std::string("aaaaa")));
@ -139,13 +139,13 @@ TEST(RegExTest, OperatorOrShortCircuits) {
}
TEST(RegExTest, OperatorAnd) {
RegEx emptySet = RegEx('a') && RegEx();
RegEx emptySet = RegEx('a') & RegEx();
EXPECT_FALSE(emptySet.Matches(std::string("a")));
}
TEST(RegExTest, OperatorAndShortCircuits) {
RegEx ex1 = RegEx(std::string("aaaa")) && RegEx(std::string("aa"));
RegEx ex2 = RegEx(std::string("aa")) && RegEx(std::string("aaaa"));
RegEx ex1 = RegEx(std::string("aaaa")) & RegEx(std::string("aa"));
RegEx ex2 = RegEx(std::string("aa")) & RegEx(std::string("aaaa"));
EXPECT_TRUE(ex1.Matches(std::string("aaaaa")));
EXPECT_EQ(4, ex1.Match(std::string("aaaaa")));