38 for (INIContentHandler* handler : handlers) handler->startDocument(); |
38 for (INIContentHandler* handler : handlers) handler->startDocument(); |
39 |
39 |
40 std::regex whitespacePattrern("\\s*"); |
40 std::regex whitespacePattrern("\\s*"); |
41 std::regex commentPattrern("\\s*(;|#)\\s*(.*)"); |
41 std::regex commentPattrern("\\s*(;|#)\\s*(.*)"); |
42 std::regex sectionPattrern("\\s*\\[\\s*([^\\]]+)\\s*\\]\\s*(\\[\\s*([^\\]]+)\\s*\\])?\\s*((;|#)\\s*(.*))?"); |
42 std::regex sectionPattrern("\\s*\\[\\s*([^\\]]+)\\s*\\]\\s*(\\[\\s*([^\\]]+)\\s*\\])?\\s*((;|#)\\s*(.*))?"); |
43 std::regex entryQuotedPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*(\"|')((?:(?!\\5).)*)(\\5)\\s*((;|#)\\s*(.*))?"); |
43 std::regex entryQuotedPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*(\"|')((?:(?!\\5).)*)(\\5)?\\s*((;|#)\\s*(.*))?"); |
44 std::regex entryPlainPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*(.*?)\\s*"); |
44 std::regex entryPlainPattrern("\\s*(([^=\\]]+?[^=\\s\\]]*)(\\[([^\\]]+)\\])?)\\s*=\\s*(.*?)\\s*"); |
45 |
45 |
46 std::smatch match; |
46 std::smatch match; |
47 bool inSection = false; |
47 bool inSection = false; |
48 std::string line; |
48 std::string line; |
85 event.key = match[2]; |
85 event.key = match[2]; |
86 event.subKey = match[4]; |
86 event.subKey = match[4]; |
87 event.fullKey = match[1]; |
87 event.fullKey = match[1]; |
88 event.value = match[6]; |
88 event.value = match[6]; |
89 event.comment = match[10]; |
89 event.comment = match[10]; |
|
90 |
|
91 // the "/' at the end is missing → line continues |
|
92 if (match.length(7) == 0) { |
|
93 std::regex endPattern(std::string("(.*?)") + (match[5] == "'" ? "'" : "\"") + "\\s*((;|#)\\s*(.*))?"); |
|
94 while (std::getline(input, line)) { |
|
95 lineNumber++; |
|
96 event.value += "\n"; |
|
97 if (std::regex_match(line, match, endPattern)) { |
|
98 event.value += std::string(match[1]); |
|
99 event.comment = match[4]; |
|
100 break; |
|
101 } else { |
|
102 event.value += line; |
|
103 } |
|
104 } |
|
105 } |
|
106 |
90 for (INIContentHandler* handler : handlers) handler->entry(event); |
107 for (INIContentHandler* handler : handlers) handler->entry(event); |
91 } else if (std::regex_match(line, match, entryPlainPattrern)) { |
108 } else if (std::regex_match(line, match, entryPlainPattrern)) { |
92 INIContentHandler::EntryEvent event; |
109 INIContentHandler::EntryEvent event; |
93 event.lineNumber = lineNumber; |
110 event.lineNumber = lineNumber; |
94 event.eventNumber = ++eventNumber; |
111 event.eventNumber = ++eventNumber; |
95 event.key = match[2]; |
112 event.key = match[2]; |
96 event.subKey = match[4]; |
113 event.subKey = match[4]; |
97 event.fullKey = match[1]; |
114 event.fullKey = match[1]; |
98 event.value = match[5]; |
115 event.value = match[5]; |
99 |
116 |
|
117 // the \ at the end → line continues |
100 while (line.back() == '\\' && std::getline(input, line)) { |
118 while (line.back() == '\\' && std::getline(input, line)) { |
|
119 lineNumber++; |
101 line = std::regex_replace(line, std::regex("^\\s+|\\s+$"), ""); // trim the spaces: continuing lines might be aligned to the first line (desired spaces – if any – should be at the line end before the \ character) |
120 line = std::regex_replace(line, std::regex("^\\s+|\\s+$"), ""); // trim the spaces: continuing lines might be aligned to the first line (desired spaces – if any – should be at the line end before the \ character) |
102 event.value = event.value.substr(0, event.value.size() - 1); // cut the trailing \ backslash |
121 event.value = event.value.substr(0, event.value.size() - 1); // cut the trailing \ backslash |
103 event.value = event.value + line; |
122 event.value = event.value + line; |
104 } |
123 } |
105 |
124 |