equal
deleted
inserted
replaced
40 * Related specifications: |
40 * Related specifications: |
41 * - https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Properties.html |
41 * - https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Properties.html |
42 */ |
42 */ |
43 bool trimLeadingSpacesOnContinuingLines = true; |
43 bool trimLeadingSpacesOnContinuingLines = true; |
44 |
44 |
|
45 |
|
46 /** |
|
47 * Some dialects or configuration files in general does not support sections. |
|
48 * Then a line, that looks like an INI section, should be interpreted as a key |
|
49 * (or error, if does not have a proper key-value separator). |
|
50 */ |
|
51 bool allowSections = true; |
|
52 |
45 /** |
53 /** |
46 * KDE uses some weird INI dialect that allows [section][x] syntax where „x“ is kind of „tag“ that signalizes some properties of given section. |
54 * KDE uses some weird INI dialect that allows [section][x] syntax where „x“ is kind of „tag“ that signalizes some properties of given section. |
47 * Line „[section_1][$i]“ means that the „section_1“ is „locked“. |
55 * Line „[section_1][$i]“ means that the „section_1“ is „locked“. |
48 * We may emit this information somehow later, but for now, it is just ignored. |
56 * We may emit this information somehow later, but for now, it is just ignored. |
49 * |
57 * |
237 void setDialect(const std::string& name) { |
245 void setDialect(const std::string& name) { |
238 if (name == "default-ini") { |
246 if (name == "default-ini") { |
239 // already set |
247 // already set |
240 } else if (name == "java-properties") { |
248 } else if (name == "java-properties") { |
241 trimLeadingSpacesOnContinuingLines = true; |
249 trimLeadingSpacesOnContinuingLines = true; |
|
250 allowSections = false; |
242 allowSectionTags = false; |
251 allowSectionTags = false; |
243 allowSubKeys = false; |
252 allowSubKeys = false; |
244 commentSeparators = "#"; |
253 commentSeparators = "#"; |
245 keyValueSeparators = "=:"; |
254 keyValueSeparators = "=:"; |
246 quotes = ""; |
255 quotes = ""; |
247 // TODO: allowSections = false; |
|
248 // TODO: enable unicode unescaping |
256 // TODO: enable unicode unescaping |
249 } else { |
257 } else { |
250 throw std::invalid_argument(std::string("Unsupported INI dialect: ") + name); |
258 throw std::invalid_argument(std::string("Unsupported INI dialect: ") + name); |
251 } |
259 } |
252 } |
260 } |
256 INIReaderImpl(std::istream& input) : input(input) { |
264 INIReaderImpl(std::istream& input) : input(input) { |
257 } |
265 } |
258 |
266 |
259 void setOption(const std::string& uri, const std::string& value) override { |
267 void setOption(const std::string& uri, const std::string& value) override { |
260 if (uri == "trim-continuing-lines") trimLeadingSpacesOnContinuingLines = parseBoolean(value); // TODO: continuing lines modes (enum), not just boolean |
268 if (uri == "trim-continuing-lines") trimLeadingSpacesOnContinuingLines = parseBoolean(value); // TODO: continuing lines modes (enum), not just boolean |
261 // TODO: else if (uri == "allow-sections") allowSections = parseBoolean(value); |
269 else if (uri == "allow-sections") allowSections = parseBoolean(value); |
262 else if (uri == "allow-section-tags") allowSectionTags = parseBoolean(value); |
270 else if (uri == "allow-section-tags") allowSectionTags = parseBoolean(value); |
263 else if (uri == "allow-sub-keys") allowSubKeys = parseBoolean(value); |
271 else if (uri == "allow-sub-keys") allowSubKeys = parseBoolean(value); |
264 else if (uri == "comment-separators") commentSeparators = value; |
272 else if (uri == "comment-separators") commentSeparators = value; |
265 else if (uri == "key-value-separators") keyValueSeparators = value; |
273 else if (uri == "key-value-separators") keyValueSeparators = value; |
266 else if (uri == "quotes") quotes = value; |
274 else if (uri == "quotes") quotes = value; |
294 |
302 |
295 char ch = peek(); |
303 char ch = peek(); |
296 |
304 |
297 if (ch == std::istream::traits_type::eof()) { |
305 if (ch == std::istream::traits_type::eof()) { |
298 break; |
306 break; |
299 } else if (ch == '[') { |
307 } else if (ch == '[' && allowSections) { |
300 if (inSection) for (INIContentHandler* handler : handlers) handler->endSection(); |
308 if (inSection) for (INIContentHandler* handler : handlers) handler->endSection(); |
301 inSection = true; |
309 inSection = true; |
302 INIContentHandler::SectionStartEvent event; |
310 INIContentHandler::SectionStartEvent event; |
303 event.lineNumber = lineNumber; |
311 event.lineNumber = lineNumber; |
304 event.eventNumber = ++eventNumber; |
312 event.eventNumber = ++eventNumber; |
305 get(); |
313 get(); |
306 readAllWhitespace(); |
314 readAllWhitespace(); |
307 event.name = readTokenAndEatTerminator(']', "e, &found); |
315 event.name = readTokenAndEatTerminator(']', "e, &found); |
|
316 // TODO: if (!quote) event.name = trim(event.name); |
308 |
317 |
309 readSpacesAndTabs(); |
318 readSpacesAndTabs(); |
310 if (allowSectionTags && peek() == '[') { |
319 if (allowSectionTags && peek() == '[') { |
311 get(); |
320 get(); |
312 event.tag = readTokenAndEatTerminator(']', "e, &found); |
321 event.tag = readTokenAndEatTerminator(']', "e, &found); |