summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-01-05 00:23:40 +0100
committerJon Bergli Heier <snakebite@jvnv.net>2011-01-05 00:23:40 +0100
commit102992da75edfcb671eb408bd801703a3f9137d0 (patch)
tree354a0885fa92acf44e1cc2b004cb4dfc494f9977
parentf0db6a4e4e6b3059c6553b819ac8788b62486103 (diff)
Replaced regex parser in telnet::Connection::parse_args() with a spirit-based parser.
-rw-r--r--telnet_connection.cpp43
-rw-r--r--telnet_connection.h2
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;