diff options
-rw-r--r-- | telnet_connection.cpp | 43 | ||||
-rw-r--r-- | telnet_connection.h | 2 |
2 files changed, 18 insertions, 27 deletions
diff --git a/telnet_connection.cpp b/telnet_connection.cpp index 8d6675d..9eeecdf 100644 --- a/telnet_connection.cpp +++ b/telnet_connection.cpp @@ -3,11 +3,12 @@ #include <boost/bind.hpp> #include <boost/algorithm/string.hpp> -#include <boost/algorithm/string/regex.hpp> -#include <boost/format.hpp> +#include <boost/spirit/include/qi.hpp> #include <iostream> +namespace qi = boost::spirit::qi; + telnet::Connection::Connection(boost::asio::io_service& io_service) : socket(io_service) { } @@ -25,9 +26,10 @@ void telnet::Connection::handle_read(const boost::system::error_code& error, siz return; } - std::vector<std::string> args = parse_args(line); - // no arguments, i.e. empty line - if(!args.size()) { + std::vector<std::string> args; + + // failed to parse or no arguments, i.e. empty line + if(!parse_args(line, args) || !args.size()) { start(); return; } @@ -54,27 +56,16 @@ void telnet::Connection::handle_read(const boost::system::error_code& error, siz /** Parse a given line and return a vector with its arguments. * Arguments which are surrounded by "quotes" are interpreted as a single argument. */ -std::vector<std::string> telnet::Connection::parse_args(std::string& line) { - std::string::const_iterator begin = line.begin(); - std::string::const_iterator end = line.end(); - - boost::regex re("(\")?((?(1)[^\"]|[^ ])+)(?(1)\")"); - boost::match_results<std::string::const_iterator> what; - boost::match_flag_type flags = boost::match_default; - - std::vector<std::string> args; - - while(boost::regex_search(begin, end, what, re, flags)) { - std::string s = std::string(what[2].first, what[2].second); - boost::algorithm::trim(s); - // avoid empty strings when parsing multi-word arguments (a "b c") - if(s.size()) { - args.push_back(s); - } - begin = what[0].second; - } - - return args; +bool telnet::Connection::parse_args(std::string& line, std::vector<std::string>& args) { + std::string::const_iterator begin = line.begin(), end = line.end(); + + return qi::parse(begin, end, + // find "words in quotes" + (('"' >> *(qi::char_ - '"') >> '"') | + // single words + *(qi::char_ - ' ')) % + // skip spaces between arguments + +qi::char_(' '), args); } void telnet::Connection::start() { diff --git a/telnet_connection.h b/telnet_connection.h index 68d652e..2109b05 100644 --- a/telnet_connection.h +++ b/telnet_connection.h @@ -16,7 +16,7 @@ namespace telnet { private: Connection(boost::asio::io_service& io_service); void handle_read(const boost::system::error_code& error, size_t bytes_transferred); - std::vector<std::string> parse_args(std::string& line); + bool parse_args(std::string& line, std::vector<std::string>& args); tcp::socket socket; boost::asio::streambuf buf; |