diff options
Diffstat (limited to 'trunk/src/lib/util/options.h')
-rw-r--r-- | trunk/src/lib/util/options.h | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/trunk/src/lib/util/options.h b/trunk/src/lib/util/options.h new file mode 100644 index 00000000000..03aa293bebf --- /dev/null +++ b/trunk/src/lib/util/options.h @@ -0,0 +1,206 @@ +/*************************************************************************** + + options.h + + Core options code code + +**************************************************************************** + + Copyright Aaron Giles + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + * Neither the name 'MAME' nor the names of its contributors may be + used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY AARON GILES ''AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL AARON GILES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +***************************************************************************/ + +#ifndef __OPTIONS_H__ +#define __OPTIONS_H__ + +#include "osdcore.h" +#include "corefile.h" +#include "tagmap.h" + + + +//************************************************************************** +// CONSTANTS +//************************************************************************** + +// option types +const UINT32 OPTION_TYPE_MASK = 0x0007; // up to 8 different types +enum +{ + OPTION_INVALID, // invalid + OPTION_HEADER, // a header item + OPTION_COMMAND, // a command + OPTION_BOOLEAN, // boolean option + OPTION_INTEGER, // integer option + OPTION_FLOAT, // floating-point option + OPTION_STRING // string option +}; + +// option priorities +const int OPTION_PRIORITY_DEFAULT = 0; // defaults are at 0 priority +const int OPTION_PRIORITY_LOW = 50; // low priority +const int OPTION_PRIORITY_NORMAL = 100; // normal priority +const int OPTION_PRIORITY_HIGH = 150; // high priority +const int OPTION_PRIORITY_MAXIMUM = 255; // maximum priority + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// static structure describing a single option with its description and default value +struct options_entry +{ + const char * name; // name on the command line + const char * defvalue; // default value of this argument + UINT32 flags; // flags to describe the option + const char * description; // description for -showusage +}; + + +// structure holding information about a collection of options +class core_options +{ + static const int MAX_UNADORNED_OPTIONS = 16; + +public: + // information about a single entry in the options + class entry + { + friend class core_options; + + // construction/destruction + entry(const options_entry &entry); + + public: + // getters + entry *next() const { return m_next; } + const char *name() const { return m_name[0] ? m_name[0].cstr() : NULL; } + const char *description() const { return m_description; } + const char *value() const { return m_data; } + const char *default_value() const { return m_defdata; } + const char *minimum() const { return m_minimum; } + const char *maximum() const { return m_maximum; } + UINT32 seqid() const { return m_seqid; } + int type() const { return (m_flags & OPTION_TYPE_MASK); } + UINT32 flags() const { return m_flags; } + bool is_header() const { return type() == OPTION_HEADER; } + bool is_command() const { return type() == OPTION_COMMAND; } + bool has_range() const { return (m_minimum && m_maximum); } + + // setters + void set_value(const char *newvalue, int priority); + void set_default_value(const char *defvalue); + void revert(int priority); + + private: + // internal state + entry * m_next; // link to the next data + UINT32 m_flags; // flags from the entry + UINT32 m_seqid; // sequence ID; bumped on each change + bool m_error_reported; // have we reported an error on this option yet? + int m_priority; // priority of the data set + const char * m_description; // description for this item + astring m_name[4]; // up to 4 names for the item + astring m_data; // data for this item + astring m_defdata; // default data for this item + astring m_minimum; // minimum value + astring m_maximum; // maximum value + }; + + // construction/destruction + core_options(); + core_options(const options_entry *entrylist); + core_options(const options_entry *entrylist1, const options_entry *entrylist2); + core_options(const options_entry *entrylist1, const options_entry *entrylist2, const options_entry *entrylist3); + core_options(const core_options &src); + virtual ~core_options(); + + // operators + core_options &operator=(const core_options &rhs); + bool operator==(const core_options &rhs); + bool operator!=(const core_options &rhs); + + // getters + entry *first() const { return m_entrylist; } + const char *command() const { return m_command; } + + // configuration + void add_entries(const options_entry *entrylist, bool override_existing = false); + void set_default_value(const char *name, const char *defvalue); + void remove_entry(entry &delentry); + + // parsing/input + bool parse_command_line(int argc, char **argv, int priority, astring &error_string); + bool parse_ini_file(core_file &inifile, int priority, int ignore_priority, astring &error_string); + + // reverting + void revert(int priority = OPTION_PRIORITY_MAXIMUM); + + // output + const char *output_ini(astring &buffer, const core_options *diff = NULL); + const char *output_help(astring &buffer); + + // reading + const char *value(const char *option) const; + bool bool_value(const char *name) const { return (atoi(value(name)) != 0); } + int int_value(const char *name) const { return atoi(value(name)); } + float float_value(const char *name) const { return atof(value(name)); } + UINT32 seqid(const char *name) const; + bool exists(const char *name) const; + + // setting + void set_command(const char *command); + bool set_value(const char *name, const char *value, int priority, astring &error_string); + bool set_value(const char *name, int value, int priority, astring &error_string); + bool set_value(const char *name, float value, int priority, astring &error_string); + + // misc + static const char *unadorned(int x = 0) { return s_option_unadorned[MIN(x, MAX_UNADORNED_OPTIONS)]; } + +private: + // internal helpers + void reset(); + void append_entry(entry &newentry); + void copyfrom(const core_options &src); + bool validate_and_set_data(entry &curentry, const char *newdata, int priority, astring &error_string); + + // internal state + entry * m_entrylist; // head of list of entries + entry ** m_entrylist_tailptr; // pointer to tail of entry list + tagmap_t<entry *> m_entrymap; // map for fast lookup + astring m_command; // command found + static const char *const s_option_unadorned[]; // array of unadorned option "names" +}; + + + +#endif /* __OPTIONS_H__ */ |