jes/src/core/CommandParser.cc

73 lines
1.7 KiB
C++

#include "CommandParser.h"
bool CommandParser::parse(const EncodedString & command)
{
std::vector<uint8_t> current_arg;
EncodedString::iterator end = command.end();
EncodedString::iterator it = command.begin();
uint32_t quote = 0u;
bool arg_content = false;
auto append_char = [&current_arg, &it, &command, &arg_content]() {
size_t offset = it.offset();
for (size_t i = 0u, sz = it.size(); i < sz; i++)
{
current_arg.push_back(command[offset + i]);
}
arg_content = true;
};
auto collect_arg = [this, &current_arg, &arg_content] {
if (arg_content)
{
m_args.push_back(EncodedString(&current_arg[0], current_arg.size()));
current_arg.clear();
arg_content = false;
}
arg_content = false;
};
while (it != end)
{
uint32_t cp = *it;
if (cp == '\n')
{
/* Skip newline character */
}
else if ((quote != 0u) && (cp == quote))
{
quote = 0u;
}
else if ((quote == 0u) && ((cp == '\'') || (cp == '"')))
{
quote = cp;
arg_content = true;
}
else if (cp == '\\')
{
if (++it == end)
{
m_parse_error = "Unterminated escape sequence";
return false;
}
append_char();
}
else if ((cp == ' ') && (quote == 0u))
{
collect_arg();
}
else
{
append_char();
}
++it;
}
if (quote != 0u)
{
m_parse_error = std::string("Unterminated quoted region");
return false;
}
collect_arg();
return true;
}