From 3f4a0d5370ae6c34afe180df96add3b8522f4af1 Mon Sep 17 00:00:00 2001 From: mattkae Date: Wed, 11 May 2022 09:23:58 -0400 Subject: initial commit --- .../server/src/support/CommandLineParser.cpp | 119 +++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp (limited to 'elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp') diff --git a/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp b/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp new file mode 100644 index 0000000..a838092 --- /dev/null +++ b/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp @@ -0,0 +1,119 @@ +/** + * \file + * \author Guillaume Papin + * + * This file is distributed under the GNU General Public License. See + * COPYING for details. + */ + +#include "CommandLineParser.h" + +namespace { + +/// \brief A parser for escaped strings of command line arguments. +/// +/// Assumes \-escaping for quoted arguments (see the documentation of +/// unescapeCommandLine(...)). +class CommandLineArgumentParser { +public: + CommandLineArgumentParser(const std::string &commandLine) + : input_(commandLine), position_(input_.begin() - 1) { + } + + std::vector parse() { + bool hasMoreInput = true; + while (hasMoreInput && nextNonWhitespace()) { + std::string argument; + hasMoreInput = parseStringInto(argument); + commandLine_.push_back(argument); + } + return commandLine_; + } + +private: + // All private methods return true if there is more input available. + + bool parseStringInto(std::string &string) { + do { + if (*position_ == '"') { + if (!parseDoubleQuotedStringInto(string)) + return false; + } else if (*position_ == '\'') { + if (!parseSingleQuotedStringInto(string)) + return false; + } else { + if (!parseFreeStringInto(string)) + return false; + } + } while (*position_ != ' '); + return true; + } + + bool parseDoubleQuotedStringInto(std::string &string) { + if (!next()) + return false; + while (*position_ != '"') { + if (!skipEscapeCharacter()) + return false; + string.push_back(*position_); + if (!next()) + return false; + } + return next(); + } + + bool parseSingleQuotedStringInto(std::string &string) { + if (!next()) + return false; + while (*position_ != '\'') { + string.push_back(*position_); + if (!next()) + return false; + } + return next(); + } + + bool parseFreeStringInto(std::string &string) { + do { + if (!skipEscapeCharacter()) + return false; + string.push_back(*position_); + if (!next()) + return false; + } while (*position_ != ' ' && *position_ != '"' && *position_ != '\''); + return true; + } + + bool skipEscapeCharacter() { + if (*position_ == '\\') { + return next(); + } + return true; + } + + bool nextNonWhitespace() { + do { + if (!next()) + return false; + } while (*position_ == ' '); + return true; + } + + bool next() { + ++position_; + return position_ != input_.end(); + } + +private: + const std::string input_; + std::string::const_iterator position_; + std::vector commandLine_; +}; + +} // unnamed namespace + +std::vector +unescapeCommandLine(const std::string &escapedCommandLine) { + CommandLineArgumentParser parser(escapedCommandLine); + return parser.parse(); +} -- cgit v1.2.1