summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2025-01-25 12:57:24 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2025-01-25 12:57:24 +0100
commit5d268488b2861ce73db233d71bdb527f89001a4e (patch)
treedd7ebe2a9a4f9e66d7e8d869a13187211aa93a84
parent6628a2d8b18030dd3ebc714f65e7af90bd0b711a (diff)
Add PointerList class for working with, and propagating, argc/argvpointerlist
-rw-r--r--src/pointerlist.cc28
-rw-r--r--src/pointerlist.h26
-rw-r--r--test/ctor.cc17
-rw-r--r--test/pointerlist_test.cc90
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;