summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2025-09-16 14:17:38 -0400
committerpommicket <pommicket@gmail.com>2025-09-16 14:17:38 -0400
commit76f68d6c93b55f9cd96a369bf2e5785ed16fa184 (patch)
treeddd657b9036fe80696e9c2e2f596ca91ce863680
parent9f817b370e55c24db5dee3f6948d2d95df7c3207 (diff)
More work on C++ library
-rw-r--r--CMakeLists.txt19
-rw-r--r--Makefile2
-rw-r--r--cpp/CMakeLists.txt15
-rw-r--r--cpp/examples/read_conf.cpp15
-rw-r--r--cpp/pom.cpp32
-rw-r--r--cpp/pom.hpp10
6 files changed, 58 insertions, 35 deletions
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 <pom.hpp>
+#include <iostream>
+
+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<const pom_error *>(C));
- m_next = std::unique_ptr<Error>(new Error(static_cast<const void *>(next)));
+ if (next)
+ m_next = std::unique_ptr<Error>(new Error(static_cast<const void *>(next)));
}
// const_cast here to avoid creating a separate ConstError type
Error::Error(const void *C_error): C(const_cast<void *>(C_error)), m_is_original(false) {
const pom_error *next = pom_error_next(static_cast<const pom_error *>(C));
- m_next = std::unique_ptr<Error>(new Error(static_cast<const void *>(next)));
+ if (next)
+ m_next = std::unique_ptr<Error>(new Error(static_cast<const void *>(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<Reader *>(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<void *>(&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<void *>(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<void *>(&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<void *>(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<const pom_conf *>(other.C));
+ return;
+ }
pom_conf_merge(static_cast<pom_conf *>(C), static_cast<const pom_conf *>(other.C));
}
std::optional<std::string_view> Configuration::get(std::string_view key) const {
+ if (!C) return {};
std::string key_str(key);
const char *value = pom_conf_get(static_cast<const pom_conf *>(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<std::string_view> 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;
};