diff options
Diffstat (limited to 'src/lib/util/options.h')
-rw-r--r-- | src/lib/util/options.h | 126 |
1 files changed, 71 insertions, 55 deletions
diff --git a/src/lib/util/options.h b/src/lib/util/options.h index 3fcd9d5e144..8b85b9f58e6 100644 --- a/src/lib/util/options.h +++ b/src/lib/util/options.h @@ -11,9 +11,20 @@ #ifndef MAME_LIB_UTIL_OPTIONS_H #define MAME_LIB_UTIL_OPTIONS_H -#include "corefile.h" +#include "strformat.h" +#include "utilfwd.h" + +#include <algorithm> +#include <exception> +#include <functional> +#include <iosfwd> +#include <memory> #include <unordered_map> #include <sstream> +#include <string> +#include <string_view> +#include <utility> +#include <vector> //************************************************************************** @@ -93,7 +104,9 @@ public: BOOLEAN, // boolean option INTEGER, // integer option FLOAT, // floating-point option - STRING // string option + STRING, // string option + PATH, // single path option + MULTIPATH // semicolon-delimited paths option }; // information about a single entry in the options @@ -101,6 +114,7 @@ public: { public: typedef std::shared_ptr<entry> shared_ptr; + typedef std::shared_ptr<const entry> shared_const_ptr; typedef std::weak_ptr<entry> weak_ptr; // constructor/destructor @@ -113,32 +127,35 @@ public: virtual ~entry(); // accessors - const std::vector<std::string> &names() const { return m_names; } - const std::string &name() const { return m_names[0]; } - virtual const char *value() const; - int priority() const { return m_priority; } - void set_priority(int priority) { m_priority = priority; } - option_type type() const { return m_type; } - const char *description() const { return m_description; } - virtual const std::string &default_value() const; - virtual const char *minimum() const; - virtual const char *maximum() const; - bool has_range() const; + const std::vector<std::string> &names() const noexcept { return m_names; } + const std::string &name() const noexcept { return m_names[0]; } + virtual const char *value() const noexcept; + virtual const char *value_unsubstituted() const noexcept; + int priority() const noexcept { return m_priority; } + void set_priority(int priority) noexcept { m_priority = priority; } + option_type type() const noexcept { return m_type; } + const char *description() const noexcept { return m_description; } + virtual const std::string &default_value() const noexcept; + virtual const char *minimum() const noexcept; + virtual const char *maximum() const noexcept; + bool has_range() const noexcept; // mutators - void set_value(std::string &&newvalue, int priority, bool always_override = false); + void copy_from(const entry &that, bool always_override); + void set_value(std::string &&newvalue, int priority, bool always_override = false, bool perform_substitutions = false); virtual void set_default_value(std::string &&newvalue); void set_description(const char *description) { m_description = description; } void set_value_changed_handler(std::function<void(const char *)> &&handler) { m_value_changed_handler = std::move(handler); } virtual void revert(int priority_hi, int priority_lo) { } protected: - virtual void internal_set_value(std::string &&newvalue) = 0; + virtual void internal_set_value(std::string &&newvalue, bool perform_substitutions) = 0; + virtual bool internal_copy_value(const entry &that); - private: void validate(const std::string &value); - std::vector<std::string> m_names; + private: + const std::vector<std::string> m_names; int m_priority; core_options::option_type m_type; const char * m_description; @@ -154,13 +171,13 @@ public: virtual ~core_options(); // getters - const std::string &command() const { return m_command; } - const std::vector<std::string> &command_arguments() const { assert(!m_command.empty()); return m_command_arguments; } - const entry::shared_ptr get_entry(const std::string &name) const; - entry::shared_ptr get_entry(const std::string &name); - const std::vector<entry::shared_ptr> &entries() const { return m_entries; } - bool exists(const std::string &name) const { return get_entry(name) != nullptr; } - bool header_exists(const char *description) const; + const std::string &command() const noexcept { return m_command; } + const std::vector<std::string> &command_arguments() const noexcept { assert(!m_command.empty()); return m_command_arguments; } + entry::shared_const_ptr get_entry(std::string_view name) const noexcept; + entry::shared_ptr get_entry(std::string_view name) noexcept; + const std::vector<entry::shared_ptr> &entries() const noexcept { return m_entries; } + bool exists(std::string_view name) const noexcept { return get_entry(name) != nullptr; } + bool header_exists(const char *description) const noexcept; // configuration void add_entry(entry::shared_ptr &&entry, const char *after_header = nullptr); @@ -168,10 +185,12 @@ public: void add_entry(std::vector<std::string> &&names, const char *description, option_type type, std::string &&default_value = "", std::string &&minimum = "", std::string &&maximum = ""); void add_header(const char *description); void add_entries(const options_entry *entrylist, bool override_existing = false); - void set_default_value(const char *name, const char *defvalue); - void set_description(const char *name, const char *description); + void set_default_value(std::string_view name, std::string &&defvalue); + void set_default_value(std::string_view name, std::string_view defvalue) { set_default_value(name, std::string(defvalue)); } + void set_default_value(std::string_view name, const char *defvalue) { set_default_value(name, std::string(defvalue)); } + void set_description(std::string_view name, const char *description); void remove_entry(entry &delentry); - void set_value_changed_handler(const std::string &name, std::function<void(const char *)> &&handler); + void set_value_changed_handler(std::string_view name, std::function<void(const char *)> &&handler); void revert(int priority_hi = OPTION_PRIORITY_MAXIMUM, int priority_lo = OPTION_PRIORITY_DEFAULT); // parsing/input @@ -184,20 +203,21 @@ public: std::string output_help() const; // reading - const char *value(const char *option) const; - const char *description(const char *option) const; - bool bool_value(const char *option) const { return int_value(option) != 0; } - int int_value(const char *option) const { return atoi(value(option)); } - float float_value(const char *option) const { return atof(value(option)); } + const char *value(std::string_view option) const noexcept; + const char *description(std::string_view option) const noexcept; + bool bool_value(std::string_view option) const { return int_value(option) != 0; } + int int_value(std::string_view option) const; + float float_value(std::string_view option) const; // setting - void set_value(const std::string &name, const std::string &value, int priority); - void set_value(const std::string &name, std::string &&value, int priority); - void set_value(const std::string &name, int value, int priority); - void set_value(const std::string &name, float value, int priority); + void set_value(std::string_view name, std::string_view value, int priority); + void set_value(std::string_view name, const char *value, int priority); + void set_value(std::string_view name, std::string &&value, int priority); + void set_value(std::string_view name, int value, int priority); + void set_value(std::string_view name, float value, int priority); // misc - static const char *unadorned(int x = 0) { return s_option_unadorned[std::min(x, MAX_UNADORNED_OPTIONS - 1)]; } + static const char *unadorned(int x = 0) noexcept { return s_option_unadorned[std::min(x, MAX_UNADORNED_OPTIONS - 1)]; } protected: virtual void command_argument_processed() { } @@ -215,23 +235,29 @@ private: ~simple_entry(); // getters - virtual const char *value() const override; - virtual const char *minimum() const override; - virtual const char *maximum() const override; - virtual const std::string &default_value() const override; + virtual const char *value() const noexcept override; + virtual const char *value_unsubstituted() const noexcept override; + virtual const char *minimum() const noexcept override; + virtual const char *maximum() const noexcept override; + virtual const std::string &default_value() const noexcept override; virtual void revert(int priority_hi, int priority_lo) override; virtual void set_default_value(std::string &&newvalue) override; protected: - virtual void internal_set_value(std::string &&newvalue) override; + virtual void internal_set_value(std::string &&newvalue, bool perform_substitutions) override; + virtual bool internal_copy_value(const entry &that) override; private: // internal state std::string m_data; // data for this item + std::string m_data_unsubst; // data for this item, prior to any substitution std::string m_defdata; // default data for this item + std::string m_defdata_unsubst; // default data for this item, prior to any substitution std::string m_minimum; // minimum value std::string m_maximum; // maximum value + + std::string type_specific_substitutions(std::string_view s) const noexcept; }; // used internally in core_options @@ -243,13 +269,13 @@ private: }; // internal helpers - void add_to_entry_map(std::string &&name, entry::shared_ptr &entry); - void do_set_value(entry &curentry, std::string &&data, int priority, std::ostream &error_stream, condition_type &condition); + void add_to_entry_map(const std::string &name, entry::shared_ptr &entry); + void do_set_value(entry &curentry, std::string_view data, int priority, std::ostream &error_stream, condition_type &condition, bool perform_substitutions); void throw_options_exception_if_appropriate(condition_type condition, std::ostringstream &error_stream); // internal state std::vector<entry::shared_ptr> m_entries; // canonical list of entries - std::unordered_map<std::string, entry::weak_ptr> m_entrymap; // map for fast lookup + std::unordered_map<std::string_view, entry::weak_ptr> m_entrymap; // map for fast lookup std::string m_command; // command found std::vector<std::string> m_command_arguments; // command arguments static const char *const s_option_unadorned[]; // array of unadorned option "names" @@ -265,14 +291,4 @@ struct options_entry const char * description; // description for -showusage }; -// legacy option types -const core_options::option_type OPTION_INVALID = core_options::option_type::INVALID; -const core_options::option_type OPTION_HEADER = core_options::option_type::HEADER; -const core_options::option_type OPTION_COMMAND = core_options::option_type::COMMAND; -const core_options::option_type OPTION_BOOLEAN = core_options::option_type::BOOLEAN; -const core_options::option_type OPTION_INTEGER = core_options::option_type::INTEGER; -const core_options::option_type OPTION_FLOAT = core_options::option_type::FLOAT; -const core_options::option_type OPTION_STRING = core_options::option_type::STRING; - - #endif // MAME_LIB_UTIL_OPTIONS_H |