aboutsummaryrefslogtreecommitdiff
path: root/src/util/string.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-09-17 10:55:32 +0000
committer_ov4 <ov4@ov4.org>2026-09-17 10:55:32 +0000
commit103c8137011c5987741cd9a67c2f31ee7a62d65e (patch)
treed8a146e1379ffe00477b6efb3180453ca96329e7 /src/util/string.cc
parent64717eba9de6e3dc60e47c322b5f1c1632ed3b21 (diff)
add string2argv with auto memory allocation
Diffstat (limited to 'src/util/string.cc')
-rw-r--r--src/util/string.cc49
1 files changed, 41 insertions, 8 deletions
diff --git a/src/util/string.cc b/src/util/string.cc
index 9fad804..3bf34f7 100644
--- a/src/util/string.cc
+++ b/src/util/string.cc
@@ -7,36 +7,69 @@ using namespace std;
namespace ov4
{
-void string2argv(const vector<string> &s, char **argv)
+/*
+ * construct C-style **argv
+ * user should be responsible for allocation of **argv
+ * and make sure it's large enough
+ * argv should be the address to an empty and continuous memory space
+ */
+void string2argv(const vector<string> &v, char **argv)
{
// pointers [0, size)
// nullptr [size]
// data [size+1, ...)
- char *p = (char*)(argv + s.size() + 1);
+ char *p = (char*)(argv + v.size() + 1);
- argv[s.size()] = nullptr;
+ argv[v.size()] = nullptr;
- for (size_t i = 0; i < s.size(); i++)
+ for (size_t i = 0; i < v.size(); i++)
{
- strcpy(p, s[i].c_str());
+ strcpy(p, v[i].c_str());
argv[i] = p;
- p += s[i].size() + 1; // for '\0'
+ p += v[i].size() + 1; // for '\0'
}
}
-void argv2string(vector<string> &s, const char * const * argv)
+/*
+ * allocate heap memory, and construct C-style **argv
+ * NB: user should be responsible to ::operator delete();
+ */
+char **string2argv(const std::vector<std::string> &v)
+{
+ size_t size = argv_get_required_size(v);
+ char **p = static_cast<char**>(operator new(size));
+ string2argv(v, p);
+ return p;
+}
+
+void argv2string(vector<string> &v, const char * const * argv)
{
if (argv == nullptr) return;
+
+ v.clear();
for (size_t i = 0; true; i++)
{
if (argv[i] == nullptr) return;
- s.push_back(argv[i]);
+ v.push_back(argv[i]);
}
}
+/*
+ * return the memory size required to construct argv[][]
+ * in byte
+ */
+size_t argv_get_required_size(const std::vector<std::string> &v)
+{
+ size_t ret = 0;
+ ret += sizeof(char*) * (v.size() + 1); // point to every strings in v, and nullptr terminator
+ for (auto &sub : v)
+ ret += sizeof(char) * (sub.size() + 1); // chars, and null terminator
+ return ret;
+}
+
std::string safe_str(const char *s, const char *fallback)
{
return (s != nullptr) ? s : fallback;