From 76f68d6c93b55f9cd96a369bf2e5785ed16fa184 Mon Sep 17 00:00:00 2001 From: pommicket Date: Tue, 16 Sep 2025 14:17:38 -0400 Subject: More work on C++ library --- CMakeLists.txt | 19 +++++++++++++++++++ Makefile | 2 +- cpp/CMakeLists.txt | 15 --------------- cpp/examples/read_conf.cpp | 15 +++++++++++++++ cpp/pom.cpp | 32 ++++++++++++++++++-------------- cpp/pom.hpp | 10 +++++----- 6 files changed, 58 insertions(+), 35 deletions(-) delete mode 100644 cpp/CMakeLists.txt create mode 100644 cpp/examples/read_conf.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a24f75..ff27660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,25 @@ add_executable(example_all_functions examples/all_functions.c) target_include_directories(example_all_functions PRIVATE .) target_link_libraries(example_all_functions pom) + # Installation install(TARGETS pom pom-shared DESTINATION lib) install(FILES pom.h DESTINATION include) + +if (BUILD_CXX) + + # C++ library + add_library(pom++ STATIC cpp/pom.cpp) + add_library(pom++-shared SHARED cpp/pom.cpp) + set_target_properties(pom++-shared PROPERTIES OUTPUT_NAME pom++) + target_include_directories(pom++ PRIVATE .) + target_include_directories(pom++-shared PRIVATE .) + target_link_libraries(pom++ PRIVATE pom) + target_link_libraries(pom++-shared PRIVATE pom-shared) + + # C++ Examples + add_executable(example++_read_conf cpp/examples/read_conf.cpp) + target_include_directories(example++_read_conf PRIVATE cpp) + target_link_libraries(example++_read_conf pom++) + +endif() diff --git a/Makefile b/Makefile index 0629ef3..0561492 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ PROFILE ?= Release BUILD_DIR ?= $(PROFILE) __build: mkdir -p $(BUILD_DIR) - P=`pwd` && cd $(BUILD_DIR) && cmake -DCMAKE_BUILD_TYPE=$(PROFILE) -DCMAKE_EXPORT_COMPILE_COMMANDS=1 $$P + P=`pwd` && cd $(BUILD_DIR) && cmake -DCMAKE_BUILD_TYPE=$(PROFILE) -DCMAKE_EXPORT_COMPILE_COMMANDS=1 -DBUILD_CXX=yes $$P $(MAKE) -C $(BUILD_DIR) test: __build diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt deleted file mode 100644 index f26258d..0000000 --- a/cpp/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -cmake_minimum_required(VERSION 3.0...3.31) -project(pom) - -if (MSVC) - add_compile_options(/W4) -else() - add_compile_options(-Wall -Wextra -Wpedantic -Wshadow) -endif() - - -add_library(pom++ STATIC pom.cpp) -add_library(pom++-shared SHARED pom.cpp) -set_target_properties(pom++-shared PROPERTIES OUTPUT_NAME pom++) -target_include_directories(pom++ PRIVATE ..) -target_include_directories(pom++-shared PRIVATE ..) diff --git a/cpp/examples/read_conf.cpp b/cpp/examples/read_conf.cpp new file mode 100644 index 0000000..0a7ef51 --- /dev/null +++ b/cpp/examples/read_conf.cpp @@ -0,0 +1,15 @@ +#include +#include + +int main(void) { + try { + pom::Configuration conf = pom::Configuration("conf.pom"); + auto indentation_type = conf.get("indentation-type"); + if (indentation_type.has_value()) + std::cout << "Indenting with " << indentation_type.value() << "\n"; + else + std::cout << "No indentation type set!\n"; + } catch (pom::Error &error) { + std::cerr << error.what() << "\n"; + } +} diff --git a/cpp/pom.cpp b/cpp/pom.cpp index a883d34..4e4f7e0 100644 --- a/cpp/pom.cpp +++ b/cpp/pom.cpp @@ -14,19 +14,19 @@ Configuration::~Configuration() { Configuration::Configuration(): C(nullptr) {} -Configuration::Configuration(void *c): C(c) {} - Error::~Error() { if (m_is_original) free(C); } Error::Error(void *C_error): C(C_error), m_is_original(true) { const pom_error *next = pom_error_next(static_cast(C)); - m_next = std::unique_ptr(new Error(static_cast(next))); + if (next) + m_next = std::unique_ptr(new Error(static_cast(next))); } // const_cast here to avoid creating a separate ConstError type Error::Error(const void *C_error): C(const_cast(C_error)), m_is_original(false) { const pom_error *next = pom_error_next(static_cast(C)); - m_next = std::unique_ptr(new Error(static_cast(next))); + if (next) + m_next = std::unique_ptr(new Error(static_cast(next))); } std::string_view Error::file() const noexcept { @@ -89,32 +89,30 @@ static size_t readable_read(void *udata, char *buf, size_t count) { return static_cast(udata)->read(buf, count); } -Configuration Configuration::load(std::string_view filename, Reader &source, const Settings *settings) { +Configuration::Configuration(std::string_view filename, Reader &source, const Settings *settings) { pom_settings C_settings = {}; if (settings) { settings->to_C(static_cast(&C_settings)); } pom_error *error; std::string filename_str(filename); - void *C_conf = pom_load(&C_settings, filename_str.c_str(), readable_read, &source, &error); + C = pom_load(&C_settings, filename_str.c_str(), readable_read, &source, &error); if (error) { throw Error(static_cast(error)); } - return Configuration(C_conf); } -Configuration Configuration::load(std::string_view path, const Settings *settings) { +Configuration::Configuration(std::string_view path, const Settings *settings) { pom_settings C_settings = {}; if (settings) { settings->to_C(static_cast(&C_settings)); } pom_error *error; std::string path_str(path); - void *C_conf = pom_load_path(&C_settings, path_str.c_str(), &error); + C = pom_load_path(&C_settings, path_str.c_str(), &error); if (error) { throw Error(static_cast(error)); } - return Configuration(C_conf); } class StringViewReader: public Reader { @@ -129,9 +127,9 @@ private: std::string_view string; }; -Configuration Configuration::load(std::string_view filename, std::string_view string, const Settings *settings) { +Configuration::Configuration(std::string_view filename, std::string_view string, const Settings *settings) { StringViewReader reader(string); - return load(filename, reader, settings); + Configuration(filename, reader, settings); } class IStreamReader: public Reader { @@ -146,16 +144,22 @@ private: }; -Configuration Configuration::load(std::string_view filename, std::istream &stream, const Settings *settings) { +Configuration::Configuration(std::string_view filename, std::istream &stream, const Settings *settings) { IStreamReader reader(stream); - return load(filename, reader, settings); + Configuration(filename, reader, settings); } void Configuration::merge(const Configuration &other) { + if (!other.C) return; + if (!C) { + C = pom_conf_copy(static_cast(other.C)); + return; + } pom_conf_merge(static_cast(C), static_cast(other.C)); } std::optional Configuration::get(std::string_view key) const { + if (!C) return {}; std::string key_str(key); const char *value = pom_conf_get(static_cast(C), key_str.c_str()); if (!value) diff --git a/cpp/pom.hpp b/cpp/pom.hpp index e3c66d4..bf16a29 100644 --- a/cpp/pom.hpp +++ b/cpp/pom.hpp @@ -64,17 +64,17 @@ public: class Configuration { public: Configuration(); + Configuration(std::string_view filename, Reader &source, const Settings *settings = nullptr); + Configuration(std::string_view filename, std::istream &stream, const Settings *settings = nullptr); + Configuration(std::string_view path, const Settings *settings = nullptr); + Configuration(std::string_view filename, std::string_view string, const Settings *settings = nullptr); ~Configuration(); std::optional get(std::string_view key) const; std::string_view get_or_default(std::string_view key, std::string_view dflt) const; Configuration section(std::string_view name) const; void merge(const Configuration &other); - static Configuration load(std::string_view filename, Reader &source, const Settings *settings = nullptr); - static Configuration load(std::string_view filename, std::istream &stream, const Settings *settings = nullptr); - static Configuration load(std::string_view path, const Settings *settings = nullptr); - static Configuration load(std::string_view filename, std::string_view string, const Settings *settings = nullptr); private: - explicit Configuration(void *c); + explicit Configuration(void *c): C(c) {} void *C; }; -- cgit v1.2.3