diff options
Diffstat (limited to 'src/lib/util/opresolv.h')
-rw-r--r-- | src/lib/util/opresolv.h | 201 |
1 files changed, 136 insertions, 65 deletions
diff --git a/src/lib/util/opresolv.h b/src/lib/util/opresolv.h index 097d6e303ac..4c059a88d72 100644 --- a/src/lib/util/opresolv.h +++ b/src/lib/util/opresolv.h @@ -50,45 +50,79 @@ // TYPE DEFINITIONS //************************************************************************** -enum option_type -{ - OPTIONTYPE_END, - OPTIONTYPE_INT, - OPTIONTYPE_STRING, - OPTIONTYPE_ENUM_BEGIN, - OPTIONTYPE_ENUM_VALUE -}; - -struct option_guide -{ - enum option_type option_type; - int parameter; - const char *identifier; - const char *display_name; -}; - #define OPTION_GUIDE_START(option_guide_) \ - const option_guide option_guide_[] = \ + const util::option_guide option_guide_ = \ { #define OPTION_GUIDE_END \ - { OPTIONTYPE_END } \ }; #define OPTION_GUIDE_EXTERN(option_guide_) \ - extern const option_guide option_guide_[] + extern const util::option_guide option_guide_ #define OPTION_INT(option_char, identifier, display_name) \ - { OPTIONTYPE_INT, (option_char), (identifier), (display_name) }, + { util::option_guide::entry::option_type::INT, (option_char), (identifier), (display_name) }, #define OPTION_STRING(option_char, identifier, display_name) \ - { OPTIONTYPE_STRING, (option_char), (identifier), (display_name) }, + { util::option_guide::entry::option_type::STRING, (option_char), (identifier), (display_name) }, #define OPTION_ENUM_START(option_char, identifier, display_name) \ - { OPTIONTYPE_ENUM_BEGIN, (option_char), (identifier), (display_name) }, + { util::option_guide::entry::option_type::ENUM_BEGIN, (option_char), (identifier), (display_name) }, #define OPTION_ENUM(value, identifier, display_name) \ - { OPTIONTYPE_ENUM_VALUE, (value), (identifier), (display_name) }, + { util::option_guide::entry::option_type::ENUM_VALUE, (value), (identifier), (display_name) }, #define OPTION_ENUM_END namespace util { + +// ======================> option_guide + +class option_guide +{ +public: + class entry + { + public: + enum class option_type + { + INT, + STRING, + ENUM_BEGIN, + ENUM_VALUE + }; + + constexpr entry(option_type type, int parameter = 0, const char *identifier = nullptr, const char *display_name = nullptr) + : m_type(type), m_parameter(parameter), m_identifier(identifier), m_display_name(display_name) + { + } + + // accessors + const option_type type() const { return m_type; } + int parameter() const { return m_parameter; } + const char *identifier() const { return m_identifier; } + const char *display_name() const { return m_display_name; } + + private: + option_type m_type; + int m_parameter; + const char *m_identifier; + const char *m_display_name; + }; + + typedef std::vector<option_guide::entry> entrylist; + + option_guide(std::initializer_list<entry> entries) + : m_entries(entries) + { + } + + // methods + const entrylist &entries() const { return m_entries; } + +private: + entrylist m_entries; +}; + +// ======================> option_resolution + class option_resolution { public: + // TODO - audit unused parameters enum class error { SUCCESS, @@ -102,61 +136,98 @@ public: INTERNAL }; + template<typename T> struct range { - int min, max; + range() { min = -1; max = -1; } + T min, max; }; - option_resolution(const option_guide *guide, const char *specification); - ~option_resolution(); - - // processing options with option_resolution objects - error add_param(const char *param, const std::string &value); - error finish(); - int lookup_int(int option_char) const; - const char *lookup_string(int option_char) const; + // class to represent specific entry + class entry + { + friend class option_resolution; + + public: + typedef std::vector<range<int> > rangelist; + + // ctor + entry(const option_guide::entry &guide_entry); + + // returns true if this entry is subject to range constraints + bool is_ranged() const { return !m_ranges.empty(); } + + // accessors + bool is_pertinent() const { return m_is_pertinent; } + const std::string &value() const; + int value_int() const; + const std::string &default_value() const { return m_default_value; } + const rangelist &ranges() const { return m_ranges; } + const option_guide::entrylist::const_iterator enum_value_begin() const { return m_enum_value_begin; } + const option_guide::entrylist::const_iterator enum_value_end() const { return m_enum_value_end; } + + // accessors for guide data + option_guide::entry::option_type option_type() const { return m_guide_entry.type(); } + const char *display_name() const { return m_guide_entry.display_name(); } + const char *identifier() const { return m_guide_entry.identifier(); } + int parameter() const { return m_guide_entry.parameter(); } + + + // mutators + bool set_value(const std::string &value); + bool set_value(int value) { return set_value(numeric_value(value)); } + + // higher level operations + bool can_bump_lower() const; + bool can_bump_higher() const; + bool bump_lower(); + bool bump_higher(); + + private: + // references to the option guide + const option_guide::entry & m_guide_entry; + option_guide::entrylist::const_iterator m_enum_value_begin; + option_guide::entrylist::const_iterator m_enum_value_end; + + // runtime state + bool m_is_pertinent; + std::string m_value; + std::string m_default_value; + rangelist m_ranges; + + // methods + void parse_specification(const char *specification); + void set_enum_value_range(option_guide::entrylist::const_iterator begin, option_guide::entrylist::const_iterator end); + static std::string numeric_value(int value); + rangelist::const_iterator find_in_ranges(int value) const; + }; - // accessors - const char *specification() const { return m_specification; } - const option_guide *find_option(int option_char) const; - const option_guide *index_option(int indx) const; + // ctor/dtor + option_resolution(const option_guide &guide); + ~option_resolution(); - // processing option guides - static size_t count_options(const option_guide *guide, const char *specification); + // sets a specification + void set_specification(const std::string &specification); - // processing option specifications - static error list_ranges(const char *specification, int option_char, - range *range, size_t range_count); - static error get_default(const char *specification, int option_char, int *val); - static error is_valid_value(const char *specification, int option_char, int val); - static bool contains(const char *specification, int option_char); + // entry lookup - note that we're not exposing m_entries directly because we don't really + // have a way of making the list be immutable but the members be mutable at the same time + std::vector<entry>::iterator entries_begin() { return m_entries.begin(); } + std::vector<entry>::iterator entries_end() { return m_entries.end(); } + entry *find(int parameter); + entry *find(const std::string &identifier); + int lookup_int(int parameter); + const std::string &lookup_string(int parameter); // misc static const char *error_string(error err); + static error get_default(const char *specification, int option_char, int *val); private: - enum class entry_state - { - UNSPECIFIED, - SPECIFIED - }; - - struct entry - { - const option_guide *guide_entry; - entry_state state; - std::string value; - - int int_value() const; - void set_int_value(int i); - }; - - const char *m_specification; std::vector<entry> m_entries; - static error resolve_single_param(const char *specification, entry *param_value, - struct range *range, size_t range_count); - static const char *lookup_in_specification(const char *specification, const option_guide *option); + error set_parameter(std::vector<entry>::iterator iter, const std::string &value); + + static const char *lookup_in_specification(const char *specification, const option_guide::entry &option); const entry *lookup_entry(int option_char) const; }; |