summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2012-12-07 14:27:10 +0100
committerMaxime Coste <frrrwww@gmail.com>2012-12-07 19:20:26 +0100
commit158f5a5c84471618ab19e75a249e79e0ff0e7ef3 (patch)
tree956d974a26121404b99668c429a2dd8f5e5143d1 /src
parentd25bafa95dd1cd4a2dde79f988ce238ca3628d75 (diff)
extract ParametersParser to it's own file
Diffstat (limited to 'src')
-rw-r--r--src/commands.cc183
-rw-r--r--src/parameters_parser.cc103
-rw-r--r--src/parameters_parser.hh118
3 files changed, 222 insertions, 182 deletions
diff --git a/src/commands.cc b/src/commands.cc
index 62d9f1e0..507ec0c3 100644
--- a/src/commands.cc
+++ b/src/commands.cc
@@ -17,6 +17,7 @@
#include "event_manager.hh"
#include "color_registry.hh"
#include "client_manager.hh"
+#include "parameters_parser.hh"
#include <sys/types.h>
#include <sys/stat.h>
@@ -38,188 +39,6 @@ struct wrong_argument_count : runtime_error
wrong_argument_count() : runtime_error("wrong argument count") {}
};
-struct unknown_option : public runtime_error
-{
- unknown_option(const String& name)
- : runtime_error("unknown option '" + name + "'") {}
-};
-
-struct missing_option_value: public runtime_error
-{
- missing_option_value(const String& name)
- : runtime_error("missing value for option '" + name + "'") {}
-};
-
-// ParameterParser provides tools to parse command parameters.
-// There are 3 types of parameters:
-// * unnamed options, which are accessed by position (ignoring named ones)
-// * named boolean options, which are enabled using '-name' syntax
-// * named string options, which are defined using '-name value' syntax
-struct ParametersParser
-{
- // the options defines named options, if they map to true, then
- // they are understood as string options, else they are understood as
- // boolean option.
- ParametersParser(const CommandParameters& params,
- std::unordered_map<String, bool> options)
- : m_params(params), m_positional(params.size(), true), m_options(options)
- {
- for (size_t i = 0; i < params.size(); ++i)
- {
- if (params[i][0] == '-')
- {
- auto it = options.find(params[i].substr(1_byte));
- if (it == options.end())
- throw unknown_option(params[i]);
-
- if (it->second)
- {
- if (i + 1 == params.size() or params[i+1][0] == '-')
- throw missing_option_value(params[i]);
-
- m_positional[i+1] = false;
- }
- m_positional[i] = false;
- }
-
- // all options following -- are positional
- if (params[i] == "--")
- break;
- }
- }
-
- // check if a named option (either string or boolean) is specified
- bool has_option(const String& name) const
- {
- assert(m_options.find(name) != m_options.end());
- for (auto& param : m_params)
- {
- if (param[0] == '-' and param.substr(1_byte) == name)
- return true;
-
- if (param == "--")
- break;
- }
- return false;
- }
-
- // get a string option value, returns an empty string if the option
- // is not defined
- const String& option_value(const String& name) const
- {
- auto it = m_options.find(name);
- assert(it != m_options.end());
- assert(it->second == true);
-
- for (size_t i = 0; i < m_params.size(); ++i)
- {
- if (m_params[i][0] == '-' and m_params[i].substr(1_byte) == name)
- return m_params[i+1];
-
- if (m_params[i] == "--")
- break;
- }
- static String empty;
- return empty;
- }
-
- size_t positional_count() const
- {
- size_t res = 0;
- for (bool positional : m_positional)
- {
- if (positional)
- ++res;
- }
- return res;
- }
-
- struct iterator
- {
- public:
- typedef String value_type;
- typedef const value_type* pointer;
- typedef const value_type& reference;
- typedef size_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
-
- iterator(const ParametersParser& parser, size_t index)
- : m_parser(parser), m_index(index) {}
-
- const String& operator*() const
- {
- assert(m_parser.m_positional[m_index]);
- return m_parser.m_params[m_index];
- }
-
- const String* operator->() const
- {
- assert(m_parser.m_positional[m_index]);
- return &m_parser.m_params[m_index];
- }
-
- iterator& operator++()
- {
- while (m_index < m_parser.m_positional.size() and
- not m_parser.m_positional[++m_index]) {}
- return *this;
- }
-
- bool operator==(const iterator& other) const
- {
- return &m_parser == &other.m_parser and m_index == other.m_index;
- }
-
- bool operator!=(const iterator& other) const
- {
- return &m_parser != &other.m_parser or m_index != other.m_index;
- }
-
- bool operator<(const iterator& other) const
- {
- assert(&m_parser == &other.m_parser);
- return m_index < other.m_index;
- }
-
- private:
- const ParametersParser& m_parser;
- size_t m_index;
- };
-
- // positional parameter begin
- iterator begin() const
- {
- int index = 0;
- while (index < m_positional.size() and not m_positional[index])
- ++index;
- return iterator(*this, index);
- }
-
- // positional parameter end
- iterator end() const
- {
- return iterator(*this, m_params.size());
- }
-
- // access positional parameter by index
- const String& operator[] (size_t index) const
- {
- assert(index < positional_count());
- iterator it = begin();
- while (index)
- {
- ++it;
- --index;
- }
- return *it;
- }
-
-private:
- const CommandParameters& m_params;
- std::vector<bool> m_positional;
- std::unordered_map<String, bool> m_options;
-};
-
Buffer* open_or_create(const String& filename, Context& context)
{
Buffer* buffer = create_buffer_from_file(filename);
diff --git a/src/parameters_parser.cc b/src/parameters_parser.cc
new file mode 100644
index 00000000..cdcfb0c1
--- /dev/null
+++ b/src/parameters_parser.cc
@@ -0,0 +1,103 @@
+#include "parameters_parser.hh"
+
+namespace Kakoune
+{
+
+ParametersParser::ParametersParser(const ParameterList& params,
+ std::unordered_map<String, bool> options)
+ : m_params(params), m_positional(params.size(), true),
+ m_options(std::move(options))
+{
+ for (size_t i = 0; i < params.size(); ++i)
+ {
+ if (params[i][0] == '-')
+ {
+ auto it = m_options.find(params[i].substr(1_byte));
+ if (it == m_options.end())
+ throw unknown_option(params[i]);
+
+ if (it->second)
+ {
+ if (i + 1 == params.size() or params[i+1][0] == '-')
+ throw missing_option_value(params[i]);
+
+ m_positional[i+1] = false;
+ }
+ m_positional[i] = false;
+ }
+
+ // all options following -- are positional
+ if (params[i] == "--")
+ break;
+ }
+}
+
+bool ParametersParser::has_option(const String& name) const
+{
+ assert(m_options.find(name) != m_options.end());
+ for (auto& param : m_params)
+ {
+ if (param[0] == '-' and param.substr(1_byte) == name)
+ return true;
+
+ if (param == "--")
+ break;
+ }
+ return false;
+}
+
+const String& ParametersParser::option_value(const String& name) const
+{
+ auto it = m_options.find(name);
+ assert(it != m_options.end());
+ assert(it->second == true);
+
+ for (size_t i = 0; i < m_params.size(); ++i)
+ {
+ if (m_params[i][0] == '-' and m_params[i].substr(1_byte) == name)
+ return m_params[i+1];
+
+ if (m_params[i] == "--")
+ break;
+ }
+ static String empty;
+ return empty;
+}
+
+size_t ParametersParser::positional_count() const
+{
+ size_t res = 0;
+ for (bool positional : m_positional)
+ {
+ if (positional)
+ ++res;
+ }
+ return res;
+}
+
+const String& ParametersParser::operator[] (size_t index) const
+{
+ assert(index < positional_count());
+ iterator it = begin();
+ while (index)
+ {
+ ++it;
+ --index;
+ }
+ return *it;
+}
+
+ParametersParser::iterator ParametersParser::begin() const
+{
+ int index = 0;
+ while (index < m_positional.size() and not m_positional[index])
+ ++index;
+ return iterator(*this, index);
+}
+
+ParametersParser::iterator ParametersParser::end() const
+{
+ return iterator(*this, m_params.size());
+}
+
+}
diff --git a/src/parameters_parser.hh b/src/parameters_parser.hh
new file mode 100644
index 00000000..2ba77c76
--- /dev/null
+++ b/src/parameters_parser.hh
@@ -0,0 +1,118 @@
+#ifndef parameters_parser_hh_INCLUDED
+#define parameters_parser_hh_INCLUDED
+
+#include "string.hh"
+#include "memoryview.hh"
+#include "exception.hh"
+
+#include <unordered_map>
+
+namespace Kakoune
+{
+
+using ParameterList = memoryview<String>;
+
+struct unknown_option : public runtime_error
+{
+ unknown_option(const String& name)
+ : runtime_error("unknown option '" + name + "'") {}
+};
+
+struct missing_option_value: public runtime_error
+{
+ missing_option_value(const String& name)
+ : runtime_error("missing value for option '" + name + "'") {}
+};
+
+// ParameterParser provides tools to parse command parameters.
+// There are 3 types of parameters:
+// * unnamed options, which are accessed by position (ignoring named ones)
+// * named boolean options, which are enabled using '-name' syntax
+// * named string options, which are defined using '-name value' syntax
+struct ParametersParser
+{
+ // the options defines named options, if they map to true, then
+ // they are understood as string options, else they are understood as
+ // boolean option.
+ ParametersParser(const ParameterList& params,
+ std::unordered_map<String, bool> options);
+
+ // check if a named option (either string or boolean) is specified
+ bool has_option(const String& name) const;
+
+ // get a string option value, returns an empty string if the option
+ // is not defined
+ const String& option_value(const String& name) const;
+
+ // positional parameters count
+ size_t positional_count() const;
+
+ struct iterator
+ {
+ public:
+ typedef String value_type;
+ typedef const value_type* pointer;
+ typedef const value_type& reference;
+ typedef size_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
+
+ iterator(const ParametersParser& parser, size_t index)
+ : m_parser(parser), m_index(index) {}
+
+ const String& operator*() const
+ {
+ assert(m_parser.m_positional[m_index]);
+ return m_parser.m_params[m_index];
+ }
+
+ const String* operator->() const
+ {
+ assert(m_parser.m_positional[m_index]);
+ return &m_parser.m_params[m_index];
+ }
+
+ iterator& operator++()
+ {
+ while (m_index < m_parser.m_positional.size() and
+ not m_parser.m_positional[++m_index]) {}
+ return *this;
+ }
+
+ bool operator==(const iterator& other) const
+ {
+ return &m_parser == &other.m_parser and m_index == other.m_index;
+ }
+
+ bool operator!=(const iterator& other) const
+ {
+ return &m_parser != &other.m_parser or m_index != other.m_index;
+ }
+
+ bool operator<(const iterator& other) const
+ {
+ assert(&m_parser == &other.m_parser);
+ return m_index < other.m_index;
+ }
+
+ private:
+ const ParametersParser& m_parser;
+ size_t m_index;
+ };
+
+ // access positional parameter by index
+ const String& operator[] (size_t index) const;
+ // positional parameter begin
+ iterator begin() const;
+ // positional parameter end
+ iterator end() const;
+
+private:
+ ParameterList m_params;
+ std::vector<bool> m_positional;
+ std::unordered_map<String, bool> m_options;
+};
+
+}
+
+#endif // parameters_parser_hh_INCLUDED
+