summaryrefslogtreecommitdiff
path: root/src/util.cc
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2025-02-06 17:27:18 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2025-02-06 17:27:18 +0100
commit608addf75a6283d6db9467dc27272a9e28fe4670 (patch)
tree68d63c29ede9d4eec64f3a0c8a2a7fdc651af738 /src/util.cc
parentf3fedaf53ed90cb5f1eda704c6f199a8b34ecc96 (diff)
Add argsplit to support multiple arguments in CXXFLAGS, CFLAGS and LDFLAGS.
Diffstat (limited to 'src/util.cc')
-rw-r--r--src/util.cc93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/util.cc b/src/util.cc
index dbd4c3c..6fc650a 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -6,6 +6,7 @@
#include <iostream>
#include <fstream>
#include <algorithm>
+#include <sstream>
std::string to_lower(const std::string& str)
{
@@ -184,3 +185,95 @@ std::string locate(const std::string& prog,
return {};
}
+
+std::vector<std::string> argsplit(const std::string& str)
+{
+ enum class state
+ {
+ normal,
+ in_quot,
+ in_apotrophe,
+ } state{state::normal};
+ bool esc{false};
+
+ std::string token;
+ std::vector<std::string> tokens;
+ for(auto c : str)
+ {
+ switch(state)
+ {
+ case state::normal:
+ if(esc)
+ {
+ esc = false;
+ }
+ else
+ {
+ if(c == ' ')
+ {
+ tokens.push_back(token);
+ token.clear();
+ continue;
+ }
+ if(c == '\\')
+ {
+ esc = true;
+ }
+ if(c == '"')
+ {
+ state = state::in_quot;
+ }
+ if(c == '\'')
+ {
+ state = state::in_apotrophe;
+ }
+ }
+
+ token += c;
+ break;
+ case state::in_quot:
+ if(esc)
+ {
+ esc = false;
+ }
+ else
+ {
+ if(c == '\\')
+ {
+ esc = true;
+ }
+ if(c == '"')
+ {
+ state = state::normal;
+ }
+ }
+
+ token += c;
+ break;
+ case state::in_apotrophe:
+ if(esc)
+ {
+ esc = false;
+ }
+ else
+ {
+ if(c == '\\')
+ {
+ esc = true;
+ }
+ if(c == '\'')
+ {
+ state = state::normal;
+ }
+ }
+
+ token += c;
+ break;
+ }
+ }
+ if(!token.empty())
+ {
+ tokens.push_back(token);
+ }
+ return tokens;
+}