1 /*
2 * cArgSchema.h
3 * Avida
4 *
5 * Created by David Bryson on 9/12/06.
6 * Copyright 1999-2011 Michigan State University. All rights reserved.
7 *
8 *
9 * This file is part of Avida.
10 *
11 * Avida is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
12 * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
13 *
14 * Avida is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License along with Avida.
18 * If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22 #ifndef cArgSchema_h
23 #define cArgSchema_h
24
25 #ifndef tDictionary_h
26 #include "tDictionary.h"
27 #endif
28
29
30 class cArgSchema
31 {
32 public:
33 enum tType { SCHEMA_INT, SCHEMA_DOUBLE, SCHEMA_STRING };
34
35 private:
36 struct sArgSchemaEntry
37 {
38 cString name;
39 tType type;
40 int index;
41 bool optional;
42 union {
43 int def_int;
44 double def_double;
45 cString* def_string;
46 };
47 bool has_range_limits;
48 union {
49 int r_l_int;
50 double r_l_double;
51 };
52 union {
53 int r_u_int;
54 double r_u_double;
55 };
56
57
sArgSchemaEntrysArgSchemaEntry58 sArgSchemaEntry() { ; }
sArgSchemaEntrysArgSchemaEntry59 sArgSchemaEntry(const cString& in_name, int in_idx, tType in_type) // Required Argument (supplied type)
60 : name(in_name), type(in_type), index(in_idx), optional(false), has_range_limits(false) { ; }
sArgSchemaEntrysArgSchemaEntry61 sArgSchemaEntry(const cString& in_name, int in_idx, int def) // Optional Int Argument
62 : name(in_name), type(SCHEMA_INT), index(in_idx), optional(true), def_int(def), has_range_limits(false) { ; }
sArgSchemaEntrysArgSchemaEntry63 sArgSchemaEntry(const cString& in_name, int in_idx, double def) // Optional Double Argument
64 : name(in_name), type(SCHEMA_DOUBLE), index(in_idx), optional(true), def_double(def), has_range_limits(false) { ; }
sArgSchemaEntrysArgSchemaEntry65 sArgSchemaEntry(const cString& in_name, int in_idx, cString* def) // Optional String Argument
66 : name(in_name), type(SCHEMA_STRING), index(in_idx), optional(true), def_string(def), has_range_limits(false) { ; }
~sArgSchemaEntrysArgSchemaEntry67 ~sArgSchemaEntry() { if (type == SCHEMA_STRING && optional) delete def_string; } // Cleanup string object
68 };
69
70
71 tDictionary<sArgSchemaEntry*> m_entries;
72 tArray<sArgSchemaEntry*> m_ints;
73 tArray<sArgSchemaEntry*> m_doubles;
74 tArray<sArgSchemaEntry*> m_strings;
75
76 char m_sep_entry;
77 char m_sep_value;
78
79 bool m_case_sensitive;
80
81
82 public:
83 cArgSchema(char entry = ',', char value = '=', bool case_sensitive = false)
m_sep_entry(entry)84 : m_sep_entry(entry), m_sep_value(value), m_case_sensitive(case_sensitive) { ; }
85 ~cArgSchema();
86
87 inline void AdjustArgName(cString& in_name) const;
88
GetEntrySeparator()89 char GetEntrySeparator() const { return m_sep_entry; }
GetValueSeparator()90 char GetValueSeparator() const { return m_sep_value; }
IsCaseSensitive()91 bool IsCaseSensitive() const { return m_case_sensitive; }
92
93 bool AddEntry(cString in_name, int in_idx, tType in_type); // Required Argument (supplied type)
94 bool AddEntry(cString in_name, int in_idx, int def); // Optional Int Argument
95 bool AddEntry(cString in_name, int in_idx, int lower, int upper); // Required Int Argument (with range limits)
96 bool AddEntry(cString in_name, int in_idx, int lower, int upper, int def); // Optional Int Argument (with range limits)
97 bool AddEntry(cString in_name, int in_idx, double def); // Optional Double Argument
98 bool AddEntry(cString in_name, int in_idx, double lower, double upper); // Required Double Argument (with range limits)
99 bool AddEntry(cString in_name, int in_idx, double lower, double upper, double def); // Optional Double (with range limits)
100 bool AddEntry(cString in_name, int in_idx, const cString& def); // Optional String Argument
101
102 bool FindEntry(const cString& in_name, tType& ret_type, int& ret_idx) const;
103
GetNumIntArgs()104 inline int GetNumIntArgs() const { return m_ints.GetSize(); }
GetNumDoubleArgs()105 inline int GetNumDoubleArgs() const { return m_doubles.GetSize(); }
GetNumStringArgs()106 inline int GetNumStringArgs() const { return m_strings.GetSize(); }
107
108 inline bool IsOptionalInt(int i) const;
109 inline bool IsOptionalDouble(int i) const;
110 inline bool IsOptionalString(int i) const;
111
112 inline void SetDefaultInt(int i, int& v) const;
113 inline void SetDefaultDouble(int i, double& v) const;
114 inline void SetDefaultString(int i, cString& v) const;
115
116 inline bool GetIntName(int i, cString& name) const;
117 inline bool GetDoubleName(int i, cString& name) const;
118 inline bool GetStringName(int i, cString& name) const;
119
120 inline bool ValidateInt(int i, int v) const;
121 inline bool ValidateDouble(int i, double v) const;
122 };
123
124
AdjustArgName(cString & in_name)125 inline void cArgSchema::AdjustArgName(cString& in_name) const
126 {
127 in_name.Trim();
128 if (!m_case_sensitive) in_name.ToLower();
129 }
130
131
SetDefaultInt(int i,int & v)132 inline void cArgSchema::SetDefaultInt(int i, int& v) const
133 {
134 if (IsOptionalInt(i)) v = m_ints[i]->def_int;
135 }
136
SetDefaultDouble(int i,double & v)137 inline void cArgSchema::SetDefaultDouble(int i, double& v) const
138 {
139 if (IsOptionalDouble(i)) v = m_doubles[i]->def_double;
140 }
141
SetDefaultString(int i,cString & v)142 inline void cArgSchema::SetDefaultString(int i, cString& v) const
143 {
144 if (IsOptionalString(i)) v = *m_strings[i]->def_string;
145 }
146
147
IsOptionalInt(int i)148 inline bool cArgSchema::IsOptionalInt(int i) const
149 {
150 if (i < m_ints.GetSize() && m_ints[i]) return m_ints[i]->optional;
151 return false;
152 }
153
IsOptionalDouble(int i)154 inline bool cArgSchema::IsOptionalDouble(int i) const
155 {
156 if (i < m_doubles.GetSize() && m_doubles[i]) return m_doubles[i]->optional;
157 return false;
158 }
159
IsOptionalString(int i)160 inline bool cArgSchema::IsOptionalString(int i) const
161 {
162 if (i < m_strings.GetSize() && m_strings[i]) return m_strings[i]->optional;
163 return false;
164 }
165
166
GetIntName(int i,cString & name)167 inline bool cArgSchema::GetIntName(int i, cString& name) const
168 {
169 if (i < m_ints.GetSize() && m_ints[i]) {
170 name = m_ints[i]->name;
171 return true;
172 }
173 return false;
174 }
175
GetDoubleName(int i,cString & name)176 inline bool cArgSchema::GetDoubleName(int i, cString& name) const
177 {
178 if (i < m_doubles.GetSize() && m_doubles[i]) {
179 name = m_doubles[i]->name;
180 return true;
181 }
182 return false;
183 }
184
GetStringName(int i,cString & name)185 inline bool cArgSchema::GetStringName(int i, cString& name) const
186 {
187 if (i < m_strings.GetSize() && m_strings[i]) {
188 name = m_strings[i]->name;
189 return true;
190 }
191 return false;
192 }
193
ValidateInt(int i,int v)194 inline bool cArgSchema::ValidateInt(int i, int v) const
195 {
196 if (i < m_ints.GetSize() && m_ints[i] &&
197 (!m_ints[i]->has_range_limits || (v <= m_ints[i]->r_u_int && v >= m_ints[i]->r_l_int))) {
198 return true;
199 }
200
201 return false;
202 }
203
ValidateDouble(int i,double v)204 inline bool cArgSchema::ValidateDouble(int i, double v) const
205 {
206 if (i < m_doubles.GetSize() && m_doubles[i] &&
207 (!m_doubles[i]->has_range_limits || (v <= m_doubles[i]->r_u_double && v >= m_doubles[i]->r_l_double))) {
208 return true;
209 }
210
211 return false;
212 }
213
214
215 #endif
216