Mercurial > code
annotate C++/Parser.h @ 196:274b4f216e65
DynLib: Windows support complete
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 28 Nov 2013 20:03:07 +0100 |
parents | 600754c27c88 |
children | 1ffe6d4937b7 |
rev | line source |
---|---|
179 | 1 /* |
2 * Parser.h -- config file parser | |
3 * | |
4 * Copyright (c) 2011, 2012, 2013 David Demelier <markand@malikania.fr> | |
5 * | |
6 * Permission to use, copy, modify, and/or distribute this software for any | |
7 * purpose with or without fee is hereby granted, provided that the above | |
8 * copyright notice and this permission notice appear in all copies. | |
9 * | |
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
17 */ | |
18 | |
19 #ifndef _PARSER_H_ | |
20 #define _PARSER_H_ | |
21 | |
22 #include <cstdlib> | |
23 #include <exception> | |
180 | 24 #include <functional> |
179 | 25 #include <iostream> |
26 #include <string> | |
27 #include <vector> | |
28 | |
29 /** | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
30 * @class NotFoundException |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
31 * @brief Exception raised when a section or option is not found |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
32 * |
179 | 33 * Thrown when a section or an option is not found. |
34 */ | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
35 class NotFoundException : public std::exception { |
179 | 36 private: |
37 std::string m_key; | |
38 | |
39 public: | |
40 NotFoundException(const std::string &key) | |
180 | 41 : m_key(key) |
179 | 42 { |
43 } | |
44 | |
45 const std::string & which() const | |
46 { | |
47 return m_key; | |
48 } | |
49 | |
50 virtual const char *what() const throw() | |
51 { | |
52 return "Property not found"; | |
53 } | |
54 }; | |
55 | |
56 /** | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
57 * @struct Option |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
58 * @brief A key-value pair |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
59 * |
179 | 60 * An option referenced by a key and a value. |
61 */ | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
62 struct Option { |
179 | 63 std::string m_key; /*! option name */ |
64 std::string m_value; /*! option value */ | |
65 }; | |
66 | |
67 bool operator==(const Option &o1, const Option &o2); | |
68 | |
69 /** | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
70 * @class Section |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
71 * @brief The option container |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
72 * |
179 | 73 * A list of section found in the file. If root |
74 * options are allowed (default behavior), the root | |
75 * section is "". | |
76 */ | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
77 class Section { |
180 | 78 private: |
79 const std::string findOption(const std::string &name) const; | |
80 | |
81 public: | |
179 | 82 std::string m_name; /*! name of section */ |
83 std::vector<Option> m_options; /*! list of options inside */ | |
84 bool m_allowed; /*! is authorized to push */ | |
85 | |
180 | 86 /** |
87 * Default constructor. | |
88 */ | |
179 | 89 Section(); |
90 | |
91 /** | |
92 * Get the section name | |
93 * | |
94 * @return the section name | |
95 */ | |
180 | 96 const std::string &getName() const; |
179 | 97 |
98 /** | |
99 * Get all options from that section. | |
100 * | |
101 * @return the list of options | |
102 */ | |
180 | 103 const std::vector<Option> &getOptions() const; |
179 | 104 |
105 /** | |
106 * Tells if that section has the specified option name. | |
107 * | |
108 * @param name the option name | |
109 * @return true if has | |
110 */ | |
111 bool hasOption(const std::string &name) const; | |
112 | |
113 /** | |
114 * Template all functions for retrieving options value. | |
115 * | |
116 * @param name the option name | |
117 * @return the value if found | |
118 */ | |
119 template <typename T> | |
180 | 120 T getValue(const std::string &name) const; |
179 | 121 |
122 /** | |
123 * Requires an option, this works like getOption except | |
124 * that if an option is not found, an exception is | |
125 * thrown. | |
126 * | |
127 * @param name the name | |
180 | 128 * @return the value |
179 | 129 * @throw NotFoundException if not found |
130 */ | |
131 template <typename T> | |
180 | 132 T requireValue(const std::string &name) const |
179 | 133 { |
134 if (!hasOption(name)) | |
135 throw NotFoundException(name); | |
136 | |
180 | 137 return getValue<T>(name); |
179 | 138 } |
139 | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
140 friend std::ostream &operator<<(std::ostream & stream, const Section §ion) |
179 | 141 { |
142 stream << "[" << section.getName() << "]" << std::endl; | |
143 | |
144 for (auto p : section.getOptions()) | |
145 stream << p.m_key << "=" << p.m_value << std::endl; | |
146 | |
147 return stream; | |
148 } | |
149 }; | |
150 | |
151 bool operator==(const Section &s1, const Section &s2); | |
152 | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
153 /** |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
154 * @class Parser |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
155 * @brief Config file parser |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
156 * |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
157 * Open and read .ini files. |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
158 */ |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
159 class Parser { |
179 | 160 public: |
161 /** | |
162 * Options available for the parser. | |
163 */ | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
164 enum Tuning { |
179 | 165 DisableRootSection = 1, /*! disable options on root */ |
166 DisableRedefinition = 2, /*! disable multiple redefinition */ | |
167 DisableVerbosity = 4 /*! be verbose by method */ | |
168 }; | |
169 | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
170 using FindFunc = std::function<void (const Section &)>; |
180 | 171 |
179 | 172 private: |
173 std::vector<Section> m_sections; /*! list of sections found */ | |
174 std::string m_error; /*! if an error occured */ | |
175 std::string m_path; /*! path file */ | |
176 int m_tuning; /*! options for parsing */ | |
177 char m_commentChar; /*! the comment token default (#) */ | |
178 | |
179 void addSection(const std::string &name); | |
180 void addOption(const std::string &key, const std::string &value); | |
181 | |
182 void readSection(int lineno, const std::string &line); | |
183 void readOption(int lineno, const std::string &line); | |
184 | |
185 void readLine(int lineno, const std::string &line); | |
186 | |
187 public: | |
188 static const char DEFAULT_COMMENT_CHAR; | |
189 | |
190 /** | |
191 * Create a parser at the specified file path. Optional | |
192 * options may be added. | |
193 * | |
194 * @param path the file path | |
195 * @param tuning optional tuning flags | |
196 * @param commentToken an optional comment delimiter | |
197 * @see Tuning | |
198 */ | |
199 Parser(const std::string &path, int tuning = 0, char commentToken = Parser::DEFAULT_COMMENT_CHAR); | |
200 | |
201 /** | |
202 * Default constructor. | |
203 */ | |
204 Parser(); | |
205 | |
206 /** | |
207 * Default destructor. | |
208 */ | |
209 virtual ~Parser(); | |
210 | |
211 /** | |
212 * Open the config file. | |
213 * | |
214 * @return true on success | |
215 */ | |
216 bool open(); | |
217 | |
218 /** | |
219 * Get the error message if any | |
220 * | |
221 * @return the error message | |
222 */ | |
180 | 223 const std::string &getError() const; |
179 | 224 |
225 /** | |
226 * Get all sections found | |
227 * | |
228 * @return all sections | |
229 */ | |
180 | 230 const std::vector<Section> &getSections() const; |
179 | 231 |
232 /** | |
180 | 233 * Find all sections matching the name. |
179 | 234 * |
235 * @param name the sections name | |
180 | 236 * @param func the function |
179 | 237 * @return a list of section with the options |
238 */ | |
180 | 239 void findSections(const std::string &name, FindFunc func) const; |
179 | 240 |
241 /** | |
242 * Tell if a section is existing. | |
243 * | |
244 * @return true if exists | |
245 */ | |
246 bool hasSection(const std::string &name) const; | |
247 | |
248 /** | |
249 * Get a specified section. | |
250 * | |
251 * @param name the section name | |
252 * @return a section | |
180 | 253 * @throw NotFoundException if not found |
179 | 254 */ |
180 | 255 const Section &getSection(const std::string &name) const; |
179 | 256 |
257 /** | |
258 * Logging function, used only if DisableVerbosity is not set. The | |
259 * default behavior is to print to stdout something like: | |
260 * line 10: syntax error | |
261 * line 8: missing = | |
262 * | |
263 * @param number the line number | |
264 * @param section the current section worked on | |
265 * @param message the message | |
266 */ | |
267 virtual void log(int number, const std::string §ion, const std::string &message); | |
268 | |
269 /** | |
270 * Dump all sections and options. | |
271 */ | |
272 void dump(); | |
273 | |
274 /** | |
275 * Dump function used in the dump() method. This default method | |
276 * only print the section name like: | |
277 * Section foo | |
278 * | |
279 * @param section the current section | |
280 * @see dump | |
281 */ | |
282 virtual void dumpSection(const Section §ion); | |
283 | |
284 /** | |
285 * Dump the option. The default method only print the option name | |
286 * and value. | |
287 * | |
288 * @param option the current option | |
289 * @see dump | |
290 */ | |
291 virtual void dumpOption(const Option &option); | |
292 | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
293 /** |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
294 * Write the configuration to the output stream. |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
295 * |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
296 * @param stream the output |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
297 * @param parser the configuration |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
298 * @return the stream |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
299 */ |
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
300 friend std::ostream &operator<<(std::ostream &stream, const Parser &parser) |
179 | 301 { |
302 for (auto s : parser.m_sections) | |
187
600754c27c88
Update parser to style and remove useless stuff
David Demelier <markand@malikania.fr>
parents:
180
diff
changeset
|
303 stream << s; |
179 | 304 |
305 return stream; | |
306 } | |
307 }; | |
308 | |
309 #endif // !_PARSER_H_ |