annotate common/ini.cpp @ 28:9a907e58f978

Plugin ask: fix errors in documentation
author David Demelier <markand@malikania.fr>
date Mon, 22 Feb 2016 13:00:56 +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.cpp -- .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 #include <cassert>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
20 #include <cctype>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
21 #include <cstring>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
22 #include <iostream>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
23 #include <iterator>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
24 #include <fstream>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
25 #include <sstream>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
26 #include <stdexcept>
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
27
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
28 #if defined(_WIN32)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
29 # include <Shlwapi.h> // for PathIsRelative
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
30 #endif
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
31
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
32 #include "ini.h"
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
33
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
34 namespace {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
35
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
36 using namespace irccd;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
37 using namespace irccd::ini;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
38
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
39 using StreamIterator = std::istreambuf_iterator<char>;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
40 using TokenIterator = std::vector<Token>::const_iterator;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
41
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
42 inline bool isAbsolute(const std::string &path) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
43 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
44 #if defined(_WIN32)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
45 return !PathIsRelative(path.c_str());
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
46 #else
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
47 return path.size() > 0 && path[0] == '/';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
48 #endif
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
49 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
50
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
51 inline bool isQuote(char c) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
52 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
53 return c == '\'' || c == '"';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
54 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
55
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
56 inline bool isSpace(char c) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
57 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
58 /* Custom version because std::isspace includes \n as space */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
59 return c == ' ' || c == '\t';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
60 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
61
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
62 inline bool isList(char c) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
63 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
64 return c == '(' || c == ')' || c == ',';
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 inline bool isReserved(char c) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
68 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
69 return isList(c) || isQuote(c) || c == '[' || c == ']' || c == '@' || c == '#' || c == '=';
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
70 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
71
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
72 void analyzeLine(int &line, int &column, StreamIterator &it) 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 assert(*it == '\n');
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
75
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
76 ++ line;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
77 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
78 column = 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
79 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
80
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
81 void analyzeComment(int &column, StreamIterator &it, StreamIterator end) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
82 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
83 assert(*it == '#');
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
84
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
85 while (it != end && *it != '\n') {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
86 ++ column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
87 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
88 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
89 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
90
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
91 void analyzeSpaces(int &column, StreamIterator &it, StreamIterator end) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
92 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
93 assert(isSpace(*it));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
94
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
95 while (it != end && isSpace(*it)) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
96 ++ column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
97 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
98 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
99 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
100
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
101 void analyzeList(Tokens &list, int line, int &column, StreamIterator &it) noexcept
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
102 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
103 assert(isList(*it));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
104
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
105 switch (*it++) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
106 case '(':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
107 list.emplace_back(Token::ListBegin, line, column++);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
108 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
109 case ')':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
110 list.emplace_back(Token::ListEnd, line, column++);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
111 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
112 case ',':
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
113 list.emplace_back(Token::Comma, line, column++);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
114 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
115 default:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
116 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
117 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
118 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
119
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
120 void analyzeSection(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
121 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
122 assert(*it == '[');
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
123
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
124 std::string value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
125 int save = column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
126
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
127 /* Read section name */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
128 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
129 while (it != end && *it != ']') {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
130 if (*it == '\n')
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
131 throw Error(line, column, "section not terminated, missing ']'");
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
132 if (isReserved(*it))
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
133 throw Error(line, column, "section name expected after '[', got '" + std::string(1, *it) + "'");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
134 ++ column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
135 value += *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
136 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
137
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
138 if (it == end)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
139 throw Error(line, column, "section name expected after '[', got <EOF>");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
140
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
141 /* Remove ']' */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
142 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
143
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
144 list.emplace_back(Token::Section, line, save, std::move(value));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
145 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
146
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
147 void analyzeAssign(Tokens &list, int &line, int &column, StreamIterator &it)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
148 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
149 assert(*it == '=');
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
150
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
151 list.push_back({ Token::Assign, line, column++ });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
152 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
153 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
154
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
155 void analyzeQuotedWord(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
156 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
157 std::string value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
158 int save = column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
159 char quote = *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
160
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
161 while (it != end && *it != quote) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
162 // TODO: escape sequence
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
163 ++ column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
164 value += *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
165 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
166
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
167 if (it == end)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
168 throw Error(line, column, "undisclosed '" + std::string(1, quote) + "', got <EOF>");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
169
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
170 /* Remove quote */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
171 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
172
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
173 list.push_back({ Token::QuotedWord, line, save, std::move(value) });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
174 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
175
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
176 void analyzeWord(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
177 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
178 assert(!isReserved(*it));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
179
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
180 std::string value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
181 int save = column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
182
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
183 while (it != end && !std::isspace(*it) && !isReserved(*it)) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
184 ++ column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
185 value += *it++;
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 list.push_back({ Token::Word, line, save, std::move(value) });
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
189 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
190
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
191 void analyzeInclude(Tokens &list, int &line, int &column, StreamIterator &it, StreamIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
192 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
193 assert(*it == '@');
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
194
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
195 std::string include;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
196 int save = column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
197
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
198 /* Read include */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
199 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
200 while (it != end && !isSpace(*it)) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
201 ++ column;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
202 include += *it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
203 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
204
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
205 if (include != "include")
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
206 throw Error(line, column, "expected include after '@' token");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
207
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
208 list.push_back({ Token::Include, line, save });
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 Tokens analyze(StreamIterator &it, StreamIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
212 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
213 Tokens list;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
214 int line = 1;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
215 int column = 0;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
216
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
217 while (it != end) {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
218 if (*it == '\n')
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
219 analyzeLine(line, column, it);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
220 else if (*it == '#')
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
221 analyzeComment(column, it, end);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
222 else if (*it == '[')
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
223 analyzeSection(list, line, column, it, end);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
224 else if (*it == '=')
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
225 analyzeAssign(list, line, column, it);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
226 else if (isSpace(*it))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
227 analyzeSpaces(column, it, end);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
228 else if (*it == '@')
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
229 analyzeInclude(list, line, column, it, end);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
230 else if (isQuote(*it))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
231 analyzeQuotedWord(list, line, column, it, end);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
232 else if (isList(*it))
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
233 analyzeList(list, line, column, it);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
234 else
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
235 analyzeWord(list, line, column, it, end);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
236 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
237
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
238 return list;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
239 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
240
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
241 void parseOptionValueSimple(Option &option, TokenIterator &it)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
242 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
243 assert(it->type() == Token::Word || it->type() == Token::QuotedWord);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
244
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
245 option.push_back((it++)->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 void parseOptionValueList(Option &option, TokenIterator &it, TokenIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
249 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
250 assert(it->type() == Token::ListBegin);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
251
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
252 TokenIterator save = it++;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
253
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
254 while (it != end && it->type() != Token::ListEnd) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
255 switch (it->type()) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
256 case Token::Comma:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
257 /* Previous must be a word */
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
258 if (it[-1].type() != Token::Word && it[-1].type() != Token::QuotedWord)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
259 throw Error(it->line(), it->column(), "unexpected comma after '" + it[-1].value() + "'");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
260
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
261 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
262 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
263 case Token::Word:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
264 case Token::QuotedWord:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
265 option.push_back((it++)->value());
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
266 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
267 default:
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
268 throw Error(it->line(), it->column(), "unexpected '" + it[-1].value() + "' in list construct");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
269 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
270 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
271 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
272
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
273 if (it == end)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
274 throw Error(save->line(), save->column(), "unterminated list construct");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
275
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
276 /* Remove ) */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
277 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
278 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
279
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
280 void parseOption(Section &sc, TokenIterator &it, TokenIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
281 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
282 Option option(it->value());
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
283
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
284 TokenIterator save = it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
285
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
286 /* No '=' or something else? */
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
287 if (++it == end)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
288 throw Error(save->line(), save->column(), "expected '=' assignment, got <EOF>");
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
289 if (it->type() != Token::Assign)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
290 throw Error(it->line(), it->column(), "expected '=' assignment, got " + it->value());
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
291
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
292 /* Empty options are allowed so just test for words */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
293 if (++it != end) {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
294 if (it->type() == Token::Word || it->type() == Token::QuotedWord)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
295 parseOptionValueSimple(option, it);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
296 else if (it->type() == Token::ListBegin)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
297 parseOptionValueList(option, it, end);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
298 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
299
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
300 sc.push_back(std::move(option));
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 void parseInclude(Document &doc, TokenIterator &it, TokenIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
304 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
305 TokenIterator save = it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
306
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
307 if (++it == end)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
308 throw Error(save->line(), save->column(), "expected file name after '@include' statement, got <EOF>");
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
309 if (it->type() != Token::Word && it->type() != Token::QuotedWord)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
310 throw Error(it->line(), it->column(), "expected file name after '@include' statement, got " + it->value());
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
311 if (doc.path().empty())
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
312 throw Error(it->line(), it->column(), "'@include' statement invalid with buffer documents");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
313
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
314 std::string value = (it++)->value();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
315 std::string file;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
316
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
317 if (!isAbsolute(value)) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
318 #if defined(_WIN32)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
319 file = doc.path() + "\\" + value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
320 #else
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
321 file = doc.path() + "/" + value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
322 #endif
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
323 } else {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
324 file = value;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
325 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
326
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
327 Document child(File{file});
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
328
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
329 for (const auto &sc : child)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
330 doc.push_back(sc);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
331 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
332
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
333 void parseSection(Document &doc, TokenIterator &it, TokenIterator end)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
334 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
335 Section sc(it->value());
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
336
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
337 /* Skip [section] */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
338 ++ it;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
339
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
340 /* Read until next section */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
341 while (it != end && it->type() != Token::Section) {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
342 if (it->type() != Token::Word)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
343 throw Error(it->line(), it->column(), "unexpected token '" + it->value() + "' in section definition");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
344
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
345 parseOption(sc, it, end);
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 doc.push_back(std::move(sc));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
349 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
350
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
351 void parse(Document &doc, const Tokens &tokens)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
352 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
353 TokenIterator it = tokens.cbegin();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
354 TokenIterator end = tokens.cend();
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
355
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
356 while (it != end) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
357 /* Just ignore this */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
358 switch (it->type()) {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
359 case Token::Include:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
360 parseInclude(doc, it, end);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
361 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
362 case Token::Section:
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
363 parseSection(doc, it, end);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
364 break;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
365 default:
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
366 throw Error(it->line(), it->column(), "unexpected '" + it->value() + "' on root document");
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
367 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
368 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
369 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
370
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
371 } // !namespace
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
372
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
373 namespace irccd {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
374
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
375 namespace ini {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
376
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
377 Tokens Document::analyze(const File &file)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
378 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
379 std::fstream stream(file.path);
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
380
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
381 if (!stream)
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
382 throw std::runtime_error(std::strerror(errno));
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
383
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
384 std::istreambuf_iterator<char> it(stream);
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
385 std::istreambuf_iterator<char> end;
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
386
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
387 return ::analyze(it, end);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
388 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
389
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
390 Tokens Document::analyze(const Buffer &buffer)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
391 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
392 std::istringstream stream(buffer.text);
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
393 std::istreambuf_iterator<char> it(stream);
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
394 std::istreambuf_iterator<char> end;
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
395
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
396 return ::analyze(it, end);
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
397 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
398
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
399 Document::Document(const File &file)
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
400 : m_path(file.path)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
401 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
402 /* Update path */
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
403 auto pos = m_path.find_last_of("/\\");
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
404
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
405 if (pos != std::string::npos)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
406 m_path.erase(pos);
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
407 else
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
408 m_path = ".";
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
409
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
410 parse(*this, analyze(file));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
411 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
412
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
413 Document::Document(const Buffer &buffer)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
414 {
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
415 parse(*this, analyze(buffer));
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
416 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
417
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
418 void Document::dump(const Tokens &tokens)
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
419 {
23
03068f5ed79d Misc: various style issues, #419
David Demelier <markand@malikania.fr>
parents: 0
diff changeset
420 for (const Token &token: tokens)
0
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
421 // TODO: add better description
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
422 std::cout << token.line() << ":" << token.column() << ": " << token.value() << std::endl;
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
423 }
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
424
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
425 } // !ini
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
426
1158cffe5a5e Initial import
David Demelier <markand@malikania.fr>
parents:
diff changeset
427 } // !irccd