From 8e44b0957e185b47efa199dbadb06dc57113dbde Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sun, 20 Sep 2020 18:11:41 +0700 Subject: [PATCH 01/29] Fixed #4 implemented removeElement for map --- src/wsjcpp_yaml.cpp | 14 ++- src/wsjcpp_yaml.h | 19 ++++ unit-tests.wsjcpp/CMakeLists.txt | 9 +- .../src/unit_test_line_parser.cpp | 17 +++- unit-tests.wsjcpp/src/unit_test_line_parser.h | 14 --- .../src/unit_test_remove_element_for_map.cpp | 91 +++++++++++++++++++ .../src/unit_test_yaml_parser_all.cpp | 36 +++++--- .../src/unit_test_yaml_parser_all.h | 14 --- wsjcpp.yml | 3 +- 9 files changed, 164 insertions(+), 53 deletions(-) delete mode 100644 unit-tests.wsjcpp/src/unit_test_line_parser.h create mode 100644 unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_all.h diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 7b03a21..83c5236 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -82,6 +82,9 @@ WsjcppYamlItem::WsjcppYamlItem( // --------------------------------------------------------------------- WsjcppYamlItem::~WsjcppYamlItem() { + for (int i = 0; i < m_vObjects.size(); i++) { + delete m_vObjects[i]; + } m_vObjects.clear(); } @@ -249,7 +252,15 @@ bool WsjcppYamlItem::removeElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { WsjcppLog::throw_err(TAG, "removeElement: Element must be map"); } - // TODO erase + std::vector::iterator it; + for (it = m_vObjects.begin(); it != m_vObjects.end(); ++it) { + WsjcppYamlItem *pItem = *it; + if (pItem->getName() == sName) { + m_vObjects.erase(it); + delete pItem; + return true; + } + } return false; } @@ -431,6 +442,7 @@ bool WsjcppYamlItem::removeElement(int i) { std::vector::iterator it; for (it = m_vObjects.begin(); it != m_vObjects.end(); ++it) { if (*it == pItem) { + delete pItem; m_vObjects.erase(it); return true; } diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 445e328..61b6c4f 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -213,5 +213,24 @@ class WsjcppYaml { WsjcppYamlItem *m_pRoot; }; +// --------------------------------------------------------------------- + +/* +class WsjcppYamlCursor { + public: + WsjcppYamlCursor(WsjcppYaml *pYaml); + ~WsjcppYamlCursor(); + WsjcppYamlCursor(WsjcppYaml *pYaml, WsjcppYamlItem *pCurrentNode); + WsjcppYamlCursor &operator[](int idx) { + return WsjcppYamlCursor(pYaml, pYaml->getRoot()->getElement(idx)); // will be call destructor ? + } + WsjcppYamlCursor &operator[](const std::string &sName) { return *(getRoot()->getElement(sName)); } + + private: + WsjcppYaml *m_pYaml; + WsjcppYamlItem *m_pCurrentNode; +}; +*/ + #endif // WSJCPP_YAML_H diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index ec00433..2c43044 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -34,22 +34,15 @@ list (APPEND WSJCPP_SOURCES "../src/wsjcpp_yaml.h") # unit-tests list (APPEND WSJCPP_INCLUDE_DIRS "src") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_line_parser.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_line_parser.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_all.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp") -list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.h") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp") # required-libraries list (APPEND WSJCPP_LIBRARIES "-lpthread") diff --git a/unit-tests.wsjcpp/src/unit_test_line_parser.cpp b/unit-tests.wsjcpp/src/unit_test_line_parser.cpp index 08ccfe0..5b55e6b 100644 --- a/unit-tests.wsjcpp/src/unit_test_line_parser.cpp +++ b/unit-tests.wsjcpp/src/unit_test_line_parser.cpp @@ -1,8 +1,19 @@ -#include "unit_test_line_parser.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestLineParser + +class UnitTestLineParser : public WsjcppUnitTestBase { + public: + UnitTestLineParser(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestLineParser) UnitTestLineParser::UnitTestLineParser() @@ -13,7 +24,7 @@ UnitTestLineParser::UnitTestLineParser() // --------------------------------------------------------------------- bool UnitTestLineParser::doBeforeTest() { - // nothing + // do something before test return true; } @@ -84,6 +95,6 @@ void UnitTestLineParser::executeTest() { // --------------------------------------------------------------------- bool UnitTestLineParser::doAfterTest() { - // nothing + // do somethig after test return true; } \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_line_parser.h b/unit-tests.wsjcpp/src/unit_test_line_parser.h deleted file mode 100644 index e685ece..0000000 --- a/unit-tests.wsjcpp/src/unit_test_line_parser.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_LINE_PARSER_H -#define UNIT_TEST_LINE_PARSER_H - -#include - -class UnitTestLineParser : public WsjcppUnitTestBase { - public: - UnitTestLineParser(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_LINE_PARSER_H \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp new file mode 100644 index 0000000..5b84d15 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp @@ -0,0 +1,91 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestRemoveElementForMap + +class UnitTestRemoveElementForMap : public WsjcppUnitTestBase { + public: + UnitTestRemoveElementForMap(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestRemoveElementForMap) + +UnitTestRemoveElementForMap::UnitTestRemoveElementForMap() + : WsjcppUnitTestBase("UnitTestRemoveElementForMap") { +} + +// --------------------------------------------------------------------- + +bool UnitTestRemoveElementForMap::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestRemoveElementForMap::executeTest() { + + std::string sTestYaml = + "# Some comment 1\n" + "map1: \n" + " map11: \n" + " map111: \n" + " param1111: v1111\n" + " param1112: v1112\n" + " map112: \n" + " param1121: v1121\n" + " param1122: v1122\n" + " map113: \n" + " param1131: v1131\n" + " param1132: v1132\n" + " map12: \n" + " param121: v121\n" + " param122: v122\n" + " map123: \n" + " param1231: v1231\n" + " param1232: v1232\n" + "param2: v2 # some comment 2\n" + "\n" // empty line + ; + + WsjcppYaml yaml; + if (!compare("Error parsing", yaml.loadFromString(sTestYaml), true)) { + return; + } + + WsjcppYamlItem *pMap1 = yaml.getRoot()->getElement("map1"); + WsjcppYamlItem *pMap11 = pMap1->getElement("map11"); + + compare("has map111", pMap11->hasElement("map111"), true); + compare("has map112", pMap11->hasElement("map112"), true); + compare("has map113", pMap11->hasElement("map113"), true); + pMap11->removeElement("map112"); + + compare("has map111", pMap11->hasElement("map111"), true); + compare("has map112", pMap11->hasElement("map112"), false); + compare("has map113", pMap11->hasElement("map113"), true); + pMap11->removeElement("map111"); + + compare("has map111", pMap11->hasElement("map111"), false); + compare("has map112", pMap11->hasElement("map112"), false); + compare("has map113", pMap11->hasElement("map113"), true); + + compare("has map11", pMap1->hasElement("map11"), true); + yaml.getRoot()->getElement("map1")->removeElement("map11"); + compare("has map11", pMap1->hasElement("map11"), false); +} + +// --------------------------------------------------------------------- + +bool UnitTestRemoveElementForMap::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp index 0a11dba..f70af9a 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp @@ -1,9 +1,20 @@ -#include "unit_test_yaml_parser_all.h" +#include #include #include -#include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserAll + +class UnitTestYamlParserAll : public WsjcppUnitTestBase { + public: + UnitTestYamlParserAll(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserAll) UnitTestYamlParserAll::UnitTestYamlParserAll() @@ -14,7 +25,7 @@ UnitTestYamlParserAll::UnitTestYamlParserAll() // --------------------------------------------------------------------- bool UnitTestYamlParserAll::doBeforeTest() { - // nothing + // do something before test return true; } @@ -22,7 +33,7 @@ bool UnitTestYamlParserAll::doBeforeTest() { void UnitTestYamlParserAll::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "# Some comment 1\n" "test10: one\n" "test20: two # some comment 2\n" @@ -48,13 +59,14 @@ void UnitTestYamlParserAll::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + if (!compare("Error parsing", yaml.loadFromString(sTestYaml), true)) { return; } - std::string sSaved = ""; - if (yaml.saveToString(sSaved)) { - WsjcppLog::info(TAG, "\n>>>>\n" + sSaved); + std::string sSaved1 = ""; + if (!compare("Error saving", yaml.saveToString(sSaved1), true)) { + compare("yaml_saved 2-test", sSaved1, sTestYaml); + return; } WsjcppYamlItem *pItem = nullptr; @@ -83,15 +95,15 @@ void UnitTestYamlParserAll::executeTest() { pItem = yaml.getRoot()->getElement("map60")->getElement("test80"); compare("test80_comment", pItem->getValue(), "opa2"); - sSaved = ""; - if (compare("save yaml", yaml.saveToString(sSaved), true)) { - compare("yaml_save", sSaved, g_sTestYaml); + std::string sSaved2 = ""; + if (compare("saving yaml", yaml.saveToString(sSaved2), true)) { + compare("yaml_saved 1-2", sSaved1, sSaved2); } } // --------------------------------------------------------------------- bool UnitTestYamlParserAll::doAfterTest() { - // nothing + // do something after test return true; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.h deleted file mode 100644 index 2383eef..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_ALL_H -#define UNIT_TEST_YAML_PARSER_ALL_H - -#include - -class UnitTestYamlParserAll : public WsjcppUnitTestBase { - public: - UnitTestYamlParserAll(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_ALL_H \ No newline at end of file diff --git a/wsjcpp.yml b/wsjcpp.yml index be57f36..6160105 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -58,4 +58,5 @@ unit-tests: description: YamlParserAll - name: YamlParserArrayIncludedMap description: YamlParserArrayIncludedMap - + - name: "RemoveElementForMap" + description: "" From d1c76a7f40ee5223f80adb8db8e1dd1e62bbbfe9 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Mon, 21 Sep 2020 15:06:04 +0700 Subject: [PATCH 02/29] Fixed #3 Add test for removeElement and getLength (array) --- src/main.cpp | 5 +- src/wsjcpp_yaml.cpp | 82 +++++++++++++------ src/wsjcpp_yaml.h | 16 ++-- unit-tests.wsjcpp/CMakeLists.txt | 1 + .../src/unit_test_line_parser.cpp | 10 ++- .../src/unit_test_remove_element_for_map.cpp | 4 +- .../src/unit_test_remove_element_in_array.cpp | 73 +++++++++++++++++ .../src/unit_test_yaml_parser_all.cpp | 4 +- ...it_test_yaml_parser_array_included_map.cpp | 19 ++++- ...unit_test_yaml_parser_array_included_map.h | 14 ---- .../src/unit_test_yaml_parser_comments.cpp | 19 ++++- .../src/unit_test_yaml_parser_comments.h | 14 ---- ...unit_test_yaml_parser_hierarchical_map.cpp | 19 ++++- .../unit_test_yaml_parser_hierarchical_map.h | 14 ---- .../src/unit_test_yaml_parser_quotes.cpp | 19 ++++- .../src/unit_test_yaml_parser_quotes.h | 14 ---- .../unit_test_yaml_parser_simple_array.cpp | 19 ++++- .../src/unit_test_yaml_parser_simple_array.h | 14 ---- .../src/unit_test_yaml_parser_simple_map.cpp | 19 ++++- .../src/unit_test_yaml_parser_simple_map.h | 14 ---- wsjcpp.yml | 10 +-- 21 files changed, 253 insertions(+), 150 deletions(-) create mode 100644 unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.h delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.h delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.h delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.h delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.h delete mode 100644 unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.h diff --git a/src/main.cpp b/src/main.cpp index 8af3f86..bfc25a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,8 +15,9 @@ int main(int argc, char* argv[]) { WsjcppCore::makeDir(appLogPath); } WsjcppYaml yaml; - if (!yaml.loadFromFile("./wsjcpp.yml")) { - WsjcppLog::err(TAG, "Could not read data from file"); + std::string sError; + if (!yaml.loadFromFile("./wsjcpp.yml", sError)) { + WsjcppLog::err(TAG, "Could not read data from file: " + sError); return -1; } diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 83c5236..de01c46 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -575,7 +575,7 @@ std::string WsjcppYamlItem::getForLogFormat() { WsjcppYamlParsebleLine::WsjcppYamlParsebleLine(int nLine) { TAG = "WsjcppYamlParsebleLine(line:" + std::to_string(nLine) + ")"; - m_nLine = nLine; + m_nLineNumber = nLine; } // --------------------------------------------------------------------- @@ -588,7 +588,7 @@ WsjcppYamlParsebleLine::WsjcppYamlParsebleLine() // --------------------------------------------------------------------- int WsjcppYamlParsebleLine::getLineNumber() { - return m_nLine; + return m_nLineNumber; } // --------------------------------------------------------------------- @@ -617,6 +617,12 @@ std::string WsjcppYamlParsebleLine::getComment() { // --------------------------------------------------------------------- +bool WsjcppYamlParsebleLine::hasComment() { + return m_bHasComment; +} + +// --------------------------------------------------------------------- + std::string WsjcppYamlParsebleLine::getName() { return m_sName; } @@ -653,15 +659,29 @@ bool WsjcppYamlParsebleLine::isEmptyValue() { // --------------------------------------------------------------------- -void WsjcppYamlParsebleLine::parseLine(const std::string &sLine) { +bool WsjcppYamlParsebleLine::isEmptyLine() { + return m_bEmptyLine; +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sError) { // reset variables m_bArrayItem = false; m_sPrefix = ""; m_sComment = ""; m_sName = ""; m_sValue = ""; + m_bHasComment = false; m_bNameHasQuotes = false; m_bValueHasQuotes = false; + m_bEmptyLine = false; + std::string sLineTrim = sLine; + sLineTrim = WsjcppCore::trim(sLineTrim); + if (sLineTrim.length() == 0) { + m_bEmptyLine = true; + return true; + } WsjcppYamlParserLineStates state = WsjcppYamlParserLineStates::NO; for (int i = 0; i < sLine.length(); i++) { @@ -670,6 +690,7 @@ void WsjcppYamlParsebleLine::parseLine(const std::string &sLine) { m_sPrefix += c; } else if (c == '#' && (state == WsjcppYamlParserLineStates::NO || state == WsjcppYamlParserLineStates::VALUE)) { state = WsjcppYamlParserLineStates::COMMENT; + m_bHasComment = true; } else if (state == WsjcppYamlParserLineStates::COMMENT) { if (c != '\r') { m_sComment += c; @@ -714,7 +735,8 @@ void WsjcppYamlParsebleLine::parseLine(const std::string &sLine) { if (state == WsjcppYamlParserLineStates::STRING || state == WsjcppYamlParserLineStates::ESCAPING ) { - WsjcppLog::throw_err(TAG, "wrong format"); + sError = "Line has wrong format."; + return false; } // split name and value @@ -728,7 +750,7 @@ void WsjcppYamlParsebleLine::parseLine(const std::string &sLine) { } }*/ - WsjcppCore::trim(m_sName); + m_sName = WsjcppCore::trim(m_sName); if (m_sName.length() > 0 && m_sName[0] == '"') { m_bNameHasQuotes = true; m_sName = removeStringDoubleQuotes(m_sName); @@ -740,7 +762,8 @@ void WsjcppYamlParsebleLine::parseLine(const std::string &sLine) { m_sValue = removeStringDoubleQuotes(m_sValue); } - WsjcppCore::trim(m_sComment); + m_sComment = WsjcppCore::trim(m_sComment); + return true; } // --------------------------------------------------------------------- @@ -776,10 +799,13 @@ std::string WsjcppYamlParsebleLine::removeStringDoubleQuotes(const std::string & // WsjcppYamlParserStatus void WsjcppYamlParserStatus::logUnknownLine(const std::string &sPrefix) { - WsjcppLog::warn(sPrefix, "Unknown line (" + std::to_string(placeInFile.getNumberOfLine()) + "): '" + placeInFile.getLine() + "' \n" - + "Current Intent: " + std::to_string(nIntent) + "\n" - + "Current Item(line: " + std::to_string(pCurItem->getPlaceInFile().getNumberOfLine()) + "): '" + pCurItem->getPlaceInFile().getLine() + "'" - + "Current Item(filename: " + pCurItem->getPlaceInFile().getFilename() + "'" + WsjcppLog::warn(sPrefix, "\n" + " error:\n" + " desc: \"unknown_line\"\n" + " line_number: " + std::to_string(pCurItem->getPlaceInFile().getNumberOfLine()) + "\n" + " line: \"" + placeInFile.getLine() + "\"\n" + " intent: " + std::to_string(nIntent) + "\n" + " filename: \"" + pCurItem->getPlaceInFile().getFilename() + "\"" ); } @@ -788,6 +814,7 @@ void WsjcppYamlParserStatus::logUnknownLine(const std::string &sPrefix) { WsjcppYaml::WsjcppYaml() { m_pRoot = new WsjcppYamlItem(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_ITEM_MAP); + TAG = "WsjcppYaml"; } // --------------------------------------------------------------------- @@ -798,12 +825,12 @@ WsjcppYaml::~WsjcppYaml() { // --------------------------------------------------------------------- -bool WsjcppYaml::loadFromFile(const std::string &sFileName) { +bool WsjcppYaml::loadFromFile(const std::string &sFileName, std::string &sError) { std::string sTextContent; if (!WsjcppCore::readTextFile(sFileName, sTextContent)) { return false; } - return parse(sFileName, sTextContent); + return parse(sFileName, sTextContent, sError); } // --------------------------------------------------------------------- @@ -818,14 +845,8 @@ bool WsjcppYaml::saveToFile(const std::string &sFileName) { // --------------------------------------------------------------------- -bool WsjcppYaml::loadFromString(const std::string &sBuffer) { - return false; -} - -// --------------------------------------------------------------------- - -bool WsjcppYaml::loadFromString(std::string &sBuffer) { - return parse("", sBuffer); +bool WsjcppYaml::loadFromString(const std::string &sBufferName, const std::string &sBuffer, std::string &sError) { + return parse(sBufferName, sBuffer, sError); } // --------------------------------------------------------------------- @@ -864,7 +885,7 @@ std::vector WsjcppYaml::splitToLines(const std::string &sBuffer) { // --------------------------------------------------------------------- -bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer) { +bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError) { std::vector vLines = this->splitToLines(sBuffer); WsjcppYamlParserStatus st; st.pCurItem = m_pRoot; // TODO recreate again new root element @@ -877,25 +898,32 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer) // WsjcppLog::info(TAG, "Line(" + std::to_string(nLine) + ") '" + st.sLine + "'"); st.placeInFile.setNumberOfLine(nLine); st.line = WsjcppYamlParsebleLine(nLine); - st.line.parseLine(st.placeInFile.getLine()); + if (!st.line.parseLine(st.placeInFile.getLine(), sError)) { + return false; + } bool isEmptyName = st.line.isEmptyName(); bool isEmptyValue = st.line.isEmptyValue(); bool isArrayItem = st.line.isArrayItem(); int nLineIntent = st.line.getIntent(); int nDiffIntent = nLineIntent - st.nIntent; - - // TODO check comment - /*if (isEmptyName && isEmptyValue && isArrayItem) { + + if (st.line.isEmptyLine()) { + WsjcppYamlItem *pItem = new WsjcppYamlItem( + st.pCurItem, st.placeInFile, + WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY + ); + st.pCurItem->appendElement(pItem); continue; - }*/ + } while (nDiffIntent < 0) { st.pCurItem = st.pCurItem->getParent(); st.nIntent = st.nIntent - 2; nDiffIntent = nLineIntent - st.nIntent; if (st.pCurItem == nullptr) { - WsjcppLog::throw_err(TAG, "cur item is nullptr"); + sError = "Current item is nullptr"; + return false; } } diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 61b6c4f..5bbd931 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -144,18 +144,20 @@ class WsjcppYamlParsebleLine { int getIntent(); // prefix length bool isArrayItem(); std::string getComment(); + bool hasComment(); std::string getName(); bool hasNameDoubleQuotes(); bool isEmptyName(); std::string getValue(); bool hasValueDoubleQuotes(); bool isEmptyValue(); + bool isEmptyLine(); - void parseLine(const std::string &sLine); + bool parseLine(const std::string &sLine, std::string &sError); private: std::string TAG; - int m_nLine; + int m_nLineNumber; std::string m_sPrefix; bool m_bArrayItem; @@ -164,6 +166,8 @@ class WsjcppYamlParsebleLine { std::string m_sValue; bool m_bNameHasQuotes; bool m_bValueHasQuotes; + bool m_bHasComment; + bool m_bEmptyLine; std::string removeStringDoubleQuotes(const std::string &sValue); }; @@ -185,10 +189,9 @@ class WsjcppYaml { public: WsjcppYaml(); ~WsjcppYaml(); - bool loadFromFile(const std::string &sFileName); + bool loadFromFile(const std::string &sFileName, std::string &sError); bool saveToFile(const std::string &sFileName); - bool loadFromString(const std::string &sBuffer); - bool loadFromString(std::string &sBuffer); + bool loadFromString(const std::string &sBufferName, const std::string &sBuffer, std::string &sError); bool saveToString(std::string &sBuffer); WsjcppYamlItem *getRoot(); @@ -198,8 +201,9 @@ class WsjcppYaml { private: std::string TAG; + // TODO replace to WsjcppCore::split() std::vector splitToLines(const std::string &sBuffer); - bool parse(const std::string &sFileName, const std::string &sBuffer); + bool parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError); void process_sameIntent_hasName_emptyValue_arrayItem(WsjcppYamlParserStatus &st); void process_sameIntent_hasName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st); void process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserStatus &st); diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index 2c43044..6c78403 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -43,6 +43,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_comm list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp") # required-libraries list (APPEND WSJCPP_LIBRARIES "-lpthread") diff --git a/unit-tests.wsjcpp/src/unit_test_line_parser.cpp b/unit-tests.wsjcpp/src/unit_test_line_parser.cpp index 5b55e6b..fc5d5a0 100644 --- a/unit-tests.wsjcpp/src/unit_test_line_parser.cpp +++ b/unit-tests.wsjcpp/src/unit_test_line_parser.cpp @@ -77,11 +77,15 @@ void UnitTestLineParser::executeTest() { for (int i = 0; i < vTestLines.size(); i++) { LineTest test = vTestLines[i]; - + std::string tagline = "{line:" + std::to_string(test.nNumberOfTest) + ": '" + test.sLine + "'}"; + WsjcppYamlParsebleLine line(test.nNumberOfTest); - line.parseLine(test.sLine); + std::string sError; + if (!compare(tagline + ", parseLine", line.parseLine(test.sLine, sError), true)) { + WsjcppLog::err(tagline + ", parseLine", sError); + return; + } - std::string tagline = "{line:" + std::to_string(test.nNumberOfTest) + ": '" + test.sLine + "'}"; compare(tagline + ", prefix", line.getPrefix(), test.sPrefix); compare(tagline + ", arrayitem", line.isArrayItem(), test.isArrayItem); compare(tagline + ", name", line.getName(), test.sName); diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp index 5b84d15..c3f99b3 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp @@ -55,7 +55,9 @@ void UnitTestRemoveElementForMap::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("rm_elem_in_map", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp new file mode 100644 index 0000000..789632e --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp @@ -0,0 +1,73 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestRemoveElementInArray + +class UnitTestRemoveElementInArray : public WsjcppUnitTestBase { + public: + UnitTestRemoveElementInArray(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestRemoveElementInArray) + +UnitTestRemoveElementInArray::UnitTestRemoveElementInArray() + : WsjcppUnitTestBase("UnitTestRemoveElementInArray") { +} + +// --------------------------------------------------------------------- + +bool UnitTestRemoveElementInArray::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestRemoveElementInArray::executeTest() { + std::string sTestYaml = + "# Some comment 1\n" + " \n" + "arr1: \n" + "\n" + " - name: i1\n" + " var2: 2\n" + " - name: i2\n" + " - name: i3\n" + "\n" // empty line + ; + + WsjcppYaml yaml; + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("rm_elem_in_arr", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + + WsjcppYamlItem *pArr1 = yaml.getRoot()->getElement("arr1"); + compare("arr1 len", pArr1->getLength(), 3); + compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); + compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i2"); + compare("arr1 name2 ", pArr1->getElement(2)->getElement("name")->getValue(), "i3"); + + pArr1->removeElement(1); + + compare("arr1 len", pArr1->getLength(), 2); + compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); + compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i3"); +} + +// --------------------------------------------------------------------- + +bool UnitTestRemoveElementInArray::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp index f70af9a..9c52efe 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp @@ -59,7 +59,9 @@ void UnitTestYamlParserAll::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("parse_all", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp index 1467d64..7f2d0bd 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp @@ -1,8 +1,19 @@ -#include "unit_test_yaml_parser_array_included_map.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserArrayIncludedMap + +class UnitTestYamlParserArrayIncludedMap : public WsjcppUnitTestBase { + public: + UnitTestYamlParserArrayIncludedMap(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserArrayIncludedMap) UnitTestYamlParserArrayIncludedMap::UnitTestYamlParserArrayIncludedMap() @@ -21,7 +32,7 @@ bool UnitTestYamlParserArrayIncludedMap::doBeforeTest() { void UnitTestYamlParserArrayIncludedMap::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "#test array included map\n" "param1: none value1 # it's value for something # olala \n" "array-test2 : # some comment 2 \n" @@ -38,7 +49,9 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("map_in_array", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.h deleted file mode 100644 index 97cfbc1..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_ARRAY_INCLUDED_MAP_H -#define UNIT_TEST_YAML_PARSER_ARRAY_INCLUDED_MAP_H - -#include - -class UnitTestYamlParserArrayIncludedMap : public WsjcppUnitTestBase { - public: - UnitTestYamlParserArrayIncludedMap(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_ARRAY_INCLUDED_MAP_H \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp index b0ad677..74b2018 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp @@ -1,8 +1,19 @@ -#include "unit_test_yaml_parser_comments.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserComments + +class UnitTestYamlParserComments : public WsjcppUnitTestBase { + public: + UnitTestYamlParserComments(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserComments) UnitTestYamlParserComments::UnitTestYamlParserComments() @@ -21,7 +32,7 @@ bool UnitTestYamlParserComments::doBeforeTest() { void UnitTestYamlParserComments::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "# Some comment 1\n" "param1: value1 # comment 2 # comment\n" "param2: value2 # some \"comment 3\"\n" @@ -40,7 +51,9 @@ void UnitTestYamlParserComments::executeTest() { WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("comments", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.h deleted file mode 100644 index 0acc039..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_COMMENTS_H -#define UNIT_TEST_YAML_PARSER_COMMENTS_H - -#include - -class UnitTestYamlParserComments : public WsjcppUnitTestBase { - public: - UnitTestYamlParserComments(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_COMMENTS_H \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp index d218a4f..bb57a45 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp @@ -1,8 +1,19 @@ -#include "unit_test_yaml_parser_hierarchical_map.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserHierarchicalMap + +class UnitTestYamlParserHierarchicalMap : public WsjcppUnitTestBase { + public: + UnitTestYamlParserHierarchicalMap(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserHierarchicalMap) UnitTestYamlParserHierarchicalMap::UnitTestYamlParserHierarchicalMap() @@ -21,7 +32,7 @@ bool UnitTestYamlParserHierarchicalMap::doBeforeTest() { void UnitTestYamlParserHierarchicalMap::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "# Some comment 1\n" "map1: \n" " map11: \n" @@ -45,7 +56,9 @@ void UnitTestYamlParserHierarchicalMap::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("hard_map", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.h deleted file mode 100644 index f3b7541..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_HIERARCHICAL_MAP_H -#define UNIT_TEST_YAML_PARSER_HIERARCHICAL_MAP_H - -#include - -class UnitTestYamlParserHierarchicalMap : public WsjcppUnitTestBase { - public: - UnitTestYamlParserHierarchicalMap(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_HIERARCHICAL_MAP_H \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp index b913b9f..701f1bb 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp @@ -1,8 +1,19 @@ -#include "unit_test_yaml_parser_quotes.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserQuotes + +class UnitTestYamlParserQuotes : public WsjcppUnitTestBase { + public: + UnitTestYamlParserQuotes(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserQuotes) UnitTestYamlParserQuotes::UnitTestYamlParserQuotes() @@ -21,7 +32,7 @@ bool UnitTestYamlParserQuotes::doBeforeTest() { void UnitTestYamlParserQuotes::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "# Some comment 1\n" "param1: \"value1\" # v1\n" "param2: \" #$!!!value2\" # val 2\n" @@ -36,7 +47,9 @@ void UnitTestYamlParserQuotes::executeTest() { WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("parse_quotes", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.h deleted file mode 100644 index 21d379c..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_QUOTES_H -#define UNIT_TEST_YAML_PARSER_QUOTES_H - -#include - -class UnitTestYamlParserQuotes : public WsjcppUnitTestBase { - public: - UnitTestYamlParserQuotes(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_QUOTES_H \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp index 76d4013..c9233fc 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp @@ -1,8 +1,19 @@ -#include "unit_test_yaml_parser_simple_array.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserSimpleArray + +class UnitTestYamlParserSimpleArray : public WsjcppUnitTestBase { + public: + UnitTestYamlParserSimpleArray(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserSimpleArray) UnitTestYamlParserSimpleArray::UnitTestYamlParserSimpleArray() @@ -21,7 +32,7 @@ bool UnitTestYamlParserSimpleArray::doBeforeTest() { void UnitTestYamlParserSimpleArray::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "# simple array test\n" "param1: none value1 # it's value for something # olala \n" "array-test2 : # some comment 2 \n" @@ -37,7 +48,9 @@ void UnitTestYamlParserSimpleArray::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("parse_array", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.h deleted file mode 100644 index a9f29f7..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_SIMPLE_ARRAY_H -#define UNIT_TEST_YAML_PARSER_SIMPLE_ARRAY_H - -#include - -class UnitTestYamlParserSimpleArray : public WsjcppUnitTestBase { - public: - UnitTestYamlParserSimpleArray(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_SIMPLE_ARRAY_H \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp index 287ac6a..6607e78 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp @@ -1,8 +1,19 @@ -#include "unit_test_yaml_parser_simple_map.h" +#include #include #include #include +// --------------------------------------------------------------------- +// UnitTestYamlParserSimpleMap + +class UnitTestYamlParserSimpleMap : public WsjcppUnitTestBase { + public: + UnitTestYamlParserSimpleMap(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + REGISTRY_WSJCPP_UNIT_TEST(UnitTestYamlParserSimpleMap) UnitTestYamlParserSimpleMap::UnitTestYamlParserSimpleMap() @@ -21,7 +32,7 @@ bool UnitTestYamlParserSimpleMap::doBeforeTest() { void UnitTestYamlParserSimpleMap::executeTest() { - std::string g_sTestYaml = + std::string sTestYaml = "# Some comment 1\n" "param1: value1\n" "param2: value2 # some comment 2\n" @@ -29,7 +40,9 @@ void UnitTestYamlParserSimpleMap::executeTest() { ; WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromString(g_sTestYaml), true)) { + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("simple_map", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.h b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.h deleted file mode 100644 index 1f74d69..0000000 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef UNIT_TEST_YAML_PARSER_SIMPLE_MAP_H -#define UNIT_TEST_YAML_PARSER_SIMPLE_MAP_H - -#include - -class UnitTestYamlParserSimpleMap : public WsjcppUnitTestBase { - public: - UnitTestYamlParserSimpleMap(); - virtual bool doBeforeTest() override; - virtual void executeTest() override; - virtual bool doAfterTest() override; -}; - -#endif // UNIT_TEST_YAML_PARSER_SIMPLE_MAP_H \ No newline at end of file diff --git a/wsjcpp.yml b/wsjcpp.yml index 6160105..35815c1 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -1,37 +1,30 @@ wsjcpp_version: v0.0.1 cmake_minimum_required: 3.0 cmake_cxx_standard: 11 - name: wsjcpp-yaml version: v0.1.3 description: Read/Write yaml files issues: https://github.com/wsjcpp/wsjcpp-yaml/issues - repositories: - type: main url: "https://github.com/wsjcpp/wsjcpp-yaml" - keywords: - c++ - yaml - parser - reader - writer - authors: - name: Evgenii Sopov email: mrseakg@gmail.com - required-libraries: - pthread - dependencies: - name: "wsjcpp-core" version: "v0.2.1" url: "https://github.com/wsjcpp/wsjcpp-core:master" origin: "https://github.com/" installation-dir: "./src.wsjcpp/wsjcpp_core" - distribution: - source-file: src/wsjcpp_yaml.cpp target-file: wsjcpp_yaml.cpp @@ -39,7 +32,6 @@ distribution: - source-file: src/wsjcpp_yaml.h target-file: wsjcpp_yaml.h type: "source-code" - unit-tests: cases: - name: LineParser @@ -60,3 +52,5 @@ unit-tests: description: YamlParserArrayIncludedMap - name: "RemoveElementForMap" description: "" + - name: "RemoveElementInArray" + description: "" From de755936e63be78b385b6dc8eab1cec6ff364417 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Tue, 22 Sep 2020 01:31:49 +0700 Subject: [PATCH 03/29] Moved 'enum WsjcppYamlParserLineStates' to source file --- src/wsjcpp_yaml.cpp | 56 ++++++++++++++++++++++++++------------------- src/wsjcpp_yaml.h | 10 -------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index de01c46..456f417 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -665,6 +665,16 @@ bool WsjcppYamlParsebleLine::isEmptyLine() { // --------------------------------------------------------------------- +enum WsjcppYamlParserLineStates { + WSJCPP_YAML_PARSER_LINE_STATE_NO, + WSJCPP_YAML_PARSER_LINE_STATE_VALUE, + WSJCPP_YAML_PARSER_LINE_STATE_COMMENT, + WSJCPP_YAML_PARSER_LINE_STATE_STRING, + WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES, + WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES, + WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING +}; + bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sError) { // reset variables m_bArrayItem = false; @@ -683,57 +693,57 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE return true; } - WsjcppYamlParserLineStates state = WsjcppYamlParserLineStates::NO; + WsjcppYamlParserLineStates state = WSJCPP_YAML_PARSER_LINE_STATE_NO; for (int i = 0; i < sLine.length(); i++) { char c = sLine[i]; - if ((c == ' ' || c == '\t') && state == WsjcppYamlParserLineStates::NO) { + if ((c == ' ' || c == '\t') && state == WSJCPP_YAML_PARSER_LINE_STATE_NO) { m_sPrefix += c; - } else if (c == '#' && (state == WsjcppYamlParserLineStates::NO || state == WsjcppYamlParserLineStates::VALUE)) { - state = WsjcppYamlParserLineStates::COMMENT; + } else if (c == '#' && (state == WSJCPP_YAML_PARSER_LINE_STATE_NO || state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE)) { + state = WSJCPP_YAML_PARSER_LINE_STATE_COMMENT; m_bHasComment = true; - } else if (state == WsjcppYamlParserLineStates::COMMENT) { + } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_COMMENT) { if (c != '\r') { m_sComment += c; } - } else if (c == '-' && state == WsjcppYamlParserLineStates::NO) { + } else if (c == '-' && state == WSJCPP_YAML_PARSER_LINE_STATE_NO) { m_bArrayItem = true; - state = WsjcppYamlParserLineStates::VALUE; - } else if ((c != ' ' && c != '\t') && state == WsjcppYamlParserLineStates::NO) { - state = WsjcppYamlParserLineStates::VALUE; + state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; + } else if ((c != ' ' && c != '\t') && state == WSJCPP_YAML_PARSER_LINE_STATE_NO) { + state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; m_sValue += c; if (c == '"') { - state = WsjcppYamlParserLineStates::STRING; + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING; } - } else if (c == '"' && state == WsjcppYamlParserLineStates::VALUE) { - state = WsjcppYamlParserLineStates::STRING; + } else if (c == '"' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING; m_sValue += c; - } else if (c == '\\' && state == WsjcppYamlParserLineStates::STRING) { - state = WsjcppYamlParserLineStates::ESCAPING; + } else if (c == '\\' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING) { + state = WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING; m_sValue += c; - } else if (state == WsjcppYamlParserLineStates::ESCAPING) { - state = WsjcppYamlParserLineStates::STRING; + } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING) { + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING; m_sValue += c; - } else if (c == '"' && state == WsjcppYamlParserLineStates::STRING) { - state = WsjcppYamlParserLineStates::VALUE; + } else if (c == '"' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING) { + state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; m_sValue += c; - } else if (c == ':' && state == WsjcppYamlParserLineStates::VALUE) { + } else if (c == ':' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { if (m_sName.length() == 0) { m_sName = m_sValue; m_sValue = ""; // reset value it was param name } else { m_sValue += c; } - } else if (state == WsjcppYamlParserLineStates::STRING) { + } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_STRING) { m_sValue += c; - } else if (state == WsjcppYamlParserLineStates::VALUE) { + } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { m_sValue += c; } else { // skip } } - if (state == WsjcppYamlParserLineStates::STRING - || state == WsjcppYamlParserLineStates::ESCAPING + if (state == WSJCPP_YAML_PARSER_LINE_STATE_STRING + || state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING ) { sError = "Line has wrong format."; return false; diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 5bbd931..13bc9ee 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -124,16 +124,6 @@ class WsjcppYamlItem { // TODO: rename to node // --------------------------------------------------------------------- -enum WsjcppYamlParserLineStates { - NO, - VALUE, - COMMENT, - STRING, - ESCAPING -}; - -// --------------------------------------------------------------------- - class WsjcppYamlParsebleLine { public: WsjcppYamlParsebleLine(int nLine); From 7f9d90dc06f34a2450e95cabb7ff12824076301c Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Tue, 22 Sep 2020 02:31:04 +0700 Subject: [PATCH 04/29] Added support quotes single/double --- src/wsjcpp_yaml.cpp | 185 +++++++++++++----- src/wsjcpp_yaml.h | 44 +++-- .../src/unit_test_line_parser.cpp | 72 +++++-- .../src/unit_test_yaml_parser_quotes.cpp | 9 +- 4 files changed, 227 insertions(+), 83 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 456f417..379cb79 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -74,8 +74,8 @@ WsjcppYamlItem::WsjcppYamlItem( m_placeInFile.setLine(placeInFile.getLine()); m_placeInFile.setNumberOfLine(placeInFile.getNumberOfLine()); m_nItemType = nItemType; - m_bValueHasDoubleQuotes = false; - m_bNameHasDoubleQuotes = false; + m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; + m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; TAG = "WsjcppYamlNode"; } @@ -122,9 +122,9 @@ std::string WsjcppYamlItem::getComment() { // --------------------------------------------------------------------- -void WsjcppYamlItem::setName(const std::string &sName, bool bHasQuotes) { +void WsjcppYamlItem::setName(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { m_sName = sName; - m_bNameHasDoubleQuotes = bHasQuotes; + m_nNameQuotes = nNameQuotes; } // --------------------------------------------------------------------- @@ -135,8 +135,8 @@ std::string WsjcppYamlItem::getName() { // --------------------------------------------------------------------- -bool WsjcppYamlItem::hasNameDoubleQuotes() { - return m_bNameHasDoubleQuotes; +WsjcppYamlQuotes WsjcppYamlItem::getNameQuotes() { + return m_nNameQuotes; } // --------------------------------------------------------------------- @@ -283,7 +283,12 @@ std::vector WsjcppYamlItem::getKeys() { // --------------------------------------------------------------------- -bool WsjcppYamlItem::setElementValue(const std::string &sName, bool bHasNameQuotes, const std::string &sValue, bool bHasValueQuotes) { +bool WsjcppYamlItem::setElementValue( + const std::string &sName, + const std::string &sValue, + WsjcppYamlQuotes nNameQuotes, + WsjcppYamlQuotes nValueQuotes +) { if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { m_nItemType = WSJCPP_YAML_ITEM_MAP; // change item type to map on first element } @@ -294,12 +299,12 @@ bool WsjcppYamlItem::setElementValue(const std::string &sName, bool bHasNameQuot if (this->hasElement(sName)) { WsjcppYamlItem *pItem = this->getElement(sName); - pItem->setValue(sValue, bHasValueQuotes); + pItem->setValue(sValue, nValueQuotes); } else { WsjcppYamlPlaceInFile pl; WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE); - pNewItem->setName(sName, bHasNameQuotes); - pNewItem->setValue(sValue, bHasValueQuotes); + pNewItem->setName(sName, nNameQuotes); + pNewItem->setValue(sValue, nValueQuotes); this->setElement(sName, pNewItem); } return true; @@ -307,7 +312,7 @@ bool WsjcppYamlItem::setElementValue(const std::string &sName, bool bHasNameQuot // --------------------------------------------------------------------- -bool WsjcppYamlItem::createElementMap(const std::string &sName, bool bHasNameQuotes) { +bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_MAP ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } @@ -316,7 +321,7 @@ bool WsjcppYamlItem::createElementMap(const std::string &sName, bool bHasNameQuo } WsjcppYamlPlaceInFile pl; WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_MAP); - pNewItem->setName(sName, bHasNameQuotes); + pNewItem->setName(sName, nNameQuotes); this->setElement(sName, pNewItem); return true; } @@ -335,7 +340,7 @@ WsjcppYamlItem *WsjcppYamlItem::createElementMap() { // --------------------------------------------------------------------- -bool WsjcppYamlItem::createElementArray(const std::string &sName, bool bHasNameQuotes) { +bool WsjcppYamlItem::createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_MAP ) { WsjcppLog::throw_err(TAG, "createElementArray, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } @@ -344,7 +349,7 @@ bool WsjcppYamlItem::createElementArray(const std::string &sName, bool bHasNameQ } WsjcppYamlPlaceInFile pl; WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_ARRAY); - pNewItem->setName(sName, bHasNameQuotes); + pNewItem->setName(sName, nNameQuotes); this->setElement(sName, pNewItem); return true; } @@ -409,13 +414,13 @@ bool WsjcppYamlItem::appendElement(WsjcppYamlItem *pItem) { // --------------------------------------------------------------------- -bool WsjcppYamlItem::appendElementValue(const std::string &sValue, bool bHasValueQuotes) { +bool WsjcppYamlItem::appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY) { WsjcppLog::throw_err(TAG, "appendElementValue, Element must be array for " + this->getForLogFormat()); } WsjcppYamlPlaceInFile pl; WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE); - pNewItem->setValue(sValue, bHasValueQuotes); + pNewItem->setValue(sValue, nValueQuotes); return this->appendElement(pNewItem); } @@ -467,18 +472,18 @@ std::string WsjcppYamlItem::getValue() { // --------------------------------------------------------------------- -void WsjcppYamlItem::setValue(const std::string &sValue, bool bHasQuotes) { +void WsjcppYamlItem::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { WsjcppLog::throw_err(TAG, "setValue, Element must be value for " + this->getForLogFormat()); } - m_bValueHasDoubleQuotes = bHasQuotes; + m_nValueQuotes = nQuotes; m_sValue = sValue; } // --------------------------------------------------------------------- -bool WsjcppYamlItem::hasValueDoubleQuotes() { - return m_bValueHasDoubleQuotes; +WsjcppYamlQuotes WsjcppYamlItem::getValueQuotes() { + return m_nValueQuotes; } // --------------------------------------------------------------------- @@ -486,8 +491,10 @@ bool WsjcppYamlItem::hasValueDoubleQuotes() { std::string WsjcppYamlItem::toString(std::string sIntent) { std::string sRet = ""; if (this->isValue()) { - if (m_bValueHasDoubleQuotes) { + if (m_nValueQuotes == WSJCPP_YAML_QUOTES_DOUBLE) { sRet = "\"" + m_sValue + "\""; + } else if (m_nValueQuotes == WSJCPP_YAML_QUOTES_SINGLE) { + sRet = "\'" + m_sValue + "\'"; } else { sRet = m_sValue; } @@ -522,8 +529,10 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { sRet += sIntent + pItem->toString(); sRet += "\n"; } else if (pItem->isArray() || pItem->isMap()) { - if (pItem->hasNameDoubleQuotes()) { + if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { sRet += sIntent + "\"" + pItem->getName() + "\":"; + } else if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { + sRet += sIntent + "\'" + pItem->getName() + "\':"; } else { sRet += sIntent + pItem->getName() + ":"; } @@ -533,8 +542,10 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { sRet += "\n"; sRet += pItem->toString(sIntent + " "); } else { - if (pItem->hasNameDoubleQuotes()) { + if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { sRet += sIntent + "\"" + pItem->getName() + "\": " + pItem->toString(); + } else if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { + sRet += sIntent + "\'" + pItem->getName() + "\': " + pItem->toString(); } else { sRet += sIntent + pItem->getName() + ": " + pItem->toString(); } @@ -576,6 +587,15 @@ std::string WsjcppYamlItem::getForLogFormat() { WsjcppYamlParsebleLine::WsjcppYamlParsebleLine(int nLine) { TAG = "WsjcppYamlParsebleLine(line:" + std::to_string(nLine) + ")"; m_nLineNumber = nLine; + m_sPrefix = ""; + m_bArrayItem = false; + m_sComment = ""; + m_sName = ""; + m_sValue = ""; + m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; + m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; + m_bHasComment = false; + m_bEmptyLine = false; } // --------------------------------------------------------------------- @@ -629,8 +649,8 @@ std::string WsjcppYamlParsebleLine::getName() { // --------------------------------------------------------------------- -bool WsjcppYamlParsebleLine::hasNameDoubleQuotes() { - return m_bNameHasQuotes; +WsjcppYamlQuotes WsjcppYamlParsebleLine::getNameQuotes() { + return m_nNameQuotes; } // --------------------------------------------------------------------- @@ -647,8 +667,8 @@ std::string WsjcppYamlParsebleLine::getValue() { // --------------------------------------------------------------------- -bool WsjcppYamlParsebleLine::hasValueDoubleQuotes() { - return m_bValueHasQuotes; +WsjcppYamlQuotes WsjcppYamlParsebleLine::getValueQuotes() { + return m_nValueQuotes; } // --------------------------------------------------------------------- @@ -669,10 +689,10 @@ enum WsjcppYamlParserLineStates { WSJCPP_YAML_PARSER_LINE_STATE_NO, WSJCPP_YAML_PARSER_LINE_STATE_VALUE, WSJCPP_YAML_PARSER_LINE_STATE_COMMENT, - WSJCPP_YAML_PARSER_LINE_STATE_STRING, WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES, WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES, - WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING + WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_DOUBLE_QUOTES, + WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_SINGLE_QUOTES }; bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sError) { @@ -683,8 +703,8 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE m_sName = ""; m_sValue = ""; m_bHasComment = false; - m_bNameHasQuotes = false; - m_bValueHasQuotes = false; + m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; + m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; m_bEmptyLine = false; std::string sLineTrim = sLine; sLineTrim = WsjcppCore::trim(sLineTrim); @@ -712,18 +732,33 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; m_sValue += c; if (c == '"') { - state = WSJCPP_YAML_PARSER_LINE_STATE_STRING; + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES; + } + if (c == '\'') { + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES; } } else if (c == '"' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { - state = WSJCPP_YAML_PARSER_LINE_STATE_STRING; + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES; + m_sValue += c; + } else if (c == '\'' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES; + m_sValue += c; + } else if (c == '\\' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES) { + state = WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_DOUBLE_QUOTES; m_sValue += c; - } else if (c == '\\' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING) { - state = WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING; + } else if (c == '\\' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES) { + state = WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_SINGLE_QUOTES; m_sValue += c; - } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING) { - state = WSJCPP_YAML_PARSER_LINE_STATE_STRING; + } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_DOUBLE_QUOTES) { + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES; m_sValue += c; - } else if (c == '"' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING) { + } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_SINGLE_QUOTES) { + state = WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES; + m_sValue += c; + } else if (c == '"' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES) { + state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; + m_sValue += c; + } else if (c == '\'' && state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES) { state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; m_sValue += c; } else if (c == ':' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { @@ -733,7 +768,10 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE } else { m_sValue += c; } - } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_STRING) { + } else if ( + state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES + || state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES + ) { m_sValue += c; } else if (state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { m_sValue += c; @@ -742,8 +780,11 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE } } - if (state == WSJCPP_YAML_PARSER_LINE_STATE_STRING - || state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING + if ( + state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_DOUBLE_QUOTES + || state == WSJCPP_YAML_PARSER_LINE_STATE_STRING_SINGLE_QUOTES + || state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_DOUBLE_QUOTES + || state == WSJCPP_YAML_PARSER_LINE_STATE_ESCAPING_SINGLE_QUOTES ) { sError = "Line has wrong format."; return false; @@ -762,15 +803,23 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE m_sName = WsjcppCore::trim(m_sName); if (m_sName.length() > 0 && m_sName[0] == '"') { - m_bNameHasQuotes = true; + m_nNameQuotes = WSJCPP_YAML_QUOTES_DOUBLE; m_sName = removeStringDoubleQuotes(m_sName); } + if (m_sName.length() > 0 && m_sName[0] == '\'') { + m_nNameQuotes = WSJCPP_YAML_QUOTES_SINGLE; + m_sName = removeStringSingleQuotes(m_sName); + } - WsjcppCore::trim(m_sValue); + m_sValue = WsjcppCore::trim(m_sValue); if (m_sValue.length() > 0 && m_sValue[0] == '"') { - m_bValueHasQuotes = true; + m_nValueQuotes = WSJCPP_YAML_QUOTES_DOUBLE; m_sValue = removeStringDoubleQuotes(m_sValue); } + if (m_sValue.length() > 0 && m_sValue[0] == '\'') { + m_nValueQuotes = WSJCPP_YAML_QUOTES_SINGLE; + m_sValue = removeStringSingleQuotes(m_sValue); + } m_sComment = WsjcppCore::trim(m_sComment); return true; @@ -805,6 +854,36 @@ std::string WsjcppYamlParsebleLine::removeStringDoubleQuotes(const std::string & return sRet; } + +// --------------------------------------------------------------------- + +std::string WsjcppYamlParsebleLine::removeStringSingleQuotes(const std::string &sValue) { + if (sValue.size() > 0 && sValue[0] != '\'') { + return sValue; + } + int nStartPos = 1; + int nEndPos = sValue.size()-1; + std::string sRet = ""; + bool bEscape = false; + for (int i = nStartPos; i < nEndPos; i++) { + char c = sValue[i]; + if (bEscape) { + if (c == 'n') { + sRet += '\n'; + } else if (c == 'r') { + sRet += '\r'; + } else { + sRet += c; + } + } else if (c == '\\') { + bEscape = true; + } else { + sRet += c; + } + } + return sRet; +} + // --------------------------------------------------------------------- // WsjcppYamlParserStatus @@ -985,11 +1064,11 @@ void WsjcppYaml::process_sameIntent_hasName_emptyValue_noArrayItem(WsjcppYamlPar st.pCurItem, st.placeInFile, WsjcppYamlItemType::WSJCPP_YAML_ITEM_UNDEFINED ); - if (st.line.hasValueDoubleQuotes()) { + if (st.line.getValueQuotes() != WSJCPP_YAML_QUOTES_NONE) { pItem->doValue(); - pItem->setValue(st.line.getValue(), st.line.hasValueDoubleQuotes()); + pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); } - pItem->setName(st.line.getName(), st.line.hasNameDoubleQuotes()); + pItem->setName(st.line.getName(), st.line.getNameQuotes()); pItem->setComment(st.line.getComment()); st.pCurItem->setElement(st.line.getName(), pItem); st.pCurItem = pItem; @@ -1015,8 +1094,8 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE ); pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.hasValueDoubleQuotes()); - pItem->setName(st.line.getName(), st.line.hasNameDoubleQuotes()); + pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); + pItem->setName(st.line.getName(), st.line.getNameQuotes()); pMapItem->setElement(st.line.getName(), pItem); st.pCurItem = pItem; st.nIntent = st.nIntent + 2; @@ -1030,8 +1109,8 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_noArrayItem(WsjcppYamlParse WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE ); pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.hasValueDoubleQuotes()); - pItem->setName(st.line.getName(), st.line.hasNameDoubleQuotes()); + pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); + pItem->setName(st.line.getName(), st.line.getNameQuotes()); st.pCurItem->setElement(st.line.getName(), pItem); st.pCurItem = pItem; st.nIntent = st.nIntent + 2; @@ -1048,7 +1127,7 @@ void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem(WsjcppYamlParse WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE ); pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.hasValueDoubleQuotes()); + pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); st.pCurItem->appendElement(pItem); st.pCurItem = pItem; st.nIntent = st.nIntent + 2; @@ -1071,7 +1150,7 @@ void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlPar WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE ); pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.hasValueDoubleQuotes()); + pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); st.pCurItem->appendElement(pItem); st.pCurItem = pItem; st.nIntent = st.nIntent + 2; diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 13bc9ee..f5e1395 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -42,6 +42,15 @@ class WsjcppYamlPlaceInFile { std::string m_sLine; }; +// --------------------------------------------------------------------- +// WsjcppYamlQuotes + +enum WsjcppYamlQuotes { + WSJCPP_YAML_QUOTES_NONE, + WSJCPP_YAML_QUOTES_DOUBLE, + WSJCPP_YAML_QUOTES_SINGLE +}; + // --------------------------------------------------------------------- /*! \brief Class for keep data of yaml node @@ -65,9 +74,9 @@ class WsjcppYamlItem { // TODO: rename to node void setComment(const std::string &sComment); std::string getComment(); - void setName(const std::string &sName, bool bHasQuotes); + void setName(const std::string &sName, WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE); std::string getName(); - bool hasNameDoubleQuotes(); + WsjcppYamlQuotes getNameQuotes(); bool isEmpty(); void doEmpty(); @@ -84,22 +93,27 @@ class WsjcppYamlItem { // TODO: rename to node bool removeElement(const std::string &sName); std::vector getKeys(); - bool setElementValue(const std::string &sName, bool bHasNameQuotes, const std::string &sValue, bool bHasValueQuotes); - bool createElementMap(const std::string &sName, bool bHasNameQuotes); + bool setElementValue( + const std::string &sName, + const std::string &sValue, + WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, + WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE + ); + bool createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes); WsjcppYamlItem *createElementMap(); - bool createElementArray(const std::string &sName, bool bHasNameQuotes); + bool createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes); bool isArray(); int getLength(); WsjcppYamlItem *getElement(int i); bool appendElement(WsjcppYamlItem *pItem); - bool appendElementValue(const std::string &sValue, bool bHasValueQuotes); + bool appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE); bool removeElement(int i); bool isValue(); std::string getValue(); - void setValue(const std::string &sValue, bool bHasQuotes); - bool hasValueDoubleQuotes(); + void setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes = WSJCPP_YAML_QUOTES_NONE); + WsjcppYamlQuotes getValueQuotes(); std::string toString(std::string sIntent = ""); std::string getItemTypeAsString(); @@ -116,9 +130,10 @@ class WsjcppYamlItem { // TODO: rename to node WsjcppYamlItemType m_nItemType; std::vector m_vObjects; std::string m_sValue; // if it is not array or map - bool m_bValueHasDoubleQuotes; + WsjcppYamlQuotes m_nValueQuotes; std::string m_sName; - bool m_bNameHasDoubleQuotes; + WsjcppYamlQuotes m_nNameQuotes; + std::string m_sComment; }; @@ -136,10 +151,10 @@ class WsjcppYamlParsebleLine { std::string getComment(); bool hasComment(); std::string getName(); - bool hasNameDoubleQuotes(); + WsjcppYamlQuotes getNameQuotes(); bool isEmptyName(); std::string getValue(); - bool hasValueDoubleQuotes(); + WsjcppYamlQuotes getValueQuotes(); bool isEmptyValue(); bool isEmptyLine(); @@ -154,12 +169,13 @@ class WsjcppYamlParsebleLine { std::string m_sComment; std::string m_sName; std::string m_sValue; - bool m_bNameHasQuotes; - bool m_bValueHasQuotes; + WsjcppYamlQuotes m_nNameQuotes; + WsjcppYamlQuotes m_nValueQuotes; bool m_bHasComment; bool m_bEmptyLine; std::string removeStringDoubleQuotes(const std::string &sValue); + std::string removeStringSingleQuotes(const std::string &sValue); }; // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_line_parser.cpp b/unit-tests.wsjcpp/src/unit_test_line_parser.cpp index fc5d5a0..9dca9ca 100644 --- a/unit-tests.wsjcpp/src/unit_test_line_parser.cpp +++ b/unit-tests.wsjcpp/src/unit_test_line_parser.cpp @@ -38,18 +38,18 @@ void UnitTestLineParser::executeTest() { std::string sPrefix, bool isArrayItem, std::string sName, - bool bNameHasQuotes, + WsjcppYamlQuotes nNameQuotes, std::string sValue, - bool bValueHasQuotes, + WsjcppYamlQuotes nValueQuotes, std::string sComment ) : nNumberOfTest(nNumberOfTest), sLine(sLine), sPrefix(sPrefix), isArrayItem(isArrayItem), sName(sName), - bNameHasQuotes(bNameHasQuotes), + nNameQuotes(nNameQuotes), sValue(sValue), - bValueHasQuotes(bValueHasQuotes), + nValueQuotes(nValueQuotes), sComment(sComment) { // @@ -59,21 +59,63 @@ void UnitTestLineParser::executeTest() { std::string sPrefix; bool isArrayItem; std::string sName; - bool bNameHasQuotes; + WsjcppYamlQuotes nNameQuotes; std::string sValue; - bool bValueHasQuotes; + WsjcppYamlQuotes nValueQuotes; std::string sComment; }; std::vector vTestLines; - vTestLines.push_back(LineTest(1, "# Some comment 1 ", "", false, "", false, "", false, "Some comment 1")); - vTestLines.push_back(LineTest(2, " test2: \"t\\\"wo\" # some comment 2 ", " ", false, "test2", false, "t\"wo", true, "some comment 2")); - vTestLines.push_back(LineTest(3, " test3:", " ", false, "test3", false, "", false, "")); - vTestLines.push_back(LineTest(4, " - test4", " ", true, "", false, "test4", false, "")); - vTestLines.push_back(LineTest(5, "", "", false, "", false, "", false, "")); - vTestLines.push_back(LineTest(6, " - \"test4:111\"", " ", true, "", false, "test4:111", true, "")); - vTestLines.push_back(LineTest(7, "issues: https://github.com/wsjcpp/wsjcpp-yaml/issues", "", false, "issues", false, "https://github.com/wsjcpp/wsjcpp-yaml/issues", false, "")); + vTestLines.push_back(LineTest(1, + "# Some comment 1 ", "", + false, // array node + "", WSJCPP_YAML_QUOTES_NONE, // name + "", WSJCPP_YAML_QUOTES_NONE, // value + "Some comment 1" // comment + )); + vTestLines.push_back(LineTest(2, + " test2: \"t\\\"wo\" # some comment 2 ", " ", + false, // array node + "test2", WSJCPP_YAML_QUOTES_NONE, // name + "t\"wo", WSJCPP_YAML_QUOTES_DOUBLE, // value + "some comment 2" // comment + )); + vTestLines.push_back(LineTest(3, + " test3:", " ", + false, // array node + "test3", WSJCPP_YAML_QUOTES_NONE, // name + "", WSJCPP_YAML_QUOTES_NONE, // value + "" // comment + )); + vTestLines.push_back(LineTest(4, + " - test4", " ", + true, // array node + "", WSJCPP_YAML_QUOTES_NONE, // name + "test4", WSJCPP_YAML_QUOTES_NONE, // value + "" // comment + )); + vTestLines.push_back(LineTest(5, + "", "", + false, // array node + "", WSJCPP_YAML_QUOTES_NONE, // name + "", WSJCPP_YAML_QUOTES_NONE, // value + "" // comment + )); + vTestLines.push_back(LineTest(6, + " - \"test4:111\"", " ", + true, // array node + "", WSJCPP_YAML_QUOTES_NONE, // name + "test4:111", WSJCPP_YAML_QUOTES_DOUBLE, // value + "" // comment + )); + vTestLines.push_back(LineTest(7, + "issues: https://github.com/wsjcpp/wsjcpp-yaml/issues", "", + false, // array node + "issues", WSJCPP_YAML_QUOTES_NONE, // name + "https://github.com/wsjcpp/wsjcpp-yaml/issues", WSJCPP_YAML_QUOTES_NONE, // value + "" // comment + )); for (int i = 0; i < vTestLines.size(); i++) { LineTest test = vTestLines[i]; @@ -89,9 +131,9 @@ void UnitTestLineParser::executeTest() { compare(tagline + ", prefix", line.getPrefix(), test.sPrefix); compare(tagline + ", arrayitem", line.isArrayItem(), test.isArrayItem); compare(tagline + ", name", line.getName(), test.sName); - compare(tagline + ", name-has-quotes", line.hasNameDoubleQuotes(), test.bNameHasQuotes); + compare(tagline + ", name-has-quotes", line.getNameQuotes(), test.nNameQuotes); compare(tagline + ", value", line.getValue(), test.sValue); - compare(tagline + ", value-has-quotes", line.hasValueDoubleQuotes(), test.bValueHasQuotes); + compare(tagline + ", value-quotes", line.getValueQuotes(), test.nValueQuotes); compare(tagline + ", comment", line.getComment(), test.sComment); } } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp index 701f1bb..33bfb49 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp @@ -37,6 +37,8 @@ void UnitTestYamlParserQuotes::executeTest() { "param1: \"value1\" # v1\n" "param2: \" #$!!!value2\" # val 2\n" "\" param3 olala\" : val 3 # val 3*** \n" + "param4: ' #$!!!value4' # val 4\n" + "'param5 aha': ' #$!!!value5' # val 5\n" "url: \"https://github.com/wsjcpp/wsjcpp-yaml\"\n" "issues: https://github.com/wsjcpp/wsjcpp-yaml/issues\n" "empty: \"\"\n" @@ -64,6 +66,9 @@ void UnitTestYamlParserQuotes::executeTest() { compare(" param3 olala", yaml[" param3 olala"].getValue(), "val 3"); compare(" param3 olala", yaml[" param3 olala"].getComment(), "val 3***"); + compare("param4 val", yaml["param4"].getValue(), " #$!!!value4"); + compare("param4 comment", yaml["param4"].getValue(), " #$!!!value4"); + compare("url-value", yaml["url"].getValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); compare("issues-value", yaml["issues"].getValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); compare("empty-value", yaml["empty"].getValue(), ""); @@ -77,12 +82,14 @@ void UnitTestYamlParserQuotes::executeTest() { "param1: \"value1\" # v1\n" "param2: \" #$!!!value2\" # val 2\n" "\" param3 olala\": val 3 # val 3***\n" + "param4: ' #$!!!value4' # val 4\n" + "'param5 aha': ' #$!!!value5' # val 5\n" "url: \"https://github.com/wsjcpp/wsjcpp-yaml\"\n" "issues: https://github.com/wsjcpp/wsjcpp-yaml/issues\n" "empty: \"\"\n" "array:\n" " - \"https://github.com/wsjcpp/wsjcpp-core:v0.0.1\"" - ); + ); } // --------------------------------------------------------------------- From 0b57a8087c06ef1df26496a247e7706a91236f63 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Tue, 22 Sep 2020 14:40:08 +0700 Subject: [PATCH 05/29] Fixed #13 Added unit-tests for memory leaks --- src.wsjcpp/CMakeLists.txt | 5 +- unit-tests.wsjcpp/CMakeLists.txt | 14 +-- .../data-tests/for-memory-leak/some.yml | 61 ++++++++++ .../src/unit_test_memory_leaks.cpp | 115 ++++++++++++++++++ .../src/unit_test_remove_element_for_map.cpp | 1 - wsjcpp.yml | 7 +- 6 files changed, 184 insertions(+), 19 deletions(-) create mode 100644 unit-tests.wsjcpp/data-tests/for-memory-leak/some.yml create mode 100644 unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp diff --git a/src.wsjcpp/CMakeLists.txt b/src.wsjcpp/CMakeLists.txt index c168c43..ec5b1de 100644 --- a/src.wsjcpp/CMakeLists.txt +++ b/src.wsjcpp/CMakeLists.txt @@ -1,4 +1,4 @@ -# Automaticly generated by wsjcpp@v0.1.7 +# Automaticly generated by wsjcpp@v0.2.0 cmake_minimum_required(VERSION 3.0) add_definitions(-DWSJCPP_APP_VERSION="v0.1.3") @@ -22,7 +22,4 @@ list (APPEND WSJCPP_INCLUDE_DIRS "./src.wsjcpp/wsjcpp_core/") list (APPEND WSJCPP_SOURCES "./src.wsjcpp/wsjcpp_core/wsjcpp_core.cpp") list (APPEND WSJCPP_SOURCES "./src.wsjcpp/wsjcpp_core/wsjcpp_core.h") -# required-libraries -list (APPEND WSJCPP_LIBRARIES "-lpthread") - diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index 6c78403..305a6b6 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -1,4 +1,4 @@ -# Automaticly generated by wsjcpp@v0.1.7 +# Automaticly generated by wsjcpp@v0.2.0 cmake_minimum_required(VERSION 3.0) project(unit-tests C CXX) @@ -44,9 +44,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_all. list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp") - -# required-libraries -list (APPEND WSJCPP_LIBRARIES "-lpthread") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) @@ -57,11 +55,3 @@ add_executable ("unit-tests" ${WSJCPP_SOURCES}) target_link_libraries("unit-tests" -lpthread ${WSJCPP_LIBRARIES} ) -install( - TARGETS - "unit-tests" - RUNTIME DESTINATION - /usr/bin -) - - diff --git a/unit-tests.wsjcpp/data-tests/for-memory-leak/some.yml b/unit-tests.wsjcpp/data-tests/for-memory-leak/some.yml new file mode 100644 index 0000000..123edfc --- /dev/null +++ b/unit-tests.wsjcpp/data-tests/for-memory-leak/some.yml @@ -0,0 +1,61 @@ +# example yaml for test memeoty leak +doe: "a deer, a female deer" +ray: "a drop of golden sun" +pi: 3.14159 +xmas: true +french-hens: 3 +calling-birds: + - huey + - dewey + - louie + - fred +xmas-fifth-day: + calling-birds: four + french-hens: 3 + golden-rings: 5 + partridges: + count: 1 + location: "a pear tree" + turtle-doves: two + +# example yaml again +again0: + doe: "a deer, a female deer" + ray: "a drop of golden sun" + pi: 3.14159 + xmas: true + french-hens: 3 + calling-birds: + - huey + - dewey + - louie + - fred + xmas-fifth-day: + calling-birds: four + french-hens: 3 + golden-rings: 5 + partridges: + count: 1 + location: "a pear tree" + turtle-doves: two + +# example yaml again2 +again2: + doe: "a deer, a female deer" + ray: "a drop of golden sun" + pi: 3.14159 + xmas: true + french-hens: 3 + calling-birds: + - huey + - dewey + - louie + - fred + xmas-fifth-day: + calling-birds: four + french-hens: 3 + golden-rings: 5 + partridges: + count: 1 + location: "a pear tree" + turtle-doves: two \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp new file mode 100644 index 0000000..62df2ae --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp @@ -0,0 +1,115 @@ + +#include +#include +#include +#include +#include +#include +#include +#include + +////////////////////////////////////////////////////////////////////////////// +// +// process_mem_usage(double &, double &) - takes two doubles by reference, +// attempts to read the system-dependent data for a process' virtual memory +// size and resident set size, and return the results in KB. +// +// On failure, returns 0.0, 0.0 + +void process_mem_usage(double& vm_usage, double& resident_set) +{ + using std::ios_base; + using std::ifstream; + using std::string; + + vm_usage = 0.0; + resident_set = 0.0; + + // 'file' stat seems to give the most reliable results + // + ifstream stat_stream("/proc/self/stat",ios_base::in); + + // dummy vars for leading entries in stat that we don't care about + // + string pid, comm, state, ppid, pgrp, session, tty_nr; + string tpgid, flags, minflt, cminflt, majflt, cmajflt; + string utime, stime, cutime, cstime, priority, nice; + string O, itrealvalue, starttime; + + // the two fields we want + // + unsigned long vsize; + long rss; + + stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr + >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt + >> utime >> stime >> cutime >> cstime >> priority >> nice + >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest + + stat_stream.close(); + + long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages + vm_usage = vsize / 1024.0; + resident_set = rss * page_size_kb; +} + +// --------------------------------------------------------------------- +// UnitTestMemoryLeaks + +class UnitTestMemoryLeaks : public WsjcppUnitTestBase { + public: + UnitTestMemoryLeaks(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestMemoryLeaks) + +UnitTestMemoryLeaks::UnitTestMemoryLeaks() + : WsjcppUnitTestBase("UnitTestMemoryLeaks") { +} + +// --------------------------------------------------------------------- + +bool UnitTestMemoryLeaks::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestMemoryLeaks::executeTest() { + double nBeforeVm, nBeforeRss; + process_mem_usage(nBeforeVm, nBeforeRss); + // std::cout << "nBeforeVm: " << nBeforeVm << std::endl; + // std::cout << "nBeforeRss: " << nBeforeRss << std::endl; + compare("memory vm not null", (int)nBeforeVm > 0, true); + compare("memory vm not null", (int)nBeforeRss > 0, true); + + for (int i = 0; i < 1000; i++) { + WsjcppYaml *pYaml = new WsjcppYaml(); + std::string sError; + if (!compare("Error parsing", pYaml->loadFromFile("./data-tests/for-memory-leak/some.yml", sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + delete pYaml; + } + + double nAfterVm, nAfterRss; + process_mem_usage(nAfterVm, nAfterRss); + // std::cout << "nAfterVm: " << nAfterVm << std::endl; + // std::cout << "nAfterRss: " << nAfterRss << std::endl; + compare("memory vm", (int)nAfterVm, (int)nBeforeVm); + compare("memory rss", (int)nAfterRss, (int)nBeforeRss); +} + +// --------------------------------------------------------------------- + +bool UnitTestMemoryLeaks::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp index c3f99b3..f94723c 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp @@ -30,7 +30,6 @@ bool UnitTestRemoveElementForMap::doBeforeTest() { // --------------------------------------------------------------------- void UnitTestRemoveElementForMap::executeTest() { - std::string sTestYaml = "# Some comment 1\n" "map1: \n" diff --git a/wsjcpp.yml b/wsjcpp.yml index 35815c1..b9c9e80 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -17,14 +17,14 @@ keywords: authors: - name: Evgenii Sopov email: mrseakg@gmail.com -required-libraries: - - pthread + dependencies: - name: "wsjcpp-core" version: "v0.2.1" url: "https://github.com/wsjcpp/wsjcpp-core:master" origin: "https://github.com/" installation-dir: "./src.wsjcpp/wsjcpp_core" + distribution: - source-file: src/wsjcpp_yaml.cpp target-file: wsjcpp_yaml.cpp @@ -32,6 +32,7 @@ distribution: - source-file: src/wsjcpp_yaml.h target-file: wsjcpp_yaml.h type: "source-code" + unit-tests: cases: - name: LineParser @@ -54,3 +55,5 @@ unit-tests: description: "" - name: "RemoveElementInArray" description: "" + - name: "MemoryLeaks" + description: "" From 95eae42f3e740802c06b7287ccfa13bfd14abbdf Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 14:47:52 +0700 Subject: [PATCH 06/29] Fixed #12 Added unit-test for read yml like docker-compose samples --- unit-tests.wsjcpp/CMakeLists.txt | 1 + .../example-voiting-app/docker-compose.yml | 61 +++++++++++++++++++ .../src/unit_test_memory_leaks.cpp | 15 +++-- unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 58 ++++++++++++++++++ wsjcpp.yml | 2 + 5 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 unit-tests.wsjcpp/data-tests/read-file/example-voiting-app/docker-compose.yml create mode 100644 unit-tests.wsjcpp/src/unit_test_read_yaml.cpp diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index 305a6b6..ef92f8e 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -45,6 +45,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_yaml_parser_arra list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_yaml.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) diff --git a/unit-tests.wsjcpp/data-tests/read-file/example-voiting-app/docker-compose.yml b/unit-tests.wsjcpp/data-tests/read-file/example-voiting-app/docker-compose.yml new file mode 100644 index 0000000..0a02219 --- /dev/null +++ b/unit-tests.wsjcpp/data-tests/read-file/example-voiting-app/docker-compose.yml @@ -0,0 +1,61 @@ +# https://github.com/dockersamples/example-voting-app/blob/master/docker-compose.yml + +version: "3" + +services: + vote: + build: ./vote + command: python app.py + volumes: + - ./vote:/app + ports: + - "5000:80" + networks: + - front-tier + - back-tier + + result: + build: ./result + command: nodemon server.js + volumes: + - ./result:/app + ports: + - "5001:80" + - "5858:5858" + networks: + - front-tier + - back-tier + + worker: + build: + context: ./worker + depends_on: + - "redis" + - "db" + networks: + - back-tier + + redis: + image: redis:alpine + container_name: redis + ports: ["6379"] + networks: + - back-tier + + db: + image: postgres:9.4 + container_name: db + environment: + POSTGRES_USER: "postgres" + POSTGRES_PASSWORD: "postgres" + volumes: + - "db-data:/var/lib/postgresql/data" + networks: + - back-tier + +volumes: + db-data: + +networks: + front-tier: + back-tier: diff --git a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp index 62df2ae..f1c040a 100644 --- a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp +++ b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include ////////////////////////////////////////////////////////////////////////////// // @@ -81,6 +83,10 @@ bool UnitTestMemoryLeaks::doBeforeTest() { void UnitTestMemoryLeaks::executeTest() { double nBeforeVm, nBeforeRss; + double nAfterVm, nAfterRss; + std::string sFilepath = "./data-tests/for-memory-leak/some.yml"; + std::string sError; + process_mem_usage(nBeforeVm, nBeforeRss); // std::cout << "nBeforeVm: " << nBeforeVm << std::endl; // std::cout << "nBeforeRss: " << nBeforeRss << std::endl; @@ -88,16 +94,13 @@ void UnitTestMemoryLeaks::executeTest() { compare("memory vm not null", (int)nBeforeRss > 0, true); for (int i = 0; i < 1000; i++) { - WsjcppYaml *pYaml = new WsjcppYaml(); - std::string sError; - if (!compare("Error parsing", pYaml->loadFromFile("./data-tests/for-memory-leak/some.yml", sError), true)) { + WsjcppYaml yaml; + if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { WsjcppLog::err(TAG, sError); return; } - delete pYaml; } - - double nAfterVm, nAfterRss; + // std::this_thread::sleep_for(std::chrono::seconds(1)); process_mem_usage(nAfterVm, nAfterRss); // std::cout << "nAfterVm: " << nAfterVm << std::endl; // std::cout << "nAfterRss: " << nAfterRss << std::endl; diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp new file mode 100644 index 0000000..1e9f3f4 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -0,0 +1,58 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestReadYaml + +class UnitTestReadYaml : public WsjcppUnitTestBase { + public: + UnitTestReadYaml(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestReadYaml) + +UnitTestReadYaml::UnitTestReadYaml() + : WsjcppUnitTestBase("UnitTestReadYaml") { +} + +// --------------------------------------------------------------------- + +bool UnitTestReadYaml::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestReadYaml::executeTest() { + WsjcppYaml yaml; + std::string sFilepath = "./data-tests/read-file/example-voiting-app/docker-compose.yml"; + std::string sError; + if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + compare("has version", yaml.getRoot()->hasElement("version"), true); + compare("has volumes", yaml.getRoot()->hasElement("volumes"), true); + compare("has networks", yaml.getRoot()->hasElement("networks"), true); + compare("has services", yaml.getRoot()->hasElement("services"), true); + + compare("version-value", yaml.getRoot()->getElement("version")->getValue(), "3"); + + // TODO unit test source code here +} + +// --------------------------------------------------------------------- + +bool UnitTestReadYaml::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/wsjcpp.yml b/wsjcpp.yml index b9c9e80..e0c980b 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -57,3 +57,5 @@ unit-tests: description: "" - name: "MemoryLeaks" description: "" + - name: "ReadYaml" + description: "" From 251ea4c275236f0d1e81f18fbbba9ca880951bc1 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 15:04:07 +0700 Subject: [PATCH 07/29] Redesign code for unit_test_memory_leaks --- unit-tests.wsjcpp/src/get_current_rss.h | 121 ++++++++++++++++++ unit-tests.wsjcpp/src/process_mem_usage.h | 51 ++++++++ .../src/unit_test_memory_leaks.cpp | 76 ++++------- 3 files changed, 195 insertions(+), 53 deletions(-) create mode 100644 unit-tests.wsjcpp/src/get_current_rss.h create mode 100644 unit-tests.wsjcpp/src/process_mem_usage.h diff --git a/unit-tests.wsjcpp/src/get_current_rss.h b/unit-tests.wsjcpp/src/get_current_rss.h new file mode 100644 index 0000000..54231fd --- /dev/null +++ b/unit-tests.wsjcpp/src/get_current_rss.h @@ -0,0 +1,121 @@ +/* + * Author: David Robert Nadeau + * Site: http://NadeauSoftware.com/ + * License: Creative Commons Attribution 3.0 Unported License + * http://creativecommons.org/licenses/by/3.0/deed.en_US + */ +// https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c + +#if defined(_WIN32) +#include +#include + +#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +#include + +#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) +#include +#include + +#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) +#include + +#endif + +#else +#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS." +#endif + + + +/** + * Returns the peak (maximum so far) resident set size (physical + * memory use) measured in bytes, or zero if the value cannot be + * determined on this OS. + */ +size_t getPeakRSS( ) +{ +#if defined(_WIN32) + /* Windows -------------------------------------------------- */ + PROCESS_MEMORY_COUNTERS info; + GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); + return (size_t)info.PeakWorkingSetSize; + +#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__))) + /* AIX and Solaris ------------------------------------------ */ + struct psinfo psinfo; + int fd = -1; + if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 ) + return (size_t)0L; /* Can't open? */ + if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) ) + { + close( fd ); + return (size_t)0L; /* Can't read? */ + } + close( fd ); + return (size_t)(psinfo.pr_rssize * 1024L); + +#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) + /* BSD, Linux, and OSX -------------------------------------- */ + struct rusage rusage; + getrusage( RUSAGE_SELF, &rusage ); +#if defined(__APPLE__) && defined(__MACH__) + return (size_t)rusage.ru_maxrss; +#else + return (size_t)(rusage.ru_maxrss * 1024L); +#endif + +#else + /* Unknown OS ----------------------------------------------- */ + return (size_t)0L; /* Unsupported. */ +#endif +} + + + + + +/** + * Returns the current resident set size (physical memory use) measured + * in bytes, or zero if the value cannot be determined on this OS. + */ +size_t getCurrentRSS( ) +{ +#if defined(_WIN32) + /* Windows -------------------------------------------------- */ + PROCESS_MEMORY_COUNTERS info; + GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) ); + return (size_t)info.WorkingSetSize; + +#elif defined(__APPLE__) && defined(__MACH__) + /* OSX ------------------------------------------------------ */ + struct mach_task_basic_info info; + mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT; + if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO, + (task_info_t)&info, &infoCount ) != KERN_SUCCESS ) + return (size_t)0L; /* Can't access? */ + return (size_t)info.resident_size; + +#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__) + /* Linux ---------------------------------------------------- */ + long rss = 0L; + FILE* fp = NULL; + if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL ) + return (size_t)0L; /* Can't open? */ + if ( fscanf( fp, "%*s%ld", &rss ) != 1 ) + { + fclose( fp ); + return (size_t)0L; /* Can't read? */ + } + fclose( fp ); + return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE); + +#else + /* AIX, BSD, Solaris, and Unknown OS ------------------------ */ + return (size_t)0L; /* Unsupported. */ +#endif +} \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/process_mem_usage.h b/unit-tests.wsjcpp/src/process_mem_usage.h new file mode 100644 index 0000000..84d3e1f --- /dev/null +++ b/unit-tests.wsjcpp/src/process_mem_usage.h @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +// https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c + +////////////////////////////////////////////////////////////////////////////// +// +// process_mem_usage(double &, double &) - takes two doubles by reference, +// attempts to read the system-dependent data for a process' virtual memory +// size and resident set size, and return the results in KB. +// +// On failure, returns 0.0, 0.0 + +void process_mem_usage(double& vm_usage, double& resident_set) +{ + using std::ios_base; + using std::ifstream; + using std::string; + + vm_usage = 0.0; + resident_set = 0.0; + + // 'file' stat seems to give the most reliable results + // + ifstream stat_stream("/proc/self/stat",ios_base::in); + + // dummy vars for leading entries in stat that we don't care about + // + string pid, comm, state, ppid, pgrp, session, tty_nr; + string tpgid, flags, minflt, cminflt, majflt, cmajflt; + string utime, stime, cutime, cstime, priority, nice; + string O, itrealvalue, starttime; + + // the two fields we want + // + unsigned long vsize; + long rss; + + stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr + >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt + >> utime >> stime >> cutime >> cstime >> priority >> nice + >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest + + stat_stream.close(); + + long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages + vm_usage = vsize / 1024.0; + resident_set = rss * page_size_kb; +} \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp index f1c040a..6624dc0 100644 --- a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp +++ b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp @@ -1,59 +1,10 @@ #include #include -#include -#include -#include -#include -#include #include -#include -#include - -////////////////////////////////////////////////////////////////////////////// -// -// process_mem_usage(double &, double &) - takes two doubles by reference, -// attempts to read the system-dependent data for a process' virtual memory -// size and resident set size, and return the results in KB. -// -// On failure, returns 0.0, 0.0 - -void process_mem_usage(double& vm_usage, double& resident_set) -{ - using std::ios_base; - using std::ifstream; - using std::string; - - vm_usage = 0.0; - resident_set = 0.0; - - // 'file' stat seems to give the most reliable results - // - ifstream stat_stream("/proc/self/stat",ios_base::in); - - // dummy vars for leading entries in stat that we don't care about - // - string pid, comm, state, ppid, pgrp, session, tty_nr; - string tpgid, flags, minflt, cminflt, majflt, cmajflt; - string utime, stime, cutime, cstime, priority, nice; - string O, itrealvalue, starttime; - - // the two fields we want - // - unsigned long vsize; - long rss; - - stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr - >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt - >> utime >> stime >> cutime >> cstime >> priority >> nice - >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest - - stat_stream.close(); - - long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages - vm_usage = vsize / 1024.0; - resident_set = rss * page_size_kb; -} +#include "get_current_rss.h" +#include "process_mem_usage.h" + // --------------------------------------------------------------------- // UnitTestMemoryLeaks @@ -87,12 +38,29 @@ void UnitTestMemoryLeaks::executeTest() { std::string sFilepath = "./data-tests/for-memory-leak/some.yml"; std::string sError; + // std::cout << "currentSize "<< getCurrentRSS() << std::endl; + // std::cout << "peakSize "<< getPeakRSS() << std::endl; + + // first use for memory alloc some + for (int i = 0; i < 1000; i++) { + WsjcppYaml yaml; + if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + } + process_mem_usage(nBeforeVm, nBeforeRss); // std::cout << "nBeforeVm: " << nBeforeVm << std::endl; // std::cout << "nBeforeRss: " << nBeforeRss << std::endl; compare("memory vm not null", (int)nBeforeVm > 0, true); compare("memory vm not null", (int)nBeforeRss > 0, true); + // std::cout << "currentSize "<< getCurrentRSS() << std::endl; + // std::cout << "peakSize "<< getPeakRSS() << std::endl; + + // code again check the memoty leak + for (int i = 0; i < 1000; i++) { WsjcppYaml yaml; if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { @@ -100,12 +68,14 @@ void UnitTestMemoryLeaks::executeTest() { return; } } - // std::this_thread::sleep_for(std::chrono::seconds(1)); + process_mem_usage(nAfterVm, nAfterRss); // std::cout << "nAfterVm: " << nAfterVm << std::endl; // std::cout << "nAfterRss: " << nAfterRss << std::endl; compare("memory vm", (int)nAfterVm, (int)nBeforeVm); compare("memory rss", (int)nAfterRss, (int)nBeforeRss); + // std::cout << "currentSize "<< getCurrentRSS() << std::endl; + // std::cout << "peakSize "<< getPeakRSS() << std::endl; } // --------------------------------------------------------------------- From 2444e177c5ba0a7b4c92287152005b8634c16b50 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 15:13:11 +0700 Subject: [PATCH 08/29] Fixed #5 added setElementValue for bool, int, long --- src/wsjcpp_yaml.cpp | 33 +++++++++++++++++++++++++++++++++ src/wsjcpp_yaml.h | 22 ++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 379cb79..018eac5 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -312,6 +312,39 @@ bool WsjcppYamlItem::setElementValue( // --------------------------------------------------------------------- +bool WsjcppYamlItem::setElementValue( + const std::string &sName, + long nValue, + WsjcppYamlQuotes nNameQuotes, + WsjcppYamlQuotes nValueQuotes +) { + return setElementValue(sName, std::to_string(nValue), nNameQuotes, nValueQuotes); +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlItem::setElementValue( + const std::string &sName, + int nValue, + WsjcppYamlQuotes nNameQuotes, + WsjcppYamlQuotes nValueQuotes +) { + return setElementValue(sName, std::to_string(nValue), nNameQuotes, nValueQuotes); +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlItem::setElementValue( + const std::string &sName, + bool bValue, + WsjcppYamlQuotes nNameQuotes, + WsjcppYamlQuotes nValueQuotes +) { + return setElementValue(sName, (bValue ? "yes" : "no"), nNameQuotes, nValueQuotes); +} + +// --------------------------------------------------------------------- + bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_MAP ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index f5e1395..e4e5a8b 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -94,11 +94,29 @@ class WsjcppYamlItem { // TODO: rename to node std::vector getKeys(); bool setElementValue( - const std::string &sName, - const std::string &sValue, + const std::string &sName, const std::string &sValue, WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE ); + + bool setElementValue( + const std::string &sName, int nValue, + WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, + WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE + ); + + bool setElementValue( + const std::string &sName, long nValue, + WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, + WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE + ); + + bool setElementValue( + const std::string &sName, bool bValue, + WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, + WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE + ); + bool createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes); WsjcppYamlItem *createElementMap(); bool createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes); From 3e54caeeef4e8f44cb8b969ad4635f582a327bfb Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 15:34:34 +0700 Subject: [PATCH 09/29] Fixed #7 Added new methods get*Value --- src/main.cpp | 5 +- src/wsjcpp_yaml.cpp | 51 +++++++++++++++++++ src/wsjcpp_yaml.h | 8 ++- unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 3 +- .../src/unit_test_remove_element_in_array.cpp | 10 ++-- .../src/unit_test_yaml_parser_all.cpp | 12 ++--- ...it_test_yaml_parser_array_included_map.cpp | 18 +++---- .../src/unit_test_yaml_parser_comments.cpp | 10 ++-- ...unit_test_yaml_parser_hierarchical_map.cpp | 22 ++++---- .../src/unit_test_yaml_parser_quotes.cpp | 18 +++---- .../unit_test_yaml_parser_simple_array.cpp | 18 +++---- .../src/unit_test_yaml_parser_simple_map.cpp | 4 +- 12 files changed, 119 insertions(+), 60 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bfc25a5..3be199b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,12 +16,13 @@ int main(int argc, char* argv[]) { } WsjcppYaml yaml; std::string sError; - if (!yaml.loadFromFile("./wsjcpp.yml", sError)) { + std::string sFilePath = "./unit-tests.wsjcpp/data-tests/read-file/example-voiting-app/docker-compose.yml"; + if (!yaml.loadFromFile(sFilePath, sError)) { WsjcppLog::err(TAG, "Could not read data from file: " + sError); return -1; } - if (!yaml.saveToFile("./wsjcpp.yml")) { + if (!yaml.saveToFile(sFilePath)) { WsjcppLog::err(TAG, "Could not save data to file"); return -1; } diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 018eac5..bbc9574 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -1,6 +1,7 @@ #include "wsjcpp_yaml.h" #include +#include // --------------------------------------------------------------------- // WsjcppYamlPlaceInFile @@ -497,6 +498,7 @@ bool WsjcppYamlItem::isValue() { // --------------------------------------------------------------------- std::string WsjcppYamlItem::getValue() { + WsjcppLog::warn(TAG, "getValue is deprecated try getStringValue, getBoolValue, getLongValue, getIntValue..."); if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { WsjcppLog::throw_err(TAG, "getValue, Element must be value for " + this->getForLogFormat()); } @@ -505,6 +507,55 @@ std::string WsjcppYamlItem::getValue() { // --------------------------------------------------------------------- +std::string WsjcppYamlItem::getStringValue() { + if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { + WsjcppLog::throw_err(TAG, "getStringValue, Element must be value for " + this->getForLogFormat()); + } + return m_sValue; +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlItem::getBoolValue() { + std::string sValue = getStringValue(); + sValue = WsjcppCore::toLower(sValue); + if (sValue == "yes" || sValue == "true") { + return true; + } else if (sValue == "no" || sValue == "false") { + return false; + } else { + WsjcppLog::throw_err(TAG, "getBoolValue, Element must be bool expected with ignore case like" + "['yes','no','true','false'] for " + this->getForLogFormat()); + } + return false; +} + +// --------------------------------------------------------------------- + +long WsjcppYamlItem::getLongValue() { + std::string sValue = getStringValue(); + sValue = WsjcppCore::toLower(sValue); + long nValue = std::atol(sValue.c_str()); + if (std::to_string(nValue) != sValue) { + WsjcppLog::throw_err(TAG, "getLongValue, Element must be long or int but have a string" + this->getForLogFormat()); + } + return nValue; +} + +// --------------------------------------------------------------------- + +int WsjcppYamlItem::getIntValue() { + std::string sValue = getStringValue(); + sValue = WsjcppCore::toLower(sValue); + int nValue = std::atoi(sValue.c_str()); + if (std::to_string(nValue) != sValue) { + WsjcppLog::throw_err(TAG, "getLongValue, Element must be int but have a string" + this->getForLogFormat()); + } + return nValue; +} + +// --------------------------------------------------------------------- + void WsjcppYamlItem::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { WsjcppLog::throw_err(TAG, "setValue, Element must be value for " + this->getForLogFormat()); diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index e4e5a8b..55c2cc7 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -129,7 +129,13 @@ class WsjcppYamlItem { // TODO: rename to node bool removeElement(int i); bool isValue(); - std::string getValue(); + + std::string getValue(); // deprecated + std::string getStringValue(); // simular 'getValue' + bool getBoolValue(); + long getLongValue(); + int getIntValue(); + void setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes = WSJCPP_YAML_QUOTES_NONE); WsjcppYamlQuotes getValueQuotes(); diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index 1e9f3f4..fe8176c 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -43,7 +43,8 @@ void UnitTestReadYaml::executeTest() { compare("has networks", yaml.getRoot()->hasElement("networks"), true); compare("has services", yaml.getRoot()->hasElement("services"), true); - compare("version-value", yaml.getRoot()->getElement("version")->getValue(), "3"); + compare("version-value", yaml.getRoot()->getElement("version")->getStringValue(), "3"); + compare("version-value", yaml.getRoot()->getElement("version")->getIntValue(), 3); // wrong or not ? // TODO unit test source code here } diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp index 789632e..ed4256e 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp @@ -52,15 +52,15 @@ void UnitTestRemoveElementInArray::executeTest() { WsjcppYamlItem *pArr1 = yaml.getRoot()->getElement("arr1"); compare("arr1 len", pArr1->getLength(), 3); - compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); - compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i2"); - compare("arr1 name2 ", pArr1->getElement(2)->getElement("name")->getValue(), "i3"); + compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getStringValue(), "i1"); + compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getStringValue(), "i2"); + compare("arr1 name2 ", pArr1->getElement(2)->getElement("name")->getStringValue(), "i3"); pArr1->removeElement(1); compare("arr1 len", pArr1->getLength(), 2); - compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); - compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i3"); + compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getStringValue(), "i1"); + compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getStringValue(), "i3"); } // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp index 9c52efe..ee5d6c0 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp @@ -72,17 +72,17 @@ void UnitTestYamlParserAll::executeTest() { } WsjcppYamlItem *pItem = nullptr; - compare("test10", yaml.getRoot()->getElement("test10")->getValue(), "one"); - compare("test20", yaml.getRoot()->getElement("test20")->getValue(), "two"); + compare("test10", yaml.getRoot()->getElement("test10")->getStringValue(), "one"); + compare("test20", yaml.getRoot()->getElement("test20")->getStringValue(), "two"); pItem = yaml.getRoot()->getElement("array30"); compare("array30_length", pItem->getLength(), 3); pItem = yaml.getRoot()->getElement("array30")->getElement(0); - compare("test30_value", pItem->getValue(), "one31"); + compare("test30_value", pItem->getStringValue(), "one31"); compare("test30_comment", pItem->getComment(), "this field for test array30"); pItem = yaml.getRoot()->getElement("array30")->getElement(1); - compare("test40_value", pItem->getValue(), "two32"); + compare("test40_value", pItem->getStringValue(), "two32"); compare("test40_comment", pItem->getComment(), ""); pItem = yaml.getRoot()->getElement("array40"); @@ -92,10 +92,10 @@ void UnitTestYamlParserAll::executeTest() { compare("array50_length", pItem->getLength(), 2); pItem = yaml.getRoot()->getElement("map60")->getElement("test70"); - compare("test70_value", pItem->getValue(), "opa1"); + compare("test70_value", pItem->getStringValue(), "opa1"); pItem = yaml.getRoot()->getElement("map60")->getElement("test80"); - compare("test80_comment", pItem->getValue(), "opa2"); + compare("test80_comment", pItem->getStringValue(), "opa2"); std::string sSaved2 = ""; if (compare("saving yaml", yaml.saveToString(sSaved2), true)) { diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp index 7f2d0bd..595c9e0 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp @@ -57,7 +57,7 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { WsjcppYamlItem *pItem = nullptr; - compare("param1-value", yaml.getRoot()->getElement("param1")->getValue(), "none value1"); + compare("param1-value", yaml.getRoot()->getElement("param1")->getStringValue(), "none value1"); compare("param1-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getLine(), "param1: none value1 # it's value for something # olala "); compare("param1-original-number-of-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getNumberOfLine(), 1); compare("param1-comment", yaml.getRoot()->getElement("param1")->getComment(), "it's value for something # olala"); @@ -66,28 +66,28 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { compare("array-test2-comment", yaml.getRoot()->getElement("array-test2")->getComment(), "some comment 2"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(0); - compare("array-test2-element0-value", pItem->getValue(), "value21"); + compare("array-test2-element0-value", pItem->getStringValue(), "value21"); compare("array-test2-element0-comment", pItem->getComment(), "comment v21"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(1); - compare("array-test2-element1-value", yaml["array-test2"][1].getValue(), "value22"); + compare("array-test2-element1-value", yaml["array-test2"][1].getStringValue(), "value22"); compare("array-test2-element1-comment", yaml["array-test2"][1].getComment(), "comment v22"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(2); - compare("array-test2-element2-value", pItem->getValue(), "true"); + compare("array-test2-element2-value", pItem->getStringValue(), "true"); compare("array-test2-element2-comment", pItem->getComment(), "comment true"); compare("array-and-map-length", yaml["array-and-map"].getLength(), 2); pItem = yaml.getRoot()->getElement("array-and-map")->getElement(0); - compare("array-and-map-element0-value", pItem->getElement("submap-param1")->getValue(), "v01"); - compare("array-and-map-element0-value", pItem->getElement("submap-param2")->getValue(), "v02"); + compare("array-and-map-element0-value", pItem->getElement("submap-param1")->getStringValue(), "v01"); + compare("array-and-map-element0-value", pItem->getElement("submap-param2")->getStringValue(), "v02"); pItem = yaml.getRoot()->getElement("array-and-map")->getElement(1); - compare("array-and-map-element1-value", pItem->getElement("submap-param1")->getValue(), "v11"); - compare("array-and-map-element1-value", pItem->getElement("submap-param2")->getValue(), "v12"); + compare("array-and-map-element1-value", pItem->getElement("submap-param1")->getStringValue(), "v11"); + compare("array-and-map-element1-value", pItem->getElement("submap-param2")->getStringValue(), "v12"); - compare("param2-value", yaml.getRoot()->getElement("param2")->getValue(), "v2"); + compare("param2-value", yaml.getRoot()->getElement("param2")->getStringValue(), "v2"); std::string sSaved = ""; if (compare("save yaml", yaml.saveToString(sSaved), true)) { diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp index 74b2018..0aae450 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp @@ -59,21 +59,21 @@ void UnitTestYamlParserComments::executeTest() { // TODO: .findLine(0) - compare("param1", yaml["param1"].getValue(), "value1"); + compare("param1", yaml["param1"].getStringValue(), "value1"); compare("param1", yaml["param1"].getComment(), "comment 2 # comment"); - compare("param2", yaml["param2"].getValue(), "value2"); + compare("param2", yaml["param2"].getStringValue(), "value2"); compare("param2", yaml["param2"].getComment(), "some \"comment 3\""); compare("array1-comment", yaml["array1"].getComment(), "comment 5"); compare("array1-length", yaml["array1"].getLength(), 2); - compare("array1-element0-value", yaml["array1"][0].getValue(), "val1"); + compare("array1-element0-value", yaml["array1"][0].getStringValue(), "val1"); compare("array1-element0-comment", yaml["array1"][0].getComment(), "comment 6"); // TODO: .findLine(7) - compare("array1-element1-value", yaml["array1"][1].getValue(), "val2"); + compare("array1-element1-value", yaml["array1"][1].getStringValue(), "val2"); compare("array1-element1-comment", yaml["array1"][1].getComment(), "comment 8"); compare("map1-comment", yaml["map1"].getComment(), "comment 9"); @@ -81,7 +81,7 @@ void UnitTestYamlParserComments::executeTest() { compare("map1-p2-comment", yaml["map1"]["p2"].getComment(), "comment 12"); - // compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "value2"); + // compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); // compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); std::string sSaved = ""; diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp index bb57a45..7a82cc3 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp @@ -65,26 +65,26 @@ void UnitTestYamlParserHierarchicalMap::executeTest() { WsjcppYamlItem *pItem = nullptr; pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map111"); - compare("param1111", pItem->getElement("param1111")->getValue(), "v1111"); - compare("param1112", pItem->getElement("param1112")->getValue(), "v1112"); + compare("param1111", pItem->getElement("param1111")->getStringValue(), "v1111"); + compare("param1112", pItem->getElement("param1112")->getStringValue(), "v1112"); pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map112"); - compare("param1121", pItem->getElement("param1121")->getValue(), "v1121"); - compare("param1122", pItem->getElement("param1122")->getValue(), "v1122"); + compare("param1121", pItem->getElement("param1121")->getStringValue(), "v1121"); + compare("param1122", pItem->getElement("param1122")->getStringValue(), "v1122"); pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map113"); - compare("param1131", pItem->getElement("param1131")->getValue(), "v1131"); - compare("param1132", pItem->getElement("param1132")->getValue(), "v1132"); + compare("param1131", pItem->getElement("param1131")->getStringValue(), "v1131"); + compare("param1132", pItem->getElement("param1132")->getStringValue(), "v1132"); pItem = yaml.getRoot()->getElement("map1")->getElement("map12"); - compare("param121", pItem->getElement("param121")->getValue(), "v121"); - compare("param122", pItem->getElement("param122")->getValue(), "v122"); + compare("param121", pItem->getElement("param121")->getStringValue(), "v121"); + compare("param122", pItem->getElement("param122")->getStringValue(), "v122"); pItem = yaml.getRoot()->getElement("map1")->getElement("map12")->getElement("map123"); - compare("param1231", pItem->getElement("param1231")->getValue(), "v1231"); - compare("param1232", pItem->getElement("param1232")->getValue(), "v1232"); + compare("param1231", pItem->getElement("param1231")->getStringValue(), "v1231"); + compare("param1232", pItem->getElement("param1232")->getStringValue(), "v1232"); - compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "v2"); + compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "v2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); std::string sSaved = ""; diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp index 33bfb49..36cee40 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp @@ -57,23 +57,23 @@ void UnitTestYamlParserQuotes::executeTest() { // TODO: .findLine(0) - compare("param1", yaml["param1"].getValue(), "value1"); + compare("param1", yaml["param1"].getStringValue(), "value1"); compare("param1", yaml["param1"].getComment(), "v1"); - compare("param2", yaml["param2"].getValue(), " #$!!!value2"); + compare("param2", yaml["param2"].getStringValue(), " #$!!!value2"); compare("param2", yaml["param2"].getComment(), "val 2"); - compare(" param3 olala", yaml[" param3 olala"].getValue(), "val 3"); + compare(" param3 olala", yaml[" param3 olala"].getStringValue(), "val 3"); compare(" param3 olala", yaml[" param3 olala"].getComment(), "val 3***"); - compare("param4 val", yaml["param4"].getValue(), " #$!!!value4"); - compare("param4 comment", yaml["param4"].getValue(), " #$!!!value4"); + compare("param4 val", yaml["param4"].getStringValue(), " #$!!!value4"); + compare("param4 comment", yaml["param4"].getStringValue(), " #$!!!value4"); - compare("url-value", yaml["url"].getValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); - compare("issues-value", yaml["issues"].getValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); - compare("empty-value", yaml["empty"].getValue(), ""); + compare("url-value", yaml["url"].getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); + compare("issues-value", yaml["issues"].getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); + compare("empty-value", yaml["empty"].getStringValue(), ""); - compare("array-element0-value", yaml["array"][0].getValue(), "https://github.com/wsjcpp/wsjcpp-core:v0.0.1"); + compare("array-element0-value", yaml["array"][0].getStringValue(), "https://github.com/wsjcpp/wsjcpp-core:v0.0.1"); std::string sSaved = ""; compare("save yaml", yaml.saveToString(sSaved), true); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp index c9233fc..4b0bef5 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp @@ -56,7 +56,7 @@ void UnitTestYamlParserSimpleArray::executeTest() { WsjcppYamlItem *pItem = nullptr; - compare("param1-value", yaml.getRoot()->getElement("param1")->getValue(), "none value1"); + compare("param1-value", yaml.getRoot()->getElement("param1")->getStringValue(), "none value1"); compare("param1-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getLine(), "param1: none value1 # it's value for something # olala "); compare("param1-original-number-of-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getNumberOfLine(), 1); compare("param1-comment", yaml.getRoot()->getElement("param1")->getComment(), "it's value for something # olala"); @@ -65,39 +65,39 @@ void UnitTestYamlParserSimpleArray::executeTest() { compare("array-test2-comment", yaml.getRoot()->getElement("array-test2")->getComment(), "some comment 2"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(0); - compare("array-test2-element0-value", pItem->getValue(), "value21"); + compare("array-test2-element0-value", pItem->getStringValue(), "value21"); compare("array-test2-element0-comment", pItem->getComment(), "comment v21"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(1); - compare("array-test2-element1-value", pItem->getValue(), "value22"); + compare("array-test2-element1-value", pItem->getStringValue(), "value22"); compare("array-test2-element1-comment", pItem->getComment(), "comment v22"); - compare("array-test2-element2-value", yaml["array-test2"][2].getValue(), "true"); + compare("array-test2-element2-value", yaml["array-test2"][2].getStringValue(), "true"); compare("array-test2-element2-line", yaml["array-test2"][2].getPlaceInFile().getLine(), " - true # comment true "); compare("array-test2-element2-original-number-of-line", yaml["array-test2"][2].getPlaceInFile().getNumberOfLine(), 5); compare("array-test2-element2-comment", yaml["array-test2"][2].getComment(), "comment true"); - compare("array-test2-element3-value", yaml["array-test2"][3].getValue(), "falsesome"); + compare("array-test2-element3-value", yaml["array-test2"][3].getStringValue(), "falsesome"); compare("array-test2-element3-line", yaml["array-test2"][3].getPlaceInFile().getLine(), " - falsesome "); compare("array-test2-element3-original-number-of-line", yaml["array-test2"][3].getPlaceInFile().getNumberOfLine(), 7); compare("array-test2-element3-comment", yaml["array-test2"][3].getComment(), ""); - compare("array-test2-element4-value", yaml["array-test2"][4].getValue(), "free@free"); + compare("array-test2-element4-value", yaml["array-test2"][4].getStringValue(), "free@free"); compare("array-test2-element4-line", yaml["array-test2"][4].getPlaceInFile().getLine(), " - free@free "); compare("array-test2-element4-original-number-of-line", yaml["array-test2"][4].getPlaceInFile().getNumberOfLine(), 8); compare("array-test2-element4-comment", yaml["array-test2"][4].getComment(), ""); - compare("array-test2-element5-value", yaml["array-test2"][5].getValue(), ""); + compare("array-test2-element5-value", yaml["array-test2"][5].getStringValue(), ""); compare("array-test2-element5-line", yaml["array-test2"][5].getPlaceInFile().getLine(), " - # empty "); compare("array-test2-element5-original-number-of-line", yaml["array-test2"][5].getPlaceInFile().getNumberOfLine(), 9); compare("array-test2-element5-comment", yaml["array-test2"][5].getComment(), "empty"); - compare("array-test2-element6-value", yaml["array-test2"][6].getValue(), "1"); + compare("array-test2-element6-value", yaml["array-test2"][6].getStringValue(), "1"); compare("array-test2-element6-line", yaml["array-test2"][6].getPlaceInFile().getLine(), " - 1"); compare("array-test2-element6-original-number-of-line", yaml["array-test2"][6].getPlaceInFile().getNumberOfLine(), 10); compare("array-test2-element6-comment", yaml["array-test2"][6].getComment(), ""); - compare("param2-value", yaml.getRoot()->getElement("param2")->getValue(), "val2"); + compare("param2-value", yaml.getRoot()->getElement("param2")->getStringValue(), "val2"); compare("param2-line", yaml.getRoot()->getElement("param2")->getPlaceInFile().getLine(), "param2: val2 # value 2 "); compare("param2-original-number-of-line", yaml.getRoot()->getElement("param2")->getPlaceInFile().getNumberOfLine(), 11); compare("param2-comment", yaml.getRoot()->getElement("param2")->getComment(), "value 2"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp index 6607e78..5821954 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp @@ -47,8 +47,8 @@ void UnitTestYamlParserSimpleMap::executeTest() { } WsjcppYamlItem *pItem = nullptr; - compare("param1", yaml.getRoot()->getElement("param1")->getValue(), "value1"); - compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "value2"); + compare("param1", yaml.getRoot()->getElement("param1")->getStringValue(), "value1"); + compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); std::string sSaved = ""; From 40eb5c540cd4cab6ad3f7233615bdcca9d507b52 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 15:47:24 +0700 Subject: [PATCH 10/29] Added read-write unit-test --- .gitignore | 1 + unit-tests.wsjcpp/CMakeLists.txt | 1 + .../read-write-file/docker-compose.yml | 61 ++++++++++++++++ .../src/unit_test_read_write_file.cpp | 71 +++++++++++++++++++ wsjcpp.yml | 2 + 5 files changed, 136 insertions(+) create mode 100644 unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml create mode 100644 unit-tests.wsjcpp/src/unit_test_read_write_file.cpp diff --git a/.gitignore b/.gitignore index 60170d9..0abcd13 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ tmp/* .wsjcpp-cache/* .wsjcpp-logs/* .wsjcpp/* +unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.output.yml # Prerequisites *.d diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index ef92f8e..b047f54 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -46,6 +46,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_f list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_yaml.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_write_file.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) diff --git a/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml b/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml new file mode 100644 index 0000000..0a02219 --- /dev/null +++ b/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml @@ -0,0 +1,61 @@ +# https://github.com/dockersamples/example-voting-app/blob/master/docker-compose.yml + +version: "3" + +services: + vote: + build: ./vote + command: python app.py + volumes: + - ./vote:/app + ports: + - "5000:80" + networks: + - front-tier + - back-tier + + result: + build: ./result + command: nodemon server.js + volumes: + - ./result:/app + ports: + - "5001:80" + - "5858:5858" + networks: + - front-tier + - back-tier + + worker: + build: + context: ./worker + depends_on: + - "redis" + - "db" + networks: + - back-tier + + redis: + image: redis:alpine + container_name: redis + ports: ["6379"] + networks: + - back-tier + + db: + image: postgres:9.4 + container_name: db + environment: + POSTGRES_USER: "postgres" + POSTGRES_PASSWORD: "postgres" + volumes: + - "db-data:/var/lib/postgresql/data" + networks: + - back-tier + +volumes: + db-data: + +networks: + front-tier: + back-tier: diff --git a/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp b/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp new file mode 100644 index 0000000..ebf3541 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp @@ -0,0 +1,71 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestReadWriteFile + +class UnitTestReadWriteFile : public WsjcppUnitTestBase { + public: + UnitTestReadWriteFile(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestReadWriteFile) + +UnitTestReadWriteFile::UnitTestReadWriteFile() + : WsjcppUnitTestBase("UnitTestReadWriteFile") { +} + +// --------------------------------------------------------------------- + +bool UnitTestReadWriteFile::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestReadWriteFile::executeTest() { + WsjcppYaml yaml; + std::string sFilepath = "./data-tests/read-write-file/docker-compose.yml"; + std::string sFilepathOutput = "./data-tests/read-write-file/docker-compose.output.yml"; + std::string sError; + if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + compare("has version", yaml.getRoot()->hasElement("version"), true); + compare("has volumes", yaml.getRoot()->hasElement("volumes"), true); + compare("has networks", yaml.getRoot()->hasElement("networks"), true); + compare("has services", yaml.getRoot()->hasElement("services"), true); + + compare("version-value", yaml.getRoot()->getElement("version")->getStringValue(), "3"); + compare("version-value", yaml.getRoot()->getElement("version")->getIntValue(), 3); // wrong or not ? + + if (!compare("Error parsing", yaml.saveToFile(sFilepathOutput), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + std::string sOriginalFileContent; + WsjcppCore::readTextFile(sFilepath, sOriginalFileContent); + std::string sOutputFileContent; + WsjcppCore::readTextFile(sFilepathOutput, sOutputFileContent); + + compare("compare conteent ", sOutputFileContent, sOriginalFileContent); + +} + +// --------------------------------------------------------------------- + +bool UnitTestReadWriteFile::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/wsjcpp.yml b/wsjcpp.yml index e0c980b..e8fe982 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -59,3 +59,5 @@ unit-tests: description: "" - name: "ReadYaml" description: "" + - name: "ReadWriteFile" + description: "" From 80c799721d1d5f3786f722c8ca16fea29f21abaa Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 16:14:37 +0700 Subject: [PATCH 11/29] Fixed #15 removed dangerous operators --- src/wsjcpp_yaml.h | 8 ++-- ...it_test_yaml_parser_array_included_map.cpp | 6 +-- .../src/unit_test_yaml_parser_comments.cpp | 26 +++++------ .../src/unit_test_yaml_parser_quotes.cpp | 24 +++++----- .../unit_test_yaml_parser_simple_array.cpp | 46 +++++++++---------- 5 files changed, 54 insertions(+), 56 deletions(-) diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 55c2cc7..31ce402 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -142,9 +142,6 @@ class WsjcppYamlItem { // TODO: rename to node std::string toString(std::string sIntent = ""); std::string getItemTypeAsString(); - WsjcppYamlItem &operator[](int idx) { return *(this->getElement(idx)); } - WsjcppYamlItem &operator[](const std::string &sName) { return *(this->getElement(sName)); } - std::string getForLogFormat(); private: @@ -225,8 +222,6 @@ class WsjcppYaml { bool saveToString(std::string &sBuffer); WsjcppYamlItem *getRoot(); - WsjcppYamlItem &operator[](int idx) { return *(getRoot()->getElement(idx)); } - WsjcppYamlItem &operator[](const std::string &sName) { return *(getRoot()->getElement(sName)); } private: std::string TAG; @@ -259,6 +254,9 @@ class WsjcppYamlCursor { return WsjcppYamlCursor(pYaml, pYaml->getRoot()->getElement(idx)); // will be call destructor ? } WsjcppYamlCursor &operator[](const std::string &sName) { return *(getRoot()->getElement(sName)); } + + WsjcppYamlItem &operator[](int idx) { return *(getRoot()->getElement(idx)); } + WsjcppYamlItem &operator[](const std::string &sName) { return *(getRoot()->getElement(sName)); } private: WsjcppYaml *m_pYaml; diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp index 595c9e0..cf3945f 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp @@ -70,14 +70,14 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { compare("array-test2-element0-comment", pItem->getComment(), "comment v21"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(1); - compare("array-test2-element1-value", yaml["array-test2"][1].getStringValue(), "value22"); - compare("array-test2-element1-comment", yaml["array-test2"][1].getComment(), "comment v22"); + compare("array-test2-element1-value", yaml.getRoot()->getElement("array-test2")->getElement(1)->getStringValue(), "value22"); + compare("array-test2-element1-comment", yaml.getRoot()->getElement("array-test2")->getElement(1)->getComment(), "comment v22"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(2); compare("array-test2-element2-value", pItem->getStringValue(), "true"); compare("array-test2-element2-comment", pItem->getComment(), "comment true"); - compare("array-and-map-length", yaml["array-and-map"].getLength(), 2); + compare("array-and-map-length", yaml.getRoot()->getElement("array-and-map")->getLength(), 2); pItem = yaml.getRoot()->getElement("array-and-map")->getElement(0); compare("array-and-map-element0-value", pItem->getElement("submap-param1")->getStringValue(), "v01"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp index 0aae450..f394d9a 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp @@ -59,26 +59,26 @@ void UnitTestYamlParserComments::executeTest() { // TODO: .findLine(0) - compare("param1", yaml["param1"].getStringValue(), "value1"); - compare("param1", yaml["param1"].getComment(), "comment 2 # comment"); + compare("param1", yaml.getRoot()->getElement("param1")->getStringValue(), "value1"); + compare("param1", yaml.getRoot()->getElement("param1")->getComment(), "comment 2 # comment"); - compare("param2", yaml["param2"].getStringValue(), "value2"); - compare("param2", yaml["param2"].getComment(), "some \"comment 3\""); + compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); + compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some \"comment 3\""); - compare("array1-comment", yaml["array1"].getComment(), "comment 5"); - compare("array1-length", yaml["array1"].getLength(), 2); - compare("array1-element0-value", yaml["array1"][0].getStringValue(), "val1"); - compare("array1-element0-comment", yaml["array1"][0].getComment(), "comment 6"); + compare("array1-comment", yaml.getRoot()->getElement("array1")->getComment(), "comment 5"); + compare("array1-length", yaml.getRoot()->getElement("array1")->getLength(), 2); + compare("array1-element0-value", yaml.getRoot()->getElement("array1")->getElement(0)->getStringValue(), "val1"); + compare("array1-element0-comment", yaml.getRoot()->getElement("array1")->getElement(0)->getComment(), "comment 6"); // TODO: .findLine(7) - compare("array1-element1-value", yaml["array1"][1].getStringValue(), "val2"); - compare("array1-element1-comment", yaml["array1"][1].getComment(), "comment 8"); + compare("array1-element1-value", yaml.getRoot()->getElement("array1")->getElement(1)->getStringValue(), "val2"); + compare("array1-element1-comment", yaml.getRoot()->getElement("array1")->getElement(1)->getComment(), "comment 8"); - compare("map1-comment", yaml["map1"].getComment(), "comment 9"); - compare("map1-p1-comment", yaml["map1"]["p1"].getComment(), "comment 10"); - compare("map1-p2-comment", yaml["map1"]["p2"].getComment(), "comment 12"); + compare("map1-comment", yaml.getRoot()->getElement("map1")->getComment(), "comment 9"); + compare("map1-p1-comment", yaml.getRoot()->getElement("map1")->getElement("p1")->getComment(), "comment 10"); + compare("map1-p2-comment", yaml.getRoot()->getElement("map1")->getElement("p2")->getComment(), "comment 12"); // compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp index 36cee40..a33dec8 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp @@ -57,23 +57,23 @@ void UnitTestYamlParserQuotes::executeTest() { // TODO: .findLine(0) - compare("param1", yaml["param1"].getStringValue(), "value1"); - compare("param1", yaml["param1"].getComment(), "v1"); + compare("param1", yaml.getRoot()->getElement("param1")->getStringValue(), "value1"); + compare("param1", yaml.getRoot()->getElement("param1")->getComment(), "v1"); - compare("param2", yaml["param2"].getStringValue(), " #$!!!value2"); - compare("param2", yaml["param2"].getComment(), "val 2"); + compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), " #$!!!value2"); + compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "val 2"); - compare(" param3 olala", yaml[" param3 olala"].getStringValue(), "val 3"); - compare(" param3 olala", yaml[" param3 olala"].getComment(), "val 3***"); + compare(" param3 olala", yaml.getRoot()->getElement(" param3 olala")->getStringValue(), "val 3"); + compare(" param3 olala", yaml.getRoot()->getElement(" param3 olala")->getComment(), "val 3***"); - compare("param4 val", yaml["param4"].getStringValue(), " #$!!!value4"); - compare("param4 comment", yaml["param4"].getStringValue(), " #$!!!value4"); + compare("param4 val", yaml.getRoot()->getElement("param4")->getStringValue(), " #$!!!value4"); + compare("param4 comment", yaml.getRoot()->getElement("param4")->getStringValue(), " #$!!!value4"); - compare("url-value", yaml["url"].getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); - compare("issues-value", yaml["issues"].getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); - compare("empty-value", yaml["empty"].getStringValue(), ""); + compare("url-value", yaml.getRoot()->getElement("url")->getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); + compare("issues-value", yaml.getRoot()->getElement("issues")->getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); + compare("empty-value", yaml.getRoot()->getElement("empty")->getStringValue(), ""); - compare("array-element0-value", yaml["array"][0].getStringValue(), "https://github.com/wsjcpp/wsjcpp-core:v0.0.1"); + compare("array-element0-value", yaml.getRoot()->getElement("array")->getElement(0)->getStringValue(), "https://github.com/wsjcpp/wsjcpp-core:v0.0.1"); std::string sSaved = ""; compare("save yaml", yaml.saveToString(sSaved), true); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp index 4b0bef5..ef44221 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp @@ -72,30 +72,30 @@ void UnitTestYamlParserSimpleArray::executeTest() { compare("array-test2-element1-value", pItem->getStringValue(), "value22"); compare("array-test2-element1-comment", pItem->getComment(), "comment v22"); - compare("array-test2-element2-value", yaml["array-test2"][2].getStringValue(), "true"); - compare("array-test2-element2-line", yaml["array-test2"][2].getPlaceInFile().getLine(), " - true # comment true "); - compare("array-test2-element2-original-number-of-line", yaml["array-test2"][2].getPlaceInFile().getNumberOfLine(), 5); - compare("array-test2-element2-comment", yaml["array-test2"][2].getComment(), "comment true"); - - compare("array-test2-element3-value", yaml["array-test2"][3].getStringValue(), "falsesome"); - compare("array-test2-element3-line", yaml["array-test2"][3].getPlaceInFile().getLine(), " - falsesome "); - compare("array-test2-element3-original-number-of-line", yaml["array-test2"][3].getPlaceInFile().getNumberOfLine(), 7); - compare("array-test2-element3-comment", yaml["array-test2"][3].getComment(), ""); + compare("array-test2-element2-value", yaml.getRoot()->getElement("array-test2")->getElement(2)->getStringValue(), "true"); + compare("array-test2-element2-line", yaml.getRoot()->getElement("array-test2")->getElement(2)->getPlaceInFile().getLine(), " - true # comment true "); + compare("array-test2-element2-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(2)->getPlaceInFile().getNumberOfLine(), 5); + compare("array-test2-element2-comment", yaml.getRoot()->getElement("array-test2")->getElement(2)->getComment(), "comment true"); + + compare("array-test2-element3-value", yaml.getRoot()->getElement("array-test2")->getElement(3)->getStringValue(), "falsesome"); + compare("array-test2-element3-line", yaml.getRoot()->getElement("array-test2")->getElement(3)->getPlaceInFile().getLine(), " - falsesome "); + compare("array-test2-element3-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(3)->getPlaceInFile().getNumberOfLine(), 7); + compare("array-test2-element3-comment", yaml.getRoot()->getElement("array-test2")->getElement(3)->getComment(), ""); - compare("array-test2-element4-value", yaml["array-test2"][4].getStringValue(), "free@free"); - compare("array-test2-element4-line", yaml["array-test2"][4].getPlaceInFile().getLine(), " - free@free "); - compare("array-test2-element4-original-number-of-line", yaml["array-test2"][4].getPlaceInFile().getNumberOfLine(), 8); - compare("array-test2-element4-comment", yaml["array-test2"][4].getComment(), ""); - - compare("array-test2-element5-value", yaml["array-test2"][5].getStringValue(), ""); - compare("array-test2-element5-line", yaml["array-test2"][5].getPlaceInFile().getLine(), " - # empty "); - compare("array-test2-element5-original-number-of-line", yaml["array-test2"][5].getPlaceInFile().getNumberOfLine(), 9); - compare("array-test2-element5-comment", yaml["array-test2"][5].getComment(), "empty"); - - compare("array-test2-element6-value", yaml["array-test2"][6].getStringValue(), "1"); - compare("array-test2-element6-line", yaml["array-test2"][6].getPlaceInFile().getLine(), " - 1"); - compare("array-test2-element6-original-number-of-line", yaml["array-test2"][6].getPlaceInFile().getNumberOfLine(), 10); - compare("array-test2-element6-comment", yaml["array-test2"][6].getComment(), ""); + compare("array-test2-element4-value", yaml.getRoot()->getElement("array-test2")->getElement(4)->getStringValue(), "free@free"); + compare("array-test2-element4-line", yaml.getRoot()->getElement("array-test2")->getElement(4)->getPlaceInFile().getLine(), " - free@free "); + compare("array-test2-element4-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(4)->getPlaceInFile().getNumberOfLine(), 8); + compare("array-test2-element4-comment", yaml.getRoot()->getElement("array-test2")->getElement(4)->getComment(), ""); + + compare("array-test2-element5-value", yaml.getRoot()->getElement("array-test2")->getElement(5)->getStringValue(), ""); + compare("array-test2-element5-line", yaml.getRoot()->getElement("array-test2")->getElement(5)->getPlaceInFile().getLine(), " - # empty "); + compare("array-test2-element5-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(5)->getPlaceInFile().getNumberOfLine(), 9); + compare("array-test2-element5-comment", yaml.getRoot()->getElement("array-test2")->getElement(5)->getComment(), "empty"); + + compare("array-test2-element6-value", yaml.getRoot()->getElement("array-test2")->getElement(6)->getStringValue(), "1"); + compare("array-test2-element6-line", yaml.getRoot()->getElement("array-test2")->getElement(6)->getPlaceInFile().getLine(), " - 1"); + compare("array-test2-element6-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(6)->getPlaceInFile().getNumberOfLine(), 10); + compare("array-test2-element6-comment", yaml.getRoot()->getElement("array-test2")->getElement(6)->getComment(), ""); compare("param2-value", yaml.getRoot()->getElement("param2")->getStringValue(), "val2"); compare("param2-line", yaml.getRoot()->getElement("param2")->getPlaceInFile().getLine(), "param2: val2 # value 2 "); From b25e4d2c73e89baf2f7f8d8325755297147a8b00 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Wed, 23 Sep 2020 18:06:11 +0700 Subject: [PATCH 12/29] Prepare WsjcppYamlCursor #13 --- src/wsjcpp_yaml.cpp | 79 ++++++++++++++++ src/wsjcpp_yaml.h | 76 ++++++++++----- unit-tests.wsjcpp/CMakeLists.txt | 1 + unit-tests.wsjcpp/src/unit_test_cursor.cpp | 93 +++++++++++++++++++ unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 2 - wsjcpp.yml | 2 + 6 files changed, 228 insertions(+), 25 deletions(-) create mode 100644 unit-tests.wsjcpp/src/unit_test_cursor.cpp diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index bbc9574..99fd852 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -982,6 +982,67 @@ void WsjcppYamlParserStatus::logUnknownLine(const std::string &sPrefix) { ); } +// --------------------------------------------------------------------- +// WsjcppYamlCursor + +WsjcppYamlCursor::WsjcppYamlCursor(WsjcppYamlItem *pCurrentNode) { + m_pCurrentNode = pCurrentNode; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor::WsjcppYamlCursor() { + m_pCurrentNode = nullptr; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor::~WsjcppYamlCursor() { + // do nothing +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlCursor::isNull() const { + return m_pCurrentNode == nullptr; +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlCursor::isArray() const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isArray(); +} + +// --------------------------------------------------------------------- + +size_t WsjcppYamlCursor::size() const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isArray() ? m_pCurrentNode->getLength() : -1; +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlCursor::isMap() const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isMap(); +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor WsjcppYamlCursor::operator[](int idx) const { + if (m_pCurrentNode != nullptr && m_pCurrentNode->isArray() && idx < m_pCurrentNode->getLength() && idx >= 0) { + return WsjcppYamlCursor(m_pCurrentNode->getElement(idx)); + } + return WsjcppYamlCursor(); +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor WsjcppYamlCursor::operator[](const std::string &sName) const { + if (m_pCurrentNode != nullptr && m_pCurrentNode->isMap() && m_pCurrentNode->hasElement(sName)) { + return WsjcppYamlCursor(m_pCurrentNode->getElement(sName)); + } + return WsjcppYamlCursor(); +} + // --------------------------------------------------------------------- // WsjcppYaml @@ -1037,6 +1098,24 @@ WsjcppYamlItem *WsjcppYaml::getRoot() { // --------------------------------------------------------------------- +WsjcppYamlCursor WsjcppYaml::getCursor() const { + return WsjcppYamlCursor(m_pRoot); +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor WsjcppYaml::operator[](int idx) const { + return this->getCursor()[idx]; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor WsjcppYaml::operator[](const std::string &sName) const { + return this->getCursor()[sName]; +} + +// --------------------------------------------------------------------- + std::vector WsjcppYaml::splitToLines(const std::string &sBuffer) { std::vector vLines; std::string sLine = ""; diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 31ce402..333a8de 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -210,6 +210,55 @@ class WsjcppYamlParserStatus { void logUnknownLine(const std::string &sPrefix); }; + +// --------------------------------------------------------------------- + +class WsjcppYamlCursor { + public: + WsjcppYamlCursor(WsjcppYamlItem *pCurrentNode); + WsjcppYamlCursor(); + ~WsjcppYamlCursor(); + + // null or undefined + bool isNull() const; + + // array + bool isArray() const; + size_t size() const; + WsjcppYamlCursor &push(const std::string &sVal); + WsjcppYamlCursor &push(int nVal); + WsjcppYamlCursor &push(bool bVal); + WsjcppYamlCursor &remove(int nIdx); + + // map + bool isMap() const; + std::vector keys(); + WsjcppYamlCursor &set(const std::string &sName, const std::string &sValue); + WsjcppYamlCursor &set(const std::string &sName, int nValue); + WsjcppYamlCursor &set(const std::string &sName, bool bValue); + WsjcppYamlCursor &remove(const std::string &sKey); + + // comment + std::string comment(); + WsjcppYamlCursor &comment(const std::string& sComment); + + // val + std::string valStr(); + WsjcppYamlCursor &val(const std::string &sValue); + bool valInt(); + WsjcppYamlCursor &val(int nValue); + bool valBool(); + WsjcppYamlCursor &val(bool bValue); + + + WsjcppYamlCursor operator[](int idx) const; + WsjcppYamlCursor operator[](const std::string &sName) const; + + private: + WsjcppYamlItem *m_pCurrentNode; +}; + + // --------------------------------------------------------------------- class WsjcppYaml { @@ -220,9 +269,12 @@ class WsjcppYaml { bool saveToFile(const std::string &sFileName); bool loadFromString(const std::string &sBufferName, const std::string &sBuffer, std::string &sError); bool saveToString(std::string &sBuffer); - WsjcppYamlItem *getRoot(); + WsjcppYamlCursor getCursor() const; + WsjcppYamlCursor operator[](int idx) const; + WsjcppYamlCursor operator[](const std::string &sName) const; + private: std::string TAG; @@ -242,27 +294,5 @@ class WsjcppYaml { WsjcppYamlItem *m_pRoot; }; -// --------------------------------------------------------------------- - -/* -class WsjcppYamlCursor { - public: - WsjcppYamlCursor(WsjcppYaml *pYaml); - ~WsjcppYamlCursor(); - WsjcppYamlCursor(WsjcppYaml *pYaml, WsjcppYamlItem *pCurrentNode); - WsjcppYamlCursor &operator[](int idx) { - return WsjcppYamlCursor(pYaml, pYaml->getRoot()->getElement(idx)); // will be call destructor ? - } - WsjcppYamlCursor &operator[](const std::string &sName) { return *(getRoot()->getElement(sName)); } - - WsjcppYamlItem &operator[](int idx) { return *(getRoot()->getElement(idx)); } - WsjcppYamlItem &operator[](const std::string &sName) { return *(getRoot()->getElement(sName)); } - - private: - WsjcppYaml *m_pYaml; - WsjcppYamlItem *m_pCurrentNode; -}; -*/ - #endif // WSJCPP_YAML_H diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index b047f54..4c801c0 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -47,6 +47,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_remove_element_i list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_yaml.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_write_file.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_cursor.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) diff --git a/unit-tests.wsjcpp/src/unit_test_cursor.cpp b/unit-tests.wsjcpp/src/unit_test_cursor.cpp new file mode 100644 index 0000000..aeaa346 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_cursor.cpp @@ -0,0 +1,93 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestCursor + +class UnitTestCursor : public WsjcppUnitTestBase { + public: + UnitTestCursor(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestCursor) + +UnitTestCursor::UnitTestCursor() + : WsjcppUnitTestBase("UnitTestCursor") { +} + +// --------------------------------------------------------------------- + +bool UnitTestCursor::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestCursor::executeTest() { + + std::string sTestYaml = + "# Some comment 1\n" + "map1: \n" + " map11: \n" + " map111: \n" + " param1111: v1111\n" + " param1112: v1112\n" + " map112: \n" + " param1121: v1121\n" + " param1122: v1122\n" + " map113: \n" + " param1131: v1131\n" + " param1132: v1132\n" + " map12: \n" + " param121: v121\n" + " param122: v122\n" + " map123: \n" + " param1231: v1231\n" + " param1232: v1232\n" + "param2: v2 # some comment 2\n" + "arr1: # some comment 2\n" + " - some1\n" + " - some2\n" + " - some3\n" + "\n" // empty line + ; + + WsjcppYaml yaml; + std::string sError; + if (!compare("Error parsing", yaml.loadFromString("test_cursor", sTestYaml, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + compare("map1 is null", yaml["map1"].isNull(), false); + compare("map1 is array", yaml["map1"].isArray(), false); + compare("map1 is map", yaml["map1"].isMap(), true); + + compare("map1-1111 is null", yaml["map1-1111"].isNull(), true); + compare("map1-1111 is array", yaml["map1-1111"].isArray(), false); + compare("map1-1111 is map", yaml["map1-1111"].isMap(), false); + + compare("arr1 is null", yaml["arr1"].isNull(), false); + compare("arr1 is array", yaml["arr1"].isArray(), true); + compare("arr1 is map", yaml["arr1"].isMap(), false); + + + compare("map use as array", yaml["map1"][0].isNull(), true); + compare("array use as map", yaml["arr1"]["0"].isNull(), true); + +} + +// --------------------------------------------------------------------- + +bool UnitTestCursor::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index fe8176c..e913a25 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -45,8 +45,6 @@ void UnitTestReadYaml::executeTest() { compare("version-value", yaml.getRoot()->getElement("version")->getStringValue(), "3"); compare("version-value", yaml.getRoot()->getElement("version")->getIntValue(), 3); // wrong or not ? - - // TODO unit test source code here } // --------------------------------------------------------------------- diff --git a/wsjcpp.yml b/wsjcpp.yml index e8fe982..476994c 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -61,3 +61,5 @@ unit-tests: description: "" - name: "ReadWriteFile" description: "" + - name: "Cursor" + description: "" From 8e91fa3b14434137de539de9262c198e67f2a1bb Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Thu, 24 Sep 2020 17:32:53 +0700 Subject: [PATCH 13/29] Partial fix for #13 WsjcppYamlCursor --- src/wsjcpp_yaml.cpp | 225 +++++++++++------- src/wsjcpp_yaml.h | 53 ++--- unit-tests.wsjcpp/src/unit_test_cursor.cpp | 91 ++++++- .../src/unit_test_read_write_file.cpp | 3 +- unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 4 +- .../src/unit_test_remove_element_in_array.cpp | 10 +- .../src/unit_test_yaml_parser_all.cpp | 12 +- ...it_test_yaml_parser_array_included_map.cpp | 18 +- .../src/unit_test_yaml_parser_comments.cpp | 10 +- ...unit_test_yaml_parser_hierarchical_map.cpp | 22 +- .../src/unit_test_yaml_parser_quotes.cpp | 18 +- .../unit_test_yaml_parser_simple_array.cpp | 18 +- .../src/unit_test_yaml_parser_simple_map.cpp | 4 +- 13 files changed, 306 insertions(+), 182 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 99fd852..291c764 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -313,39 +313,6 @@ bool WsjcppYamlItem::setElementValue( // --------------------------------------------------------------------- -bool WsjcppYamlItem::setElementValue( - const std::string &sName, - long nValue, - WsjcppYamlQuotes nNameQuotes, - WsjcppYamlQuotes nValueQuotes -) { - return setElementValue(sName, std::to_string(nValue), nNameQuotes, nValueQuotes); -} - -// --------------------------------------------------------------------- - -bool WsjcppYamlItem::setElementValue( - const std::string &sName, - int nValue, - WsjcppYamlQuotes nNameQuotes, - WsjcppYamlQuotes nValueQuotes -) { - return setElementValue(sName, std::to_string(nValue), nNameQuotes, nValueQuotes); -} - -// --------------------------------------------------------------------- - -bool WsjcppYamlItem::setElementValue( - const std::string &sName, - bool bValue, - WsjcppYamlQuotes nNameQuotes, - WsjcppYamlQuotes nValueQuotes -) { - return setElementValue(sName, (bValue ? "yes" : "no"), nNameQuotes, nValueQuotes); -} - -// --------------------------------------------------------------------- - bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_MAP ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); @@ -498,7 +465,6 @@ bool WsjcppYamlItem::isValue() { // --------------------------------------------------------------------- std::string WsjcppYamlItem::getValue() { - WsjcppLog::warn(TAG, "getValue is deprecated try getStringValue, getBoolValue, getLongValue, getIntValue..."); if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { WsjcppLog::throw_err(TAG, "getValue, Element must be value for " + this->getForLogFormat()); } @@ -507,55 +473,6 @@ std::string WsjcppYamlItem::getValue() { // --------------------------------------------------------------------- -std::string WsjcppYamlItem::getStringValue() { - if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { - WsjcppLog::throw_err(TAG, "getStringValue, Element must be value for " + this->getForLogFormat()); - } - return m_sValue; -} - -// --------------------------------------------------------------------- - -bool WsjcppYamlItem::getBoolValue() { - std::string sValue = getStringValue(); - sValue = WsjcppCore::toLower(sValue); - if (sValue == "yes" || sValue == "true") { - return true; - } else if (sValue == "no" || sValue == "false") { - return false; - } else { - WsjcppLog::throw_err(TAG, "getBoolValue, Element must be bool expected with ignore case like" - "['yes','no','true','false'] for " + this->getForLogFormat()); - } - return false; -} - -// --------------------------------------------------------------------- - -long WsjcppYamlItem::getLongValue() { - std::string sValue = getStringValue(); - sValue = WsjcppCore::toLower(sValue); - long nValue = std::atol(sValue.c_str()); - if (std::to_string(nValue) != sValue) { - WsjcppLog::throw_err(TAG, "getLongValue, Element must be long or int but have a string" + this->getForLogFormat()); - } - return nValue; -} - -// --------------------------------------------------------------------- - -int WsjcppYamlItem::getIntValue() { - std::string sValue = getStringValue(); - sValue = WsjcppCore::toLower(sValue); - int nValue = std::atoi(sValue.c_str()); - if (std::to_string(nValue) != sValue) { - WsjcppLog::throw_err(TAG, "getLongValue, Element must be int but have a string" + this->getForLogFormat()); - } - return nValue; -} - -// --------------------------------------------------------------------- - void WsjcppYamlItem::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { WsjcppLog::throw_err(TAG, "setValue, Element must be value for " + this->getForLogFormat()); @@ -987,12 +904,14 @@ void WsjcppYamlParserStatus::logUnknownLine(const std::string &sPrefix) { WsjcppYamlCursor::WsjcppYamlCursor(WsjcppYamlItem *pCurrentNode) { m_pCurrentNode = pCurrentNode; + TAG = "WsjcppYamlCursor"; } // --------------------------------------------------------------------- -WsjcppYamlCursor::WsjcppYamlCursor() { - m_pCurrentNode = nullptr; +WsjcppYamlCursor::WsjcppYamlCursor() +: WsjcppYamlCursor(nullptr) { + // nothing } // --------------------------------------------------------------------- @@ -1009,6 +928,18 @@ bool WsjcppYamlCursor::isNull() const { // --------------------------------------------------------------------- +bool WsjcppYamlCursor::isUndefined() const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isUndefined(); +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlCursor::isValue() const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isValue(); +} + +// --------------------------------------------------------------------- + bool WsjcppYamlCursor::isArray() const { return m_pCurrentNode != nullptr && m_pCurrentNode->isArray(); } @@ -1027,6 +958,130 @@ bool WsjcppYamlCursor::isMap() const { // --------------------------------------------------------------------- +std::vector WsjcppYamlCursor::keys() const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isMap() ? m_pCurrentNode->getKeys() : std::vector(); +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlCursor::hasKey(const std::string &sKey) const { + return m_pCurrentNode != nullptr && m_pCurrentNode->isMap() && m_pCurrentNode->hasElement(sKey); +} + +// --------------------------------------------------------------------- + +// WsjcppYamlCursor &WsjcppYamlCursor::set(const std::string &sName, const std::string &sValue) { +// return *this; +// } +// +// // --------------------------------------------------------------------- +// +// WsjcppYamlCursor &WsjcppYamlCursor::set(const std::string &sName, int nValue) { +// return *this; +// } +// +// // --------------------------------------------------------------------- +// +// WsjcppYamlCursor &WsjcppYamlCursor::set(const std::string &sName, bool bValue) { +// return *this; +// } +// +// // --------------------------------------------------------------------- +// +// WsjcppYamlCursor &WsjcppYamlCursor::remove(const std::string &sKey) { +// return *this; +// } + +// --------------------------------------------------------------------- + +std::string WsjcppYamlCursor::comment() { + return m_pCurrentNode != nullptr ? m_pCurrentNode->getComment() : ""; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor &WsjcppYamlCursor::comment(const std::string& sComment) { + if (m_pCurrentNode != nullptr) { + m_pCurrentNode->setComment(sComment); + } + return *this; +} + +// --------------------------------------------------------------------- + +std::string WsjcppYamlCursor::valStr() { + return m_pCurrentNode != nullptr ? m_pCurrentNode->getValue() : ""; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor &WsjcppYamlCursor::val(const std::string &sValue) { + if (m_pCurrentNode != nullptr) { + m_pCurrentNode->setValue(sValue); // TODO reserch need or not add quotes + } + return *this; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor &WsjcppYamlCursor::val(const char *sValue) { + this->val(std::string(sValue)); + return *this; +} + +// --------------------------------------------------------------------- + +int WsjcppYamlCursor::valInt() { + if (m_pCurrentNode != nullptr) { + std::string sValue = m_pCurrentNode->getValue(); + sValue = WsjcppCore::toLower(sValue); + int nValue = std::atoi(sValue.c_str()); + if (std::to_string(nValue) != sValue) { + WsjcppLog::throw_err(TAG, "valInt, Element must be int but have a string" + m_pCurrentNode->getForLogFormat()); + } + return nValue; + } + return 0; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor &WsjcppYamlCursor::val(int nValue) { + if (m_pCurrentNode != nullptr) { + m_pCurrentNode->setValue(std::to_string(nValue)); + } + return *this; +} + +// --------------------------------------------------------------------- + +bool WsjcppYamlCursor::valBool() { + if (m_pCurrentNode != nullptr) { + std::string sValue = m_pCurrentNode->getValue(); + sValue = WsjcppCore::toLower(sValue); + if (sValue == "yes" || sValue == "true") { + return true; + } else if (sValue == "no" || sValue == "false") { + return false; + } else { + WsjcppLog::throw_err(TAG, "valBool, Element must be bool expected with ignore case like" + "['yes','no','true','false'] for " + m_pCurrentNode->getForLogFormat()); + } + } + return false; +} + +// --------------------------------------------------------------------- + +WsjcppYamlCursor &WsjcppYamlCursor::val(bool bValue) { + if (m_pCurrentNode != nullptr) { + m_pCurrentNode->setValue((bValue ? "yes" : "no")); + } + return *this; +} + +// --------------------------------------------------------------------- + WsjcppYamlCursor WsjcppYamlCursor::operator[](int idx) const { if (m_pCurrentNode != nullptr && m_pCurrentNode->isArray() && idx < m_pCurrentNode->getLength() && idx >= 0) { return WsjcppYamlCursor(m_pCurrentNode->getElement(idx)); diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 333a8de..ffd58c0 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -99,24 +99,6 @@ class WsjcppYamlItem { // TODO: rename to node WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE ); - bool setElementValue( - const std::string &sName, int nValue, - WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, - WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE - ); - - bool setElementValue( - const std::string &sName, long nValue, - WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, - WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE - ); - - bool setElementValue( - const std::string &sName, bool bValue, - WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE, - WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE - ); - bool createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes); WsjcppYamlItem *createElementMap(); bool createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes); @@ -130,11 +112,7 @@ class WsjcppYamlItem { // TODO: rename to node bool isValue(); - std::string getValue(); // deprecated - std::string getStringValue(); // simular 'getValue' - bool getBoolValue(); - long getLongValue(); - int getIntValue(); + std::string getValue(); // contains only strings void setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes = WSJCPP_YAML_QUOTES_NONE); WsjcppYamlQuotes getValueQuotes(); @@ -222,21 +200,28 @@ class WsjcppYamlCursor { // null or undefined bool isNull() const; + // isUndefined + bool isUndefined() const; + + // value + bool isValue() const; + // array bool isArray() const; size_t size() const; - WsjcppYamlCursor &push(const std::string &sVal); - WsjcppYamlCursor &push(int nVal); - WsjcppYamlCursor &push(bool bVal); - WsjcppYamlCursor &remove(int nIdx); + // WsjcppYamlCursor &push(const std::string &sVal); + // WsjcppYamlCursor &push(int nVal); + // WsjcppYamlCursor &push(bool bVal); + // WsjcppYamlCursor &remove(int nIdx); // map bool isMap() const; - std::vector keys(); - WsjcppYamlCursor &set(const std::string &sName, const std::string &sValue); - WsjcppYamlCursor &set(const std::string &sName, int nValue); - WsjcppYamlCursor &set(const std::string &sName, bool bValue); - WsjcppYamlCursor &remove(const std::string &sKey); + std::vector keys() const; + bool hasKey(const std::string &sKey) const; + // WsjcppYamlCursor &set(const std::string &sName, const std::string &sValue); + // WsjcppYamlCursor &set(const std::string &sName, int nValue); + // WsjcppYamlCursor &set(const std::string &sName, bool bValue); + // WsjcppYamlCursor &remove(const std::string &sKey); // comment std::string comment(); @@ -245,7 +230,8 @@ class WsjcppYamlCursor { // val std::string valStr(); WsjcppYamlCursor &val(const std::string &sValue); - bool valInt(); + WsjcppYamlCursor &val(const char *sValue); + int valInt(); WsjcppYamlCursor &val(int nValue); bool valBool(); WsjcppYamlCursor &val(bool bValue); @@ -255,6 +241,7 @@ class WsjcppYamlCursor { WsjcppYamlCursor operator[](const std::string &sName) const; private: + std::string TAG; WsjcppYamlItem *m_pCurrentNode; }; diff --git a/unit-tests.wsjcpp/src/unit_test_cursor.cpp b/unit-tests.wsjcpp/src/unit_test_cursor.cpp index aeaa346..d9ef0d6 100644 --- a/unit-tests.wsjcpp/src/unit_test_cursor.cpp +++ b/unit-tests.wsjcpp/src/unit_test_cursor.cpp @@ -35,6 +35,7 @@ void UnitTestCursor::executeTest() { "# Some comment 1\n" "map1: \n" " map11: \n" + " sss: \n" " map111: \n" " param1111: v1111\n" " param1112: v1112\n" @@ -50,11 +51,17 @@ void UnitTestCursor::executeTest() { " map123: \n" " param1231: v1231\n" " param1232: v1232\n" + " param1232: v1232\n" "param2: v2 # some comment 2\n" - "arr1: # some comment 2\n" + "arr1: # some comment array 1\n" " - some1\n" - " - some2\n" - " - some3\n" + " - 3\n" + "\n" + " - Yes\n" + " # empty\n" + " - no\n" + " - true\n" + " - False\n" "\n" // empty line ; @@ -66,21 +73,97 @@ void UnitTestCursor::executeTest() { } compare("map1 is null", yaml["map1"].isNull(), false); + compare("map1 is undefined", yaml["map1"].isUndefined(), false); + compare("map1 is value", yaml["map1"].isValue(), false); compare("map1 is array", yaml["map1"].isArray(), false); compare("map1 is map", yaml["map1"].isMap(), true); compare("map1-1111 is null", yaml["map1-1111"].isNull(), true); + compare("map1 is undefined", yaml["map1-1111"].isUndefined(), false); + compare("map1 is value", yaml["map1-1111"].isValue(), false); compare("map1-1111 is array", yaml["map1-1111"].isArray(), false); compare("map1-1111 is map", yaml["map1-1111"].isMap(), false); compare("arr1 is null", yaml["arr1"].isNull(), false); + compare("arr1 is undefined", yaml["arr1"].isUndefined(), false); + compare("arr1 is value", yaml["arr1"].isValue(), false); compare("arr1 is array", yaml["arr1"].isArray(), true); compare("arr1 is map", yaml["arr1"].isMap(), false); - + + compare("map1.map11.sss is null", yaml["map1"]["map11"]["sss"].isNull(), false); + compare("map1.map11.sss is undefined", yaml["map1"]["map11"]["sss"].isUndefined(), true); + compare("map1.map11.sss is value", yaml["map1"]["map11"]["sss"].isValue(), false); + compare("map1.map11.sss is array", yaml["map1"]["map11"]["sss"].isArray(), false); + compare("map1.map11.sss is map", yaml["map1"]["map11"]["sss"].isMap(), false); + + compare("map1.map11.map111.param1111 is null", yaml["map1"]["map11"]["map111"]["param1111"].isNull(), false); + compare("map1.map11.map111.param1111 is undefined", yaml["map1"]["map11"]["map111"]["param1111"].isUndefined(), false); + compare("map1.map11.map111.param1111 is value", yaml["map1"]["map11"]["map111"]["param1111"].isValue(), true); + compare("map1.map11.map111.param1111 is array", yaml["map1"]["map11"]["map111"]["param1111"].isArray(), false); + compare("map1.map11.map111.param1111 is map", yaml["map1"]["map11"]["map111"]["param1111"].isMap(), false); compare("map use as array", yaml["map1"][0].isNull(), true); compare("array use as map", yaml["arr1"]["0"].isNull(), true); + compare("array use as map", yaml["arr1"][0].isNull(), false); + + compare("array size", yaml["arr1"].comment(), "some comment array 1"); + compare("array size", yaml["arr1"].size(), 6); + compare("array el 0", yaml["arr1"][0].valStr(), "some1"); + compare("array el 1", yaml["arr1"][1].valStr(), "3"); + compare("array el 2", yaml["arr1"][2].valStr(), "Yes"); + compare("array el 3", yaml["arr1"][3].valStr(), "no"); + compare("array el 4", yaml["arr1"][4].valStr(), "true"); + compare("array el 5", yaml["arr1"][5].valStr(), "False"); + + compare("array bool el 2", yaml["arr1"][2].valBool(), true); + compare("array bool el 3", yaml["arr1"][3].valBool(), false); + compare("array bool el 4", yaml["arr1"][4].valBool(), true); + compare("array bool el 5", yaml["arr1"][5].valBool(), false); + + // int + compare("array size", yaml["arr1"][1].valInt(), 3); + yaml["arr1"][1].val(10); + compare("array size", yaml["arr1"][1].valInt(), 10); + + // string + compare("array el 0 - 1", yaml["arr1"][0].valStr(), "some1"); + yaml["arr1"][0].val("different value").comment("1234"); + compare("array el 0 - 2", yaml["arr1"][0].valStr(), "different value"); + compare("array el 0 - 3", yaml["arr1"][0].comment(), "1234"); + + // bool + compare("array bool el 4", yaml["arr1"][4].valStr(), "true"); + compare("array bool el 4", yaml["arr1"][4].valBool(), true); + yaml["arr1"][4].val(true); + compare("array bool el 4", yaml["arr1"][4].valStr(), "yes"); + compare("array bool el 4", yaml["arr1"][4].valBool(), true); + yaml["arr1"][4].val(false); + compare("array bool el 4", yaml["arr1"][4].valStr(), "no"); + compare("array bool el 4", yaml["arr1"][4].valBool(), false); + + // map + compare("map1.map12", yaml["map1"]["map12"].isMap(), true); + + std::vector vKeys = yaml["map1"]["map12"].keys(); + compare("map1.map12 keys size", vKeys.size(), 4); + if (vKeys.size() == 4) { + compare("map1.map12 keys 0", vKeys[0], "param121"); + compare("map1.map12 keys 1", vKeys[1], "param122"); + compare("map1.map12 keys 2", vKeys[2], "map123"); + compare("map1.map12 keys 3", vKeys[3], "param1232"); + } + compare("map1.map12 has key1", yaml["map1"]["map12"].hasKey("some"), false); + compare("map1.map12 has key2", yaml["map1"]["map12"].hasKey("map123"), true); + compare("map1.map12 is value", yaml["map1"]["map12"]["map123"].isValue(), false); + compare("map1.map12 is value", yaml["map1"]["map12"]["param122"].isValue(), true); + + /* WsjcppYamlCursor &push(const std::string &sVal); + WsjcppYamlCursor &push(int nVal); + WsjcppYamlCursor &push(bool bVal); + WsjcppYamlCursor &remove(int nIdx);*/ + + } // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp b/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp index ebf3541..361233d 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_write_file.cpp @@ -44,8 +44,7 @@ void UnitTestReadWriteFile::executeTest() { compare("has networks", yaml.getRoot()->hasElement("networks"), true); compare("has services", yaml.getRoot()->hasElement("services"), true); - compare("version-value", yaml.getRoot()->getElement("version")->getStringValue(), "3"); - compare("version-value", yaml.getRoot()->getElement("version")->getIntValue(), 3); // wrong or not ? + compare("version-value", yaml.getRoot()->getElement("version")->getValue(), "3"); if (!compare("Error parsing", yaml.saveToFile(sFilepathOutput), true)) { WsjcppLog::err(TAG, sError); diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index e913a25..25104a5 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -43,8 +43,8 @@ void UnitTestReadYaml::executeTest() { compare("has networks", yaml.getRoot()->hasElement("networks"), true); compare("has services", yaml.getRoot()->hasElement("services"), true); - compare("version-value", yaml.getRoot()->getElement("version")->getStringValue(), "3"); - compare("version-value", yaml.getRoot()->getElement("version")->getIntValue(), 3); // wrong or not ? + compare("version-value", yaml.getRoot()->getElement("version")->getValue(), "3"); + } // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp index ed4256e..789632e 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp @@ -52,15 +52,15 @@ void UnitTestRemoveElementInArray::executeTest() { WsjcppYamlItem *pArr1 = yaml.getRoot()->getElement("arr1"); compare("arr1 len", pArr1->getLength(), 3); - compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getStringValue(), "i1"); - compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getStringValue(), "i2"); - compare("arr1 name2 ", pArr1->getElement(2)->getElement("name")->getStringValue(), "i3"); + compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); + compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i2"); + compare("arr1 name2 ", pArr1->getElement(2)->getElement("name")->getValue(), "i3"); pArr1->removeElement(1); compare("arr1 len", pArr1->getLength(), 2); - compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getStringValue(), "i1"); - compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getStringValue(), "i3"); + compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); + compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i3"); } // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp index ee5d6c0..9c52efe 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp @@ -72,17 +72,17 @@ void UnitTestYamlParserAll::executeTest() { } WsjcppYamlItem *pItem = nullptr; - compare("test10", yaml.getRoot()->getElement("test10")->getStringValue(), "one"); - compare("test20", yaml.getRoot()->getElement("test20")->getStringValue(), "two"); + compare("test10", yaml.getRoot()->getElement("test10")->getValue(), "one"); + compare("test20", yaml.getRoot()->getElement("test20")->getValue(), "two"); pItem = yaml.getRoot()->getElement("array30"); compare("array30_length", pItem->getLength(), 3); pItem = yaml.getRoot()->getElement("array30")->getElement(0); - compare("test30_value", pItem->getStringValue(), "one31"); + compare("test30_value", pItem->getValue(), "one31"); compare("test30_comment", pItem->getComment(), "this field for test array30"); pItem = yaml.getRoot()->getElement("array30")->getElement(1); - compare("test40_value", pItem->getStringValue(), "two32"); + compare("test40_value", pItem->getValue(), "two32"); compare("test40_comment", pItem->getComment(), ""); pItem = yaml.getRoot()->getElement("array40"); @@ -92,10 +92,10 @@ void UnitTestYamlParserAll::executeTest() { compare("array50_length", pItem->getLength(), 2); pItem = yaml.getRoot()->getElement("map60")->getElement("test70"); - compare("test70_value", pItem->getStringValue(), "opa1"); + compare("test70_value", pItem->getValue(), "opa1"); pItem = yaml.getRoot()->getElement("map60")->getElement("test80"); - compare("test80_comment", pItem->getStringValue(), "opa2"); + compare("test80_comment", pItem->getValue(), "opa2"); std::string sSaved2 = ""; if (compare("saving yaml", yaml.saveToString(sSaved2), true)) { diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp index cf3945f..5190cd4 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp @@ -57,7 +57,7 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { WsjcppYamlItem *pItem = nullptr; - compare("param1-value", yaml.getRoot()->getElement("param1")->getStringValue(), "none value1"); + compare("param1-value", yaml.getRoot()->getElement("param1")->getValue(), "none value1"); compare("param1-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getLine(), "param1: none value1 # it's value for something # olala "); compare("param1-original-number-of-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getNumberOfLine(), 1); compare("param1-comment", yaml.getRoot()->getElement("param1")->getComment(), "it's value for something # olala"); @@ -66,28 +66,28 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { compare("array-test2-comment", yaml.getRoot()->getElement("array-test2")->getComment(), "some comment 2"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(0); - compare("array-test2-element0-value", pItem->getStringValue(), "value21"); + compare("array-test2-element0-value", pItem->getValue(), "value21"); compare("array-test2-element0-comment", pItem->getComment(), "comment v21"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(1); - compare("array-test2-element1-value", yaml.getRoot()->getElement("array-test2")->getElement(1)->getStringValue(), "value22"); + compare("array-test2-element1-value", yaml.getRoot()->getElement("array-test2")->getElement(1)->getValue(), "value22"); compare("array-test2-element1-comment", yaml.getRoot()->getElement("array-test2")->getElement(1)->getComment(), "comment v22"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(2); - compare("array-test2-element2-value", pItem->getStringValue(), "true"); + compare("array-test2-element2-value", pItem->getValue(), "true"); compare("array-test2-element2-comment", pItem->getComment(), "comment true"); compare("array-and-map-length", yaml.getRoot()->getElement("array-and-map")->getLength(), 2); pItem = yaml.getRoot()->getElement("array-and-map")->getElement(0); - compare("array-and-map-element0-value", pItem->getElement("submap-param1")->getStringValue(), "v01"); - compare("array-and-map-element0-value", pItem->getElement("submap-param2")->getStringValue(), "v02"); + compare("array-and-map-element0-value", pItem->getElement("submap-param1")->getValue(), "v01"); + compare("array-and-map-element0-value", pItem->getElement("submap-param2")->getValue(), "v02"); pItem = yaml.getRoot()->getElement("array-and-map")->getElement(1); - compare("array-and-map-element1-value", pItem->getElement("submap-param1")->getStringValue(), "v11"); - compare("array-and-map-element1-value", pItem->getElement("submap-param2")->getStringValue(), "v12"); + compare("array-and-map-element1-value", pItem->getElement("submap-param1")->getValue(), "v11"); + compare("array-and-map-element1-value", pItem->getElement("submap-param2")->getValue(), "v12"); - compare("param2-value", yaml.getRoot()->getElement("param2")->getStringValue(), "v2"); + compare("param2-value", yaml.getRoot()->getElement("param2")->getValue(), "v2"); std::string sSaved = ""; if (compare("save yaml", yaml.saveToString(sSaved), true)) { diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp index f394d9a..28963ad 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp @@ -59,21 +59,21 @@ void UnitTestYamlParserComments::executeTest() { // TODO: .findLine(0) - compare("param1", yaml.getRoot()->getElement("param1")->getStringValue(), "value1"); + compare("param1", yaml.getRoot()->getElement("param1")->getValue(), "value1"); compare("param1", yaml.getRoot()->getElement("param1")->getComment(), "comment 2 # comment"); - compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); + compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "value2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some \"comment 3\""); compare("array1-comment", yaml.getRoot()->getElement("array1")->getComment(), "comment 5"); compare("array1-length", yaml.getRoot()->getElement("array1")->getLength(), 2); - compare("array1-element0-value", yaml.getRoot()->getElement("array1")->getElement(0)->getStringValue(), "val1"); + compare("array1-element0-value", yaml.getRoot()->getElement("array1")->getElement(0)->getValue(), "val1"); compare("array1-element0-comment", yaml.getRoot()->getElement("array1")->getElement(0)->getComment(), "comment 6"); // TODO: .findLine(7) - compare("array1-element1-value", yaml.getRoot()->getElement("array1")->getElement(1)->getStringValue(), "val2"); + compare("array1-element1-value", yaml.getRoot()->getElement("array1")->getElement(1)->getValue(), "val2"); compare("array1-element1-comment", yaml.getRoot()->getElement("array1")->getElement(1)->getComment(), "comment 8"); compare("map1-comment", yaml.getRoot()->getElement("map1")->getComment(), "comment 9"); @@ -81,7 +81,7 @@ void UnitTestYamlParserComments::executeTest() { compare("map1-p2-comment", yaml.getRoot()->getElement("map1")->getElement("p2")->getComment(), "comment 12"); - // compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); + // compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "value2"); // compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); std::string sSaved = ""; diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp index 7a82cc3..bb57a45 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp @@ -65,26 +65,26 @@ void UnitTestYamlParserHierarchicalMap::executeTest() { WsjcppYamlItem *pItem = nullptr; pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map111"); - compare("param1111", pItem->getElement("param1111")->getStringValue(), "v1111"); - compare("param1112", pItem->getElement("param1112")->getStringValue(), "v1112"); + compare("param1111", pItem->getElement("param1111")->getValue(), "v1111"); + compare("param1112", pItem->getElement("param1112")->getValue(), "v1112"); pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map112"); - compare("param1121", pItem->getElement("param1121")->getStringValue(), "v1121"); - compare("param1122", pItem->getElement("param1122")->getStringValue(), "v1122"); + compare("param1121", pItem->getElement("param1121")->getValue(), "v1121"); + compare("param1122", pItem->getElement("param1122")->getValue(), "v1122"); pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map113"); - compare("param1131", pItem->getElement("param1131")->getStringValue(), "v1131"); - compare("param1132", pItem->getElement("param1132")->getStringValue(), "v1132"); + compare("param1131", pItem->getElement("param1131")->getValue(), "v1131"); + compare("param1132", pItem->getElement("param1132")->getValue(), "v1132"); pItem = yaml.getRoot()->getElement("map1")->getElement("map12"); - compare("param121", pItem->getElement("param121")->getStringValue(), "v121"); - compare("param122", pItem->getElement("param122")->getStringValue(), "v122"); + compare("param121", pItem->getElement("param121")->getValue(), "v121"); + compare("param122", pItem->getElement("param122")->getValue(), "v122"); pItem = yaml.getRoot()->getElement("map1")->getElement("map12")->getElement("map123"); - compare("param1231", pItem->getElement("param1231")->getStringValue(), "v1231"); - compare("param1232", pItem->getElement("param1232")->getStringValue(), "v1232"); + compare("param1231", pItem->getElement("param1231")->getValue(), "v1231"); + compare("param1232", pItem->getElement("param1232")->getValue(), "v1232"); - compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "v2"); + compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "v2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); std::string sSaved = ""; diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp index a33dec8..dbfc4d1 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_quotes.cpp @@ -57,23 +57,23 @@ void UnitTestYamlParserQuotes::executeTest() { // TODO: .findLine(0) - compare("param1", yaml.getRoot()->getElement("param1")->getStringValue(), "value1"); + compare("param1", yaml.getRoot()->getElement("param1")->getValue(), "value1"); compare("param1", yaml.getRoot()->getElement("param1")->getComment(), "v1"); - compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), " #$!!!value2"); + compare("param2", yaml.getRoot()->getElement("param2")->getValue(), " #$!!!value2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "val 2"); - compare(" param3 olala", yaml.getRoot()->getElement(" param3 olala")->getStringValue(), "val 3"); + compare(" param3 olala", yaml.getRoot()->getElement(" param3 olala")->getValue(), "val 3"); compare(" param3 olala", yaml.getRoot()->getElement(" param3 olala")->getComment(), "val 3***"); - compare("param4 val", yaml.getRoot()->getElement("param4")->getStringValue(), " #$!!!value4"); - compare("param4 comment", yaml.getRoot()->getElement("param4")->getStringValue(), " #$!!!value4"); + compare("param4 val", yaml.getRoot()->getElement("param4")->getValue(), " #$!!!value4"); + compare("param4 comment", yaml.getRoot()->getElement("param4")->getValue(), " #$!!!value4"); - compare("url-value", yaml.getRoot()->getElement("url")->getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); - compare("issues-value", yaml.getRoot()->getElement("issues")->getStringValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); - compare("empty-value", yaml.getRoot()->getElement("empty")->getStringValue(), ""); + compare("url-value", yaml.getRoot()->getElement("url")->getValue(), "https://github.com/wsjcpp/wsjcpp-yaml"); + compare("issues-value", yaml.getRoot()->getElement("issues")->getValue(), "https://github.com/wsjcpp/wsjcpp-yaml/issues"); + compare("empty-value", yaml.getRoot()->getElement("empty")->getValue(), ""); - compare("array-element0-value", yaml.getRoot()->getElement("array")->getElement(0)->getStringValue(), "https://github.com/wsjcpp/wsjcpp-core:v0.0.1"); + compare("array-element0-value", yaml.getRoot()->getElement("array")->getElement(0)->getValue(), "https://github.com/wsjcpp/wsjcpp-core:v0.0.1"); std::string sSaved = ""; compare("save yaml", yaml.saveToString(sSaved), true); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp index ef44221..c4b4903 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp @@ -56,7 +56,7 @@ void UnitTestYamlParserSimpleArray::executeTest() { WsjcppYamlItem *pItem = nullptr; - compare("param1-value", yaml.getRoot()->getElement("param1")->getStringValue(), "none value1"); + compare("param1-value", yaml.getRoot()->getElement("param1")->getValue(), "none value1"); compare("param1-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getLine(), "param1: none value1 # it's value for something # olala "); compare("param1-original-number-of-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getNumberOfLine(), 1); compare("param1-comment", yaml.getRoot()->getElement("param1")->getComment(), "it's value for something # olala"); @@ -65,39 +65,39 @@ void UnitTestYamlParserSimpleArray::executeTest() { compare("array-test2-comment", yaml.getRoot()->getElement("array-test2")->getComment(), "some comment 2"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(0); - compare("array-test2-element0-value", pItem->getStringValue(), "value21"); + compare("array-test2-element0-value", pItem->getValue(), "value21"); compare("array-test2-element0-comment", pItem->getComment(), "comment v21"); pItem = yaml.getRoot()->getElement("array-test2")->getElement(1); - compare("array-test2-element1-value", pItem->getStringValue(), "value22"); + compare("array-test2-element1-value", pItem->getValue(), "value22"); compare("array-test2-element1-comment", pItem->getComment(), "comment v22"); - compare("array-test2-element2-value", yaml.getRoot()->getElement("array-test2")->getElement(2)->getStringValue(), "true"); + compare("array-test2-element2-value", yaml.getRoot()->getElement("array-test2")->getElement(2)->getValue(), "true"); compare("array-test2-element2-line", yaml.getRoot()->getElement("array-test2")->getElement(2)->getPlaceInFile().getLine(), " - true # comment true "); compare("array-test2-element2-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(2)->getPlaceInFile().getNumberOfLine(), 5); compare("array-test2-element2-comment", yaml.getRoot()->getElement("array-test2")->getElement(2)->getComment(), "comment true"); - compare("array-test2-element3-value", yaml.getRoot()->getElement("array-test2")->getElement(3)->getStringValue(), "falsesome"); + compare("array-test2-element3-value", yaml.getRoot()->getElement("array-test2")->getElement(3)->getValue(), "falsesome"); compare("array-test2-element3-line", yaml.getRoot()->getElement("array-test2")->getElement(3)->getPlaceInFile().getLine(), " - falsesome "); compare("array-test2-element3-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(3)->getPlaceInFile().getNumberOfLine(), 7); compare("array-test2-element3-comment", yaml.getRoot()->getElement("array-test2")->getElement(3)->getComment(), ""); - compare("array-test2-element4-value", yaml.getRoot()->getElement("array-test2")->getElement(4)->getStringValue(), "free@free"); + compare("array-test2-element4-value", yaml.getRoot()->getElement("array-test2")->getElement(4)->getValue(), "free@free"); compare("array-test2-element4-line", yaml.getRoot()->getElement("array-test2")->getElement(4)->getPlaceInFile().getLine(), " - free@free "); compare("array-test2-element4-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(4)->getPlaceInFile().getNumberOfLine(), 8); compare("array-test2-element4-comment", yaml.getRoot()->getElement("array-test2")->getElement(4)->getComment(), ""); - compare("array-test2-element5-value", yaml.getRoot()->getElement("array-test2")->getElement(5)->getStringValue(), ""); + compare("array-test2-element5-value", yaml.getRoot()->getElement("array-test2")->getElement(5)->getValue(), ""); compare("array-test2-element5-line", yaml.getRoot()->getElement("array-test2")->getElement(5)->getPlaceInFile().getLine(), " - # empty "); compare("array-test2-element5-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(5)->getPlaceInFile().getNumberOfLine(), 9); compare("array-test2-element5-comment", yaml.getRoot()->getElement("array-test2")->getElement(5)->getComment(), "empty"); - compare("array-test2-element6-value", yaml.getRoot()->getElement("array-test2")->getElement(6)->getStringValue(), "1"); + compare("array-test2-element6-value", yaml.getRoot()->getElement("array-test2")->getElement(6)->getValue(), "1"); compare("array-test2-element6-line", yaml.getRoot()->getElement("array-test2")->getElement(6)->getPlaceInFile().getLine(), " - 1"); compare("array-test2-element6-original-number-of-line", yaml.getRoot()->getElement("array-test2")->getElement(6)->getPlaceInFile().getNumberOfLine(), 10); compare("array-test2-element6-comment", yaml.getRoot()->getElement("array-test2")->getElement(6)->getComment(), ""); - compare("param2-value", yaml.getRoot()->getElement("param2")->getStringValue(), "val2"); + compare("param2-value", yaml.getRoot()->getElement("param2")->getValue(), "val2"); compare("param2-line", yaml.getRoot()->getElement("param2")->getPlaceInFile().getLine(), "param2: val2 # value 2 "); compare("param2-original-number-of-line", yaml.getRoot()->getElement("param2")->getPlaceInFile().getNumberOfLine(), 11); compare("param2-comment", yaml.getRoot()->getElement("param2")->getComment(), "value 2"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp index 5821954..6607e78 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp @@ -47,8 +47,8 @@ void UnitTestYamlParserSimpleMap::executeTest() { } WsjcppYamlItem *pItem = nullptr; - compare("param1", yaml.getRoot()->getElement("param1")->getStringValue(), "value1"); - compare("param2", yaml.getRoot()->getElement("param2")->getStringValue(), "value2"); + compare("param1", yaml.getRoot()->getElement("param1")->getValue(), "value1"); + compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "value2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); std::string sSaved = ""; From 3ca6b38b674be908ce027e278156e8ea5b50daa0 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Thu, 24 Sep 2020 17:40:02 +0700 Subject: [PATCH 14/29] Removed printing 'TODO: undefined' --- src/wsjcpp_yaml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 291c764..844edee 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -554,7 +554,7 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { } } } else { - sRet = "TODO: undefined"; + sRet = ""; // undefined element must be empty } if (sIntent == "") { WsjcppCore::trim(sRet); From db87a3b26cd0fc8008155eaf107815b0b830387c Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 18:19:50 +0700 Subject: [PATCH 15/29] Fixed empty lines --- src/wsjcpp_yaml.cpp | 57 +++++++++++++++---- .../read-write-file/docker-compose.yml | 7 ++- unit-tests.wsjcpp/parser_yaml.py | 8 +++ .../src/unit_test_yaml_parser_comments.cpp | 2 +- 4 files changed, 61 insertions(+), 13 deletions(-) create mode 100755 unit-tests.wsjcpp/parser_yaml.py diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 844edee..276e685 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -505,29 +505,43 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { } sRet += "# " + m_sComment; } + } else if (this->isUndefined()) { + for (int i = 0; i < m_vObjects.size(); i++) { + if (m_vObjects[i]->isEmpty()) { + sRet += "\n"; + } else { + WsjcppLog::warn(TAG, "Undefined element conatins something else"); + } + // sRet += std::to_string(m_vObjects.size()); + } + return sRet; } else if (this->isEmpty()) { if (m_sComment.length() > 0) { sRet += sIntent + "# " + m_sComment; } + // sRet += "\n"; + return sRet; } else if (this->isArray()) { for (int i = 0; i < m_vObjects.size(); i++) { WsjcppYamlItem *pItem = m_vObjects[i]; if (pItem->isEmpty()) { - sRet += sIntent + pItem->toString(); + sRet += pItem->toString(sIntent) + "\n"; + // sRet += "\n"; } else if (pItem->isMap()) { std::string s = pItem->toString(sIntent + " "); WsjcppCore::trim(s); sRet += sIntent + "- " + s; + sRet += "\n"; } else { sRet += sIntent + "- " + pItem->toString(); + sRet += "\n"; } - sRet += "\n"; } } else if (this->isMap()) { for (int i = 0; i < m_vObjects.size(); i++) { WsjcppYamlItem *pItem = m_vObjects[i]; if (pItem->isEmpty() ) { - sRet += sIntent + pItem->toString(); + sRet += pItem->toString(sIntent); sRet += "\n"; } else if (pItem->isArray() || pItem->isMap()) { if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { @@ -543,12 +557,18 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { sRet += "\n"; sRet += pItem->toString(sIntent + " "); } else { + std::string sVal = pItem->toString(); + std::string sVal_ = sVal; + sVal_ = WsjcppCore::trim(sVal_); + if (sVal_.length() > 0) { + sVal = " " + sVal; + } if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { - sRet += sIntent + "\"" + pItem->getName() + "\": " + pItem->toString(); + sRet += sIntent + "\"" + pItem->getName() + "\":" + sVal; } else if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { - sRet += sIntent + "\'" + pItem->getName() + "\': " + pItem->toString(); + sRet += sIntent + "\'" + pItem->getName() + "\':" + sVal; } else { - sRet += sIntent + pItem->getName() + ": " + pItem->toString(); + sRet += sIntent + pItem->getName() + ":" + sVal; } sRet += "\n"; } @@ -1216,11 +1236,26 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, int nDiffIntent = nLineIntent - st.nIntent; if (st.line.isEmptyLine()) { - WsjcppYamlItem *pItem = new WsjcppYamlItem( - st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY - ); - st.pCurItem->appendElement(pItem); + + + if (st.pCurItem != nullptr) { + + if (st.pCurItem->isArray() || st.pCurItem->isMap() || st.pCurItem->isUndefined()) { + WsjcppYamlItem *pItem = new WsjcppYamlItem( + st.pCurItem, st.placeInFile, + WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY + ); + st.pCurItem->appendElement(pItem); + } else if (st.pCurItem->getParent() != nullptr && (st.pCurItem->getParent()->isArray() || st.pCurItem->getParent()->isMap())) { + WsjcppYamlItem *pItem = new WsjcppYamlItem( + st.pCurItem->getParent(), st.placeInFile, + WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY + ); + st.pCurItem->getParent()->appendElement(pItem); + } else { + WsjcppLog::throw_err(TAG, "Empty element can be added only to map or to array"); + } + } continue; } diff --git a/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml b/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml index 0a02219..acc6124 100644 --- a/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml +++ b/unit-tests.wsjcpp/data-tests/read-write-file/docker-compose.yml @@ -3,6 +3,7 @@ version: "3" services: + # service vote vote: build: ./vote command: python app.py @@ -14,14 +15,18 @@ services: - front-tier - back-tier + # service result result: build: ./result command: nodemon server.js volumes: - ./result:/app ports: - - "5001:80" + # ports forward + - "5001:80" # some + - "5858:5858" + networks: - front-tier - back-tier diff --git a/unit-tests.wsjcpp/parser_yaml.py b/unit-tests.wsjcpp/parser_yaml.py new file mode 100755 index 0000000..f561ff0 --- /dev/null +++ b/unit-tests.wsjcpp/parser_yaml.py @@ -0,0 +1,8 @@ +import yaml + + +a_yaml_file = open("./data-tests/read-write-file/docker-compose.yml") + +parsed_yaml_file = yaml.load(a_yaml_file, Loader=yaml.FullLoader) + +print(parsed_yaml_file) \ No newline at end of file diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp index 28963ad..0c11427 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_comments.cpp @@ -94,7 +94,7 @@ void UnitTestYamlParserComments::executeTest() { "array1: # comment 5\n" " - val1 # comment 6\n" " # comment 7\n" - " \n" + "\n" " - val2 # comment 8\n" "map1: # comment 9\n" " p1: val 1 # comment 10\n" From 7e9308aa96e7072d5acf753c8407a18f00b7ceef Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 19:55:35 +0700 Subject: [PATCH 16/29] Improved reading yaml (docker-compose example) and prepared unit-tests for tagnames --- src/wsjcpp_yaml.cpp | 9 +- src/wsjcpp_yaml.h | 2 + unit-tests.wsjcpp/CMakeLists.txt | 1 + unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 176 +++++++++++++++++- unit-tests.wsjcpp/src/unit_test_tag_names.cpp | 50 +++++ wsjcpp.yml | 2 + 6 files changed, 236 insertions(+), 4 deletions(-) create mode 100644 unit-tests.wsjcpp/src/unit_test_tag_names.cpp diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 276e685..a09c733 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -274,7 +274,7 @@ std::vector WsjcppYamlItem::getKeys() { std::vector vKeys; for (int i = 0; i < m_vObjects.size(); i++) { WsjcppYamlItem *pItem = m_vObjects[i]; - if (pItem->isValue() || pItem->isMap() || pItem->isArray()) { + if (pItem->isValue() || pItem->isMap() || pItem->isArray() || pItem->isUndefined()) { std::string sName = pItem->getName(); vKeys.push_back(sName); } @@ -783,6 +783,7 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; m_sValue += c; } else if (c == ':' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { + std::cout << m_sValue << std::endl; if (m_sName.length() == 0) { m_sName = m_sValue; m_sValue = ""; // reset value it was param name @@ -848,6 +849,12 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE // --------------------------------------------------------------------- +bool WsjcppYamlParsebleLine::canTagName(const std::string &sVal) { + return true; +} + +// --------------------------------------------------------------------- + std::string WsjcppYamlParsebleLine::removeStringDoubleQuotes(const std::string &sValue) { if (sValue.size() > 0 && sValue[0] != '"') { return sValue; diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index ffd58c0..3b60661 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -160,6 +160,7 @@ class WsjcppYamlParsebleLine { bool parseLine(const std::string &sLine, std::string &sError); private: + std::string TAG; int m_nLineNumber; @@ -173,6 +174,7 @@ class WsjcppYamlParsebleLine { bool m_bHasComment; bool m_bEmptyLine; + bool canTagName(const std::string &sVal); std::string removeStringDoubleQuotes(const std::string &sValue); std::string removeStringSingleQuotes(const std::string &sValue); }; diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index 4c801c0..f57c7f0 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -48,6 +48,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_yaml.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_write_file.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_cursor.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_tag_names.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index 25104a5..0008f5b 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -39,12 +39,182 @@ void UnitTestReadYaml::executeTest() { } compare("has version", yaml.getRoot()->hasElement("version"), true); - compare("has volumes", yaml.getRoot()->hasElement("volumes"), true); - compare("has networks", yaml.getRoot()->hasElement("networks"), true); + compare("has version is value", yaml.getRoot()->getElement("version")->isValue(), true); + compare("version-value", yaml.getRoot()->getElement("version")->getValue(), "3"); + compare("has services", yaml.getRoot()->hasElement("services"), true); + compare("has services is map", yaml.getRoot()->getElement("services")->isMap(), true); + + + WsjcppYamlItem *pServices = yaml.getRoot()->getElement("services"); + + compare("has services.vote", pServices->hasElement("vote"), true); + compare("has services.vote is map", pServices->getElement("vote")->isMap(), true); + + + /* + +services: + vote: + build: ./vote + command: python app.py + volumes: + - ./vote:/app + ports: + - "5000:80" + networks: + - front-tier + - back-tier + + result: + build: ./result + command: nodemon server.js + volumes: + - ./result:/app + */ + + // services.result + { + compare("has services.result", pServices->hasElement("result"), true); + compare("services.result is map", pServices->getElement("result")->isMap(), true); + compare("services.result keys size 5", pServices->getElement("result")->getKeys().size(), 5); + + WsjcppYamlItem *pResult = pServices->getElement("result"); + + WsjcppYamlItem *pResultVolumes = pResult->getElement("volumes"); + compare("services.result.volumes is array", pResultVolumes->isArray(), true); + compare("services.result.volumes size 1", pResultVolumes->getLength(), 1); + compare("services.result.volumes val 0", pResultVolumes->getElement(0)->getValue(), "./result:/app"); + + WsjcppYamlItem *pResultPorts = pResult->getElement("ports"); + compare("services.result.ports is array", pResultPorts->isArray(), true); + compare("services.result.ports size 2", pResultPorts->getLength(), 2); + compare("services.result.ports val 0", pResultPorts->getElement(0)->getValue(), "5001:80"); + compare("services.result.ports val 1", pResultPorts->getElement(1)->getValue(), "5858:5858"); + + WsjcppYamlItem *pResultNetworks = pResult->getElement("networks"); + compare("services.result.networks size 2", pResultNetworks->getLength(), 2); + compare("services.result.networks val 0", pResultNetworks->getElement(0)->getValue(), "front-tier"); + compare("services.result.networks val 1", pResultNetworks->getElement(1)->getValue(), "back-tier"); + } - compare("version-value", yaml.getRoot()->getElement("version")->getValue(), "3"); + // services.worker + { + compare("has services.worker", pServices->hasElement("worker"), true); + compare("has services.worker is map", pServices->getElement("worker")->isMap(), true); + compare("services.worker keys size 3", pServices->getElement("worker")->getKeys().size(), 3); + WsjcppYamlItem *pWorker = pServices->getElement("worker"); + + compare("has services.worker.build", pWorker->hasElement("build"), true); + + compare("has services.worker.depends_on", pWorker->hasElement("depends_on"), true); + compare("has services.worker.networks", pWorker->hasElement("networks"), true); + + WsjcppYamlItem *pWorkerBuild = pWorker->getElement("build"); + compare("services.worker.build is map", pWorkerBuild->isMap(), true); + compare("has services.worker.build.context", pWorkerBuild->hasElement("context"), true); + compare("services.worker.build.context val", pWorkerBuild->getElement("context")->getValue(), "./worker"); + + WsjcppYamlItem *pWorkerDependsOn = pWorker->getElement("depends_on"); + compare("has services.worker.depends_on", pWorkerDependsOn->isArray(), true); + compare("services.worker.depends_on size 2", pWorkerDependsOn->getLength(), 2); + compare("services.worker.depends_on val 0", pWorkerDependsOn->getElement(0)->getValue(), "redis"); + compare("services.worker.depends_on val 1", pWorkerDependsOn->getElement(1)->getValue(), "db"); + + WsjcppYamlItem *pWorkerNetworks = pWorker->getElement("networks"); + compare("services.worker.networks size 1", pWorkerNetworks->getLength(), 1); + compare("services.worker.networks val 0", pWorkerNetworks->getElement(0)->getValue(), "back-tier"); + } + + // services.redis + { + compare("has services.redis", pServices->hasElement("redis"), true); + compare("services.redis is map", pServices->getElement("redis")->isMap(), true); + compare("services.redis keys size 4", pServices->getElement("redis")->getKeys().size(), 4); + + WsjcppYamlItem *pRedis = pServices->getElement("redis"); + compare("has services.redis.image", pRedis->hasElement("image"), true); + compare("has services.redis.container_name", pRedis->hasElement("container_name"), true); + compare("has services.redis.ports", pRedis->hasElement("ports"), true); + compare("has services.redis.networks", pRedis->hasElement("networks"), true); + + compare("services.redis.image value", pRedis->getElement("image")->getValue(), "redis:alpine"); + compare("services.redis.container_name", pRedis->getElement("container_name")->getValue(), "redis"); + + WsjcppYamlItem *pRedisPorts = pRedis->getElement("ports"); + // TODO bug #17 + compare("services.redis.ports is value", pRedisPorts->isValue(), true); + compare("services.redis.ports value", pRedisPorts->getValue(), "[\"6379\"]"); + + WsjcppYamlItem *pRedisNetworks = pRedis->getElement("networks"); + compare("services.redis.networks size 1", pRedisNetworks->getLength(), 1); + compare("services.redis.networks val 0", pRedisNetworks->getElement(0)->getValue(), "back-tier"); + } + + // services.db + { + compare("has services.db", pServices->hasElement("db"), true); + compare("has services.db is map", pServices->getElement("db")->isMap(), true); + compare("services.db keys size 5", pServices->getElement("db")->getKeys().size(), 5); + + WsjcppYamlItem *pServicesDb = pServices->getElement("db"); + + compare("has services.db.image", pServicesDb->hasElement("image"), true); + compare("services.db.image value", pServicesDb->getElement("image")->getValue(), "postgres:9.4"); + compare("services.db.container_name", pServicesDb->getElement("container_name")->getValue(), "db"); + + compare("has services.db.environment", pServicesDb->hasElement("environment"), true); + compare("services.db.environment is map", pServicesDb->getElement("environment")->isMap(), true); + + WsjcppYamlItem *pDbEnvironment = pServicesDb->getElement("environment"); + + compare("has services.db.environment.POSTGRES_USER", pDbEnvironment->hasElement("POSTGRES_USER"), true); + compare("services.db.environment.POSTGRES_USER", pDbEnvironment->getElement("POSTGRES_USER")->getValue(), "postgres"); + compare("has services.db.environment.POSTGRES_PASSWORD", pDbEnvironment->hasElement("POSTGRES_PASSWORD"), true); + compare("services.db.environment.POSTGRES_PASSWORD", pDbEnvironment->getElement("POSTGRES_PASSWORD")->getValue(), "postgres"); + + compare("has services.db.volumes", pServicesDb->hasElement("volumes"), true); + compare("services.db.volumes is array", pServicesDb->getElement("volumes")->isArray(), true); + + WsjcppYamlItem *pDbVolumes = pServicesDb->getElement("volumes"); + compare("services.db.volumes size 1", pDbVolumes->getLength(), 1); + compare("services.db.volumes val 0", pDbVolumes->getElement(0)->getValue(), "db-data:/var/lib/postgresql/data"); + + compare("has services.db.networks", pServicesDb->hasElement("networks"), true); + compare("services.db.networks is array", pServicesDb->getElement("networks")->isArray(), true); + + WsjcppYamlItem *pDbNetworks = pServicesDb->getElement("networks"); + compare("services.db.networks size 1", pDbNetworks->getLength(), 1); + compare("services.db.networks val 0", pDbNetworks->getElement(0)->getValue(), "back-tier"); + } + + // volumes + { + compare("has volumes", yaml.getRoot()->hasElement("volumes"), true); + compare("has volumes is map", yaml.getRoot()->getElement("volumes")->isMap(), true); + + WsjcppYamlItem *pVolumes = yaml.getRoot()->getElement("volumes"); + + compare("has volumes.db-data", pVolumes->hasElement("db-data"), true); + compare("has volumes.db-data is undefined", pVolumes->getElement("db-data")->isUndefined(), true); + compare("has volumes keys size 1", pVolumes->getKeys().size(), 1); + } + + // networks + { + compare("has networks", yaml.getRoot()->hasElement("networks"), true); + compare("has networks is map", yaml.getRoot()->getElement("networks")->isMap(), true); + + WsjcppYamlItem *pNeworks = yaml.getRoot()->getElement("networks"); + compare("has networks keys size 2", pNeworks->getKeys().size(), 2); + + compare("has networks.front-tier", pNeworks->hasElement("front-tier"), true); + compare("has networks.front-tier is undefined", pNeworks->getElement("front-tier")->isUndefined(), true); + + compare("has networks.back-tier", pNeworks->hasElement("back-tier"), true); + compare("has networks.back-tier is undefined", pNeworks->getElement("back-tier")->isUndefined(), true); + } } // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_tag_names.cpp b/unit-tests.wsjcpp/src/unit_test_tag_names.cpp new file mode 100644 index 0000000..20ef176 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_tag_names.cpp @@ -0,0 +1,50 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestTagNames + +class UnitTestTagNames : public WsjcppUnitTestBase { + public: + UnitTestTagNames(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestTagNames) + +UnitTestTagNames::UnitTestTagNames() + : WsjcppUnitTestBase("UnitTestTagNames") { +} + +// --------------------------------------------------------------------- + +bool UnitTestTagNames::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestTagNames::executeTest() { + + std::string sTestYaml = "./test10: one"; + WsjcppYaml yaml; + std::string sError; + // wrong + compare("wrong name", yaml.loadFromString("wrong name", "./test10: one", sError), false); + compare("name use quotes", yaml.loadFromString("name use quotes", "\"./test10\": one", sError), true); + +} + +// --------------------------------------------------------------------- + +bool UnitTestTagNames::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/wsjcpp.yml b/wsjcpp.yml index 476994c..f05681c 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -63,3 +63,5 @@ unit-tests: description: "" - name: "Cursor" description: "" + - name: "TagNames" + description: "" From c01d1bf5f350fe19dc8b22b85c04bd648201befc Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 20:18:13 +0700 Subject: [PATCH 17/29] Fixed #19 Cleanup previously data --- src/wsjcpp_yaml.cpp | 16 +++- src/wsjcpp_yaml.h | 1 + unit-tests.wsjcpp/CMakeLists.txt | 1 + unit-tests.wsjcpp/src/unit_test_cleanup.cpp | 81 +++++++++++++++++++++ wsjcpp.yml | 2 + 5 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 unit-tests.wsjcpp/src/unit_test_cleanup.cpp diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index a09c733..417aaa6 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -83,7 +83,7 @@ WsjcppYamlItem::WsjcppYamlItem( // --------------------------------------------------------------------- WsjcppYamlItem::~WsjcppYamlItem() { - for (int i = 0; i < m_vObjects.size(); i++) { + for (int i = 0; i < m_vObjects.size(); i++) { delete m_vObjects[i]; } m_vObjects.clear(); @@ -1129,7 +1129,7 @@ WsjcppYamlCursor WsjcppYamlCursor::operator[](const std::string &sName) const { // WsjcppYaml WsjcppYaml::WsjcppYaml() { - m_pRoot = new WsjcppYamlItem(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_ITEM_MAP); + m_pRoot = nullptr; TAG = "WsjcppYaml"; } @@ -1141,6 +1141,13 @@ WsjcppYaml::~WsjcppYaml() { // --------------------------------------------------------------------- +void WsjcppYaml::clear() { + delete m_pRoot; + m_pRoot = nullptr; +} + +// --------------------------------------------------------------------- + bool WsjcppYaml::loadFromFile(const std::string &sFileName, std::string &sError) { std::string sTextContent; if (!WsjcppCore::readTextFile(sFileName, sTextContent)) { @@ -1220,6 +1227,11 @@ std::vector WsjcppYaml::splitToLines(const std::string &sBuffer) { // --------------------------------------------------------------------- bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError) { + this->clear(); + if (m_pRoot == nullptr) { + m_pRoot = new WsjcppYamlItem(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_ITEM_MAP); + } + std::vector vLines = this->splitToLines(sBuffer); WsjcppYamlParserStatus st; st.pCurItem = m_pRoot; // TODO recreate again new root element diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 3b60661..0056bca 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -254,6 +254,7 @@ class WsjcppYaml { public: WsjcppYaml(); ~WsjcppYaml(); + void clear(); bool loadFromFile(const std::string &sFileName, std::string &sError); bool saveToFile(const std::string &sFileName); bool loadFromString(const std::string &sBufferName, const std::string &sBuffer, std::string &sError); diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index f57c7f0..149b9d2 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -49,6 +49,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_yaml.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_write_file.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_cursor.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_tag_names.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_cleanup.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) diff --git a/unit-tests.wsjcpp/src/unit_test_cleanup.cpp b/unit-tests.wsjcpp/src/unit_test_cleanup.cpp new file mode 100644 index 0000000..d713084 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_cleanup.cpp @@ -0,0 +1,81 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestCleanup + +class UnitTestCleanup : public WsjcppUnitTestBase { + public: + UnitTestCleanup(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestCleanup) + +UnitTestCleanup::UnitTestCleanup() + : WsjcppUnitTestBase("UnitTestCleanup") { +} + +// --------------------------------------------------------------------- + +bool UnitTestCleanup::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestCleanup::executeTest() { + std::string sTestYaml1 = + "# Some comment 1\n" + "test10: one\n" + "test20: two # some comment 2\n" + ; + + std::string sTestYaml2 = + "# Some comment 1\n" + "test11: one\n" + "test20: two # some comment 2\n" + "test22: two # some comment 2\n" + ; + + WsjcppYaml yaml; + std::string sError; + + if (!compare("Error parsing 1", yaml.loadFromString("parse1", sTestYaml1, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + compare("(1) has test10", yaml.getRoot()->hasElement("test10"), true); + compare("(1) has test11", yaml.getRoot()->hasElement("test11"), false); + compare("(1) has test20", yaml.getRoot()->hasElement("test20"), true); + compare("(1) has test22", yaml.getRoot()->hasElement("test22"), false); + + if (!compare("Error parsing 2", yaml.loadFromString("parse2", sTestYaml2, sError), true)) { + WsjcppLog::err(TAG, sError); + return; + } + + compare("(2) has test10", yaml.getRoot()->hasElement("test10"), false); + compare("(2) has test11", yaml.getRoot()->hasElement("test11"), true); + compare("(2) has test20", yaml.getRoot()->hasElement("test20"), true); + compare("(2) has test22", yaml.getRoot()->hasElement("test22"), true); + + yaml.clear(); + + compare("(3) has root", yaml.getRoot() == nullptr, true); +} + +// --------------------------------------------------------------------- + +bool UnitTestCleanup::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/wsjcpp.yml b/wsjcpp.yml index f05681c..a8decc0 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -65,3 +65,5 @@ unit-tests: description: "" - name: "TagNames" description: "" + - name: "Cleanup" + description: "" From c01e385461b1705d58a2883fe46751f4854f2a03 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 20:27:39 +0700 Subject: [PATCH 18/29] removed unused comments and refactored code --- .../src/unit_test_memory_leaks.cpp | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp index 6624dc0..43657b9 100644 --- a/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp +++ b/unit-tests.wsjcpp/src/unit_test_memory_leaks.cpp @@ -15,6 +15,9 @@ class UnitTestMemoryLeaks : public WsjcppUnitTestBase { virtual bool doBeforeTest() override; virtual void executeTest() override; virtual bool doAfterTest() override; + + private: + void createManyTimesObjects(); }; REGISTRY_WSJCPP_UNIT_TEST(UnitTestMemoryLeaks) @@ -32,50 +35,38 @@ bool UnitTestMemoryLeaks::doBeforeTest() { // --------------------------------------------------------------------- -void UnitTestMemoryLeaks::executeTest() { - double nBeforeVm, nBeforeRss; - double nAfterVm, nAfterRss; +void UnitTestMemoryLeaks::createManyTimesObjects() { std::string sFilepath = "./data-tests/for-memory-leak/some.yml"; std::string sError; - - // std::cout << "currentSize "<< getCurrentRSS() << std::endl; - // std::cout << "peakSize "<< getPeakRSS() << std::endl; - - // first use for memory alloc some - for (int i = 0; i < 1000; i++) { + for (int i = 0; i < 10000; i++) { WsjcppYaml yaml; if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { WsjcppLog::err(TAG, sError); return; } } - +} + +// --------------------------------------------------------------------- + +void UnitTestMemoryLeaks::executeTest() { + double nBeforeVm, nBeforeRss; + double nAfterVm, nAfterRss; + std::string sFilepath = "./data-tests/for-memory-leak/some.yml"; + + // first use for memory alloc memory for work + createManyTimesObjects(); + process_mem_usage(nBeforeVm, nBeforeRss); - // std::cout << "nBeforeVm: " << nBeforeVm << std::endl; - // std::cout << "nBeforeRss: " << nBeforeRss << std::endl; compare("memory vm not null", (int)nBeforeVm > 0, true); compare("memory vm not null", (int)nBeforeRss > 0, true); - // std::cout << "currentSize "<< getCurrentRSS() << std::endl; - // std::cout << "peakSize "<< getPeakRSS() << std::endl; - // code again check the memoty leak - - for (int i = 0; i < 1000; i++) { - WsjcppYaml yaml; - if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { - WsjcppLog::err(TAG, sError); - return; - } - } + createManyTimesObjects(); process_mem_usage(nAfterVm, nAfterRss); - // std::cout << "nAfterVm: " << nAfterVm << std::endl; - // std::cout << "nAfterRss: " << nAfterRss << std::endl; compare("memory vm", (int)nAfterVm, (int)nBeforeVm); compare("memory rss", (int)nAfterRss, (int)nBeforeRss); - // std::cout << "currentSize "<< getCurrentRSS() << std::endl; - // std::cout << "peakSize "<< getPeakRSS() << std::endl; } // --------------------------------------------------------------------- From 5b01fc70ebc657ebe0d2038fc86e8344b54a69d6 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 21:40:52 +0700 Subject: [PATCH 19/29] Fixed #18 Bug in parsing element of array with colon --- src/wsjcpp_yaml.cpp | 52 ++++++++++++++----- src/wsjcpp_yaml.h | 2 +- unit-tests.wsjcpp/src/unit_test_tag_names.cpp | 17 +++++- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 417aaa6..23ac2e8 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -611,7 +611,7 @@ WsjcppYamlParsebleLine::WsjcppYamlParsebleLine(int nLine) { m_sPrefix = ""; m_bArrayItem = false; m_sComment = ""; - m_sName = ""; + m_sTagName = ""; m_sValue = ""; m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; @@ -665,7 +665,7 @@ bool WsjcppYamlParsebleLine::hasComment() { // --------------------------------------------------------------------- std::string WsjcppYamlParsebleLine::getName() { - return m_sName; + return m_sTagName; } // --------------------------------------------------------------------- @@ -677,7 +677,7 @@ WsjcppYamlQuotes WsjcppYamlParsebleLine::getNameQuotes() { // --------------------------------------------------------------------- bool WsjcppYamlParsebleLine::isEmptyName() { - return m_sName.length() == 0; + return m_sTagName.length() == 0; } // --------------------------------------------------------------------- @@ -721,7 +721,7 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE m_bArrayItem = false; m_sPrefix = ""; m_sComment = ""; - m_sName = ""; + m_sTagName = ""; m_sValue = ""; m_bHasComment = false; m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; @@ -783,9 +783,8 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE state = WSJCPP_YAML_PARSER_LINE_STATE_VALUE; m_sValue += c; } else if (c == ':' && state == WSJCPP_YAML_PARSER_LINE_STATE_VALUE) { - std::cout << m_sValue << std::endl; - if (m_sName.length() == 0) { - m_sName = m_sValue; + if (m_sTagName.length() == 0 && this->canTagName(m_sValue)) { + m_sTagName = m_sValue; m_sValue = ""; // reset value it was param name } else { m_sValue += c; @@ -823,14 +822,14 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE } }*/ - m_sName = WsjcppCore::trim(m_sName); - if (m_sName.length() > 0 && m_sName[0] == '"') { + m_sTagName = WsjcppCore::trim(m_sTagName); + if (m_sTagName.length() > 0 && m_sTagName[0] == '"') { m_nNameQuotes = WSJCPP_YAML_QUOTES_DOUBLE; - m_sName = removeStringDoubleQuotes(m_sName); + m_sTagName = removeStringDoubleQuotes(m_sTagName); } - if (m_sName.length() > 0 && m_sName[0] == '\'') { + if (m_sTagName.length() > 0 && m_sTagName[0] == '\'') { m_nNameQuotes = WSJCPP_YAML_QUOTES_SINGLE; - m_sName = removeStringSingleQuotes(m_sName); + m_sTagName = removeStringSingleQuotes(m_sTagName); } m_sValue = WsjcppCore::trim(m_sValue); @@ -844,12 +843,41 @@ bool WsjcppYamlParsebleLine::parseLine(const std::string &sLine, std::string &sE } m_sComment = WsjcppCore::trim(m_sComment); + + if (m_bArrayItem == false && m_sTagName.length() == 0 && m_sValue.length() > 0 ) { + sError = "Value of name can be empty only for array-item (line: " + sLine + ")"; + return false; + } return true; } // --------------------------------------------------------------------- bool WsjcppYamlParsebleLine::canTagName(const std::string &sVal) { + std::string sTrim = sVal; + sTrim = WsjcppCore::trim(sTrim); + int nLen = sTrim.length(); + if (nLen == 0) { + return false; + } + if (sTrim.length() > 0 && sTrim[0] == '"' && sTrim[nLen-1] == '"') { + return true; + } + if (sTrim.length() > 0 && sTrim[0] == '\'' && sTrim[nLen-1] == '\'') { + return true; + } + // check illegal char + for (int i = 0; i < nLen; i++) { + char c = sTrim[i]; + if ( + c != '-' && c != '_' + && (c < '0' || c > '9') + && (c < 'a' || c > 'z') + && (c < 'A' || c > 'Z') + ) { + return false; + } + } return true; } diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 0056bca..6bc9606 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -167,7 +167,7 @@ class WsjcppYamlParsebleLine { std::string m_sPrefix; bool m_bArrayItem; std::string m_sComment; - std::string m_sName; + std::string m_sTagName; std::string m_sValue; WsjcppYamlQuotes m_nNameQuotes; WsjcppYamlQuotes m_nValueQuotes; diff --git a/unit-tests.wsjcpp/src/unit_test_tag_names.cpp b/unit-tests.wsjcpp/src/unit_test_tag_names.cpp index 20ef176..0770534 100644 --- a/unit-tests.wsjcpp/src/unit_test_tag_names.cpp +++ b/unit-tests.wsjcpp/src/unit_test_tag_names.cpp @@ -36,8 +36,23 @@ void UnitTestTagNames::executeTest() { std::string sError; // wrong compare("wrong name", yaml.loadFromString("wrong name", "./test10: one", sError), false); - compare("name use quotes", yaml.loadFromString("name use quotes", "\"./test10\": one", sError), true); + compare("name use quotes 1", yaml.loadFromString("name use quotes", "\"./test10\": one", sError), true); + compare("name use quotes 2 - wrong", yaml.loadFromString("name use quotes", "\"./te\"st10\": one", sError), false); + compare("name use quotes 3", yaml.loadFromString("name use quotes", "\"./te\\\"st10\": one", sError), true); + compare("array", yaml.loadFromString("array", + "arr1: \n" + " - ./te:11\n" + " - \"./te\":11\n" + , sError), true); + + compare("arr1 is array", yaml.getRoot()->getElement("arr1")->isArray(), true); + compare("arr1 size 2", yaml.getRoot()->getElement("arr1")->getLength(), 2); + compare("arr1 el 0 is value", yaml.getRoot()->getElement("arr1")->getElement(0)->isValue(), true); + compare("arr1 el 0 is value", yaml.getRoot()->getElement("arr1")->getElement(0)->getValue(), "./te:11"); + compare("arr1 el 1 is map", yaml.getRoot()->getElement("arr1")->getElement(1)->isMap(), true); + compare("arr1 el 1 is map", yaml.getRoot()->getElement("arr1")->getElement(1)->hasElement("./te"), true); + compare("arr1 el 1 is map", yaml.getRoot()->getElement("arr1")->getElement(1)->getElement("./te")->getValue(), "11"); } // --------------------------------------------------------------------- From 8d8bfd5e0f0b39f5eef7852ec4443781875c39b0 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 21:54:52 +0700 Subject: [PATCH 20/29] Renamed WsjcppYamlItemType to WsjcppYamlNodeType --- src/wsjcpp_yaml.cpp | 106 ++++++++++++++++++++++---------------------- src/wsjcpp_yaml.h | 16 +++---- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 23ac2e8..58d1acb 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -68,7 +68,7 @@ std::string WsjcppYamlPlaceInFile::getForLogFormat() { WsjcppYamlItem::WsjcppYamlItem( WsjcppYamlItem *pParent, const WsjcppYamlPlaceInFile &placeInFile, - WsjcppYamlItemType nItemType + WsjcppYamlNodeType nItemType ) { m_pParent = pParent; m_placeInFile.setFilename(placeInFile.getFilename()); @@ -143,14 +143,14 @@ WsjcppYamlQuotes WsjcppYamlItem::getNameQuotes() { // --------------------------------------------------------------------- bool WsjcppYamlItem::isEmpty() { - return m_nItemType == WSJCPP_YAML_ITEM_EMPTY; + return m_nItemType == WSJCPP_YAML_NODE_EMPTY; } // --------------------------------------------------------------------- void WsjcppYamlItem::doEmpty() { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { - m_nItemType = WSJCPP_YAML_ITEM_EMPTY; + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { + m_nItemType = WSJCPP_YAML_NODE_EMPTY; } else { WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); } @@ -159,14 +159,14 @@ void WsjcppYamlItem::doEmpty() { // --------------------------------------------------------------------- bool WsjcppYamlItem::isUndefined() { - return m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED; + return m_nItemType == WSJCPP_YAML_NODE_UNDEFINED; } // --------------------------------------------------------------------- void WsjcppYamlItem::doArray() { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { - m_nItemType = WSJCPP_YAML_ITEM_ARRAY; + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { + m_nItemType = WSJCPP_YAML_NODE_ARRAY; } else { WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); } @@ -175,8 +175,8 @@ void WsjcppYamlItem::doArray() { // --------------------------------------------------------------------- void WsjcppYamlItem::doMap() { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { - m_nItemType = WSJCPP_YAML_ITEM_MAP; + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { + m_nItemType = WSJCPP_YAML_NODE_MAP; } else { WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); } @@ -185,8 +185,8 @@ void WsjcppYamlItem::doMap() { // --------------------------------------------------------------------- void WsjcppYamlItem::doValue() { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { - m_nItemType = WSJCPP_YAML_ITEM_VALUE; + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { + m_nItemType = WSJCPP_YAML_NODE_VALUE; } else { WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); } @@ -195,13 +195,13 @@ void WsjcppYamlItem::doValue() { // --------------------------------------------------------------------- bool WsjcppYamlItem::isMap() { - return m_nItemType == WSJCPP_YAML_ITEM_MAP; + return m_nItemType == WSJCPP_YAML_NODE_MAP; } // --------------------------------------------------------------------- bool WsjcppYamlItem::hasElement(const std::string &sName) { - if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "hasElement('" + sName + "'): Element must be map"); } for (int i = 0; i < m_vObjects.size(); i++) { @@ -215,7 +215,7 @@ bool WsjcppYamlItem::hasElement(const std::string &sName) { // --------------------------------------------------------------------- WsjcppYamlItem *WsjcppYamlItem::getElement(const std::string &sName) { - if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "getElement: Element must be map"); } @@ -232,11 +232,11 @@ WsjcppYamlItem *WsjcppYamlItem::getElement(const std::string &sName) { // --------------------------------------------------------------------- bool WsjcppYamlItem::setElement(const std::string &sName, WsjcppYamlItem *pItem) { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { - m_nItemType = WSJCPP_YAML_ITEM_MAP; // change item type to map on first element + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { + m_nItemType = WSJCPP_YAML_NODE_MAP; // change item type to map on first element } - if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "setElement, Element must be 'map' for " + pItem->getPlaceInFile().getForLogFormat()); } @@ -250,7 +250,7 @@ bool WsjcppYamlItem::setElement(const std::string &sName, WsjcppYamlItem *pItem) // --------------------------------------------------------------------- bool WsjcppYamlItem::removeElement(const std::string &sName) { - if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "removeElement: Element must be map"); } std::vector::iterator it; @@ -268,7 +268,7 @@ bool WsjcppYamlItem::removeElement(const std::string &sName) { // --------------------------------------------------------------------- std::vector WsjcppYamlItem::getKeys() { - if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "getKeys: Element must be map"); } std::vector vKeys; @@ -290,11 +290,11 @@ bool WsjcppYamlItem::setElementValue( WsjcppYamlQuotes nNameQuotes, WsjcppYamlQuotes nValueQuotes ) { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { - m_nItemType = WSJCPP_YAML_ITEM_MAP; // change item type to map on first element + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { + m_nItemType = WSJCPP_YAML_NODE_MAP; // change item type to map on first element } - if (m_nItemType != WSJCPP_YAML_ITEM_MAP) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "setElement, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } @@ -303,7 +303,7 @@ bool WsjcppYamlItem::setElementValue( pItem->setValue(sValue, nValueQuotes); } else { WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE); + WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_VALUE); pNewItem->setName(sName, nNameQuotes); pNewItem->setValue(sValue, nValueQuotes); this->setElement(sName, pNewItem); @@ -314,14 +314,14 @@ bool WsjcppYamlItem::setElementValue( // --------------------------------------------------------------------- bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { - if (m_nItemType != WSJCPP_YAML_ITEM_MAP ) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } if (this->hasElement(sName)) { return false; // already exists } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_MAP); + WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_MAP); pNewItem->setName(sName, nNameQuotes); this->setElement(sName, pNewItem); return true; @@ -330,11 +330,11 @@ bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes // --------------------------------------------------------------------- WsjcppYamlItem *WsjcppYamlItem::createElementMap() { - if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY ) { + if (m_nItemType != WSJCPP_YAML_NODE_ARRAY ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'array' for " + this->getPlaceInFile().getForLogFormat()); } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_MAP); + WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_MAP); this->appendElement(pNewItem); return pNewItem; } @@ -342,14 +342,14 @@ WsjcppYamlItem *WsjcppYamlItem::createElementMap() { // --------------------------------------------------------------------- bool WsjcppYamlItem::createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { - if (m_nItemType != WSJCPP_YAML_ITEM_MAP ) { + if (m_nItemType != WSJCPP_YAML_NODE_MAP ) { WsjcppLog::throw_err(TAG, "createElementArray, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } if (this->hasElement(sName)) { return false; } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_ARRAY); + WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_ARRAY); pNewItem->setName(sName, nNameQuotes); this->setElement(sName, pNewItem); return true; @@ -358,13 +358,13 @@ bool WsjcppYamlItem::createElementArray(const std::string &sName, WsjcppYamlQuot // --------------------------------------------------------------------- bool WsjcppYamlItem::isArray() { - return m_nItemType == WSJCPP_YAML_ITEM_ARRAY; + return m_nItemType == WSJCPP_YAML_NODE_ARRAY; } // --------------------------------------------------------------------- int WsjcppYamlItem::getLength() { - if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY) { + if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "getLength, Element must be array for " + this->getForLogFormat()); } int nCount = 0; @@ -379,7 +379,7 @@ int WsjcppYamlItem::getLength() { // --------------------------------------------------------------------- WsjcppYamlItem *WsjcppYamlItem::getElement(int i) { - if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY) { + if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "getElement, Element must be array"); } int nCounter = -1; @@ -406,7 +406,7 @@ bool WsjcppYamlItem::appendElement(WsjcppYamlItem *pItem) { m_vObjects.push_back(pItem); // TODO clone object return true; } - if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY) { + if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "appendElement, Element must be array for " + this->getForLogFormat()); } m_vObjects.push_back(pItem); // TODO clone object @@ -416,11 +416,11 @@ bool WsjcppYamlItem::appendElement(WsjcppYamlItem *pItem) { // --------------------------------------------------------------------- bool WsjcppYamlItem::appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes) { - if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY) { + if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "appendElementValue, Element must be array for " + this->getForLogFormat()); } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE); + WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_VALUE); pNewItem->setValue(sValue, nValueQuotes); return this->appendElement(pNewItem); } @@ -428,7 +428,7 @@ bool WsjcppYamlItem::appendElementValue(const std::string &sValue, WsjcppYamlQuo // --------------------------------------------------------------------- bool WsjcppYamlItem::removeElement(int i) { - if (m_nItemType != WSJCPP_YAML_ITEM_ARRAY) { + if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "appendElement, Element must be array for " + this->getForLogFormat()); } int nCounter = -1; @@ -459,13 +459,13 @@ bool WsjcppYamlItem::removeElement(int i) { // --------------------------------------------------------------------- bool WsjcppYamlItem::isValue() { - return m_nItemType == WSJCPP_YAML_ITEM_VALUE; + return m_nItemType == WSJCPP_YAML_NODE_VALUE; } // --------------------------------------------------------------------- std::string WsjcppYamlItem::getValue() { - if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { + if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { WsjcppLog::throw_err(TAG, "getValue, Element must be value for " + this->getForLogFormat()); } return m_sValue; @@ -474,7 +474,7 @@ std::string WsjcppYamlItem::getValue() { // --------------------------------------------------------------------- void WsjcppYamlItem::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { - if (m_nItemType != WSJCPP_YAML_ITEM_VALUE) { + if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { WsjcppLog::throw_err(TAG, "setValue, Element must be value for " + this->getForLogFormat()); } m_nValueQuotes = nQuotes; @@ -585,13 +585,13 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { // --------------------------------------------------------------------- std::string WsjcppYamlItem::getItemTypeAsString() { - if (m_nItemType == WSJCPP_YAML_ITEM_UNDEFINED) { + if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { return "undefined"; - } else if (m_nItemType == WSJCPP_YAML_ITEM_ARRAY) { + } else if (m_nItemType == WSJCPP_YAML_NODE_ARRAY) { return "array"; - } else if (m_nItemType == WSJCPP_YAML_ITEM_MAP) { + } else if (m_nItemType == WSJCPP_YAML_NODE_MAP) { return "map"; - } else if (m_nItemType == WSJCPP_YAML_ITEM_VALUE) { + } else if (m_nItemType == WSJCPP_YAML_NODE_VALUE) { return "value"; } return "unknown"; @@ -1257,7 +1257,7 @@ std::vector WsjcppYaml::splitToLines(const std::string &sBuffer) { bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError) { this->clear(); if (m_pRoot == nullptr) { - m_pRoot = new WsjcppYamlItem(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_ITEM_MAP); + m_pRoot = new WsjcppYamlItem(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_NODE_MAP); } std::vector vLines = this->splitToLines(sBuffer); @@ -1290,13 +1290,13 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, if (st.pCurItem->isArray() || st.pCurItem->isMap() || st.pCurItem->isUndefined()) { WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY + WSJCPP_YAML_NODE_EMPTY ); st.pCurItem->appendElement(pItem); } else if (st.pCurItem->getParent() != nullptr && (st.pCurItem->getParent()->isArray() || st.pCurItem->getParent()->isMap())) { WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem->getParent(), st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY + WSJCPP_YAML_NODE_EMPTY ); st.pCurItem->getParent()->appendElement(pItem); } else { @@ -1362,7 +1362,7 @@ void WsjcppYaml::process_sameIntent_hasName_emptyValue_arrayItem(WsjcppYamlParse void WsjcppYaml::process_sameIntent_hasName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st) { WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_UNDEFINED + WSJCPP_YAML_NODE_UNDEFINED ); if (st.line.getValueQuotes() != WSJCPP_YAML_QUOTES_NONE) { pItem->doValue(); @@ -1383,7 +1383,7 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS } WsjcppYamlItem *pMapItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_MAP + WSJCPP_YAML_NODE_MAP ); st.pCurItem->appendElement(pMapItem); st.pCurItem = pMapItem; @@ -1391,7 +1391,7 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE + WSJCPP_YAML_NODE_VALUE ); pItem->setComment(st.line.getComment()); pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); @@ -1406,7 +1406,7 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS void WsjcppYaml::process_sameIntent_hasName_hasValue_noArrayItem(WsjcppYamlParserStatus &st) { WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE + WSJCPP_YAML_NODE_VALUE ); pItem->setComment(st.line.getComment()); pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); @@ -1424,7 +1424,7 @@ void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem(WsjcppYamlParse } WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE + WSJCPP_YAML_NODE_VALUE ); pItem->setComment(st.line.getComment()); pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); @@ -1447,7 +1447,7 @@ void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlPar } WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_VALUE + WSJCPP_YAML_NODE_VALUE ); pItem->setComment(st.line.getComment()); pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); @@ -1461,7 +1461,7 @@ void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlPar void WsjcppYaml::process_sameIntent_emptyName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st) { WsjcppYamlItem *pItem = new WsjcppYamlItem( st.pCurItem, st.placeInFile, - WsjcppYamlItemType::WSJCPP_YAML_ITEM_EMPTY + WSJCPP_YAML_NODE_EMPTY ); pItem->setComment(st.line.getComment()); st.pCurItem->appendElement(pItem); diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 6bc9606..fdda8f7 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -11,12 +11,12 @@ // --------------------------------------------------------------------- -enum WsjcppYamlItemType { - WSJCPP_YAML_ITEM_UNDEFINED, - WSJCPP_YAML_ITEM_EMPTY, - WSJCPP_YAML_ITEM_ARRAY, - WSJCPP_YAML_ITEM_MAP, - WSJCPP_YAML_ITEM_VALUE +enum WsjcppYamlNodeType { + WSJCPP_YAML_NODE_UNDEFINED, + WSJCPP_YAML_NODE_EMPTY, + WSJCPP_YAML_NODE_ARRAY, + WSJCPP_YAML_NODE_MAP, + WSJCPP_YAML_NODE_VALUE }; // --------------------------------------------------------------------- @@ -63,7 +63,7 @@ class WsjcppYamlItem { // TODO: rename to node WsjcppYamlItem( WsjcppYamlItem *pParent, const WsjcppYamlPlaceInFile &placeInFile, - WsjcppYamlItemType nItemType + WsjcppYamlNodeType nItemType ); ~WsjcppYamlItem(); WsjcppYamlItem *getParent(); @@ -126,7 +126,7 @@ class WsjcppYamlItem { // TODO: rename to node std::string TAG; WsjcppYamlItem *m_pParent; WsjcppYamlPlaceInFile m_placeInFile; - WsjcppYamlItemType m_nItemType; + WsjcppYamlNodeType m_nItemType; std::vector m_vObjects; std::string m_sValue; // if it is not array or map WsjcppYamlQuotes m_nValueQuotes; From d555a8a168da903677666f7cb0bfd8fa56ebae3b Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 21:58:33 +0700 Subject: [PATCH 21/29] Fixed todo: Renamed WsjcppYamlItem to WsjcppYamlNode --- src/wsjcpp_yaml.cpp | 134 +++++++++--------- src/wsjcpp_yaml.h | 34 ++--- unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 36 ++--- .../src/unit_test_remove_element_for_map.cpp | 4 +- .../src/unit_test_remove_element_in_array.cpp | 2 +- .../src/unit_test_yaml_parser_all.cpp | 2 +- ...it_test_yaml_parser_array_included_map.cpp | 2 +- ...unit_test_yaml_parser_hierarchical_map.cpp | 2 +- .../unit_test_yaml_parser_simple_array.cpp | 2 +- .../src/unit_test_yaml_parser_simple_map.cpp | 2 +- 10 files changed, 110 insertions(+), 110 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 58d1acb..241afa5 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -63,10 +63,10 @@ std::string WsjcppYamlPlaceInFile::getForLogFormat() { } // --------------------------------------------------------------------- -// WsjcppYamlItem +// WsjcppYamlNode -WsjcppYamlItem::WsjcppYamlItem( - WsjcppYamlItem *pParent, +WsjcppYamlNode::WsjcppYamlNode( + WsjcppYamlNode *pParent, const WsjcppYamlPlaceInFile &placeInFile, WsjcppYamlNodeType nItemType ) { @@ -82,7 +82,7 @@ WsjcppYamlItem::WsjcppYamlItem( // --------------------------------------------------------------------- -WsjcppYamlItem::~WsjcppYamlItem() { +WsjcppYamlNode::~WsjcppYamlNode() { for (int i = 0; i < m_vObjects.size(); i++) { delete m_vObjects[i]; } @@ -91,19 +91,19 @@ WsjcppYamlItem::~WsjcppYamlItem() { // --------------------------------------------------------------------- -WsjcppYamlItem *WsjcppYamlItem::getParent() { +WsjcppYamlNode *WsjcppYamlNode::getParent() { return m_pParent; } // --------------------------------------------------------------------- -WsjcppYamlPlaceInFile WsjcppYamlItem::getPlaceInFile() { +WsjcppYamlPlaceInFile WsjcppYamlNode::getPlaceInFile() { return m_placeInFile; } // --------------------------------------------------------------------- -void WsjcppYamlItem::setPlaceInFile(const WsjcppYamlPlaceInFile &placeInFile) { +void WsjcppYamlNode::setPlaceInFile(const WsjcppYamlPlaceInFile &placeInFile) { m_placeInFile.setFilename(placeInFile.getFilename()); m_placeInFile.setLine(placeInFile.getLine()); m_placeInFile.setNumberOfLine(placeInFile.getNumberOfLine()); @@ -111,44 +111,44 @@ void WsjcppYamlItem::setPlaceInFile(const WsjcppYamlPlaceInFile &placeInFile) { // --------------------------------------------------------------------- -void WsjcppYamlItem::setComment(const std::string &sComment) { +void WsjcppYamlNode::setComment(const std::string &sComment) { m_sComment = sComment; } // --------------------------------------------------------------------- -std::string WsjcppYamlItem::getComment() { +std::string WsjcppYamlNode::getComment() { return m_sComment; } // --------------------------------------------------------------------- -void WsjcppYamlItem::setName(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { +void WsjcppYamlNode::setName(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { m_sName = sName; m_nNameQuotes = nNameQuotes; } // --------------------------------------------------------------------- -std::string WsjcppYamlItem::getName() { +std::string WsjcppYamlNode::getName() { return m_sName; } // --------------------------------------------------------------------- -WsjcppYamlQuotes WsjcppYamlItem::getNameQuotes() { +WsjcppYamlQuotes WsjcppYamlNode::getNameQuotes() { return m_nNameQuotes; } // --------------------------------------------------------------------- -bool WsjcppYamlItem::isEmpty() { +bool WsjcppYamlNode::isEmpty() { return m_nItemType == WSJCPP_YAML_NODE_EMPTY; } // --------------------------------------------------------------------- -void WsjcppYamlItem::doEmpty() { +void WsjcppYamlNode::doEmpty() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_EMPTY; } else { @@ -158,13 +158,13 @@ void WsjcppYamlItem::doEmpty() { // --------------------------------------------------------------------- -bool WsjcppYamlItem::isUndefined() { +bool WsjcppYamlNode::isUndefined() { return m_nItemType == WSJCPP_YAML_NODE_UNDEFINED; } // --------------------------------------------------------------------- -void WsjcppYamlItem::doArray() { +void WsjcppYamlNode::doArray() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_ARRAY; } else { @@ -174,7 +174,7 @@ void WsjcppYamlItem::doArray() { // --------------------------------------------------------------------- -void WsjcppYamlItem::doMap() { +void WsjcppYamlNode::doMap() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_MAP; } else { @@ -184,7 +184,7 @@ void WsjcppYamlItem::doMap() { // --------------------------------------------------------------------- -void WsjcppYamlItem::doValue() { +void WsjcppYamlNode::doValue() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_VALUE; } else { @@ -194,13 +194,13 @@ void WsjcppYamlItem::doValue() { // --------------------------------------------------------------------- -bool WsjcppYamlItem::isMap() { +bool WsjcppYamlNode::isMap() { return m_nItemType == WSJCPP_YAML_NODE_MAP; } // --------------------------------------------------------------------- -bool WsjcppYamlItem::hasElement(const std::string &sName) { +bool WsjcppYamlNode::hasElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "hasElement('" + sName + "'): Element must be map"); } @@ -214,7 +214,7 @@ bool WsjcppYamlItem::hasElement(const std::string &sName) { // --------------------------------------------------------------------- -WsjcppYamlItem *WsjcppYamlItem::getElement(const std::string &sName) { +WsjcppYamlNode *WsjcppYamlNode::getElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "getElement: Element must be map"); } @@ -231,7 +231,7 @@ WsjcppYamlItem *WsjcppYamlItem::getElement(const std::string &sName) { // --------------------------------------------------------------------- -bool WsjcppYamlItem::setElement(const std::string &sName, WsjcppYamlItem *pItem) { +bool WsjcppYamlNode::setElement(const std::string &sName, WsjcppYamlNode *pItem) { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_MAP; // change item type to map on first element } @@ -249,13 +249,13 @@ bool WsjcppYamlItem::setElement(const std::string &sName, WsjcppYamlItem *pItem) // --------------------------------------------------------------------- -bool WsjcppYamlItem::removeElement(const std::string &sName) { +bool WsjcppYamlNode::removeElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "removeElement: Element must be map"); } - std::vector::iterator it; + std::vector::iterator it; for (it = m_vObjects.begin(); it != m_vObjects.end(); ++it) { - WsjcppYamlItem *pItem = *it; + WsjcppYamlNode *pItem = *it; if (pItem->getName() == sName) { m_vObjects.erase(it); delete pItem; @@ -267,13 +267,13 @@ bool WsjcppYamlItem::removeElement(const std::string &sName) { // --------------------------------------------------------------------- -std::vector WsjcppYamlItem::getKeys() { +std::vector WsjcppYamlNode::getKeys() { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { WsjcppLog::throw_err(TAG, "getKeys: Element must be map"); } std::vector vKeys; for (int i = 0; i < m_vObjects.size(); i++) { - WsjcppYamlItem *pItem = m_vObjects[i]; + WsjcppYamlNode *pItem = m_vObjects[i]; if (pItem->isValue() || pItem->isMap() || pItem->isArray() || pItem->isUndefined()) { std::string sName = pItem->getName(); vKeys.push_back(sName); @@ -284,7 +284,7 @@ std::vector WsjcppYamlItem::getKeys() { // --------------------------------------------------------------------- -bool WsjcppYamlItem::setElementValue( +bool WsjcppYamlNode::setElementValue( const std::string &sName, const std::string &sValue, WsjcppYamlQuotes nNameQuotes, @@ -299,11 +299,11 @@ bool WsjcppYamlItem::setElementValue( } if (this->hasElement(sName)) { - WsjcppYamlItem *pItem = this->getElement(sName); + WsjcppYamlNode *pItem = this->getElement(sName); pItem->setValue(sValue, nValueQuotes); } else { WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_VALUE); + WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_VALUE); pNewItem->setName(sName, nNameQuotes); pNewItem->setValue(sValue, nValueQuotes); this->setElement(sName, pNewItem); @@ -313,7 +313,7 @@ bool WsjcppYamlItem::setElementValue( // --------------------------------------------------------------------- -bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { +bool WsjcppYamlNode::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_MAP ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } @@ -321,7 +321,7 @@ bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes return false; // already exists } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_MAP); + WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_MAP); pNewItem->setName(sName, nNameQuotes); this->setElement(sName, pNewItem); return true; @@ -329,19 +329,19 @@ bool WsjcppYamlItem::createElementMap(const std::string &sName, WsjcppYamlQuotes // --------------------------------------------------------------------- -WsjcppYamlItem *WsjcppYamlItem::createElementMap() { +WsjcppYamlNode *WsjcppYamlNode::createElementMap() { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY ) { WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'array' for " + this->getPlaceInFile().getForLogFormat()); } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_MAP); + WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_MAP); this->appendElement(pNewItem); return pNewItem; } // --------------------------------------------------------------------- -bool WsjcppYamlItem::createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { +bool WsjcppYamlNode::createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_MAP ) { WsjcppLog::throw_err(TAG, "createElementArray, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } @@ -349,7 +349,7 @@ bool WsjcppYamlItem::createElementArray(const std::string &sName, WsjcppYamlQuot return false; } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_ARRAY); + WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_ARRAY); pNewItem->setName(sName, nNameQuotes); this->setElement(sName, pNewItem); return true; @@ -357,13 +357,13 @@ bool WsjcppYamlItem::createElementArray(const std::string &sName, WsjcppYamlQuot // --------------------------------------------------------------------- -bool WsjcppYamlItem::isArray() { +bool WsjcppYamlNode::isArray() { return m_nItemType == WSJCPP_YAML_NODE_ARRAY; } // --------------------------------------------------------------------- -int WsjcppYamlItem::getLength() { +int WsjcppYamlNode::getLength() { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "getLength, Element must be array for " + this->getForLogFormat()); } @@ -378,12 +378,12 @@ int WsjcppYamlItem::getLength() { // --------------------------------------------------------------------- -WsjcppYamlItem *WsjcppYamlItem::getElement(int i) { +WsjcppYamlNode *WsjcppYamlNode::getElement(int i) { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "getElement, Element must be array"); } int nCounter = -1; - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; for (int n = 0; n < m_vObjects.size(); n++) { if (!m_vObjects[n]->isEmpty()) { nCounter++; @@ -401,7 +401,7 @@ WsjcppYamlItem *WsjcppYamlItem::getElement(int i) { // --------------------------------------------------------------------- -bool WsjcppYamlItem::appendElement(WsjcppYamlItem *pItem) { +bool WsjcppYamlNode::appendElement(WsjcppYamlNode *pItem) { if (pItem->isEmpty()) { m_vObjects.push_back(pItem); // TODO clone object return true; @@ -415,24 +415,24 @@ bool WsjcppYamlItem::appendElement(WsjcppYamlItem *pItem) { // --------------------------------------------------------------------- -bool WsjcppYamlItem::appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes) { +bool WsjcppYamlNode::appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "appendElementValue, Element must be array for " + this->getForLogFormat()); } WsjcppYamlPlaceInFile pl; - WsjcppYamlItem *pNewItem = new WsjcppYamlItem(this, pl, WSJCPP_YAML_NODE_VALUE); + WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_VALUE); pNewItem->setValue(sValue, nValueQuotes); return this->appendElement(pNewItem); } // --------------------------------------------------------------------- -bool WsjcppYamlItem::removeElement(int i) { +bool WsjcppYamlNode::removeElement(int i) { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { WsjcppLog::throw_err(TAG, "appendElement, Element must be array for " + this->getForLogFormat()); } int nCounter = -1; - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; for (int n = 0; n < m_vObjects.size(); n++) { if (!m_vObjects[n]->isEmpty()) { nCounter++; @@ -445,7 +445,7 @@ bool WsjcppYamlItem::removeElement(int i) { if (pItem == nullptr) { WsjcppLog::throw_err(TAG, "getElement(" + std::to_string(i) + "), Out of range in array for '" + this->getPlaceInFile().getLine() + "'"); } - std::vector::iterator it; + std::vector::iterator it; for (it = m_vObjects.begin(); it != m_vObjects.end(); ++it) { if (*it == pItem) { delete pItem; @@ -458,13 +458,13 @@ bool WsjcppYamlItem::removeElement(int i) { // --------------------------------------------------------------------- -bool WsjcppYamlItem::isValue() { +bool WsjcppYamlNode::isValue() { return m_nItemType == WSJCPP_YAML_NODE_VALUE; } // --------------------------------------------------------------------- -std::string WsjcppYamlItem::getValue() { +std::string WsjcppYamlNode::getValue() { if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { WsjcppLog::throw_err(TAG, "getValue, Element must be value for " + this->getForLogFormat()); } @@ -473,7 +473,7 @@ std::string WsjcppYamlItem::getValue() { // --------------------------------------------------------------------- -void WsjcppYamlItem::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { +void WsjcppYamlNode::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { WsjcppLog::throw_err(TAG, "setValue, Element must be value for " + this->getForLogFormat()); } @@ -483,13 +483,13 @@ void WsjcppYamlItem::setValue(const std::string &sValue, WsjcppYamlQuotes nQuote // --------------------------------------------------------------------- -WsjcppYamlQuotes WsjcppYamlItem::getValueQuotes() { +WsjcppYamlQuotes WsjcppYamlNode::getValueQuotes() { return m_nValueQuotes; } // --------------------------------------------------------------------- -std::string WsjcppYamlItem::toString(std::string sIntent) { +std::string WsjcppYamlNode::toString(std::string sIntent) { std::string sRet = ""; if (this->isValue()) { if (m_nValueQuotes == WSJCPP_YAML_QUOTES_DOUBLE) { @@ -523,7 +523,7 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { return sRet; } else if (this->isArray()) { for (int i = 0; i < m_vObjects.size(); i++) { - WsjcppYamlItem *pItem = m_vObjects[i]; + WsjcppYamlNode *pItem = m_vObjects[i]; if (pItem->isEmpty()) { sRet += pItem->toString(sIntent) + "\n"; // sRet += "\n"; @@ -539,7 +539,7 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { } } else if (this->isMap()) { for (int i = 0; i < m_vObjects.size(); i++) { - WsjcppYamlItem *pItem = m_vObjects[i]; + WsjcppYamlNode *pItem = m_vObjects[i]; if (pItem->isEmpty() ) { sRet += pItem->toString(sIntent); sRet += "\n"; @@ -584,7 +584,7 @@ std::string WsjcppYamlItem::toString(std::string sIntent) { // --------------------------------------------------------------------- -std::string WsjcppYamlItem::getItemTypeAsString() { +std::string WsjcppYamlNode::getItemTypeAsString() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { return "undefined"; } else if (m_nItemType == WSJCPP_YAML_NODE_ARRAY) { @@ -599,7 +599,7 @@ std::string WsjcppYamlItem::getItemTypeAsString() { // --------------------------------------------------------------------- -std::string WsjcppYamlItem::getForLogFormat() { +std::string WsjcppYamlNode::getForLogFormat() { return m_placeInFile.getForLogFormat(); } @@ -957,7 +957,7 @@ void WsjcppYamlParserStatus::logUnknownLine(const std::string &sPrefix) { // --------------------------------------------------------------------- // WsjcppYamlCursor -WsjcppYamlCursor::WsjcppYamlCursor(WsjcppYamlItem *pCurrentNode) { +WsjcppYamlCursor::WsjcppYamlCursor(WsjcppYamlNode *pCurrentNode) { m_pCurrentNode = pCurrentNode; TAG = "WsjcppYamlCursor"; } @@ -1209,7 +1209,7 @@ bool WsjcppYaml::saveToString(std::string &sBuffer) { // TODO move to WsjcppCore // --------------------------------------------------------------------- -WsjcppYamlItem *WsjcppYaml::getRoot() { +WsjcppYamlNode *WsjcppYaml::getRoot() { return m_pRoot; } @@ -1257,7 +1257,7 @@ std::vector WsjcppYaml::splitToLines(const std::string &sBuffer) { bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError) { this->clear(); if (m_pRoot == nullptr) { - m_pRoot = new WsjcppYamlItem(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_NODE_MAP); + m_pRoot = new WsjcppYamlNode(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_NODE_MAP); } std::vector vLines = this->splitToLines(sBuffer); @@ -1288,13 +1288,13 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, if (st.pCurItem != nullptr) { if (st.pCurItem->isArray() || st.pCurItem->isMap() || st.pCurItem->isUndefined()) { - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_EMPTY ); st.pCurItem->appendElement(pItem); } else if (st.pCurItem->getParent() != nullptr && (st.pCurItem->getParent()->isArray() || st.pCurItem->getParent()->isMap())) { - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem->getParent(), st.placeInFile, WSJCPP_YAML_NODE_EMPTY ); @@ -1360,7 +1360,7 @@ void WsjcppYaml::process_sameIntent_hasName_emptyValue_arrayItem(WsjcppYamlParse // --------------------------------------------------------------------- void WsjcppYaml::process_sameIntent_hasName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st) { - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_UNDEFINED ); @@ -1381,7 +1381,7 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS if (st.pCurItem->isUndefined()) { st.pCurItem->doArray(); } - WsjcppYamlItem *pMapItem = new WsjcppYamlItem( + WsjcppYamlNode *pMapItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_MAP ); @@ -1389,7 +1389,7 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS st.pCurItem = pMapItem; st.nIntent = st.nIntent + 2; - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_VALUE ); @@ -1404,7 +1404,7 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserS // --------------------------------------------------------------------- void WsjcppYaml::process_sameIntent_hasName_hasValue_noArrayItem(WsjcppYamlParserStatus &st) { - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_VALUE ); @@ -1422,7 +1422,7 @@ void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem(WsjcppYamlParse if (st.pCurItem->isUndefined()) { st.pCurItem->doArray(); } - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_VALUE ); @@ -1445,7 +1445,7 @@ void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlPar if (st.pCurItem->isUndefined()) { st.pCurItem->doArray(); } - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_VALUE ); @@ -1459,7 +1459,7 @@ void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlPar // --------------------------------------------------------------------- void WsjcppYaml::process_sameIntent_emptyName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st) { - WsjcppYamlItem *pItem = new WsjcppYamlItem( + WsjcppYamlNode *pItem = new WsjcppYamlNode( st.pCurItem, st.placeInFile, WSJCPP_YAML_NODE_EMPTY ); diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index fdda8f7..89a8d9c 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -58,15 +58,15 @@ enum WsjcppYamlQuotes { Basic class for yaml tree */ -class WsjcppYamlItem { // TODO: rename to node +class WsjcppYamlNode { public: - WsjcppYamlItem( - WsjcppYamlItem *pParent, + WsjcppYamlNode( + WsjcppYamlNode *pParent, const WsjcppYamlPlaceInFile &placeInFile, WsjcppYamlNodeType nItemType ); - ~WsjcppYamlItem(); - WsjcppYamlItem *getParent(); + ~WsjcppYamlNode(); + WsjcppYamlNode *getParent(); WsjcppYamlPlaceInFile getPlaceInFile(); void setPlaceInFile(const WsjcppYamlPlaceInFile &placeInFile); @@ -88,8 +88,8 @@ class WsjcppYamlItem { // TODO: rename to node bool isMap(); bool hasElement(const std::string &sName); - WsjcppYamlItem *getElement(const std::string &sName); - bool setElement(const std::string &sName, WsjcppYamlItem *pItem); + WsjcppYamlNode *getElement(const std::string &sName); + bool setElement(const std::string &sName, WsjcppYamlNode *pItem); bool removeElement(const std::string &sName); std::vector getKeys(); @@ -100,13 +100,13 @@ class WsjcppYamlItem { // TODO: rename to node ); bool createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes); - WsjcppYamlItem *createElementMap(); + WsjcppYamlNode *createElementMap(); bool createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes); bool isArray(); int getLength(); - WsjcppYamlItem *getElement(int i); - bool appendElement(WsjcppYamlItem *pItem); + WsjcppYamlNode *getElement(int i); + bool appendElement(WsjcppYamlNode *pItem); bool appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE); bool removeElement(int i); @@ -124,10 +124,10 @@ class WsjcppYamlItem { // TODO: rename to node private: std::string TAG; - WsjcppYamlItem *m_pParent; + WsjcppYamlNode *m_pParent; WsjcppYamlPlaceInFile m_placeInFile; WsjcppYamlNodeType m_nItemType; - std::vector m_vObjects; + std::vector m_vObjects; std::string m_sValue; // if it is not array or map WsjcppYamlQuotes m_nValueQuotes; std::string m_sName; @@ -184,7 +184,7 @@ class WsjcppYamlParsebleLine { class WsjcppYamlParserStatus { public: int nIntent; - WsjcppYamlItem *pCurItem; + WsjcppYamlNode *pCurItem; WsjcppYamlParsebleLine line; WsjcppYamlPlaceInFile placeInFile; void logUnknownLine(const std::string &sPrefix); @@ -195,7 +195,7 @@ class WsjcppYamlParserStatus { class WsjcppYamlCursor { public: - WsjcppYamlCursor(WsjcppYamlItem *pCurrentNode); + WsjcppYamlCursor(WsjcppYamlNode *pCurrentNode); WsjcppYamlCursor(); ~WsjcppYamlCursor(); @@ -244,7 +244,7 @@ class WsjcppYamlCursor { private: std::string TAG; - WsjcppYamlItem *m_pCurrentNode; + WsjcppYamlNode *m_pCurrentNode; }; @@ -259,7 +259,7 @@ class WsjcppYaml { bool saveToFile(const std::string &sFileName); bool loadFromString(const std::string &sBufferName, const std::string &sBuffer, std::string &sError); bool saveToString(std::string &sBuffer); - WsjcppYamlItem *getRoot(); + WsjcppYamlNode *getRoot(); WsjcppYamlCursor getCursor() const; WsjcppYamlCursor operator[](int idx) const; @@ -281,7 +281,7 @@ class WsjcppYaml { void process_sameIntent_emptyName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st); std::vector m_sLines; - WsjcppYamlItem *m_pRoot; + WsjcppYamlNode *m_pRoot; }; #endif // WSJCPP_YAML_H diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index 0008f5b..eb7736c 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -46,7 +46,7 @@ void UnitTestReadYaml::executeTest() { compare("has services is map", yaml.getRoot()->getElement("services")->isMap(), true); - WsjcppYamlItem *pServices = yaml.getRoot()->getElement("services"); + WsjcppYamlNode *pServices = yaml.getRoot()->getElement("services"); compare("has services.vote", pServices->hasElement("vote"), true); compare("has services.vote is map", pServices->getElement("vote")->isMap(), true); @@ -79,20 +79,20 @@ void UnitTestReadYaml::executeTest() { compare("services.result is map", pServices->getElement("result")->isMap(), true); compare("services.result keys size 5", pServices->getElement("result")->getKeys().size(), 5); - WsjcppYamlItem *pResult = pServices->getElement("result"); + WsjcppYamlNode *pResult = pServices->getElement("result"); - WsjcppYamlItem *pResultVolumes = pResult->getElement("volumes"); + WsjcppYamlNode *pResultVolumes = pResult->getElement("volumes"); compare("services.result.volumes is array", pResultVolumes->isArray(), true); compare("services.result.volumes size 1", pResultVolumes->getLength(), 1); compare("services.result.volumes val 0", pResultVolumes->getElement(0)->getValue(), "./result:/app"); - WsjcppYamlItem *pResultPorts = pResult->getElement("ports"); + WsjcppYamlNode *pResultPorts = pResult->getElement("ports"); compare("services.result.ports is array", pResultPorts->isArray(), true); compare("services.result.ports size 2", pResultPorts->getLength(), 2); compare("services.result.ports val 0", pResultPorts->getElement(0)->getValue(), "5001:80"); compare("services.result.ports val 1", pResultPorts->getElement(1)->getValue(), "5858:5858"); - WsjcppYamlItem *pResultNetworks = pResult->getElement("networks"); + WsjcppYamlNode *pResultNetworks = pResult->getElement("networks"); compare("services.result.networks size 2", pResultNetworks->getLength(), 2); compare("services.result.networks val 0", pResultNetworks->getElement(0)->getValue(), "front-tier"); compare("services.result.networks val 1", pResultNetworks->getElement(1)->getValue(), "back-tier"); @@ -103,25 +103,25 @@ void UnitTestReadYaml::executeTest() { compare("has services.worker", pServices->hasElement("worker"), true); compare("has services.worker is map", pServices->getElement("worker")->isMap(), true); compare("services.worker keys size 3", pServices->getElement("worker")->getKeys().size(), 3); - WsjcppYamlItem *pWorker = pServices->getElement("worker"); + WsjcppYamlNode *pWorker = pServices->getElement("worker"); compare("has services.worker.build", pWorker->hasElement("build"), true); compare("has services.worker.depends_on", pWorker->hasElement("depends_on"), true); compare("has services.worker.networks", pWorker->hasElement("networks"), true); - WsjcppYamlItem *pWorkerBuild = pWorker->getElement("build"); + WsjcppYamlNode *pWorkerBuild = pWorker->getElement("build"); compare("services.worker.build is map", pWorkerBuild->isMap(), true); compare("has services.worker.build.context", pWorkerBuild->hasElement("context"), true); compare("services.worker.build.context val", pWorkerBuild->getElement("context")->getValue(), "./worker"); - WsjcppYamlItem *pWorkerDependsOn = pWorker->getElement("depends_on"); + WsjcppYamlNode *pWorkerDependsOn = pWorker->getElement("depends_on"); compare("has services.worker.depends_on", pWorkerDependsOn->isArray(), true); compare("services.worker.depends_on size 2", pWorkerDependsOn->getLength(), 2); compare("services.worker.depends_on val 0", pWorkerDependsOn->getElement(0)->getValue(), "redis"); compare("services.worker.depends_on val 1", pWorkerDependsOn->getElement(1)->getValue(), "db"); - WsjcppYamlItem *pWorkerNetworks = pWorker->getElement("networks"); + WsjcppYamlNode *pWorkerNetworks = pWorker->getElement("networks"); compare("services.worker.networks size 1", pWorkerNetworks->getLength(), 1); compare("services.worker.networks val 0", pWorkerNetworks->getElement(0)->getValue(), "back-tier"); } @@ -132,7 +132,7 @@ void UnitTestReadYaml::executeTest() { compare("services.redis is map", pServices->getElement("redis")->isMap(), true); compare("services.redis keys size 4", pServices->getElement("redis")->getKeys().size(), 4); - WsjcppYamlItem *pRedis = pServices->getElement("redis"); + WsjcppYamlNode *pRedis = pServices->getElement("redis"); compare("has services.redis.image", pRedis->hasElement("image"), true); compare("has services.redis.container_name", pRedis->hasElement("container_name"), true); compare("has services.redis.ports", pRedis->hasElement("ports"), true); @@ -141,12 +141,12 @@ void UnitTestReadYaml::executeTest() { compare("services.redis.image value", pRedis->getElement("image")->getValue(), "redis:alpine"); compare("services.redis.container_name", pRedis->getElement("container_name")->getValue(), "redis"); - WsjcppYamlItem *pRedisPorts = pRedis->getElement("ports"); + WsjcppYamlNode *pRedisPorts = pRedis->getElement("ports"); // TODO bug #17 compare("services.redis.ports is value", pRedisPorts->isValue(), true); compare("services.redis.ports value", pRedisPorts->getValue(), "[\"6379\"]"); - WsjcppYamlItem *pRedisNetworks = pRedis->getElement("networks"); + WsjcppYamlNode *pRedisNetworks = pRedis->getElement("networks"); compare("services.redis.networks size 1", pRedisNetworks->getLength(), 1); compare("services.redis.networks val 0", pRedisNetworks->getElement(0)->getValue(), "back-tier"); } @@ -157,7 +157,7 @@ void UnitTestReadYaml::executeTest() { compare("has services.db is map", pServices->getElement("db")->isMap(), true); compare("services.db keys size 5", pServices->getElement("db")->getKeys().size(), 5); - WsjcppYamlItem *pServicesDb = pServices->getElement("db"); + WsjcppYamlNode *pServicesDb = pServices->getElement("db"); compare("has services.db.image", pServicesDb->hasElement("image"), true); compare("services.db.image value", pServicesDb->getElement("image")->getValue(), "postgres:9.4"); @@ -166,7 +166,7 @@ void UnitTestReadYaml::executeTest() { compare("has services.db.environment", pServicesDb->hasElement("environment"), true); compare("services.db.environment is map", pServicesDb->getElement("environment")->isMap(), true); - WsjcppYamlItem *pDbEnvironment = pServicesDb->getElement("environment"); + WsjcppYamlNode *pDbEnvironment = pServicesDb->getElement("environment"); compare("has services.db.environment.POSTGRES_USER", pDbEnvironment->hasElement("POSTGRES_USER"), true); compare("services.db.environment.POSTGRES_USER", pDbEnvironment->getElement("POSTGRES_USER")->getValue(), "postgres"); @@ -177,14 +177,14 @@ void UnitTestReadYaml::executeTest() { compare("has services.db.volumes", pServicesDb->hasElement("volumes"), true); compare("services.db.volumes is array", pServicesDb->getElement("volumes")->isArray(), true); - WsjcppYamlItem *pDbVolumes = pServicesDb->getElement("volumes"); + WsjcppYamlNode *pDbVolumes = pServicesDb->getElement("volumes"); compare("services.db.volumes size 1", pDbVolumes->getLength(), 1); compare("services.db.volumes val 0", pDbVolumes->getElement(0)->getValue(), "db-data:/var/lib/postgresql/data"); compare("has services.db.networks", pServicesDb->hasElement("networks"), true); compare("services.db.networks is array", pServicesDb->getElement("networks")->isArray(), true); - WsjcppYamlItem *pDbNetworks = pServicesDb->getElement("networks"); + WsjcppYamlNode *pDbNetworks = pServicesDb->getElement("networks"); compare("services.db.networks size 1", pDbNetworks->getLength(), 1); compare("services.db.networks val 0", pDbNetworks->getElement(0)->getValue(), "back-tier"); } @@ -194,7 +194,7 @@ void UnitTestReadYaml::executeTest() { compare("has volumes", yaml.getRoot()->hasElement("volumes"), true); compare("has volumes is map", yaml.getRoot()->getElement("volumes")->isMap(), true); - WsjcppYamlItem *pVolumes = yaml.getRoot()->getElement("volumes"); + WsjcppYamlNode *pVolumes = yaml.getRoot()->getElement("volumes"); compare("has volumes.db-data", pVolumes->hasElement("db-data"), true); compare("has volumes.db-data is undefined", pVolumes->getElement("db-data")->isUndefined(), true); @@ -206,7 +206,7 @@ void UnitTestReadYaml::executeTest() { compare("has networks", yaml.getRoot()->hasElement("networks"), true); compare("has networks is map", yaml.getRoot()->getElement("networks")->isMap(), true); - WsjcppYamlItem *pNeworks = yaml.getRoot()->getElement("networks"); + WsjcppYamlNode *pNeworks = yaml.getRoot()->getElement("networks"); compare("has networks keys size 2", pNeworks->getKeys().size(), 2); compare("has networks.front-tier", pNeworks->hasElement("front-tier"), true); diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp index f94723c..4029047 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_for_map.cpp @@ -60,8 +60,8 @@ void UnitTestRemoveElementForMap::executeTest() { return; } - WsjcppYamlItem *pMap1 = yaml.getRoot()->getElement("map1"); - WsjcppYamlItem *pMap11 = pMap1->getElement("map11"); + WsjcppYamlNode *pMap1 = yaml.getRoot()->getElement("map1"); + WsjcppYamlNode *pMap11 = pMap1->getElement("map11"); compare("has map111", pMap11->hasElement("map111"), true); compare("has map112", pMap11->hasElement("map112"), true); diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp index 789632e..7f609e7 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp @@ -50,7 +50,7 @@ void UnitTestRemoveElementInArray::executeTest() { } - WsjcppYamlItem *pArr1 = yaml.getRoot()->getElement("arr1"); + WsjcppYamlNode *pArr1 = yaml.getRoot()->getElement("arr1"); compare("arr1 len", pArr1->getLength(), 3); compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i2"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp index 9c52efe..9f2894b 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_all.cpp @@ -71,7 +71,7 @@ void UnitTestYamlParserAll::executeTest() { return; } - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; compare("test10", yaml.getRoot()->getElement("test10")->getValue(), "one"); compare("test20", yaml.getRoot()->getElement("test20")->getValue(), "two"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp index 5190cd4..b160229 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_array_included_map.cpp @@ -55,7 +55,7 @@ void UnitTestYamlParserArrayIncludedMap::executeTest() { return; } - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; compare("param1-value", yaml.getRoot()->getElement("param1")->getValue(), "none value1"); compare("param1-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getLine(), "param1: none value1 # it's value for something # olala "); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp index bb57a45..37b6612 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp @@ -62,7 +62,7 @@ void UnitTestYamlParserHierarchicalMap::executeTest() { return; } - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; pItem = yaml.getRoot()->getElement("map1")->getElement("map11")->getElement("map111"); compare("param1111", pItem->getElement("param1111")->getValue(), "v1111"); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp index c4b4903..285a12c 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp @@ -54,7 +54,7 @@ void UnitTestYamlParserSimpleArray::executeTest() { return; } - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; compare("param1-value", yaml.getRoot()->getElement("param1")->getValue(), "none value1"); compare("param1-line", yaml.getRoot()->getElement("param1")->getPlaceInFile().getLine(), "param1: none value1 # it's value for something # olala "); diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp index 6607e78..32873e1 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp @@ -46,7 +46,7 @@ void UnitTestYamlParserSimpleMap::executeTest() { return; } - WsjcppYamlItem *pItem = nullptr; + WsjcppYamlNode *pItem = nullptr; compare("param1", yaml.getRoot()->getElement("param1")->getValue(), "value1"); compare("param2", yaml.getRoot()->getElement("param2")->getValue(), "value2"); compare("param2", yaml.getRoot()->getElement("param2")->getComment(), "some comment 2"); From e068c59d381675f7c9988963946612fa13c29e44 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Fri, 25 Sep 2020 22:09:16 +0700 Subject: [PATCH 22/29] Improved unit-test readyml --- unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 50 ++++++++++++++----- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index eb7736c..c4d50d8 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -48,8 +48,7 @@ void UnitTestReadYaml::executeTest() { WsjcppYamlNode *pServices = yaml.getRoot()->getElement("services"); - compare("has services.vote", pServices->hasElement("vote"), true); - compare("has services.vote is map", pServices->getElement("vote")->isMap(), true); + /* @@ -60,18 +59,37 @@ void UnitTestReadYaml::executeTest() { command: python app.py volumes: - ./vote:/app - ports: - - "5000:80" - networks: - - front-tier - - back-tier - - result: - build: ./result - command: nodemon server.js - volumes: - - ./result:/app + */ + // services.vote + { + compare("has services.vote", pServices->hasElement("vote"), true); + compare("services.vote is map", pServices->getElement("vote")->isMap(), true); + compare("services.vote keys size 5", pServices->getElement("vote")->getKeys().size(), 5); + + WsjcppYamlNode *pVote = pServices->getElement("vote"); + + compare("has services.vote.build", pVote->hasElement("build"), true); + compare("services.vote.build val", pVote->getElement("build")->getValue(), "./vote"); + + compare("has services.vote.command", pVote->hasElement("command"), true); + compare("services.vote.command val", pVote->getElement("command")->getValue(), "python app.py"); + + WsjcppYamlNode *pVolumes = pVote->getElement("volumes"); + compare("services.vote.volumes is array", pVolumes->isArray(), true); + compare("services.vote.volumes size 1", pVolumes->getLength(), 1); + compare("services.vote.volumes val 0", pVolumes->getElement(0)->getValue(), "./vote:/app"); + + WsjcppYamlNode *pVotePorts = pVote->getElement("ports"); + compare("services.vote.ports is array", pVotePorts->isArray(), true); + compare("services.vote.ports size 1", pVotePorts->getLength(), 1); + compare("services.vote.ports val 0", pVotePorts->getElement(0)->getValue(), "5000:80"); + + WsjcppYamlNode *pVoteNetworks = pVote->getElement("networks"); + compare("services.vote.networks size 2", pVoteNetworks->getLength(), 2); + compare("services.vote.networks val 0", pVoteNetworks->getElement(0)->getValue(), "front-tier"); + compare("services.vote.networks val 1", pVoteNetworks->getElement(1)->getValue(), "back-tier"); + } // services.result { @@ -81,6 +99,12 @@ void UnitTestReadYaml::executeTest() { WsjcppYamlNode *pResult = pServices->getElement("result"); + compare("has services.result.build", pResult->hasElement("build"), true); + compare("services.result.build val", pResult->getElement("build")->getValue(), "./result"); + + compare("has services.result.command", pResult->hasElement("command"), true); + compare("services.result.command val", pResult->getElement("command")->getValue(), "nodemon server.js"); + WsjcppYamlNode *pResultVolumes = pResult->getElement("volumes"); compare("services.result.volumes is array", pResultVolumes->isArray(), true); compare("services.result.volumes size 1", pResultVolumes->getLength(), 1); From 40965c621b5295f2a347263f0dcc1963de708f99 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sat, 26 Sep 2020 01:31:18 +0700 Subject: [PATCH 23/29] Removed class WsjcppYamlParserStatus (moved variables inside WsjcppYaml) --- src/wsjcpp_yaml.cpp | 254 ++++++++++-------- src/wsjcpp_yaml.h | 42 +-- unit-tests.wsjcpp/src/unit_test_read_yaml.cpp | 13 - 3 files changed, 158 insertions(+), 151 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 241afa5..02d9678 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -77,6 +77,7 @@ WsjcppYamlNode::WsjcppYamlNode( m_nItemType = nItemType; m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; + m_nDiffIntent = 0; TAG = "WsjcppYamlNode"; } @@ -605,6 +606,19 @@ std::string WsjcppYamlNode::getForLogFormat() { // --------------------------------------------------------------------- +void WsjcppYamlNode::setNodeDiffIntent(int nDiffIntent) { + m_nDiffIntent = nDiffIntent; +} + +// --------------------------------------------------------------------- + +int WsjcppYamlNode::getNodeDiffIntent() { + return m_nDiffIntent; +} + +// --------------------------------------------------------------------- +// WsjcppYamlParsebleLine + WsjcppYamlParsebleLine::WsjcppYamlParsebleLine(int nLine) { TAG = "WsjcppYamlParsebleLine(line:" + std::to_string(nLine) + ")"; m_nLineNumber = nLine; @@ -940,20 +954,6 @@ std::string WsjcppYamlParsebleLine::removeStringSingleQuotes(const std::string & return sRet; } -// --------------------------------------------------------------------- -// WsjcppYamlParserStatus - -void WsjcppYamlParserStatus::logUnknownLine(const std::string &sPrefix) { - WsjcppLog::warn(sPrefix, "\n" - " error:\n" - " desc: \"unknown_line\"\n" - " line_number: " + std::to_string(pCurItem->getPlaceInFile().getNumberOfLine()) + "\n" - " line: \"" + placeInFile.getLine() + "\"\n" - " intent: " + std::to_string(nIntent) + "\n" - " filename: \"" + pCurItem->getPlaceInFile().getFilename() + "\"" - ); -} - // --------------------------------------------------------------------- // WsjcppYamlCursor @@ -1261,44 +1261,40 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, } std::vector vLines = this->splitToLines(sBuffer); - WsjcppYamlParserStatus st; - st.pCurItem = m_pRoot; // TODO recreate again new root element - st.placeInFile.setFilename(sFileName); - st.nIntent = 0; - m_pRoot->setPlaceInFile(st.placeInFile); + m_pParseCurrentItem = m_pRoot; + m_parsePlaceInFile.setFilename(sFileName); + m_nParseCurrentIntent = 0; + m_pRoot->setPlaceInFile(m_parsePlaceInFile); for (int nLine = 0; nLine < vLines.size(); nLine++) { - st.placeInFile.setLine(vLines[nLine]); + m_parsePlaceInFile.setLine(vLines[nLine]); // WsjcppLog::info(TAG, "Line(" + std::to_string(nLine) + ") '" + st.sLine + "'"); - st.placeInFile.setNumberOfLine(nLine); - st.line = WsjcppYamlParsebleLine(nLine); - if (!st.line.parseLine(st.placeInFile.getLine(), sError)) { + m_parsePlaceInFile.setNumberOfLine(nLine); + m_parseLine = WsjcppYamlParsebleLine(nLine); + if (!m_parseLine.parseLine(m_parsePlaceInFile.getLine(), sError)) { return false; } - bool isEmptyName = st.line.isEmptyName(); - bool isEmptyValue = st.line.isEmptyValue(); - bool isArrayItem = st.line.isArrayItem(); - int nLineIntent = st.line.getIntent(); - int nDiffIntent = nLineIntent - st.nIntent; + bool isEmptyName = m_parseLine.isEmptyName(); + bool isEmptyValue = m_parseLine.isEmptyValue(); + bool isArrayItem = m_parseLine.isArrayItem(); + int nLineIntent = m_parseLine.getIntent(); + int nDiffIntent = nLineIntent - m_nParseCurrentIntent; - if (st.line.isEmptyLine()) { - - - if (st.pCurItem != nullptr) { - - if (st.pCurItem->isArray() || st.pCurItem->isMap() || st.pCurItem->isUndefined()) { - WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + if (m_parseLine.isEmptyLine()) { + if (m_pParseCurrentItem != nullptr) { + if (m_pParseCurrentItem->isArray() || m_pParseCurrentItem->isMap() || m_pParseCurrentItem->isUndefined()) { + WsjcppYamlNode *pNode = new WsjcppYamlNode( + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - st.pCurItem->appendElement(pItem); - } else if (st.pCurItem->getParent() != nullptr && (st.pCurItem->getParent()->isArray() || st.pCurItem->getParent()->isMap())) { - WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem->getParent(), st.placeInFile, + m_pParseCurrentItem->appendElement(pNode); + } else if (m_pParseCurrentItem->getParent() != nullptr && (m_pParseCurrentItem->getParent()->isArray() || m_pParseCurrentItem->getParent()->isMap())) { + WsjcppYamlNode *pNode = new WsjcppYamlNode( + m_pParseCurrentItem->getParent(), m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - st.pCurItem->getParent()->appendElement(pItem); + m_pParseCurrentItem->getParent()->appendElement(pNode); } else { WsjcppLog::throw_err(TAG, "Empty element can be added only to map or to array"); } @@ -1307,45 +1303,50 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, } while (nDiffIntent < 0) { - st.pCurItem = st.pCurItem->getParent(); - st.nIntent = st.nIntent - 2; - nDiffIntent = nLineIntent - st.nIntent; - if (st.pCurItem == nullptr) { + int nNodeDiffIntent = m_pParseCurrentItem->getNodeDiffIntent(); + if (nNodeDiffIntent == 0) { + sError = "Node diff intent cann't be 0 "; + return false; + } + m_pParseCurrentItem = m_pParseCurrentItem->getParent(); + m_nParseCurrentIntent = m_nParseCurrentIntent - nNodeDiffIntent; + nDiffIntent = nLineIntent - m_nParseCurrentIntent; + if (m_pParseCurrentItem == nullptr) { sError = "Current item is nullptr"; return false; } } if (nDiffIntent == 0) { - if (st.line.isEmptyName()) { + if (m_parseLine.isEmptyName()) { if ( ! isEmptyValue && isArrayItem) { - process_sameIntent_emptyName_hasValue_arrayItem(st); + process_sameIntent_emptyName_hasValue_arrayItem(); } else if (! isEmptyValue && ! isArrayItem) { - process_sameIntent_emptyName_hasValue_noArrayItem(st); + process_sameIntent_emptyName_hasValue_noArrayItem(); } else if (isEmptyValue && isArrayItem) { - process_sameIntent_emptyName_emptyValue_arrayItem(st); + process_sameIntent_emptyName_emptyValue_arrayItem(); } else if (isEmptyValue && ! isArrayItem) { - process_sameIntent_emptyName_emptyValue_noArrayItem(st); + process_sameIntent_emptyName_emptyValue_noArrayItem(); } else { - st.logUnknownLine(TAG); + logUnknownParseLine(); } - } else if ( ! st.line.isEmptyName()) { + } else if ( ! m_parseLine.isEmptyName()) { if ( ! isEmptyValue && isArrayItem) { - process_sameIntent_hasName_hasValue_arrayItem(st); + process_sameIntent_hasName_hasValue_arrayItem(); } else if ( ! isEmptyValue && ! isArrayItem) { - process_sameIntent_hasName_hasValue_noArrayItem(st); + process_sameIntent_hasName_hasValue_noArrayItem(); } else if (isEmptyValue && isArrayItem) { - process_sameIntent_hasName_emptyValue_arrayItem(st); + process_sameIntent_hasName_emptyValue_arrayItem(); } else if (isEmptyValue && ! isArrayItem) { - process_sameIntent_hasName_emptyValue_noArrayItem(st); + process_sameIntent_hasName_emptyValue_noArrayItem(); } else { - st.logUnknownLine(TAG); + logUnknownParseLine(); } } else { - st.logUnknownLine(TAG); + logUnknownParseLine(); } } else { - st.logUnknownLine(TAG); + logUnknownParseLine(); } } return true; @@ -1353,119 +1354,138 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_emptyValue_arrayItem(WsjcppYamlParserStatus &st) { - st.logUnknownLine("process_sameIntent_hasName_emptyValue_arrayItem"); +void WsjcppYaml::process_sameIntent_hasName_emptyValue_arrayItem() { + WsjcppLog::warn(TAG, "process_sameIntent_hasName_emptyValue_arrayItem"); + this->logUnknownParseLine(); } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st) { +void WsjcppYaml::process_sameIntent_hasName_emptyValue_noArrayItem() { WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_UNDEFINED ); - if (st.line.getValueQuotes() != WSJCPP_YAML_QUOTES_NONE) { + if (m_parseLine.getValueQuotes() != WSJCPP_YAML_QUOTES_NONE) { pItem->doValue(); - pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); + pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); } - pItem->setName(st.line.getName(), st.line.getNameQuotes()); - pItem->setComment(st.line.getComment()); - st.pCurItem->setElement(st.line.getName(), pItem); - st.pCurItem = pItem; - st.nIntent = st.nIntent + 2; + pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + pItem->setComment(m_parseLine.getComment()); + m_pParseCurrentItem->setElement(m_parseLine.getName(), pItem); + m_pParseCurrentItem = pItem; + int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserStatus &st) { - if (st.pCurItem->isUndefined()) { - st.pCurItem->doArray(); +void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem() { + if (m_pParseCurrentItem->isUndefined()) { + m_pParseCurrentItem->doArray(); } WsjcppYamlNode *pMapItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_MAP ); - st.pCurItem->appendElement(pMapItem); - st.pCurItem = pMapItem; - st.nIntent = st.nIntent + 2; + m_pParseCurrentItem->appendElement(pMapItem); + m_pParseCurrentItem = pMapItem; + int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); - pItem->setName(st.line.getName(), st.line.getNameQuotes()); - pMapItem->setElement(st.line.getName(), pItem); - st.pCurItem = pItem; - st.nIntent = st.nIntent + 2; + pItem->setComment(m_parseLine.getComment()); + pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + pMapItem->setElement(m_parseLine.getName(), pItem); + m_pParseCurrentItem = pItem; + nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_hasValue_noArrayItem(WsjcppYamlParserStatus &st) { +void WsjcppYaml::process_sameIntent_hasName_hasValue_noArrayItem() { WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); - pItem->setName(st.line.getName(), st.line.getNameQuotes()); - st.pCurItem->setElement(st.line.getName(), pItem); - st.pCurItem = pItem; - st.nIntent = st.nIntent + 2; + pItem->setComment(m_parseLine.getComment()); + pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + m_pParseCurrentItem->setElement(m_parseLine.getName(), pItem); + m_pParseCurrentItem = pItem; + int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem(WsjcppYamlParserStatus &st) { - if (st.pCurItem->isUndefined()) { - st.pCurItem->doArray(); +void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem() { + if (m_pParseCurrentItem->isUndefined()) { + m_pParseCurrentItem->doArray(); } WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); - st.pCurItem->appendElement(pItem); - st.pCurItem = pItem; - st.nIntent = st.nIntent + 2; + pItem->setComment(m_parseLine.getComment()); + pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + m_pParseCurrentItem->appendElement(pItem); + m_pParseCurrentItem = pItem; + int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_hasValue_noArrayItem(WsjcppYamlParserStatus &st) { - st.logUnknownLine("TODO process_sameIntent_emptyName_hasValue_noArrayItem"); +void WsjcppYaml::process_sameIntent_emptyName_hasValue_noArrayItem() { + WsjcppLog::warn(TAG, "TODO process_sameIntent_emptyName_hasValue_noArrayItem"); + this->logUnknownParseLine(); + } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlParserStatus &st) { - if (st.pCurItem->isUndefined()) { - st.pCurItem->doArray(); +void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem() { + if (m_pParseCurrentItem->isUndefined()) { + m_pParseCurrentItem->doArray(); } WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(st.line.getComment()); - pItem->setValue(st.line.getValue(), st.line.getValueQuotes()); - st.pCurItem->appendElement(pItem); - st.pCurItem = pItem; - st.nIntent = st.nIntent + 2; + pItem->setComment(m_parseLine.getComment()); + pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + m_pParseCurrentItem->appendElement(pItem); + m_pParseCurrentItem = pItem; + int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st) { - WsjcppYamlNode *pItem = new WsjcppYamlNode( - st.pCurItem, st.placeInFile, +void WsjcppYaml::process_sameIntent_emptyName_emptyValue_noArrayItem() { + WsjcppYamlNode *pNode = new WsjcppYamlNode( + m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - pItem->setComment(st.line.getComment()); - st.pCurItem->appendElement(pItem); + pNode->setComment(m_parseLine.getComment()); + m_pParseCurrentItem->appendElement(pNode); } // --------------------------------------------------------------------- +void WsjcppYaml::logUnknownParseLine() { + WsjcppLog::warn(TAG, "\n" + " error:\n" + " desc: \"unknown_line\"\n" + " line_number: " + std::to_string(m_pParseCurrentItem->getPlaceInFile().getNumberOfLine()) + "\n" + " line: \"" + m_parsePlaceInFile.getLine() + "\"\n" + " intent: " + std::to_string(m_nParseCurrentIntent) + "\n" + " filename: \"" + m_pParseCurrentItem->getPlaceInFile().getFilename() + "\"" + ); +} \ No newline at end of file diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 89a8d9c..ca700cd 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -121,6 +121,8 @@ class WsjcppYamlNode { std::string getItemTypeAsString(); std::string getForLogFormat(); + void setNodeDiffIntent(int nDiffIntent); + int getNodeDiffIntent(); private: std::string TAG; @@ -132,7 +134,7 @@ class WsjcppYamlNode { WsjcppYamlQuotes m_nValueQuotes; std::string m_sName; WsjcppYamlQuotes m_nNameQuotes; - + int m_nDiffIntent; std::string m_sComment; }; @@ -179,18 +181,6 @@ class WsjcppYamlParsebleLine { std::string removeStringSingleQuotes(const std::string &sValue); }; -// --------------------------------------------------------------------- - -class WsjcppYamlParserStatus { - public: - int nIntent; - WsjcppYamlNode *pCurItem; - WsjcppYamlParsebleLine line; - WsjcppYamlPlaceInFile placeInFile; - void logUnknownLine(const std::string &sPrefix); -}; - - // --------------------------------------------------------------------- class WsjcppYamlCursor { @@ -271,17 +261,27 @@ class WsjcppYaml { // TODO replace to WsjcppCore::split() std::vector splitToLines(const std::string &sBuffer); bool parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError); - void process_sameIntent_hasName_emptyValue_arrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_hasName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_hasName_hasValue_arrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_hasName_hasValue_noArrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_emptyName_hasValue_arrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_emptyName_hasValue_noArrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_emptyName_emptyValue_arrayItem(WsjcppYamlParserStatus &st); - void process_sameIntent_emptyName_emptyValue_noArrayItem(WsjcppYamlParserStatus &st); + void process_sameIntent_hasName_emptyValue_arrayItem(); + void process_sameIntent_hasName_emptyValue_noArrayItem(); + void process_sameIntent_hasName_hasValue_arrayItem(); + void process_sameIntent_hasName_hasValue_noArrayItem(); + void process_sameIntent_emptyName_hasValue_arrayItem(); + void process_sameIntent_emptyName_hasValue_noArrayItem(); + void process_sameIntent_emptyName_emptyValue_arrayItem(); + void process_sameIntent_emptyName_emptyValue_noArrayItem(); + + std::vector m_sLines; WsjcppYamlNode *m_pRoot; + + // prsing line status + void logUnknownParseLine(); + WsjcppYamlNode *m_pParseCurrentItem; + int m_nParseCurrentIntent; + WsjcppYamlPlaceInFile m_parsePlaceInFile; + WsjcppYamlParsebleLine m_parseLine; + }; #endif // WSJCPP_YAML_H diff --git a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp index c4d50d8..c810078 100644 --- a/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp +++ b/unit-tests.wsjcpp/src/unit_test_read_yaml.cpp @@ -48,19 +48,6 @@ void UnitTestReadYaml::executeTest() { WsjcppYamlNode *pServices = yaml.getRoot()->getElement("services"); - - - - /* - -services: - vote: - build: ./vote - command: python app.py - volumes: - - ./vote:/app - - */ // services.vote { compare("has services.vote", pServices->hasElement("vote"), true); From 784e071b47ee440fa070f04e540b89a55a9ca663 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sat, 26 Sep 2020 02:02:34 +0700 Subject: [PATCH 24/29] Started #14 bug with intent --- src/wsjcpp_yaml.cpp | 122 ++++++++++++++++++++++++-------------------- src/wsjcpp_yaml.h | 18 +++---- 2 files changed, 75 insertions(+), 65 deletions(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 02d9678..5ffd0d8 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -1280,7 +1280,12 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, bool isArrayItem = m_parseLine.isArrayItem(); int nLineIntent = m_parseLine.getIntent(); int nDiffIntent = nLineIntent - m_nParseCurrentIntent; - + std::cout << nLine << ": " << m_nParseCurrentIntent << ", " << nLineIntent << " ; line:[" << m_parsePlaceInFile.getLine() << "]" << std::endl; + + /*if (nLine > 6) { + return false; + }*/ + if (m_parseLine.isEmptyLine()) { if (m_pParseCurrentItem != nullptr) { if (m_pParseCurrentItem->isArray() || m_pParseCurrentItem->isMap() || m_pParseCurrentItem->isUndefined()) { @@ -1303,6 +1308,9 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, } while (nDiffIntent < 0) { + std::cout << nLine << ": nDiffIntent = " << nDiffIntent << std::endl; + std::cout << nLine << ": m_pParseCurrentItem = " << m_pParseCurrentItem->getNodeDiffIntent() << std::endl; + std::cout << nLine << ": m_pParseCurrentItem = " << m_pParseCurrentItem->getName() << std::endl; int nNodeDiffIntent = m_pParseCurrentItem->getNodeDiffIntent(); if (nNodeDiffIntent == 0) { sError = "Node diff intent cann't be 0 "; @@ -1317,31 +1325,27 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, } } - if (nDiffIntent == 0) { - if (m_parseLine.isEmptyName()) { - if ( ! isEmptyValue && isArrayItem) { - process_sameIntent_emptyName_hasValue_arrayItem(); - } else if (! isEmptyValue && ! isArrayItem) { - process_sameIntent_emptyName_hasValue_noArrayItem(); - } else if (isEmptyValue && isArrayItem) { - process_sameIntent_emptyName_emptyValue_arrayItem(); - } else if (isEmptyValue && ! isArrayItem) { - process_sameIntent_emptyName_emptyValue_noArrayItem(); - } else { - logUnknownParseLine(); - } - } else if ( ! m_parseLine.isEmptyName()) { - if ( ! isEmptyValue && isArrayItem) { - process_sameIntent_hasName_hasValue_arrayItem(); - } else if ( ! isEmptyValue && ! isArrayItem) { - process_sameIntent_hasName_hasValue_noArrayItem(); - } else if (isEmptyValue && isArrayItem) { - process_sameIntent_hasName_emptyValue_arrayItem(); - } else if (isEmptyValue && ! isArrayItem) { - process_sameIntent_hasName_emptyValue_noArrayItem(); - } else { - logUnknownParseLine(); - } + if (m_parseLine.isEmptyName()) { + if ( ! isEmptyValue && isArrayItem) { + process_emptyName_hasValue_arrayItem(); + } else if (! isEmptyValue && ! isArrayItem) { + process_emptyName_hasValue_noArrayItem(); + } else if (isEmptyValue && isArrayItem) { + process_emptyName_emptyValue_arrayItem(); + } else if (isEmptyValue && ! isArrayItem) { + process_emptyName_emptyValue_noArrayItem(); + } else { + logUnknownParseLine(); + } + } else if ( ! m_parseLine.isEmptyName()) { + if ( ! isEmptyValue && isArrayItem) { + process_hasName_hasValue_arrayItem(); + } else if ( ! isEmptyValue && ! isArrayItem) { + process_hasName_hasValue_noArrayItem(); + } else if (isEmptyValue && isArrayItem) { + process_hasName_emptyValue_arrayItem(); + } else if (isEmptyValue && ! isArrayItem) { + process_hasName_emptyValue_noArrayItem(); } else { logUnknownParseLine(); } @@ -1354,33 +1358,36 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_emptyValue_arrayItem() { - WsjcppLog::warn(TAG, "process_sameIntent_hasName_emptyValue_arrayItem"); +void WsjcppYaml::process_hasName_emptyValue_arrayItem() { + WsjcppLog::warn(TAG, "process_hasName_emptyValue_arrayItem"); this->logUnknownParseLine(); } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_emptyValue_noArrayItem() { - WsjcppYamlNode *pItem = new WsjcppYamlNode( +void WsjcppYaml::process_hasName_emptyValue_noArrayItem() { + WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_UNDEFINED ); if (m_parseLine.getValueQuotes() != WSJCPP_YAML_QUOTES_NONE) { - pItem->doValue(); - pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + pNode->doValue(); + pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); } - pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); - pItem->setComment(m_parseLine.getComment()); - m_pParseCurrentItem->setElement(m_parseLine.getName(), pItem); - m_pParseCurrentItem = pItem; int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + pNode->setComment(m_parseLine.getComment()); + pNode->setNodeDiffIntent(nDiffIntent); + // m_pParseCurrentItem->getParent() + std::cout << "process_hasName_emptyValue_noArrayItem " << m_parseLine.getName() << " " << nDiffIntent << std::endl; + m_pParseCurrentItem->setElement(m_parseLine.getName(), pNode); + m_pParseCurrentItem = pNode; m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem() { +void WsjcppYaml::process_hasName_hasValue_arrayItem() { if (m_pParseCurrentItem->isUndefined()) { m_pParseCurrentItem->doArray(); } @@ -1393,38 +1400,40 @@ void WsjcppYaml::process_sameIntent_hasName_hasValue_arrayItem() { int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; - WsjcppYamlNode *pItem = new WsjcppYamlNode( + WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(m_parseLine.getComment()); - pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); - pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); - pMapItem->setElement(m_parseLine.getName(), pItem); - m_pParseCurrentItem = pItem; + pNode->setComment(m_parseLine.getComment()); + pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + pMapItem->setElement(m_parseLine.getName(), pNode); + m_pParseCurrentItem = pNode; nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + pNode->setNodeDiffIntent(nDiffIntent); m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_hasName_hasValue_noArrayItem() { +void WsjcppYaml::process_hasName_hasValue_noArrayItem() { WsjcppYamlNode *pItem = new WsjcppYamlNode( m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); + std::cout << m_parseLine.getName() << std::endl; pItem->setComment(m_parseLine.getComment()); pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); m_pParseCurrentItem->setElement(m_parseLine.getName(), pItem); - m_pParseCurrentItem = pItem; + // m_pParseCurrentItem = pItem; int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem() { +void WsjcppYaml::process_emptyName_hasValue_arrayItem() { if (m_pParseCurrentItem->isUndefined()) { m_pParseCurrentItem->doArray(); } @@ -1442,38 +1451,41 @@ void WsjcppYaml::process_sameIntent_emptyName_hasValue_arrayItem() { // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_hasValue_noArrayItem() { - WsjcppLog::warn(TAG, "TODO process_sameIntent_emptyName_hasValue_noArrayItem"); +void WsjcppYaml::process_emptyName_hasValue_noArrayItem() { + WsjcppLog::warn(TAG, "TODO process_emptyName_hasValue_noArrayItem"); this->logUnknownParseLine(); } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_emptyValue_arrayItem() { +void WsjcppYaml::process_emptyName_emptyValue_arrayItem() { if (m_pParseCurrentItem->isUndefined()) { m_pParseCurrentItem->doArray(); } - WsjcppYamlNode *pItem = new WsjcppYamlNode( + WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(m_parseLine.getComment()); - pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); - m_pParseCurrentItem->appendElement(pItem); - m_pParseCurrentItem = pItem; + pNode->setComment(m_parseLine.getComment()); + pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + m_pParseCurrentItem->appendElement(pNode); + m_pParseCurrentItem = pNode; int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + pNode->setNodeDiffIntent(nDiffIntent); m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; } // --------------------------------------------------------------------- -void WsjcppYaml::process_sameIntent_emptyName_emptyValue_noArrayItem() { +void WsjcppYaml::process_emptyName_emptyValue_noArrayItem() { WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentItem, m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); pNode->setComment(m_parseLine.getComment()); + int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; + pNode->setNodeDiffIntent(nDiffIntent); m_pParseCurrentItem->appendElement(pNode); } diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index ca700cd..80cffb1 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -261,16 +261,14 @@ class WsjcppYaml { // TODO replace to WsjcppCore::split() std::vector splitToLines(const std::string &sBuffer); bool parse(const std::string &sFileName, const std::string &sBuffer, std::string &sError); - void process_sameIntent_hasName_emptyValue_arrayItem(); - void process_sameIntent_hasName_emptyValue_noArrayItem(); - void process_sameIntent_hasName_hasValue_arrayItem(); - void process_sameIntent_hasName_hasValue_noArrayItem(); - void process_sameIntent_emptyName_hasValue_arrayItem(); - void process_sameIntent_emptyName_hasValue_noArrayItem(); - void process_sameIntent_emptyName_emptyValue_arrayItem(); - void process_sameIntent_emptyName_emptyValue_noArrayItem(); - - + void process_hasName_emptyValue_arrayItem(); + void process_hasName_emptyValue_noArrayItem(); + void process_hasName_hasValue_arrayItem(); + void process_hasName_hasValue_noArrayItem(); + void process_emptyName_hasValue_arrayItem(); + void process_emptyName_hasValue_noArrayItem(); + void process_emptyName_emptyValue_arrayItem(); + void process_emptyName_emptyValue_noArrayItem(); std::vector m_sLines; WsjcppYamlNode *m_pRoot; From 623fdd11c2914815c788caca3b6b61297afd3f4c Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sat, 26 Sep 2020 13:43:53 +0700 Subject: [PATCH 25/29] Fixed keep user format intent (partial fix #14) --- README.md | 3 +- src/wsjcpp_yaml.cpp | 362 ++++++++++++++++++++++++++------------------ src/wsjcpp_yaml.h | 13 +- 3 files changed, 226 insertions(+), 152 deletions(-) diff --git a/README.md b/README.md index 96d0762..1a8031b 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ [![Build Status](https://api.travis-ci.com/wsjcpp/wsjcpp-yaml.svg?branch=master)](https://travis-ci.com/wsjcpp/wsjcpp-yaml) [![Github Stars](https://img.shields.io/github/stars/wsjcpp/wsjcpp-yaml.svg?label=github%20%E2%98%85)](https://github.com/wsjcpp/wsjcpp-yaml) [![Github Stars](https://img.shields.io/github/contributors/wsjcpp/wsjcpp-yaml.svg)](https://github.com/wsjcpp/wsjcpp-yaml) [![Github Forks](https://img.shields.io/github/forks/wsjcpp/wsjcpp-yaml.svg?label=github%20forks)](https://github.com/wsjcpp/wsjcpp-yaml/network/members) [![Total alerts](https://img.shields.io/lgtm/alerts/g/wsjcpp/wsjcpp-yaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/wsjcpp/wsjcpp-yaml/alerts/) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/wsjcpp/wsjcpp-yaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/wsjcpp/wsjcpp-yaml/context:cpp) -C++ Write/Reader yaml files - +C++ YAML parser/reader and writer of *.yaml/*.yml files with keeping user formatting ## Integrate to your c++ project diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 5ffd0d8..59456dc 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -77,7 +77,8 @@ WsjcppYamlNode::WsjcppYamlNode( m_nItemType = nItemType; m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; - m_nDiffIntent = 0; + m_nNodeDiffIntent = 0; + m_sNodeDiffIntent = ""; TAG = "WsjcppYamlNode"; } @@ -153,7 +154,7 @@ void WsjcppYamlNode::doEmpty() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_EMPTY; } else { - WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); + throw std::runtime_error(TAG + ": Element already defined as '" + this->getItemTypeAsString() + "'"); } } @@ -169,7 +170,7 @@ void WsjcppYamlNode::doArray() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_ARRAY; } else { - WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); + throw std::runtime_error(TAG + ": Element already defined as '" + this->getItemTypeAsString() + "'"); } } @@ -179,7 +180,7 @@ void WsjcppYamlNode::doMap() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_MAP; } else { - WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); + throw std::runtime_error(TAG + ": Element already defined as '" + this->getItemTypeAsString() + "'"); } } @@ -189,7 +190,7 @@ void WsjcppYamlNode::doValue() { if (m_nItemType == WSJCPP_YAML_NODE_UNDEFINED) { m_nItemType = WSJCPP_YAML_NODE_VALUE; } else { - WsjcppLog::throw_err(TAG, "Element already defined as '" + this->getItemTypeAsString() + "'"); + throw std::runtime_error(TAG + ": Element already defined as '" + this->getItemTypeAsString() + "'"); } } @@ -203,7 +204,7 @@ bool WsjcppYamlNode::isMap() { bool WsjcppYamlNode::hasElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { - WsjcppLog::throw_err(TAG, "hasElement('" + sName + "'): Element must be map"); + throw std::runtime_error(TAG + ": hasElement('" + sName + "'): Element must be map"); } for (int i = 0; i < m_vObjects.size(); i++) { if (m_vObjects[i]->getName() == sName) { @@ -217,7 +218,7 @@ bool WsjcppYamlNode::hasElement(const std::string &sName) { WsjcppYamlNode *WsjcppYamlNode::getElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { - WsjcppLog::throw_err(TAG, "getElement: Element must be map"); + throw std::runtime_error(TAG + ": getElement: Element must be map"); } for (int i = 0; i < m_vObjects.size(); i++) { @@ -226,7 +227,7 @@ WsjcppYamlNode *WsjcppYamlNode::getElement(const std::string &sName) { return m_vObjects[i]; } } - WsjcppLog::throw_err(TAG, "Element '" + sName + "' not found for " + this->getForLogFormat()); + throw_error(TAG + "Element '" + sName + "' not found for " + this->getForLogFormat()); return nullptr; } @@ -238,11 +239,13 @@ bool WsjcppYamlNode::setElement(const std::string &sName, WsjcppYamlNode *pItem) } if (m_nItemType != WSJCPP_YAML_NODE_MAP) { - WsjcppLog::throw_err(TAG, "setElement, Element must be 'map' for " + pItem->getPlaceInFile().getForLogFormat()); + throw std::runtime_error(TAG + ": setElement, Element must be 'map' for " + pItem->getPlaceInFile().getForLogFormat()); } if (this->hasElement(sName)) { // TODO remove previous element - WsjcppLog::throw_err(TAG, "setElement: Map already has element with this name: '" + sName + "'"); + throw std::runtime_error(TAG + ": setElement: Current map '" + this->getName() + "' " + "(" + m_placeInFile.getFilename() + ":" + std::to_string(m_placeInFile.getNumberOfLine()) + ") " + "already has element with this name: '" + sName + "'"); } m_vObjects.push_back(pItem); // TODO create clone return true; @@ -252,7 +255,7 @@ bool WsjcppYamlNode::setElement(const std::string &sName, WsjcppYamlNode *pItem) bool WsjcppYamlNode::removeElement(const std::string &sName) { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { - WsjcppLog::throw_err(TAG, "removeElement: Element must be map"); + throw std::runtime_error(TAG + ": removeElement: Element must be map"); } std::vector::iterator it; for (it = m_vObjects.begin(); it != m_vObjects.end(); ++it) { @@ -270,7 +273,7 @@ bool WsjcppYamlNode::removeElement(const std::string &sName) { std::vector WsjcppYamlNode::getKeys() { if (m_nItemType != WSJCPP_YAML_NODE_MAP) { - WsjcppLog::throw_err(TAG, "getKeys: Element must be map"); + throw std::runtime_error(TAG + ": getKeys: Element must be map"); } std::vector vKeys; for (int i = 0; i < m_vObjects.size(); i++) { @@ -296,7 +299,7 @@ bool WsjcppYamlNode::setElementValue( } if (m_nItemType != WSJCPP_YAML_NODE_MAP) { - WsjcppLog::throw_err(TAG, "setElement, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); + throw std::runtime_error(TAG + ": setElement, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } if (this->hasElement(sName)) { @@ -316,7 +319,7 @@ bool WsjcppYamlNode::setElementValue( bool WsjcppYamlNode::createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_MAP ) { - WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); + throw std::runtime_error(TAG + ": createElementMap, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } if (this->hasElement(sName)) { return false; // already exists @@ -332,7 +335,7 @@ bool WsjcppYamlNode::createElementMap(const std::string &sName, WsjcppYamlQuotes WsjcppYamlNode *WsjcppYamlNode::createElementMap() { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY ) { - WsjcppLog::throw_err(TAG, "createElementMap, Element must be 'array' for " + this->getPlaceInFile().getForLogFormat()); + throw std::runtime_error(TAG + ": createElementMap, Element must be 'array' for " + this->getPlaceInFile().getForLogFormat()); } WsjcppYamlPlaceInFile pl; WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_MAP); @@ -344,7 +347,7 @@ WsjcppYamlNode *WsjcppYamlNode::createElementMap() { bool WsjcppYamlNode::createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_MAP ) { - WsjcppLog::throw_err(TAG, "createElementArray, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); + throw std::runtime_error(TAG + ": createElementArray, Element must be 'map' for " + this->getPlaceInFile().getForLogFormat()); } if (this->hasElement(sName)) { return false; @@ -366,7 +369,7 @@ bool WsjcppYamlNode::isArray() { int WsjcppYamlNode::getLength() { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { - WsjcppLog::throw_err(TAG, "getLength, Element must be array for " + this->getForLogFormat()); + throw std::runtime_error(TAG + ": getLength, Element must be array for " + this->getForLogFormat()); } int nCount = 0; for (int i = 0; i < m_vObjects.size(); i++) { @@ -381,7 +384,7 @@ int WsjcppYamlNode::getLength() { WsjcppYamlNode *WsjcppYamlNode::getElement(int i) { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { - WsjcppLog::throw_err(TAG, "getElement, Element must be array"); + throw std::runtime_error(TAG + ": getElement, Element must be array"); } int nCounter = -1; WsjcppYamlNode *pItem = nullptr; @@ -395,7 +398,7 @@ WsjcppYamlNode *WsjcppYamlNode::getElement(int i) { } } if (pItem == nullptr) { - WsjcppLog::throw_err(TAG, "getElement(" + std::to_string(i) + "), Out of range in array for '" + this->getPlaceInFile().getLine() + "'"); + throw std::runtime_error(TAG + ": getElement(" + std::to_string(i) + "), Out of range in array for '" + this->getPlaceInFile().getLine() + "'"); } return pItem; } @@ -408,7 +411,7 @@ bool WsjcppYamlNode::appendElement(WsjcppYamlNode *pItem) { return true; } if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { - WsjcppLog::throw_err(TAG, "appendElement, Element must be array for " + this->getForLogFormat()); + throw std::runtime_error(TAG + ": appendElement, Element must be array for " + this->getForLogFormat()); } m_vObjects.push_back(pItem); // TODO clone object return true; @@ -418,7 +421,7 @@ bool WsjcppYamlNode::appendElement(WsjcppYamlNode *pItem) { bool WsjcppYamlNode::appendElementValue(const std::string &sValue, WsjcppYamlQuotes nValueQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { - WsjcppLog::throw_err(TAG, "appendElementValue, Element must be array for " + this->getForLogFormat()); + throw std::runtime_error(TAG + ": appendElementValue, Element must be array for " + this->getForLogFormat()); } WsjcppYamlPlaceInFile pl; WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_VALUE); @@ -430,7 +433,7 @@ bool WsjcppYamlNode::appendElementValue(const std::string &sValue, WsjcppYamlQuo bool WsjcppYamlNode::removeElement(int i) { if (m_nItemType != WSJCPP_YAML_NODE_ARRAY) { - WsjcppLog::throw_err(TAG, "appendElement, Element must be array for " + this->getForLogFormat()); + throw std::runtime_error(TAG + ": appendElement, Element must be array for " + this->getForLogFormat()); } int nCounter = -1; WsjcppYamlNode *pItem = nullptr; @@ -444,7 +447,7 @@ bool WsjcppYamlNode::removeElement(int i) { } } if (pItem == nullptr) { - WsjcppLog::throw_err(TAG, "getElement(" + std::to_string(i) + "), Out of range in array for '" + this->getPlaceInFile().getLine() + "'"); + throw std::runtime_error(TAG + ": getElement(" + std::to_string(i) + "), Out of range in array for '" + this->getPlaceInFile().getLine() + "'"); } std::vector::iterator it; for (it = m_vObjects.begin(); it != m_vObjects.end(); ++it) { @@ -467,7 +470,7 @@ bool WsjcppYamlNode::isValue() { std::string WsjcppYamlNode::getValue() { if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { - WsjcppLog::throw_err(TAG, "getValue, Element must be value for " + this->getForLogFormat()); + throw std::runtime_error(TAG + ": getValue, Element must be value for " + this->getForLogFormat()); } return m_sValue; } @@ -476,7 +479,7 @@ std::string WsjcppYamlNode::getValue() { void WsjcppYamlNode::setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes) { if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { - WsjcppLog::throw_err(TAG, "setValue, Element must be value for " + this->getForLogFormat()); + throw std::runtime_error(TAG + ": setValue, Element must be value for " + this->getForLogFormat()); } m_nValueQuotes = nQuotes; m_sValue = sValue; @@ -490,6 +493,21 @@ WsjcppYamlQuotes WsjcppYamlNode::getValueQuotes() { // --------------------------------------------------------------------- +std::string WsjcppYamlNode::getSerializedName() { + std::string sRet = ""; + // TODO escape quotes + if (this->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { + sRet += "\"" + this->getName() + "\""; + } else if (this->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { + sRet += "\'" + this->getName() + "\'"; + } else { + sRet += this->getName(); + } + return sRet; +} + +// --------------------------------------------------------------------- + std::string WsjcppYamlNode::toString(std::string sIntent) { std::string sRet = ""; if (this->isValue()) { @@ -511,75 +529,73 @@ std::string WsjcppYamlNode::toString(std::string sIntent) { if (m_vObjects[i]->isEmpty()) { sRet += "\n"; } else { - WsjcppLog::warn(TAG, "Undefined element conatins something else"); + WsjcppLog::warn(TAG, "Undefined element contains something else"); } // sRet += std::to_string(m_vObjects.size()); } return sRet; } else if (this->isEmpty()) { if (m_sComment.length() > 0) { - sRet += sIntent + "# " + m_sComment; + sRet += sIntent + m_sNodeDiffIntent + "# " + m_sComment; } - // sRet += "\n"; return sRet; } else if (this->isArray()) { for (int i = 0; i < m_vObjects.size(); i++) { - WsjcppYamlNode *pItem = m_vObjects[i]; - if (pItem->isEmpty()) { - sRet += pItem->toString(sIntent) + "\n"; - // sRet += "\n"; - } else if (pItem->isMap()) { - std::string s = pItem->toString(sIntent + " "); + WsjcppYamlNode *pNode = m_vObjects[i]; + if (pNode->isEmpty()) { + std::string sVal = pNode->toString(); + sVal = WsjcppCore::trim(sVal); + if (sVal.length() > 0) { // empty string have content + sRet += sIntent + pNode->getStringNodeDiffIntent(); + } + sRet += sVal; + } else if (pNode->isMap()) { + sRet += sIntent + pNode->getStringNodeDiffIntent(); + std::string s = pNode->toString(sIntent + m_sNodeDiffIntent); WsjcppCore::trim(s); - sRet += sIntent + "- " + s; - sRet += "\n"; + sRet += "- " + s; } else { - sRet += sIntent + "- " + pItem->toString(); - sRet += "\n"; + sRet += sIntent + pNode->getStringNodeDiffIntent(); + sRet += "- " + pNode->toString(); } + sRet += "\n"; } } else if (this->isMap()) { for (int i = 0; i < m_vObjects.size(); i++) { - WsjcppYamlNode *pItem = m_vObjects[i]; - if (pItem->isEmpty() ) { - sRet += pItem->toString(sIntent); + WsjcppYamlNode *pNode = m_vObjects[i]; + if (pNode->isEmpty() ) { + // sRet += " * " + pNode->toString(sIntent); + sRet += pNode->toString(sIntent); sRet += "\n"; - } else if (pItem->isArray() || pItem->isMap()) { - if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { - sRet += sIntent + "\"" + pItem->getName() + "\":"; - } else if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { - sRet += sIntent + "\'" + pItem->getName() + "\':"; - } else { - sRet += sIntent + pItem->getName() + ":"; - } - if (pItem->getComment().length() > 0) { - sRet += " # " + pItem->getComment(); + } else if (pNode->isUndefined()) { + sRet += sIntent + pNode->getStringNodeDiffIntent() + + pNode->getSerializedName() + ":\n" + pNode->toString(); + } else if (pNode->isArray() || pNode->isMap()) { + sRet += sIntent + pNode->getStringNodeDiffIntent() + + pNode->getSerializedName() + ":"; + if (pNode->getComment().length() > 0) { + sRet += " # " + pNode->getComment(); } sRet += "\n"; - sRet += pItem->toString(sIntent + " "); + sRet += pNode->toString(sIntent + pNode->getStringNodeDiffIntent()); } else { - std::string sVal = pItem->toString(); + std::string sVal = pNode->toString(); std::string sVal_ = sVal; sVal_ = WsjcppCore::trim(sVal_); if (sVal_.length() > 0) { sVal = " " + sVal; } - if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { - sRet += sIntent + "\"" + pItem->getName() + "\":" + sVal; - } else if (pItem->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { - sRet += sIntent + "\'" + pItem->getName() + "\':" + sVal; - } else { - sRet += sIntent + pItem->getName() + ":" + sVal; - } + sRet += sIntent + pNode->getStringNodeDiffIntent() + + pNode->getSerializedName() + ":" + sVal; sRet += "\n"; } } } else { sRet = ""; // undefined element must be empty } - if (sIntent == "") { + /*if (sIntent == "") { WsjcppCore::trim(sRet); - } + }*/ return sRet; } @@ -606,14 +622,30 @@ std::string WsjcppYamlNode::getForLogFormat() { // --------------------------------------------------------------------- -void WsjcppYamlNode::setNodeDiffIntent(int nDiffIntent) { - m_nDiffIntent = nDiffIntent; +void WsjcppYamlNode::setNodeDiffIntent(int nNodeDiffIntent) { + m_nNodeDiffIntent = nNodeDiffIntent; + m_sNodeDiffIntent = ""; + for (int i = 0; i < m_nNodeDiffIntent; i++) { + m_sNodeDiffIntent += " "; + } } // --------------------------------------------------------------------- int WsjcppYamlNode::getNodeDiffIntent() { - return m_nDiffIntent; + return m_nNodeDiffIntent; +} + +// --------------------------------------------------------------------- + +std::string WsjcppYamlNode::getStringNodeDiffIntent() { + return m_sNodeDiffIntent; +} + +// --------------------------------------------------------------------- + +void WsjcppYamlNode::throw_error(const std::string &sError) { + throw std::runtime_error(sError.c_str()); } // --------------------------------------------------------------------- @@ -1092,7 +1124,7 @@ int WsjcppYamlCursor::valInt() { sValue = WsjcppCore::toLower(sValue); int nValue = std::atoi(sValue.c_str()); if (std::to_string(nValue) != sValue) { - WsjcppLog::throw_err(TAG, "valInt, Element must be int but have a string" + m_pCurrentNode->getForLogFormat()); + throw std::runtime_error(TAG + ": valInt, Element must be int but have a string" + m_pCurrentNode->getForLogFormat()); } return nValue; } @@ -1119,8 +1151,8 @@ bool WsjcppYamlCursor::valBool() { } else if (sValue == "no" || sValue == "false") { return false; } else { - WsjcppLog::throw_err(TAG, "valBool, Element must be bool expected with ignore case like" - "['yes','no','true','false'] for " + m_pCurrentNode->getForLogFormat()); + throw std::runtime_error(TAG + ": valBool, Element must be bool expected with ignore case like" + " 'yes', 'no', 'true', 'false' for " + m_pCurrentNode->getForLogFormat()); } } return false; @@ -1202,7 +1234,7 @@ bool WsjcppYaml::loadFromString(const std::string &sBufferName, const std::strin // --------------------------------------------------------------------- -bool WsjcppYaml::saveToString(std::string &sBuffer) { // TODO move to WsjcppCore +bool WsjcppYaml::saveToString(std::string &sBuffer) { sBuffer = m_pRoot->toString(); return true; } @@ -1261,14 +1293,15 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, } std::vector vLines = this->splitToLines(sBuffer); - m_pParseCurrentItem = m_pRoot; + m_pParseCurrentParentNode = m_pRoot; m_parsePlaceInFile.setFilename(sFileName); + m_vStackDiffNodeIntents.clear(); + m_vStackDiffNodeIntents.push_back(0); m_nParseCurrentIntent = 0; m_pRoot->setPlaceInFile(m_parsePlaceInFile); for (int nLine = 0; nLine < vLines.size(); nLine++) { m_parsePlaceInFile.setLine(vLines[nLine]); - // WsjcppLog::info(TAG, "Line(" + std::to_string(nLine) + ") '" + st.sLine + "'"); m_parsePlaceInFile.setNumberOfLine(nLine); m_parseLine = WsjcppYamlParsebleLine(nLine); if (!m_parseLine.parseLine(m_parsePlaceInFile.getLine(), sError)) { @@ -1280,49 +1313,89 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, bool isArrayItem = m_parseLine.isArrayItem(); int nLineIntent = m_parseLine.getIntent(); int nDiffIntent = nLineIntent - m_nParseCurrentIntent; - std::cout << nLine << ": " << m_nParseCurrentIntent << ", " << nLineIntent << " ; line:[" << m_parsePlaceInFile.getLine() << "]" << std::endl; - /*if (nLine > 6) { - return false; - }*/ + if (nDiffIntent > 0) { + m_vStackDiffNodeIntents.push_back(nDiffIntent); + m_nParseCurrentIntent = m_parseLine.getIntent(); + // std::cout << "add new DiffNodeIntents " << nDiffIntent << std::endl; + } + + // std::cout << nLine << ": " << m_nParseCurrentIntent << ", " << nLineIntent << " ; line:[" << m_parsePlaceInFile.getLine() << "]" << std::endl; if (m_parseLine.isEmptyLine()) { - if (m_pParseCurrentItem != nullptr) { - if (m_pParseCurrentItem->isArray() || m_pParseCurrentItem->isMap() || m_pParseCurrentItem->isUndefined()) { + if (m_pParseCurrentParentNode != nullptr) { + if (m_pParseCurrentParentNode->isArray() || m_pParseCurrentParentNode->isMap() || m_pParseCurrentParentNode->isUndefined()) { WsjcppYamlNode *pNode = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - m_pParseCurrentItem->appendElement(pNode); - } else if (m_pParseCurrentItem->getParent() != nullptr && (m_pParseCurrentItem->getParent()->isArray() || m_pParseCurrentItem->getParent()->isMap())) { + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + m_pParseCurrentParentNode->appendElement(pNode); + } else if (m_pParseCurrentParentNode->getParent() != nullptr && (m_pParseCurrentParentNode->getParent()->isArray() || m_pParseCurrentParentNode->getParent()->isMap())) { WsjcppYamlNode *pNode = new WsjcppYamlNode( - m_pParseCurrentItem->getParent(), m_parsePlaceInFile, + m_pParseCurrentParentNode->getParent(), m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - m_pParseCurrentItem->getParent()->appendElement(pNode); + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + m_pParseCurrentParentNode->getParent()->appendElement(pNode); } else { - WsjcppLog::throw_err(TAG, "Empty element can be added only to map or to array"); + throw std::runtime_error(TAG + ": Empty element can be added only to map or to array"); } } continue; } - while (nDiffIntent < 0) { - std::cout << nLine << ": nDiffIntent = " << nDiffIntent << std::endl; - std::cout << nLine << ": m_pParseCurrentItem = " << m_pParseCurrentItem->getNodeDiffIntent() << std::endl; - std::cout << nLine << ": m_pParseCurrentItem = " << m_pParseCurrentItem->getName() << std::endl; - int nNodeDiffIntent = m_pParseCurrentItem->getNodeDiffIntent(); + // fast switch to root + if (nDiffIntent < 0 && m_parseLine.getIntent() == 0) { + nDiffIntent = 0; + m_nParseCurrentIntent = m_parseLine.getIntent(); + m_pParseCurrentParentNode = m_pRoot; + m_vStackDiffNodeIntents.clear(); + m_vStackDiffNodeIntents.push_back(0); + } + + // switch to parent + while (nDiffIntent < 0 && m_nParseCurrentIntent != m_parseLine.getIntent()) { + if (m_pParseCurrentParentNode == nullptr) { + sError = "Current node is nullptr, line: " + std::to_string(nLine); + return false; + } + if (m_pParseCurrentParentNode->getParent() == nullptr) { + sError = "Parent of current node is nullptr, line: " + std::to_string(nLine); + return false; + } + // m_nParseCurrentIntent = m_nParseCurrentIntent - m_pParseCurrentParentNode->getParent()->getNodeDiffIntent(); + m_nParseCurrentIntent = m_nParseCurrentIntent - m_vStackDiffNodeIntents.back(); + m_vStackDiffNodeIntents.pop_back(); + m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); + // std::cout << "up to [" << m_pParseCurrentParentNode->getName() << "]" << std::endl; + if (m_nParseCurrentIntent < m_parseLine.getIntent()) { + sError = "Wrong intent, expected " + "'" + std::to_string(m_parseLine.getIntent()) + "'," + " but got '" + + " in line: (" + sFileName + ":" + std::to_string(nLine) + ")"; + return false; + } + + if (m_nParseCurrentIntent == m_parseLine.getIntent()) { + // if (m_pParseCurrentParentNode->getParent() != nullptr) { + // m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); + // } + break; + } + + /*std::cout << nLine << ": nDiffIntent = " << nDiffIntent << std::endl; + std::cout << nLine << ": m_pParseCurrentParentNode = " << m_pParseCurrentParentNode->getNodeDiffIntent() << std::endl; + std::cout << nLine << ": m_pParseCurrentParentNode = " << m_pParseCurrentParentNode->getName() << std::endl; + int nNodeDiffIntent = m_pParseCurrentParentNode->getNodeDiffIntent(); if (nNodeDiffIntent == 0) { sError = "Node diff intent cann't be 0 "; return false; } - m_pParseCurrentItem = m_pParseCurrentItem->getParent(); + m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); m_nParseCurrentIntent = m_nParseCurrentIntent - nNodeDiffIntent; nDiffIntent = nLineIntent - m_nParseCurrentIntent; - if (m_pParseCurrentItem == nullptr) { - sError = "Current item is nullptr"; - return false; - } + */ } if (m_parseLine.isEmptyName()) { @@ -1366,8 +1439,9 @@ void WsjcppYaml::process_hasName_emptyValue_arrayItem() { // --------------------------------------------------------------------- void WsjcppYaml::process_hasName_emptyValue_noArrayItem() { + // std::cout << "process_hasName_emptyValue_noArrayItem " << std::endl; WsjcppYamlNode *pNode = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_UNDEFINED ); if (m_parseLine.getValueQuotes() != WSJCPP_YAML_QUOTES_NONE) { @@ -1377,76 +1451,73 @@ void WsjcppYaml::process_hasName_emptyValue_noArrayItem() { int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); pNode->setComment(m_parseLine.getComment()); - pNode->setNodeDiffIntent(nDiffIntent); - // m_pParseCurrentItem->getParent() - std::cout << "process_hasName_emptyValue_noArrayItem " << m_parseLine.getName() << " " << nDiffIntent << std::endl; - m_pParseCurrentItem->setElement(m_parseLine.getName(), pNode); - m_pParseCurrentItem = pNode; - m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + // std::cout << "current node [" << m_vStackDiffNodeIntents.back() << "]" << std::endl; + + m_pParseCurrentParentNode->setElement(m_parseLine.getName(), pNode); + m_pParseCurrentParentNode = pNode; } // --------------------------------------------------------------------- void WsjcppYaml::process_hasName_hasValue_arrayItem() { - if (m_pParseCurrentItem->isUndefined()) { - m_pParseCurrentItem->doArray(); + // std::cout << "process_hasName_hasValue_arrayItem " << std::endl; + if (m_pParseCurrentParentNode->isUndefined()) { + m_pParseCurrentParentNode->doArray(); } WsjcppYamlNode *pMapItem = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_MAP ); - m_pParseCurrentItem->appendElement(pMapItem); - m_pParseCurrentItem = pMapItem; - int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; - m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; + m_pParseCurrentParentNode->appendElement(pMapItem); + m_pParseCurrentParentNode = pMapItem; + pMapItem->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); WsjcppYamlNode *pNode = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); pNode->setComment(m_parseLine.getComment()); pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); pMapItem->setElement(m_parseLine.getName(), pNode); - m_pParseCurrentItem = pNode; - nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; - pNode->setNodeDiffIntent(nDiffIntent); - m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; + // pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); } // --------------------------------------------------------------------- void WsjcppYaml::process_hasName_hasValue_noArrayItem() { - WsjcppYamlNode *pItem = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + // std::cout << "process_hasName_hasValue_noArrayItem " << std::endl; + WsjcppYamlNode *pNode = new WsjcppYamlNode( + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - std::cout << m_parseLine.getName() << std::endl; - pItem->setComment(m_parseLine.getComment()); - pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); - pItem->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); - m_pParseCurrentItem->setElement(m_parseLine.getName(), pItem); - // m_pParseCurrentItem = pItem; - int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; - m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; + // std::cout << "m_parseLine.getName(): " << m_parseLine.getName() << std::endl; + pNode->setComment(m_parseLine.getComment()); + pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + m_pParseCurrentParentNode->setElement(m_parseLine.getName(), pNode); + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + + // m_pParseCurrentParentNode = pItem; } // --------------------------------------------------------------------- void WsjcppYaml::process_emptyName_hasValue_arrayItem() { - if (m_pParseCurrentItem->isUndefined()) { - m_pParseCurrentItem->doArray(); + // std::cout << "process_emptyName_hasValue_arrayItem " << std::endl; + if (m_pParseCurrentParentNode->isUndefined()) { + m_pParseCurrentParentNode->doArray(); } - WsjcppYamlNode *pItem = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + WsjcppYamlNode *pNode = new WsjcppYamlNode( + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); - pItem->setComment(m_parseLine.getComment()); - pItem->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); - m_pParseCurrentItem->appendElement(pItem); - m_pParseCurrentItem = pItem; - int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; - m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; + pNode->setComment(m_parseLine.getComment()); + pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + m_pParseCurrentParentNode->appendElement(pNode); + // m_pParseCurrentParentNode = pNode; + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); } // --------------------------------------------------------------------- @@ -1460,33 +1531,32 @@ void WsjcppYaml::process_emptyName_hasValue_noArrayItem() { // --------------------------------------------------------------------- void WsjcppYaml::process_emptyName_emptyValue_arrayItem() { - if (m_pParseCurrentItem->isUndefined()) { - m_pParseCurrentItem->doArray(); + // std::cout << "process_emptyName_emptyValue_arrayItem " << std::endl; + if (m_pParseCurrentParentNode->isUndefined()) { + m_pParseCurrentParentNode->doArray(); } WsjcppYamlNode *pNode = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); pNode->setComment(m_parseLine.getComment()); pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); - m_pParseCurrentItem->appendElement(pNode); - m_pParseCurrentItem = pNode; - int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; - pNode->setNodeDiffIntent(nDiffIntent); - m_nParseCurrentIntent = m_nParseCurrentIntent + nDiffIntent; + m_pParseCurrentParentNode->appendElement(pNode); + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + m_pParseCurrentParentNode = pNode; } // --------------------------------------------------------------------- void WsjcppYaml::process_emptyName_emptyValue_noArrayItem() { + // std::cout << "process_emptyName_emptyValue_noArrayItem " << std::endl; WsjcppYamlNode *pNode = new WsjcppYamlNode( - m_pParseCurrentItem, m_parsePlaceInFile, + m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); pNode->setComment(m_parseLine.getComment()); - int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; - pNode->setNodeDiffIntent(nDiffIntent); - m_pParseCurrentItem->appendElement(pNode); + pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + m_pParseCurrentParentNode->appendElement(pNode); } // --------------------------------------------------------------------- @@ -1495,9 +1565,9 @@ void WsjcppYaml::logUnknownParseLine() { WsjcppLog::warn(TAG, "\n" " error:\n" " desc: \"unknown_line\"\n" - " line_number: " + std::to_string(m_pParseCurrentItem->getPlaceInFile().getNumberOfLine()) + "\n" + " line_number: " + std::to_string(m_pParseCurrentParentNode->getPlaceInFile().getNumberOfLine()) + "\n" " line: \"" + m_parsePlaceInFile.getLine() + "\"\n" " intent: " + std::to_string(m_nParseCurrentIntent) + "\n" - " filename: \"" + m_pParseCurrentItem->getPlaceInFile().getFilename() + "\"" + " filename: \"" + m_pParseCurrentParentNode->getPlaceInFile().getFilename() + "\"" ); } \ No newline at end of file diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 80cffb1..38e98b4 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -116,15 +116,19 @@ class WsjcppYamlNode { void setValue(const std::string &sValue, WsjcppYamlQuotes nQuotes = WSJCPP_YAML_QUOTES_NONE); WsjcppYamlQuotes getValueQuotes(); - + + std::string getSerializedName(); std::string toString(std::string sIntent = ""); std::string getItemTypeAsString(); std::string getForLogFormat(); void setNodeDiffIntent(int nDiffIntent); int getNodeDiffIntent(); + std::string getStringNodeDiffIntent(); private: + void throw_error(const std::string &sError); + std::string TAG; WsjcppYamlNode *m_pParent; WsjcppYamlPlaceInFile m_placeInFile; @@ -134,8 +138,9 @@ class WsjcppYamlNode { WsjcppYamlQuotes m_nValueQuotes; std::string m_sName; WsjcppYamlQuotes m_nNameQuotes; - int m_nDiffIntent; std::string m_sComment; + int m_nNodeDiffIntent; + std::string m_sNodeDiffIntent; }; // --------------------------------------------------------------------- @@ -275,11 +280,11 @@ class WsjcppYaml { // prsing line status void logUnknownParseLine(); - WsjcppYamlNode *m_pParseCurrentItem; + WsjcppYamlNode *m_pParseCurrentParentNode; int m_nParseCurrentIntent; WsjcppYamlPlaceInFile m_parsePlaceInFile; WsjcppYamlParsebleLine m_parseLine; - + std::vector m_vStackDiffNodeIntents; }; #endif // WSJCPP_YAML_H From 9b1dbfc5a0d0525c9b278a88744ebb63a9531388 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sat, 26 Sep 2020 23:05:58 +0700 Subject: [PATCH 26/29] Fixed #14 bug with intents --- src/wsjcpp_yaml.cpp | 119 ++++++++++-------- src/wsjcpp_yaml.h | 18 +-- .../data-tests/parser-simple-array.yml | 12 ++ .../data-tests/remove-element-in-array.yml | 9 ++ unit-tests.wsjcpp/parser_yaml.py | 11 +- .../src/unit_test_remove_element_in_array.cpp | 20 +-- ...unit_test_yaml_parser_hierarchical_map.cpp | 2 +- .../unit_test_yaml_parser_simple_array.cpp | 20 +-- .../src/unit_test_yaml_parser_simple_map.cpp | 2 +- 9 files changed, 116 insertions(+), 97 deletions(-) create mode 100644 unit-tests.wsjcpp/data-tests/parser-simple-array.yml create mode 100644 unit-tests.wsjcpp/data-tests/remove-element-in-array.yml diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 59456dc..7dfc792 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -546,16 +546,16 @@ std::string WsjcppYamlNode::toString(std::string sIntent) { std::string sVal = pNode->toString(); sVal = WsjcppCore::trim(sVal); if (sVal.length() > 0) { // empty string have content - sRet += sIntent + pNode->getStringNodeDiffIntent(); + sRet += sIntent + pNode->getStringNodeLastIntent(); } sRet += sVal; } else if (pNode->isMap()) { - sRet += sIntent + pNode->getStringNodeDiffIntent(); - std::string s = pNode->toString(sIntent + m_sNodeDiffIntent); + sRet += sIntent + pNode->getStringNodeLastIntent(); + std::string s = pNode->toString(sIntent + pNode->getStringNodeLastIntent()); WsjcppCore::trim(s); sRet += "- " + s; } else { - sRet += sIntent + pNode->getStringNodeDiffIntent(); + sRet += sIntent + pNode->getStringNodeLastIntent(); sRet += "- " + pNode->toString(); } sRet += "\n"; @@ -568,16 +568,16 @@ std::string WsjcppYamlNode::toString(std::string sIntent) { sRet += pNode->toString(sIntent); sRet += "\n"; } else if (pNode->isUndefined()) { - sRet += sIntent + pNode->getStringNodeDiffIntent() + sRet += sIntent + pNode->getStringNodeLastIntent() + pNode->getSerializedName() + ":\n" + pNode->toString(); } else if (pNode->isArray() || pNode->isMap()) { - sRet += sIntent + pNode->getStringNodeDiffIntent() + sRet += sIntent + pNode->getStringNodeLastIntent() + pNode->getSerializedName() + ":"; if (pNode->getComment().length() > 0) { sRet += " # " + pNode->getComment(); } sRet += "\n"; - sRet += pNode->toString(sIntent + pNode->getStringNodeDiffIntent()); + sRet += pNode->toString(sIntent + pNode->getStringNodeLastIntent()); } else { std::string sVal = pNode->toString(); std::string sVal_ = sVal; @@ -585,7 +585,7 @@ std::string WsjcppYamlNode::toString(std::string sIntent) { if (sVal_.length() > 0) { sVal = " " + sVal; } - sRet += sIntent + pNode->getStringNodeDiffIntent() + sRet += sIntent + pNode->getStringNodeLastIntent() + pNode->getSerializedName() + ":" + sVal; sRet += "\n"; } @@ -593,9 +593,13 @@ std::string WsjcppYamlNode::toString(std::string sIntent) { } else { sRet = ""; // undefined element must be empty } - /*if (sIntent == "") { - WsjcppCore::trim(sRet); - }*/ + + if (m_pParent == nullptr) { + int nLen = sRet.length(); + if (nLen > 0 && sRet[nLen - 1] == '\n') { + sRet = sRet.substr(0, nLen - 1); + } + } return sRet; } @@ -622,24 +626,34 @@ std::string WsjcppYamlNode::getForLogFormat() { // --------------------------------------------------------------------- -void WsjcppYamlNode::setNodeDiffIntent(int nNodeDiffIntent) { - m_nNodeDiffIntent = nNodeDiffIntent; - m_sNodeDiffIntent = ""; - for (int i = 0; i < m_nNodeDiffIntent; i++) { - m_sNodeDiffIntent += " "; - } +int WsjcppYamlNode::getNodeLastIntent() { + return m_nNodeDiffIntent; } // --------------------------------------------------------------------- -int WsjcppYamlNode::getNodeDiffIntent() { - return m_nNodeDiffIntent; +std::string WsjcppYamlNode::getStringNodeLastIntent() { + return m_sNodeDiffIntent; } // --------------------------------------------------------------------- -std::string WsjcppYamlNode::getStringNodeDiffIntent() { - return m_sNodeDiffIntent; +void WsjcppYamlNode::setNodeIntents(const std::vector & vNodeIntents) { + m_nNodeDiffIntent = vNodeIntents.back(); + m_sNodeDiffIntent = ""; + for (int i = 0; i < m_nNodeDiffIntent; i++) { + m_sNodeDiffIntent += " "; + } + m_nNodeIntent = 0; + for (int i = 0; i < vNodeIntents.size(); i++) { + m_nNodeIntent += vNodeIntents[i]; + } +} + +// --------------------------------------------------------------------- + +int WsjcppYamlNode::getNodeIntent() { + return m_nNodeIntent; } // --------------------------------------------------------------------- @@ -1317,11 +1331,8 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, if (nDiffIntent > 0) { m_vStackDiffNodeIntents.push_back(nDiffIntent); m_nParseCurrentIntent = m_parseLine.getIntent(); - // std::cout << "add new DiffNodeIntents " << nDiffIntent << std::endl; } - // std::cout << nLine << ": " << m_nParseCurrentIntent << ", " << nLineIntent << " ; line:[" << m_parsePlaceInFile.getLine() << "]" << std::endl; - if (m_parseLine.isEmptyLine()) { if (m_pParseCurrentParentNode != nullptr) { if (m_pParseCurrentParentNode->isArray() || m_pParseCurrentParentNode->isMap() || m_pParseCurrentParentNode->isUndefined()) { @@ -1329,14 +1340,14 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); m_pParseCurrentParentNode->appendElement(pNode); } else if (m_pParseCurrentParentNode->getParent() != nullptr && (m_pParseCurrentParentNode->getParent()->isArray() || m_pParseCurrentParentNode->getParent()->isMap())) { WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentParentNode->getParent(), m_parsePlaceInFile, WSJCPP_YAML_NODE_EMPTY ); - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); m_pParseCurrentParentNode->getParent()->appendElement(pNode); } else { throw std::runtime_error(TAG + ": Empty element can be added only to map or to array"); @@ -1364,11 +1375,9 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, sError = "Parent of current node is nullptr, line: " + std::to_string(nLine); return false; } - // m_nParseCurrentIntent = m_nParseCurrentIntent - m_pParseCurrentParentNode->getParent()->getNodeDiffIntent(); m_nParseCurrentIntent = m_nParseCurrentIntent - m_vStackDiffNodeIntents.back(); m_vStackDiffNodeIntents.pop_back(); m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); - // std::cout << "up to [" << m_pParseCurrentParentNode->getName() << "]" << std::endl; if (m_nParseCurrentIntent < m_parseLine.getIntent()) { sError = "Wrong intent, expected " "'" + std::to_string(m_parseLine.getIntent()) + "'," @@ -1378,24 +1387,8 @@ bool WsjcppYaml::parse(const std::string &sFileName, const std::string &sBuffer, } if (m_nParseCurrentIntent == m_parseLine.getIntent()) { - // if (m_pParseCurrentParentNode->getParent() != nullptr) { - // m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); - // } break; } - - /*std::cout << nLine << ": nDiffIntent = " << nDiffIntent << std::endl; - std::cout << nLine << ": m_pParseCurrentParentNode = " << m_pParseCurrentParentNode->getNodeDiffIntent() << std::endl; - std::cout << nLine << ": m_pParseCurrentParentNode = " << m_pParseCurrentParentNode->getName() << std::endl; - int nNodeDiffIntent = m_pParseCurrentParentNode->getNodeDiffIntent(); - if (nNodeDiffIntent == 0) { - sError = "Node diff intent cann't be 0 "; - return false; - } - m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); - m_nParseCurrentIntent = m_nParseCurrentIntent - nNodeDiffIntent; - nDiffIntent = nLineIntent - m_nParseCurrentIntent; - */ } if (m_parseLine.isEmptyName()) { @@ -1439,6 +1432,11 @@ void WsjcppYaml::process_hasName_emptyValue_arrayItem() { // --------------------------------------------------------------------- void WsjcppYaml::process_hasName_emptyValue_noArrayItem() { + if (m_parseLine.getIntent() == m_pParseCurrentParentNode->getNodeIntent()) { + if (m_pParseCurrentParentNode->getParent() != nullptr) { + m_pParseCurrentParentNode = m_pParseCurrentParentNode->getParent(); + } + } // std::cout << "process_hasName_emptyValue_noArrayItem " << std::endl; WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentParentNode, m_parsePlaceInFile, @@ -1451,9 +1449,19 @@ void WsjcppYaml::process_hasName_emptyValue_noArrayItem() { int nDiffIntent = m_parseLine.getIntent() - m_nParseCurrentIntent; pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); pNode->setComment(m_parseLine.getComment()); - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); // std::cout << "current node [" << m_vStackDiffNodeIntents.back() << "]" << std::endl; - + +/* if (nDiffIntent == 0 && m_pParseCurrentParentNode->isUndefined()) { + std::cout << "shit nDiffIntent = " << nDiffIntent << std::endl; + std::cout << "shit m_pParseCurrentParentNode->getName() = " << m_pParseCurrentParentNode->getName() << std::endl; + if (m_pParseCurrentParentNode->getParent() != nullptr) { + std::cout << "shit " + << " {" << m_pParseCurrentParentNode->getPlaceInFile().getLine() << "} " + << " {" << m_parsePlaceInFile.getLine() << "} " << std::endl; + } + } +*/ m_pParseCurrentParentNode->setElement(m_parseLine.getName(), pNode); m_pParseCurrentParentNode = pNode; } @@ -1471,7 +1479,7 @@ void WsjcppYaml::process_hasName_hasValue_arrayItem() { ); m_pParseCurrentParentNode->appendElement(pMapItem); m_pParseCurrentParentNode = pMapItem; - pMapItem->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + pMapItem->setNodeIntents(m_vStackDiffNodeIntents); WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentParentNode, m_parsePlaceInFile, @@ -1481,23 +1489,26 @@ void WsjcppYaml::process_hasName_hasValue_arrayItem() { pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); pMapItem->setElement(m_parseLine.getName(), pNode); - // pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + + // next intents must be for map + m_vStackDiffNodeIntents.push_back(2); + m_nParseCurrentIntent += 2; } // --------------------------------------------------------------------- void WsjcppYaml::process_hasName_hasValue_noArrayItem() { - // std::cout << "process_hasName_hasValue_noArrayItem " << std::endl; WsjcppYamlNode *pNode = new WsjcppYamlNode( m_pParseCurrentParentNode, m_parsePlaceInFile, WSJCPP_YAML_NODE_VALUE ); // std::cout << "m_parseLine.getName(): " << m_parseLine.getName() << std::endl; + // std::cout << "m_pParseCurrentParentNode: " << m_pParseCurrentParentNode->getPlaceInFile().getLine() << std::endl; pNode->setComment(m_parseLine.getComment()); pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); pNode->setName(m_parseLine.getName(), m_parseLine.getNameQuotes()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); m_pParseCurrentParentNode->setElement(m_parseLine.getName(), pNode); - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); // m_pParseCurrentParentNode = pItem; } @@ -1517,7 +1528,7 @@ void WsjcppYaml::process_emptyName_hasValue_arrayItem() { pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); m_pParseCurrentParentNode->appendElement(pNode); // m_pParseCurrentParentNode = pNode; - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); } // --------------------------------------------------------------------- @@ -1531,7 +1542,6 @@ void WsjcppYaml::process_emptyName_hasValue_noArrayItem() { // --------------------------------------------------------------------- void WsjcppYaml::process_emptyName_emptyValue_arrayItem() { - // std::cout << "process_emptyName_emptyValue_arrayItem " << std::endl; if (m_pParseCurrentParentNode->isUndefined()) { m_pParseCurrentParentNode->doArray(); } @@ -1541,9 +1551,8 @@ void WsjcppYaml::process_emptyName_emptyValue_arrayItem() { ); pNode->setComment(m_parseLine.getComment()); pNode->setValue(m_parseLine.getValue(), m_parseLine.getValueQuotes()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); m_pParseCurrentParentNode->appendElement(pNode); - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); - m_pParseCurrentParentNode = pNode; } // --------------------------------------------------------------------- @@ -1555,7 +1564,7 @@ void WsjcppYaml::process_emptyName_emptyValue_noArrayItem() { WSJCPP_YAML_NODE_EMPTY ); pNode->setComment(m_parseLine.getComment()); - pNode->setNodeDiffIntent(m_vStackDiffNodeIntents.back()); + pNode->setNodeIntents(m_vStackDiffNodeIntents); m_pParseCurrentParentNode->appendElement(pNode); } diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index 38e98b4..e3c2e09 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -12,11 +12,11 @@ // --------------------------------------------------------------------- enum WsjcppYamlNodeType { - WSJCPP_YAML_NODE_UNDEFINED, - WSJCPP_YAML_NODE_EMPTY, - WSJCPP_YAML_NODE_ARRAY, - WSJCPP_YAML_NODE_MAP, - WSJCPP_YAML_NODE_VALUE + WSJCPP_YAML_NODE_UNDEFINED = 0, + WSJCPP_YAML_NODE_EMPTY = 1, + WSJCPP_YAML_NODE_ARRAY = 2, + WSJCPP_YAML_NODE_MAP = 3, + WSJCPP_YAML_NODE_VALUE = 4 }; // --------------------------------------------------------------------- @@ -122,9 +122,10 @@ class WsjcppYamlNode { std::string getItemTypeAsString(); std::string getForLogFormat(); - void setNodeDiffIntent(int nDiffIntent); - int getNodeDiffIntent(); - std::string getStringNodeDiffIntent(); + int getNodeLastIntent(); + std::string getStringNodeLastIntent(); + void setNodeIntents(const std::vector & vNodeIntents); + int getNodeIntent(); private: void throw_error(const std::string &sError); @@ -141,6 +142,7 @@ class WsjcppYamlNode { std::string m_sComment; int m_nNodeDiffIntent; std::string m_sNodeDiffIntent; + int m_nNodeIntent; }; // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/data-tests/parser-simple-array.yml b/unit-tests.wsjcpp/data-tests/parser-simple-array.yml new file mode 100644 index 0000000..15fed08 --- /dev/null +++ b/unit-tests.wsjcpp/data-tests/parser-simple-array.yml @@ -0,0 +1,12 @@ +# simple array test +param1: none value1 # it's value for something # olala +array-test2 : # some comment 2 + - value21 # comment v21 + - value22 # comment v22 + - true # comment true + # some + - falsesome + - free@free + - # empty + - 1 +param2: val2 # value 2 \ No newline at end of file diff --git a/unit-tests.wsjcpp/data-tests/remove-element-in-array.yml b/unit-tests.wsjcpp/data-tests/remove-element-in-array.yml new file mode 100644 index 0000000..465166a --- /dev/null +++ b/unit-tests.wsjcpp/data-tests/remove-element-in-array.yml @@ -0,0 +1,9 @@ +# Some comment 1 + +arr1: + + - name: i1 + var2: 2 + - name: i2 + - name: i3 + - very different array items type \ No newline at end of file diff --git a/unit-tests.wsjcpp/parser_yaml.py b/unit-tests.wsjcpp/parser_yaml.py index f561ff0..9476c83 100755 --- a/unit-tests.wsjcpp/parser_yaml.py +++ b/unit-tests.wsjcpp/parser_yaml.py @@ -1,3 +1,6 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + import yaml @@ -5,4 +8,10 @@ parsed_yaml_file = yaml.load(a_yaml_file, Loader=yaml.FullLoader) -print(parsed_yaml_file) \ No newline at end of file +print(parsed_yaml_file) + +a_yaml_file2 = open("./data-tests/parser-simple-array/file.yml") + +parsed_yaml_file2 = yaml.load(a_yaml_file2, Loader=yaml.FullLoader) + +print(parsed_yaml_file2) diff --git a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp index 7f609e7..28f95de 100644 --- a/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_remove_element_in_array.cpp @@ -30,37 +30,29 @@ bool UnitTestRemoveElementInArray::doBeforeTest() { // --------------------------------------------------------------------- void UnitTestRemoveElementInArray::executeTest() { - std::string sTestYaml = - "# Some comment 1\n" - " \n" - "arr1: \n" - "\n" - " - name: i1\n" - " var2: 2\n" - " - name: i2\n" - " - name: i3\n" - "\n" // empty line - ; + std::string sFilepath = "./data-tests/remove-element-in-array.yml"; WsjcppYaml yaml; std::string sError; - if (!compare("Error parsing", yaml.loadFromString("rm_elem_in_arr", sTestYaml, sError), true)) { + if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { WsjcppLog::err(TAG, sError); return; } WsjcppYamlNode *pArr1 = yaml.getRoot()->getElement("arr1"); - compare("arr1 len", pArr1->getLength(), 3); + compare("arr1 len", pArr1->getLength(), 4); compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i2"); compare("arr1 name2 ", pArr1->getElement(2)->getElement("name")->getValue(), "i3"); + compare("arr1 name3 ", pArr1->getElement(3)->getValue(), "very different array items type"); pArr1->removeElement(1); - compare("arr1 len", pArr1->getLength(), 2); + compare("arr1 len", pArr1->getLength(), 3); compare("arr1 name0 ", pArr1->getElement(0)->getElement("name")->getValue(), "i1"); compare("arr1 name1 ", pArr1->getElement(1)->getElement("name")->getValue(), "i3"); + compare("arr1 name2 ", pArr1->getElement(2)->getValue(), "very different array items type"); } // --------------------------------------------------------------------- diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp index 37b6612..7ea6895 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_hierarchical_map.cpp @@ -109,7 +109,7 @@ void UnitTestYamlParserHierarchicalMap::executeTest() { " map123:\n" " param1231: v1231\n" " param1232: v1232\n" - "param2: v2 # some comment 2" + "param2: v2 # some comment 2\n" ); } } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp index 285a12c..a9f5b38 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_array.cpp @@ -31,25 +31,11 @@ bool UnitTestYamlParserSimpleArray::doBeforeTest() { // --------------------------------------------------------------------- void UnitTestYamlParserSimpleArray::executeTest() { - - std::string sTestYaml = - "# simple array test\n" - "param1: none value1 # it's value for something # olala \n" - "array-test2 : # some comment 2 \n" - " - value21 # comment v21 \n" - " - value22 # comment v22 \n" - " - true # comment true \n" - " # some\n" - " - falsesome \n" - " - free@free \n" - " - # empty \n" - " - 1\n" - "param2: val2 # value 2 \n" - ; - + + std::string sFilepath = "./data-tests/parser-simple-array.yml"; WsjcppYaml yaml; std::string sError; - if (!compare("Error parsing", yaml.loadFromString("parse_array", sTestYaml, sError), true)) { + if (!compare("Error parsing", yaml.loadFromFile(sFilepath, sError), true)) { WsjcppLog::err(TAG, sError); return; } diff --git a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp index 32873e1..2730591 100644 --- a/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp +++ b/unit-tests.wsjcpp/src/unit_test_yaml_parser_simple_map.cpp @@ -57,7 +57,7 @@ void UnitTestYamlParserSimpleMap::executeTest() { compare("yaml_save", sSaved, "# Some comment 1\n" "param1: value1\n" - "param2: value2 # some comment 2" + "param2: value2 # some comment 2\n" ); } } From 3e5e20630402bd3d4cc2fd608e455e2fcde3d6b9 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sun, 27 Sep 2020 00:16:00 +0700 Subject: [PATCH 27/29] Added unit-test for create yaml --- README.md | 24 +++--- src/wsjcpp_yaml.cpp | 14 +++- src/wsjcpp_yaml.h | 4 +- unit-tests.wsjcpp/CMakeLists.txt | 1 + .../src/unit_test_append_elements.cpp | 73 +++++++++++++++++++ wsjcpp.yml | 2 + 6 files changed, 101 insertions(+), 17 deletions(-) create mode 100644 unit-tests.wsjcpp/src/unit_test_append_elements.cpp diff --git a/README.md b/README.md index 1a8031b..ef98e0f 100644 --- a/README.md +++ b/README.md @@ -53,19 +53,19 @@ int main(int argc, char* argv[]) { return -1; } - std::cout << "yaml is " << yaml["yaml1"].getValue() << std::endl; - std::cout << "some-map is " << yaml["some-map"].getValue() << std::endl; - std::cout << "some-map2 is " << yaml["some-map2"].getValue() << std::endl; - std::cout << "some-array has " << std::to_string(yaml["some-array"].getLength()) << std::endl; - std::cout << "some-array element 0 is " << yaml["some-array"][0].getValue() << std::endl; - std::cout << "some-array element 1 is " << yaml["some-array"][1].getValue() << std::endl; - std::cout << "some-am has " << std::to_string(yaml["some-am"].getLength()) << std::endl; + std::cout << "yaml is " << yaml["yaml1"].valStr() << std::endl; + std::cout << "some-map is " << yaml["some-map"].valStr() << std::endl; + std::cout << "some-map2 is " << yaml["some-map2"].valStr() << std::endl; + std::cout << "some-array has " << std::to_string(yaml["some-array"].valStr()) << std::endl; + std::cout << "some-array element 0 is " << yaml["some-array"][0].valStr() << std::endl; + std::cout << "some-array element 1 is " << yaml["some-array"][1].valStr() << std::endl; + std::cout << "some-am has " << std::to_string(yaml["some-am"].size()) << std::endl; std::cout << "some-am is array: " << (yaml["some-am"].isArray() ? "yes" : "no") << std::endl; - std::cout << "some-am has comment " << yaml["some-am"].getComment() << std::endl; - std::cout << "some-am element 0 : p1 is " << yaml["some-am"][0]["p1"].getValue() << std::endl; - std::cout << "some-am element 0 : p2 is " << yaml["some-am"][0]["p2"].getValue() << std::endl; - std::cout << "some-am element 1 : p1 is " << yaml["some-am"][1]["p1"].getValue() << std::endl; - std::cout << "some-am element 1 : p2 is " << yaml["some-am"][1]["p2"].getValue() << std::endl; + std::cout << "some-am has comment " << yaml["some-am"].comment() << std::endl; + std::cout << "some-am element 0 : p1 is " << yaml["some-am"][0]["p1"].valStr() << std::endl; + std::cout << "some-am element 0 : p2 is " << yaml["some-am"][0]["p2"].valStr() << std::endl; + std::cout << "some-am element 1 : p1 is " << yaml["some-am"][1]["p1"].valStr() << std::endl; + std::cout << "some-am element 1 : p2 is " << yaml["some-am"][1]["p2"].valStr() << std::endl; return 0; } diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index 7dfc792..e199fa6 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -77,8 +77,15 @@ WsjcppYamlNode::WsjcppYamlNode( m_nItemType = nItemType; m_nValueQuotes = WSJCPP_YAML_QUOTES_NONE; m_nNameQuotes = WSJCPP_YAML_QUOTES_NONE; - m_nNodeDiffIntent = 0; - m_sNodeDiffIntent = ""; + // TODO get child intent + if (m_pParent != nullptr && m_pParent->getParent() != nullptr) { + m_nNodeDiffIntent = 2; + m_sNodeDiffIntent = " "; + } else { + m_nNodeDiffIntent = 0; + m_sNodeDiffIntent = ""; + } + TAG = "WsjcppYamlNode"; } @@ -327,6 +334,7 @@ bool WsjcppYamlNode::createElementMap(const std::string &sName, WsjcppYamlQuotes WsjcppYamlPlaceInFile pl; WsjcppYamlNode *pNewItem = new WsjcppYamlNode(this, pl, WSJCPP_YAML_NODE_MAP); pNewItem->setName(sName, nNameQuotes); + // pNewItem->setNodeIntents({2}); this->setElement(sName, pNewItem); return true; } @@ -1203,7 +1211,7 @@ WsjcppYamlCursor WsjcppYamlCursor::operator[](const std::string &sName) const { // WsjcppYaml WsjcppYaml::WsjcppYaml() { - m_pRoot = nullptr; + m_pRoot = new WsjcppYamlNode(nullptr, WsjcppYamlPlaceInFile(), WSJCPP_YAML_NODE_MAP); TAG = "WsjcppYaml"; } diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index e3c2e09..215f394 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -99,9 +99,9 @@ class WsjcppYamlNode { WsjcppYamlQuotes nValueQuotes = WSJCPP_YAML_QUOTES_NONE ); - bool createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes); + bool createElementMap(const std::string &sName, WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE); WsjcppYamlNode *createElementMap(); - bool createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes); + bool createElementArray(const std::string &sName, WsjcppYamlQuotes nNameQuotes = WSJCPP_YAML_QUOTES_NONE); bool isArray(); int getLength(); diff --git a/unit-tests.wsjcpp/CMakeLists.txt b/unit-tests.wsjcpp/CMakeLists.txt index 149b9d2..a2008dd 100644 --- a/unit-tests.wsjcpp/CMakeLists.txt +++ b/unit-tests.wsjcpp/CMakeLists.txt @@ -50,6 +50,7 @@ list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_read_write_file. list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_cursor.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_tag_names.cpp") list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_cleanup.cpp") +list (APPEND WSJCPP_SOURCES "../unit-tests.wsjcpp/src/unit_test_append_elements.cpp") include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.user-custom.txt) diff --git a/unit-tests.wsjcpp/src/unit_test_append_elements.cpp b/unit-tests.wsjcpp/src/unit_test_append_elements.cpp new file mode 100644 index 0000000..93443b6 --- /dev/null +++ b/unit-tests.wsjcpp/src/unit_test_append_elements.cpp @@ -0,0 +1,73 @@ + +#include +#include +#include + +// --------------------------------------------------------------------- +// UnitTestAppendElements + +class UnitTestAppendElements : public WsjcppUnitTestBase { + public: + UnitTestAppendElements(); + virtual bool doBeforeTest() override; + virtual void executeTest() override; + virtual bool doAfterTest() override; +}; + +REGISTRY_WSJCPP_UNIT_TEST(UnitTestAppendElements) + +UnitTestAppendElements::UnitTestAppendElements() + : WsjcppUnitTestBase("UnitTestAppendElements") { +} + +// --------------------------------------------------------------------- + +bool UnitTestAppendElements::doBeforeTest() { + // do something before test + return true; +} + +// --------------------------------------------------------------------- + +void UnitTestAppendElements::executeTest() { + + WsjcppYaml yml; + yml.getRoot()->setElementValue("p1", "val1"); + yml.getRoot()->createElementMap("some"); + WsjcppYamlNode *pSome = yml.getRoot()->getElement("some"); + pSome->setElementValue("p2", "val2"); + pSome->createElementMap("sub-some"); + WsjcppYamlNode *pSubSome = pSome->getElement("sub-some"); + pSubSome->setElementValue("p3", "val3"); + pSome->createElementArray("arr-some"); + WsjcppYamlNode *pArrSome = pSome->getElement("arr-some"); + pArrSome->appendElementValue("1234"); + WsjcppYamlPlaceInFile placeInFile; + WsjcppYamlNode *pItemMap = new WsjcppYamlNode(pArrSome, placeInFile, WSJCPP_YAML_NODE_MAP); + pArrSome->appendElement(pItemMap); + pItemMap->setElementValue("p4", "val4"); + pItemMap->setElementValue("p5", "val5"); + yml.getRoot()->setElementValue("p6", "val6"); + + compare("created yaml 1", yml.getRoot()->toString(), + "p1: val1\n" + "some:\n" + " p2: val2\n" + " sub-some:\n" + " p3: val3\n" + " arr-some:\n" + " - 1234\n" + " - p4: val4\n" + " p5: val5\n" + "p6: val6" + ); +} + +// --------------------------------------------------------------------- + +bool UnitTestAppendElements::doAfterTest() { + // do somethig after test + return true; +} + + diff --git a/wsjcpp.yml b/wsjcpp.yml index a8decc0..68fbc4e 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -67,3 +67,5 @@ unit-tests: description: "" - name: "Cleanup" description: "" + - name: "AppendElements" + description: "" From 6e16e98451f148c63a131fbd91b2bc0ff890ed6d Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sun, 27 Sep 2020 00:22:40 +0700 Subject: [PATCH 28/29] Fixed deepcode-ci warnings --- src/wsjcpp_yaml.cpp | 2 +- unit-tests.wsjcpp/src/process_mem_usage.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index e199fa6..2b00c59 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -1144,7 +1144,7 @@ int WsjcppYamlCursor::valInt() { if (m_pCurrentNode != nullptr) { std::string sValue = m_pCurrentNode->getValue(); sValue = WsjcppCore::toLower(sValue); - int nValue = std::atoi(sValue.c_str()); + int nValue = std::strtol(sValue.c_str(), nullptr, 10); if (std::to_string(nValue) != sValue) { throw std::runtime_error(TAG + ": valInt, Element must be int but have a string" + m_pCurrentNode->getForLogFormat()); } diff --git a/unit-tests.wsjcpp/src/process_mem_usage.h b/unit-tests.wsjcpp/src/process_mem_usage.h index 84d3e1f..c0aa94e 100644 --- a/unit-tests.wsjcpp/src/process_mem_usage.h +++ b/unit-tests.wsjcpp/src/process_mem_usage.h @@ -25,6 +25,9 @@ void process_mem_usage(double& vm_usage, double& resident_set) // 'file' stat seems to give the most reliable results // ifstream stat_stream("/proc/self/stat",ios_base::in); + if (!stat_stream.is_open()) { + return; + } // dummy vars for leading entries in stat that we don't care about // From 1a90d5d01b99104eeb3611e5439ca36447fcf777 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Sun, 27 Sep 2020 00:25:21 +0700 Subject: [PATCH 29/29] Added deepcode badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ef98e0f..1496141 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # wsjcpp-yaml -[![Build Status](https://api.travis-ci.com/wsjcpp/wsjcpp-yaml.svg?branch=master)](https://travis-ci.com/wsjcpp/wsjcpp-yaml) [![Github Stars](https://img.shields.io/github/stars/wsjcpp/wsjcpp-yaml.svg?label=github%20%E2%98%85)](https://github.com/wsjcpp/wsjcpp-yaml) [![Github Stars](https://img.shields.io/github/contributors/wsjcpp/wsjcpp-yaml.svg)](https://github.com/wsjcpp/wsjcpp-yaml) [![Github Forks](https://img.shields.io/github/forks/wsjcpp/wsjcpp-yaml.svg?label=github%20forks)](https://github.com/wsjcpp/wsjcpp-yaml/network/members) [![Total alerts](https://img.shields.io/lgtm/alerts/g/wsjcpp/wsjcpp-yaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/wsjcpp/wsjcpp-yaml/alerts/) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/wsjcpp/wsjcpp-yaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/wsjcpp/wsjcpp-yaml/context:cpp) +[![Build Status](https://api.travis-ci.com/wsjcpp/wsjcpp-yaml.svg?branch=master)](https://travis-ci.com/wsjcpp/wsjcpp-yaml) [![Github Stars](https://img.shields.io/github/stars/wsjcpp/wsjcpp-yaml.svg?label=github%20%E2%98%85)](https://github.com/wsjcpp/wsjcpp-yaml) [![Github Stars](https://img.shields.io/github/contributors/wsjcpp/wsjcpp-yaml.svg)](https://github.com/wsjcpp/wsjcpp-yaml) [![Github Forks](https://img.shields.io/github/forks/wsjcpp/wsjcpp-yaml.svg?label=github%20forks)](https://github.com/wsjcpp/wsjcpp-yaml/network/members) [![Total alerts](https://img.shields.io/lgtm/alerts/g/wsjcpp/wsjcpp-yaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/wsjcpp/wsjcpp-yaml/alerts/) [![Language grade: C/C++](https://img.shields.io/lgtm/grade/cpp/g/wsjcpp/wsjcpp-yaml.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/wsjcpp/wsjcpp-yaml/context:cpp) [![deepcode](https://www.deepcode.ai/api/gh/badge?key=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJwbGF0Zm9ybTEiOiJnaCIsIm93bmVyMSI6IndzamNwcCIsInJlcG8xIjoid3NqY3BwLXlhbWwiLCJpbmNsdWRlTGludCI6ZmFsc2UsImF1dGhvcklkIjoxNTY0MSwiaWF0IjoxNjAxMTQxMDc2fQ.Ueb89NfeP0aM8Bn9xpHiqQ8u5q_VF65O6PeO8aLPQ_E)](https://www.deepcode.ai/app/gh/wsjcpp/wsjcpp-yaml/_/dashboard?utm_content=gh%2Fwsjcpp%2Fwsjcpp-yaml) C++ YAML parser/reader and writer of *.yaml/*.yml files with keeping user formatting