diff options
author | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-01-25 12:57:24 +0100 |
---|---|---|
committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-01-25 12:57:24 +0100 |
commit | 5d268488b2861ce73db233d71bdb527f89001a4e (patch) | |
tree | dd7ebe2a9a4f9e66d7e8d869a13187211aa93a84 | |
parent | 6628a2d8b18030dd3ebc714f65e7af90bd0b711a (diff) |
Add PointerList class for working with, and propagating, argc/argvpointerlist
-rw-r--r-- | src/pointerlist.cc | 28 | ||||
-rw-r--r-- | src/pointerlist.h | 26 | ||||
-rw-r--r-- | test/ctor.cc | 17 | ||||
-rw-r--r-- | test/pointerlist_test.cc | 90 |
4 files changed, 161 insertions, 0 deletions
diff --git a/src/pointerlist.cc b/src/pointerlist.cc new file mode 100644 index 0000000..e642075 --- /dev/null +++ b/src/pointerlist.cc @@ -0,0 +1,28 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include "pointerlist.h" + +PointerList::PointerList(int argc, const char* argv[]) +{ + for(int i = 0; i < argc; ++i) + { + push_back(argv[i]); + } +} + +std::pair<int, const char**> PointerList::get() +{ + argptrs.clear(); + for(const auto& arg : *this) + { + argptrs.push_back(arg.data()); + } + + if(argptrs.size() == 0) + { + return {0, nullptr}; + } + + return {argptrs.size(), argptrs.data()}; +} diff --git a/src/pointerlist.h b/src/pointerlist.h new file mode 100644 index 0000000..7c51ca6 --- /dev/null +++ b/src/pointerlist.h @@ -0,0 +1,26 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. + +#include <string> +#include <vector> +#include <deque> +#include <utility> + +// Maintains an (owning) list of string args and converts them to argc/argv +// compatible arguments on request. +// The returned pointers are guaranteed to be valid as long as the PointerList +// object lifetime is not exceeded. +class PointerList : + public std::deque<std::string> +{ +public: + PointerList() = default; + PointerList(int argc, const char* argv[]); + + //! Returns argc/argv pair from the current list of args + std::pair<int, const char**> get(); + +private: + std::vector<const char*> argptrs; +}; diff --git a/test/ctor.cc b/test/ctor.cc index d69b1cf..acb232f 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -12,6 +12,23 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) { .type = ctor::target_type::unit_test, .system = ctor::output_system::build, + .target = "pointerlist_test", + .sources = { + "pointerlist_test.cc", + "testmain.cc", + "../src/pointerlist.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"pointerlist\"", + }, + }, + }, + { + .type = ctor::target_type::unit_test, + .system = ctor::output_system::build, .target = "deps_test", .sources = { "deps_test.cc", diff --git a/test/pointerlist_test.cc b/test/pointerlist_test.cc new file mode 100644 index 0000000..329e319 --- /dev/null +++ b/test/pointerlist_test.cc @@ -0,0 +1,90 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include <uunit.h> + +#include "pointerlist.h" + +class PointerListTest + : public uUnit +{ +public: + PointerListTest() + { + uTEST(PointerListTest::test_zom_push); + uTEST(PointerListTest::test_zom_from_args); + } + + void test_zom_push() + { + using namespace std::string_literals; + + { // Zero + PointerList args; + uASSERT_EQUAL(0u, args.size()); + auto [argc, argv] = args.get(); + uASSERT_EQUAL(0, argc); + uASSERT_EQUAL(nullptr, argv); + } + + { // One + PointerList args; + args.push_back("hello"); + uASSERT_EQUAL(1u, args.size()); + auto [argc, argv] = args.get(); + uASSERT_EQUAL(1, argc); + uASSERT_EQUAL("hello"s, std::string(argv[0])); + } + + { // Many + PointerList args; + args.push_back("hello"); + args.push_back("dear"); + args.push_back("world"); + uASSERT_EQUAL(3u, args.size()); + auto [argc, argv] = args.get(); + uASSERT_EQUAL(3, argc); + uASSERT_EQUAL("hello"s, std::string(argv[0])); + uASSERT_EQUAL("dear"s, std::string(argv[1])); + uASSERT_EQUAL("world"s, std::string(argv[2])); + } + } + + void test_zom_from_args() + { + using namespace std::string_literals; + + { // Zero + PointerList args(0, nullptr); + uASSERT_EQUAL(0u, args.size()); + auto [argc, argv] = args.get(); + uASSERT_EQUAL(0, argc); + uASSERT_EQUAL(nullptr, argv); + } + + { // One + int _argc{1}; + const char* _argv[] = { "hello" }; + PointerList args(_argc, _argv); + uASSERT_EQUAL(1u, args.size()); + auto [argc, argv] = args.get(); + uASSERT_EQUAL(1, argc); + uASSERT_EQUAL("hello"s, std::string(argv[0])); + } + + { // Many + int _argc{3}; + const char* _argv[] = { "hello", "dear", "world" }; + PointerList args(_argc, _argv); + uASSERT_EQUAL(3u, args.size()); + auto [argc, argv] = args.get(); + uASSERT_EQUAL(3, argc); + uASSERT_EQUAL("hello"s, std::string(argv[0])); + uASSERT_EQUAL("dear"s, std::string(argv[1])); + uASSERT_EQUAL("world"s, std::string(argv[2])); + } + } +}; + +// Registers the fixture into the 'registry' +static PointerListTest test; |