From d6d42de8e641970bbd86fa2f23e934f824bd2c9f Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Thu, 18 Dec 2025 20:59:49 +0700 Subject: [PATCH 1/3] Up version to v0.1.10 --- wsjcpp.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsjcpp.yml b/wsjcpp.yml index edfcec5..c52f8bc 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -2,7 +2,7 @@ wsjcpp_version: v0.0.1 cmake_minimum_required: 3.0 cmake_cxx_standard: 17 name: wsjcpp-yaml -version: v0.1.9 +version: v0.1.10 description: Read/Write yaml files issues: https://github.com/wsjcpp/wsjcpp-yaml/issues From 539679ab8cc022acecf89c652484b02af6a92412 Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Thu, 18 Dec 2025 21:23:43 +0700 Subject: [PATCH 2/3] Fixed #38, #24 --- CHANGELOG.md | 5 +++ src/tests/test_auto_quotes.cpp | 66 ++++++++++++++++++++++++++++++++++ src/wsjcpp_yaml.cpp | 26 ++++++++++++-- src/wsjcpp_yaml.h | 1 + 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 src/tests/test_auto_quotes.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index b6bf5ad..8a79387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to wsjcpp-yaml project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [v0.1.10] - 2025-12-?? (2025 Dec ??) + +- Fixed #38: TODO escaping names +- Fixed #24: Auto detect quotes on setValue setName + ## [v0.1.9] - 2025-12-18 (2025 Dec 18) - Migrated unit-tests.wsjcpp to ctest diff --git a/src/tests/test_auto_quotes.cpp b/src/tests/test_auto_quotes.cpp new file mode 100644 index 0000000..71821fc --- /dev/null +++ b/src/tests/test_auto_quotes.cpp @@ -0,0 +1,66 @@ +/* +MIT License + +Copyright (c) 2019-2025 wsjcpp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Official Source Code: https://github.com/wsjcpp/wsjcpp-yaml +*/ + +#include +#include + +int main() { + // https://github.com/wsjcpp/wsjcpp-yaml/issues/24 + + std::string sInput = + "# commet1:\n" + "val1: 1\n" + ; + + WsjcppYaml yaml; + std::string sError; + if (!yaml.loadFromString("input.yml", sInput, sError)) { + std::cerr << sError << std::endl; + return -1; + } + + yaml["val1"].val("some\nsome"); + yaml.getRoot()->setElementValue("v\ng", "opa\ndone"); + + std::string sOutput = ""; + if (!yaml.saveToString(sOutput, sError)) { + std::cerr << sError << std::endl; + return -1; + } + + std::string sExpected = + "# commet1:\n" + "val1: \"some\\nsome\"\n" + "\"v\\ng\": \"opa\\ndone\"\n" + ; + + if (sOutput != sExpected) { + std::cerr << "sOutput != sExpected" << std::endl; + std::cerr << "Got: \n----\n" << sOutput << "\n------\nExpected\n-----\n" << sExpected << "\n------\n" << std::endl; + return -1; + } + return 0; +} \ No newline at end of file diff --git a/src/wsjcpp_yaml.cpp b/src/wsjcpp_yaml.cpp index a28439b..de8dc47 100644 --- a/src/wsjcpp_yaml.cpp +++ b/src/wsjcpp_yaml.cpp @@ -218,6 +218,10 @@ std::string WsjcppYamlNode::getComment() { void WsjcppYamlNode::setName(const std::string &sName, WsjcppYamlQuotes nNameQuotes) { m_sName = sName; + if (m_sName.find('\n') != std::string::npos) { + // automaticly set quotes double for escaping + nNameQuotes = WSJCPP_YAML_QUOTES_DOUBLE; + } m_nNameQuotes = nNameQuotes; } @@ -524,6 +528,10 @@ void WsjcppYamlNode::setValue(const std::string &sValue, WsjcppYamlQuotes nQuote if (m_nItemType != WSJCPP_YAML_NODE_VALUE) { throw std::runtime_error(TAG + ": setValue, Element must be value for " + this->getForLogFormat()); } + if (sValue.find('\n') != std::string::npos) { + // automaticly set quotes double + nQuotes = WSJCPP_YAML_QUOTES_DOUBLE; + } m_nValueQuotes = nQuotes; m_sValue = sValue; } @@ -534,9 +542,8 @@ WsjcppYamlQuotes WsjcppYamlNode::getValueQuotes() { std::string WsjcppYamlNode::getSerializedName() { std::string sRet = ""; - // TODO escape quotes if (this->getNameQuotes() == WSJCPP_YAML_QUOTES_DOUBLE) { - sRet += "\"" + this->getName() + "\""; + sRet += "\"" + escapingString(this->getName()) + "\""; } else if (this->getNameQuotes() == WSJCPP_YAML_QUOTES_SINGLE) { sRet += "\'" + this->getName() + "\'"; } else { @@ -549,7 +556,7 @@ std::string WsjcppYamlNode::toString(std::string sIndent) { std::string sRet = ""; if (this->isValue()) { if (m_nValueQuotes == WSJCPP_YAML_QUOTES_DOUBLE) { - sRet = "\"" + m_sValue + "\""; + sRet = "\"" + escapingString(m_sValue) + "\""; } else if (m_nValueQuotes == WSJCPP_YAML_QUOTES_SINGLE) { sRet = "\'" + m_sValue + "\'"; } else { @@ -722,6 +729,19 @@ void WsjcppYamlNode::removeLastCharNewLine(std::string &sLine) { } } +std::string WsjcppYamlNode::escapingString(const std::string &sVal) { + size_t nLen = sVal.length(); + std::string res; + for (int i = 0; i < nLen; i++) { + if (sVal[i] == '\n') { + res += "\\n"; + } else { + res += sVal[i]; + } + } + return res; +} + bool WsjcppYamlNode::hasContent(const std::string &sVal) { std::string sVal_ = sVal; sVal_ = WsjcppYaml::trim(sVal_); diff --git a/src/wsjcpp_yaml.h b/src/wsjcpp_yaml.h index cdcca75..3372180 100644 --- a/src/wsjcpp_yaml.h +++ b/src/wsjcpp_yaml.h @@ -169,6 +169,7 @@ class WsjcppYamlNode { private: void throw_error(const std::string &sError); void removeLastCharNewLine(std::string &sLine); + std::string escapingString(const std::string &sVal); bool hasContent(const std::string &sVal); bool hasObjects(); std::string TAG; From e2fdcd9300b144f8da5cb90b4e0d058584153c5d Mon Sep 17 00:00:00 2001 From: Evgenii Sopov Date: Thu, 18 Dec 2025 21:32:22 +0700 Subject: [PATCH 3/3] Downgrade standart to c++ 11 --- CHANGELOG.md | 1 + CMakeLists.txt | 2 +- README.md | 2 +- src/tests/test_double_value.cpp | 7 ++++--- src/tests/test_float_value.cpp | 3 ++- wsjcpp.yml | 4 ++-- 6 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a79387..307dcd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [v0.1.10] - 2025-12-?? (2025 Dec ??) +- Downgrade min c++ standart to C++11 - Fixed #38: TODO escaping names - Fixed #24: Auto detect quotes on setValue setName diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b8e5dc..28f6540 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ project(wsjcpp-yaml) # include(${CMAKE_CURRENT_SOURCE_DIR}/src.wsjcpp/CMakeLists.txt) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 11) set(EXECUTABLE_OUTPUT_PATH ${wsjcpp-yaml_SOURCE_DIR}) # Sources diff --git a/README.md b/README.md index a25fe07..9fea620 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 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) +[![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) [![wsjcpp-yaml C++](https://img.shields.io/badge/C++-11-green.svg)](https://github.com/wsjcpp/wsjcpp-yaml) [![wsjcpp-yaml C++](https://img.shields.io/badge/C++-17-green.svg)](https://github.com/wsjcpp/wsjcpp-yaml) C++ YAML parser/reader and writer of *.yaml/*.yml files with keeping user formatting diff --git a/src/tests/test_double_value.cpp b/src/tests/test_double_value.cpp index bad453c..b624a8c 100644 --- a/src/tests/test_double_value.cpp +++ b/src/tests/test_double_value.cpp @@ -28,6 +28,7 @@ Official Source Code: https://github.com/wsjcpp/wsjcpp-yaml #include #include #include +#include #include #include "helpers.h" @@ -63,7 +64,7 @@ int main() { // std::numeric_limits::epsilon() => 2.22045e-16 // std::numeric_limits::epsilon() => 1.19209e-07 // abs(val_double - expected_double) => 3.31879e-08 - if (abs(val_double - expected_double) > std::numeric_limits::epsilon()) { + if (abs(val_double - expected_double) > FLT_EPSILON) { std::cerr << "Parameter 'double' has value number '" << val_double << "', but expected '" << expected_double << "'" << std::endl; ret = -1; } @@ -78,13 +79,13 @@ int main() { expected_double = 1.0003f; val_double = yaml["double"].valDouble(); - if (abs(val_double - expected_double) > std::numeric_limits::epsilon()) { + if (abs(val_double - expected_double) > FLT_EPSILON) { std::cerr << "Parameter 'double' has value number '" << val_double << "', but expected '" << expected_double << "'" << std::endl; ret = -1; } float val_double_like_float = yaml["double"].valFloat(); float expected_float = 1.0003f; - if (abs(val_double_like_float - expected_float) > std::numeric_limits::epsilon()) { + if (abs(val_double_like_float - expected_float) > FLT_EPSILON) { std::cerr << "Parameter 'double' has value number (like float) '" << val_double_like_float << "', but expected '" << expected_float << "'" << std::endl; ret = -1; } diff --git a/src/tests/test_float_value.cpp b/src/tests/test_float_value.cpp index f452a73..8612ed9 100644 --- a/src/tests/test_float_value.cpp +++ b/src/tests/test_float_value.cpp @@ -28,6 +28,7 @@ Official Source Code: https://github.com/wsjcpp/wsjcpp-yaml #include #include #include +#include #include #include "helpers.h" @@ -62,7 +63,7 @@ int main() { float val_float = yaml["float"].valFloat(); float expected_float = 1.0001f; - if (abs(val_float - expected_float) > std::numeric_limits::epsilon()) { + if (abs(val_float - expected_float) > FLT_EPSILON) { std::cerr << "Parameter 'float' has value '" << val_float << "', but expected '" << expected_float << "'" << std::endl; ret = -1; } diff --git a/wsjcpp.yml b/wsjcpp.yml index c52f8bc..4fe63b4 100644 --- a/wsjcpp.yml +++ b/wsjcpp.yml @@ -1,6 +1,6 @@ -wsjcpp_version: v0.0.1 +wsjcpp_version: v0.2.4 cmake_minimum_required: 3.0 -cmake_cxx_standard: 17 +cmake_cxx_standard: 11 name: wsjcpp-yaml version: v0.1.10 description: Read/Write yaml files