From 116faff062127d5ec61b17158676f0541df9e03c Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Sun, 22 Jan 2017 20:16:51 -0500 Subject: [PATCH] add CommandParser class --- src/core/CommandParser.cc | 74 +++++++++++++++++++++++++++++++++++++++ src/core/CommandParser.h | 30 ++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/core/CommandParser.cc create mode 100644 src/core/CommandParser.h diff --git a/src/core/CommandParser.cc b/src/core/CommandParser.cc new file mode 100644 index 0000000..095e1ef --- /dev/null +++ b/src/core/CommandParser.cc @@ -0,0 +1,74 @@ +#include "CommandParser.h" + +bool CommandParser::parse(const EncodedString & command) +{ + std::vector current_arg; + EncodedString::iterator end = command.end(); + EncodedString::iterator it = command.begin(); + uint32_t quote = 0u; + bool arg_content = false; + auto append_char = [¤t_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, ¤t_arg, &arg_content] { + if (arg_content) + { + m_args.push_back(std::make_shared(¤t_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; +} diff --git a/src/core/CommandParser.h b/src/core/CommandParser.h new file mode 100644 index 0000000..8ec455d --- /dev/null +++ b/src/core/CommandParser.h @@ -0,0 +1,30 @@ +#ifndef COMMANDPARSER_H +#define COMMANDPARSER_H + +#include +#include +#include "EncodedString.h" + +class CommandParser +{ +public: + bool parse(const EncodedString & command); + std::shared_ptr 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> m_args; + std::string m_parse_error; +}; + +#endif