annotate common/ini.h @ 60:223487a685b1 release-2.0

Added tag 2.0.0 for changeset 92b0be5ce4b0
author David Demelier <markand@malikania.fr>
date Tue, 01 Mar 2016 08:53:05 +0100
parents 03068f5ed79d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
1 /*
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
2 * ini.h -- .ini file parsing
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
3 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
4 * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
5 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
6 * Permission to use, copy, modify, and/or distribute this software for any
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
7 * purpose with or without fee is hereby granted, provided that the above
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
8 * copyright notice and this permission notice appear in all copies.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
9 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
17 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
18
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
19 #ifndef _INI_H_
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #define _INI_H_
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
21
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 * @file Ini.h
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 * @brief Configuration file parser.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
26
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
27 #include <algorithm>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 #include <exception>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 #include <stdexcept>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 #include <string>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
31 #include <vector>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
32
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
33 namespace irccd {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
34
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
35 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 * Namespace for ini related classes.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
38 namespace ini {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
39
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 class Document;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
41
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 * @class Error
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 * @brief Error in a file
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 class Error : public std::exception {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 private:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 int m_line; //!< line number
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 int m_column; //!< line column
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
50 std::string m_message; //!< error message
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
51
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 * Constructor.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
55 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 * @param l the line
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 * @param c the column
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 * @param m the message
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 inline Error(int l, int c, std::string m) noexcept
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
61 : m_line(l)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
62 , m_column(c)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
63 , m_message(std::move(m))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
65 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
66
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
67 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 * Get the line number.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 * @return the line
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
71 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 inline int line() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
73 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
74 return m_line;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
75 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
76
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 * Get the column number.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
80 * @return the column
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 inline int column() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
84 return m_column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
86
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 * Return the raw error message (no line and column shown).
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
90 * @return the error message
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 const char *what() const noexcept override
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
94 return m_message.c_str();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
97
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 * @class Token
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
100 * @brief Describe a token read in the .ini source
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 * This class can be used when you want to parse a .ini file yourself.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
104 * @see Document::analyze
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 class Token {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 * @brief Token type
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 enum Type {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 Include, //!< include statement
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 Section, //!< [section]
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 Word, //!< word without quotes
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 QuotedWord, //!< word with quotes
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 Assign, //!< = assignment
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 ListBegin, //!< begin of list (
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 ListEnd, //!< end of list )
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
119 Comma //!< list separation
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
121
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 private:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
123 Type m_type;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 int m_line;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 int m_column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
126 std::string m_value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
127
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
130 * Construct a token.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
131 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
132 * @param type the type
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
133 * @param line the line
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 * @param column the column
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 * @param value the value
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
137 Token(Type type, int line, int column, std::string value = "") noexcept
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
138 : m_type(type)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
139 , m_line(line)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
140 , m_column(column)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 switch (type) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
143 case Include:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 m_value = "@include";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
146 case Section:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 case Word:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 case QuotedWord:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 m_value = value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
150 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 case Assign:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 m_value = "=";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
154 case ListBegin:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 m_value = "(";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 case ListEnd:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 m_value = ")";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
160 case Comma:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 m_value = ",";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
166 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
167
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
168 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
169 * Get the type.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 * @return the type
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
172 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 inline Type type() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
175 return m_type;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
177
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
179 * Get the line.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 * @return the line
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
182 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 inline int line() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 return m_line;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
186 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
187
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
188 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 * Get the column.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
190 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 * @return the column
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 inline int column() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
194 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 return m_column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
197
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 * Get the value. For words, quoted words and section, the value is the content. Otherwise it's the
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 * characters parsed.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 * @return the value
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
204 inline const std::string &value() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
205 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
206 return m_value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
207 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
209
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
210 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
211 * List of tokens in order they are analyzed.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 using Tokens = std::vector<Token>;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
214
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
216 * @class Option
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 * @brief Option definition.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
218 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 class Option : public std::vector<std::string> {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
220 private:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 std::string m_key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
222
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
224 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 * Construct an empty option.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
226 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
228 * @param value the value
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
230 inline Option(std::string key) noexcept
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
231 : std::vector<std::string>()
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
232 , m_key(std::move(key))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
234 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
235
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
237 * Construct a single option.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
240 * @param value the value
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 inline Option(std::string key, std::string value) noexcept
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
243 : m_key(std::move(key))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
244 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 push_back(std::move(value));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
246 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
247
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
248 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 * Construct a list option.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
251 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 * @param values the values
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
253 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 inline Option(std::string key, std::vector<std::string> values) noexcept
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
255 : std::vector<std::string>(std::move(values))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
256 , m_key(std::move(key))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
258 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
259
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
260 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 * Get the option key.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 * @return the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 inline const std::string &key() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 return m_key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
268 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
269
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 * Get the option value.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
272 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
273 * @return the value
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
274 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
275 inline const std::string &value() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 static std::string dummy;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
278
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
279 return empty() ? dummy : (*this)[0];
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
282
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 * @class Section
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
285 * @brief Section that contains one or more options.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
287 class Section : public std::vector<Option> {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
288 private:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
289 std::string m_key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
290
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
291 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 * Construct a section with its name.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
294 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
296 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
297 inline Section(std::string key) noexcept
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
298 : m_key(std::move(key))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
299 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
301
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
302 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
303 * Get the section key.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 * @return the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
306 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
307 inline const std::string &key() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
308 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
309 return m_key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
310 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
311
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
312 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
313 * Check if the section contains a specific option.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 * @param key the option key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
316 * @return true if the option exists
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 inline bool contains(const std::string &key) const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 return find(key) != end();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
322
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 * Access an option at the specified key.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
326 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
327 * @return the option
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
328 * @throw std::out_of_range if the key does not exist
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
329 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 inline Option &operator[](const std::string &key)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
331 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
332 return *find(key);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
334
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
335 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
336 * Access an option at the specified key.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
339 * @return the option
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 * @throw std::out_of_range if the key does not exist
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
341 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
342 inline const Option &operator[](const std::string &key) const
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
343 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
344 return *find(key);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
346
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
347 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
348 * Find an option by key and return an iterator.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
349 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
350 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
351 * @return the iterator or end() if not found
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 inline iterator find(const std::string &key) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
354 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
355 return std::find_if(begin(), end(), [&] (const auto &o) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
356 return o.key() == key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
358 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
359
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
360 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
361 * Find an option by key and return an iterator.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
362 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
363 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
364 * @return the iterator or end() if not found
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
365 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
366 inline const_iterator find(const std::string &key) const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
367 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
368 return std::find_if(cbegin(), cend(), [&] (const auto &o) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
369 return o.key() == key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
370 });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
371 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
372
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
373 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
374 * Inherited operators.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
375 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
376 using std::vector<Option>::operator[];
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
377 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
378
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
379 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
380 * @class File
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
381 * @brief Source for reading .ini files.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
382 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
383 class File {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
384 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
385 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
386 * Path to the file.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
387 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
388 std::string path;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
389 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
390
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
391 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
392 * @class Buffer
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
393 * @brief Source for reading ini from text.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
394 * @note the include statement is not supported with buffers.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
395 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
396 class Buffer {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
397 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
398 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
399 * The ini content.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
400 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
401 std::string text;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
402 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
403
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
404 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
405 * @class Document
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
406 * @brief Ini config file loader
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
407 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
408 class Document : public std::vector<Section> {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
409 private:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
410 std::string m_path;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
411
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
412 public:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
413 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
414 * Analyze a file and extract tokens. If the function succeeds, that does not mean the content is valid,
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
415 * it just means that there are no syntax error.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
416 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
417 * For example, this class does not allow adding options under no sections and this function will not
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
418 * detect that issue.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
419 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
420 * @param file the file to read
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
421 * @return the list of tokens
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
422 * @throws Error on errors
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
423 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
424 static Tokens analyze(const File &file);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
425
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
426 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
427 * Overloaded function for buffers.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
428 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
429 * @param buffer the buffer to read
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
430 * @return the list of tokens
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
431 * @throws Error on errors
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
432 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
433 static Tokens analyze(const Buffer &buffer);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
434
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
435 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
436 * Show all tokens and their description.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
437 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
438 * @param tokens the tokens
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
439 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
440 static void dump(const Tokens &tokens);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
441
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
442 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
443 * Construct a document from a file.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
444 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
445 * @param file the file to read
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
446 * @throws Error on errors
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
447 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
448 Document(const File &file);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
449
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
450 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
451 * Overloaded constructor for buffers.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
452 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
453 * @param buffer the buffer to read
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
454 * @throws Error on errors
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
455 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
456 Document(const Buffer &buffer);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
457
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
458 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
459 * Get the current document path, only useful when constructed from File source.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
460 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
461 * @return the path
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
462 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
463 inline const std::string &path() const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
464 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
465 return m_path;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
466 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
467
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
468 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
469 * Check if a document has a specific section.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
470 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
471 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
472 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
473 inline bool contains(const std::string &key) const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
474 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
475 return std::find_if(begin(), end(), [&] (const auto &sc) { return sc.key() == key; }) != end();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
476 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
477
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
478 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
479 * Access a section at the specified key.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
480 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
481 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
482 * @return the section
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
483 * @throw std::out_of_range if the key does not exist
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
484 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
485 inline Section &operator[](const std::string &key)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
486 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
487 return *find(key);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
488 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
489
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
490 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
491 * Access a section at the specified key.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
492 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
493 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
494 * @return the section
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
495 * @throw std::out_of_range if the key does not exist
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
496 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
497 inline const Section &operator[](const std::string &key) const
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
498 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
499 return *find(key);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
500 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
501
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
502 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
503 * Find a section by key and return an iterator.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
504 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
505 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
506 * @return the iterator or end() if not found
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
507 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
508 inline iterator find(const std::string &key) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
509 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
510 return std::find_if(begin(), end(), [&] (const auto &o) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
511 return o.key() == key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
512 });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
513 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
514
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
515 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
516 * Find a section by key and return an iterator.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
517 *
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
518 * @param key the key
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
519 * @return the iterator or end() if not found
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
520 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
521 inline const_iterator find(const std::string &key) const noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
522 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
523 return std::find_if(cbegin(), cend(), [&] (const auto &o) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
524 return o.key() == key;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
525 });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
526 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
527
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
528 /**
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
529 * Inherited operators.
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
530 */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
531 using std::vector<Section>::operator[];
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
532 };
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
533
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
534 } // !ini
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
535
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
536 } // !irccd
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
537
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
538 #endif // !_INI_H_