1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
|
/***************************************************************************
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
const UINT32 OPTION_FLAG_INTERNAL = 0x40000000;
//**************************************************************************
// 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 is_internal() const { return m_flags & OPTION_FLAG_INTERNAL; }
bool has_range() const { return (m_minimum && m_maximum); }
int priority() const { return m_priority; }
// 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;
int priority(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)]; }
int options_count();
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__ */
|