summaryrefslogtreecommitdiff
path: root/src/util.cc
diff options
context:
space:
mode:
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;
+}