src/lib/INIReader.cpp
author František Kučera <franta-hg@frantovo.cz>
Wed, 25 Nov 2020 21:50:26 +0100
branchv_0
changeset 26 80e129ec3408
parent 25 ee70b17950bd
child 28 0e7c57d48d1e
permissions -rw-r--r--
new INI parser
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     1
/**
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     2
 * Relational pipes
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     3
 * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info)
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     4
 *
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     7
 * the Free Software Foundation, version 3 of the License.
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     8
 *
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful,
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    12
 * GNU General Public License for more details.
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    13
 *
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    16
 */
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    17
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    18
#include <vector>
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    19
#include <regex>
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    20
#include <sstream>
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    21
#include <stdexcept>
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    22
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    23
#include "INIReader.h"
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    24
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    25
namespace relpipe {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    26
namespace in {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    27
namespace ini {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    28
namespace lib {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    29
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    30
class INIReaderImpl : public INIReader {
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    31
private:
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    32
	std::istream& input;
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    33
	std::vector<INIContentHandler*> handlers;
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    34
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    35
	/** 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    36
	 * This might be configurable.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    37
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    38
	 * By default, we ignore all leading whitespace on continuing lines.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    39
	 * If there should be some spaces or tabs, they should be placed on the previous line before the „\“.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    40
	 * If a line break is desired, it should be written as \n (escaped) or the value should be quoted in " or '.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    41
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    42
	 * Related specifications:
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    43
	 *  - https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Properties.html
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    44
	 */
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    45
	bool consumeLeadingSpacesOnContinuingLines = true;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    46
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    47
	/**
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    48
	 * This might be configurable.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    49
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    50
	 * KDE uses some weird INI dialect that allows [section][x] syntax where „x“ is kind of „tag“ that signalizes some properties of given section.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    51
	 * Line „[section_1][$i]“ means that the „section_1“ is „locked“.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    52
	 * We may emit this information somehow later, but for now, it is just ignored.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    53
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    54
	 * TODO: Is „section tag“ right name?
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    55
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    56
	 * Related specifications:
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    57
	 *  - https://userbase.kde.org/KDE_System_Administration/Configuration_Files#Lock_Down
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    58
	 */
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    59
	bool allowSectionTags = true;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    60
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    61
	/**
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    62
	 * This might be configurable.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    63
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    64
	 * If whole key is „aaa[bbb]“ then „aaa“ is considered to be the key and „bbb“ the sub-key.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    65
	 * No \[ escaping is currently supported, so the key might not contain the bracket character.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    66
	 * 
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    67
	 * Related specifications:
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    68
	 *  - https://userbase.kde.org/KDE_System_Administration/Configuration_Files#Shell_Expansion
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    69
	 *  - https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s05.html
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    70
	 */
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    71
	bool allowSubKeys = true;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    72
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    73
	int lineNumber = 1;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    74
	int eventNumber = 0;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    75
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    76
	/**
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    77
	 * Should be always used instead of input.peek().
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    78
	 * Skips \r.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    79
	 */
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    80
	char peek() {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    81
		// In 2020 there is no need to manually return the carriage. However some legacy systems still do it.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    82
		char ch = input.peek();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    83
		if (ch == '\r') {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    84
			input.get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    85
			ch = input.peek();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    86
		}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    87
		return ch;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    88
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    89
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    90
	/**
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    91
	 * Should be always used instead of input.get().
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    92
	 * Counts the lines and skips \r.
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    93
	 */
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    94
	char get() {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    95
		char ch = input.get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    96
		if (ch == '\n') lineNumber++;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    97
		else if (ch == '\r') ch = get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    98
		return ch;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
    99
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   100
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   101
	std::string readSpacesAndTabs() {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   102
		std::stringstream result;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   103
		for (char ch = peek(); input.good() && (ch == ' ' || ch == '\t'); ch = peek()) result.put(get());
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   104
		return result.str();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   105
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   106
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   107
	std::string readAllWhitespace() {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   108
		std::stringstream result;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   109
		for (char ch = peek(); input.good() && (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); ch = peek()) result.put(get());
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   110
		return result.str();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   111
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   112
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   113
	void processContinuingLine(std::stringstream& result) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   114
		if (consumeLeadingSpacesOnContinuingLines) readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   115
		else result.put('\n');
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   116
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   117
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   118
	std::string readUntil(char until, bool* found = nullptr) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   119
		std::stringstream result;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   120
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   121
		for (char ch = peek(); input.good() && ch != until; ch = peek()) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   122
			if (ch == '\\') {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   123
				get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   124
				ch = get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   125
				if (ch == until && ch == '\n') processContinuingLine(result);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   126
				else if (ch == until) result.put(ch);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   127
				else if (ch == std::istream::traits_type::eof()) break;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   128
				else result.put('\\').put(ch);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   129
				// TODO: two-stage and modular unescaping: here unescape only \+LF or more genereally: unescape only the until character and rest leave untouched
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   130
				// second escaping stage move to separate class/wrapper (similar to hierarchical wrappers)
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   131
			} else {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   132
				ch = get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   133
				result.put(ch);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   134
			}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   135
		}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   136
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   137
		if (peek() == until) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   138
			get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   139
			if (found) *found = true;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   140
		} else {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   141
			if (found) *found = false;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   142
		}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   143
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   144
		return result.str();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   145
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   146
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   147
	std::string readToken(char until, char* quote = nullptr, bool* found = nullptr) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   148
		std::string result;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   149
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   150
		char ch = peek();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   151
		if (isQuote(ch)) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   152
			if (quote) *quote = ch;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   153
			result = readUntil(get(), found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   154
		} else {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   155
			if (quote) *quote = 0;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   156
			result = readUntil(until, found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   157
		}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   158
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   159
		return result;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   160
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   161
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   162
	std::string readTokenAndEatTerminator(char until, char* quote = nullptr, bool* found = nullptr) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   163
		std::string result = readToken(until, quote, found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   164
		if (*quote) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   165
			readAllWhitespace();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   166
			if (get() != until) throw std::logic_error(std::string("missing „") + std::string(1, until) + "“ after quoted section name");
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   167
		}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   168
		return result;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   169
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   170
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   171
	bool isComment(char ch) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   172
		return ch == '#' || ch == ';';
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   173
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   174
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   175
	bool isQuote(char ch) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   176
		return ch == '"' || ch == '\'';
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   177
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   178
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   179
	std::string trim(std::string s) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   180
		return std::regex_replace(s, std::regex("^\\s+|\\s+$"), "");
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   181
	}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   182
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   183
public:
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   184
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   185
	INIReaderImpl(std::istream& input) : input(input) {
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   186
	}
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   187
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   188
	void addHandler(INIContentHandler* handler) override {
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   189
		handlers.push_back(handler);
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   190
	}
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   191
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   192
	void process() override {
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   193
		for (INIContentHandler* handler : handlers) handler->startDocument();
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   194
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   195
		bool inSection = false;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   196
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   197
		while (input.good()) { // TODO: condition
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   198
			{
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   199
				std::string whitespace = readAllWhitespace();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   200
				if (whitespace.size()) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   201
					INIContentHandler::WhitespaceEvent event;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   202
					event.lineNumber = lineNumber;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   203
					event.eventNumber = ++eventNumber;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   204
					event.whitespace = whitespace;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   205
					for (INIContentHandler* handler : handlers) handler->whitespace(event);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   206
				}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   207
			}
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   208
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   209
			bool found;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   210
			char quote;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   211
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   212
			char ch = peek();
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   213
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   214
			if (ch == std::istream::traits_type::eof()) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   215
				break;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   216
			} else if (ch == '[') {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   217
				if (inSection) for (INIContentHandler* handler : handlers) handler->endSection();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   218
				inSection = true;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   219
				get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   220
				readAllWhitespace();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   221
				INIContentHandler::SectionStartEvent event;
19
90f2b8ca32bf improved support for comments and whitespace
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   222
				event.lineNumber = lineNumber;
90f2b8ca32bf improved support for comments and whitespace
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   223
				event.eventNumber = ++eventNumber;
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   224
				event.name = readTokenAndEatTerminator(']', &quote, &found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   225
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   226
				readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   227
				if (allowSectionTags && peek() == '[') {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   228
					get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   229
					event.tag = readTokenAndEatTerminator(']', &quote, &found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   230
				}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   231
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   232
				readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   233
				ch = peek();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   234
				if (isComment(ch)) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   235
					get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   236
					readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   237
					event.comment = readUntil('\n', &found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   238
				} else if (ch == '\n') {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   239
					get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   240
				} else {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   241
					throw std::logic_error(std::string("unexpected content after the section: '") + event.name + "'");
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   242
				}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   243
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   244
				for (INIContentHandler* handler : handlers) handler->startSection(event);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   245
			} else if (isComment(ch)) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   246
				get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   247
				readSpacesAndTabs();
19
90f2b8ca32bf improved support for comments and whitespace
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   248
				INIContentHandler::CommentEvent event;
90f2b8ca32bf improved support for comments and whitespace
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   249
				event.lineNumber = lineNumber;
90f2b8ca32bf improved support for comments and whitespace
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   250
				event.eventNumber = ++eventNumber;
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   251
				event.comment = readUntil('\n', &found);
19
90f2b8ca32bf improved support for comments and whitespace
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   252
				for (INIContentHandler* handler : handlers) handler->comment(event);
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   253
			} else {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   254
				std::string fullKey = readToken('=', &quote, &found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   255
				if (!found) throw std::logic_error(std::string("missing = after key: '") + fullKey + "'");
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   256
				if (!quote) fullKey = trim(fullKey);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   257
				readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   258
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   259
				if (quote) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   260
					ch = get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   261
					if (ch == '=') readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   262
					else throw std::logic_error(std::string("missing = after quoted key: '") + fullKey + "'");
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   263
				}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   264
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   265
				std::string value = readToken('\n', &quote, &found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   266
				if (!quote) value = trim(value);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   267
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   268
				INIContentHandler::EntryEvent event;
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   269
				event.lineNumber = lineNumber;
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   270
				event.eventNumber = ++eventNumber;
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   271
				event.key = fullKey;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   272
				event.fullKey = fullKey;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   273
				event.value = value;
25
ee70b17950bd multi-line support: quoted and apostrophed
František Kučera <franta-hg@frantovo.cz>
parents: 24
diff changeset
   274
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   275
				if (allowSubKeys) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   276
					std::smatch match;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   277
					if (std::regex_match(fullKey, match, std::regex("([^\\[]+)\\[([^\\[]+)\\]"))) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   278
						event.key = match[1];
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   279
						event.subKey = match[2];
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   280
						event.fullKey = fullKey;
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   281
					}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   282
				}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   283
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   284
				if (quote) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   285
					readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   286
					ch = peek();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   287
					if (isComment(ch)) {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   288
						get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   289
						readSpacesAndTabs();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   290
						event.comment = readUntil('\n', &found);
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   291
					} else if (ch == '\n') {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   292
						get();
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   293
					} else {
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   294
						throw std::logic_error(std::string("unexpected content after the quoted value: key='") + fullKey + "' value='" + event.value + "'");
25
ee70b17950bd multi-line support: quoted and apostrophed
František Kučera <franta-hg@frantovo.cz>
parents: 24
diff changeset
   295
					}
ee70b17950bd multi-line support: quoted and apostrophed
František Kučera <franta-hg@frantovo.cz>
parents: 24
diff changeset
   296
				}
ee70b17950bd multi-line support: quoted and apostrophed
František Kučera <franta-hg@frantovo.cz>
parents: 24
diff changeset
   297
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   298
				for (INIContentHandler* handler : handlers) handler->entry(event);
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   299
			}
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   300
		}
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   301
		// TODO: error at the end, catch premature/unexpected EOF
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   302
		// TODO: unescape + trim values + ignore \r
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   303
		// TODO: count lines
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   304
		if (inSection) for (INIContentHandler* handler : handlers) handler->endSection();
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   305
		for (INIContentHandler* handler : handlers) handler->endDocument();
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   306
	}
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   307
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   308
	// General feautres:
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   309
	// TODO: warning/error handler
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   310
	// TODO: support also escaped characters
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   311
	// TODO: support also Java .properties and manifest.mf formats?
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   312
	// TODO: support also nested sections – hierarchy
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   313
	// TODO: support also nested keys e.g. key.sub.subsub.subsubsub=value – translate them to nested sections
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   314
	// TODO: support also option for alternative key-value separator (: instead of =)
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   315
	// TODO: support also other encodings (currently only UTF-8 is supported)
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   316
	// TODO: better exceptions
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   317
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   318
	// Lossless conversions:
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   319
	// TODO: emit also the quote style ('/"/)
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   320
	// TODO: emit also the comment style (;/#) ?
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   321
	// TODO: emit also the whitespace before key name, around =, after "values"/'values', around [sections] ?
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   322
	// TODO: emit also the line-end type (LF/CRLF) ?
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   323
16
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   324
};
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   325
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   326
INIReader* INIReader::create(std::istream& input) {
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   327
	return new INIReaderImpl(input);
b9a3c806468a temporary copy INIReader.h, INIReader.cpp, INIContentHandler.h from relpipe-in-ini + XMLNameCodec.h from relpipe-in-yamltable (will be moved to alt2xml and shared)
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   328
}
26
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   329
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   330
}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   331
}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   332
}
80e129ec3408 new INI parser
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   333
}