add CommandParser class

This commit is contained in:
Josh Holtrop 2017-01-22 20:16:51 -05:00
parent 726bd8bfaa
commit 116faff062
2 changed files with 104 additions and 0 deletions

74
src/core/CommandParser.cc Normal file
View File

@ -0,0 +1,74 @@
#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(std::make_shared<EncodedString>(&current_arg[0], current_arg.size()));
current_arg.clear();
arg_content = false;
}
arg_content = false;
};
while (it != end)
{
uint32_t cp = *it;
if ((quote != 0u) && (cp == quote))
{
quote = 0u;
++it;
continue;
}
if ((quote == 0u) && ((cp == '\'') || (cp == '"')))
{
quote = cp;
++it;
continue;
}
if (cp == '\\')
{
if (++it == end)
{
m_parse_error = "Unterminated escape sequence";
return false;
}
append_char();
++it;
continue;
}
else if (cp == ' ')
{
collect_arg();
}
else
{
append_char();
++it;
continue;
}
}
if (quote != 0u)
{
m_parse_error = std::string("Unterminated quoted region");
return false;
}
collect_arg();
return true;
}

30
src/core/CommandParser.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef COMMANDPARSER_H
#define COMMANDPARSER_H
#include <vector>
#include <string>
#include "EncodedString.h"
class CommandParser
{
public:
bool parse(const EncodedString & command);
std::shared_ptr<EncodedString> operator[](size_t index) const
{
return m_args[index];
}
size_t size() const
{
return m_args.size();
}
const std::string & parse_error() const
{
return m_parse_error;
}
protected:
std::vector<std::shared_ptr<EncodedString>> m_args;
std::string m_parse_error;
};
#endif