src/lib/INIReader.cpp
branchv_0
changeset 24 07e0a2edf3bc
parent 23 b497140b0b63
child 25 b9067d2812e5
equal deleted inserted replaced
23:b497140b0b63 24:07e0a2edf3bc
    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(']', &quote, &found);
   315 				event.name = readTokenAndEatTerminator(']', &quote, &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(']', &quote, &found);
   321 					event.tag = readTokenAndEatTerminator(']', &quote, &found);