From 0cbc7dd8dd00c92570f35f901b820a1ea96acdf0 Mon Sep 17 00:00:00 2001 From: Joel Klinghed Date: Wed, 3 Jun 2015 00:07:58 +0200 Subject: Add space separated argument parser with quoting --- src/Makefile.am | 1 + src/args.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/args.hh | 22 ++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/args.cc create mode 100644 src/args.hh (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5a779fa..54ff40d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,6 +12,7 @@ libcgi_la_SOURCES = cgi.hh common.hh cgi.cc \ query_parser.hh query_parser.cc \ header_parser.hh header_parser.cc \ strutils.hh strutils.cc \ + args.hh args.cc \ multipart_formdata_parser.hh multipart_formdata_parser.cc libcgi_la_CPPFLAGS = $(AM_CPPFLAGS) @FASTCGI_CFLAGS@ libcgi_la_LIBADD = @FASTCGI_LIBS@ diff --git a/src/args.cc b/src/args.cc new file mode 100644 index 0000000..1c0ce17 --- /dev/null +++ b/src/args.cc @@ -0,0 +1,63 @@ +#include "common.hh" + +#include "args.hh" + +namespace stuff { + +// static +bool Args::parse(const std::string& input, std::vector* output, + bool nice) { + size_t last = 0, i = 0; + std::string arg; + output->clear(); + while (i < input.size() && input[i] == ' ') ++i; + if (i == input.size()) return true; + while (i < input.size()) { + if (input[i] == ' ') { + arg.append(input.substr(last, i - last)); + output->push_back(arg); + arg.clear(); + ++i; + while (i < input.size() && input[i] == ' ') ++i; + if (i == input.size()) return true; + last = i; + } else if (input[i] == '\'' || input[i] == '"') { + const char closing = input[i]; + std::string text; + size_t j = i + 1; + size_t last_j = j; + while (j < input.size()) { + if (input[j] == closing) { + break; + } else if (input[j] == '\\') { + text.append(input.substr(last_j, j - last_j)); + if (j == input.size()) { + if (!nice) return false; + break; + } + text.push_back(input[++j]); + last_j = ++j; + } else { + ++j; + } + } + if (j < input.size()) { + arg.append(input.substr(last, i - last)); + arg.append(text); + arg.append(input.substr(last_j, j - last_j)); + last = i = j + 1; + } else { + // No closing char + if (!nice) return false; + ++i; + } + } else { + ++i; + } + } + arg.append(input.substr(last, i - last)); + output->push_back(arg); + return true; +} + +} // namespace stuff diff --git a/src/args.hh b/src/args.hh new file mode 100644 index 0000000..7a0f4fc --- /dev/null +++ b/src/args.hh @@ -0,0 +1,22 @@ +#ifndef ARGS_HH +#define ARGS_HH + +#include +#include + +namespace stuff { + +class Args { +public: + static bool parse(const std::string& input, + std::vector* output, + bool nice = true); + +private: + Args() = delete; + ~Args() = delete; +}; + +} // namespace stuff + +#endif /* ARGS_HH */ -- cgit v1.2.3-70-g09d2