toml parser update + 'toml' module is built-in now

This commit is contained in:
MihailRis
2024-05-20 01:28:42 +03:00
parent ffdeac5c1f
commit c94d40ab02
15 changed files with 252 additions and 178 deletions
+83 -38
View File
@@ -7,15 +7,14 @@
#include "../files/settings_io.hpp"
#include <math.h>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <assert.h>
using namespace toml;
class Reader : BasicParser {
SettingsHandler& handler;
class TomlReader : BasicParser {
dynamic::Map_sptr root;
void skipWhitespace() override {
BasicParser::skipWhitespace();
@@ -26,7 +25,34 @@ class Reader : BasicParser {
}
}
}
void readSection(const std::string& section) {
dynamic::Map& getSection(const std::string& section) {
if (section.empty()) {
return *root;
}
size_t offset = 0;
auto& rootMap = *root;
do {
size_t index = section.find('.', offset);
if (index == std::string::npos) {
auto map = rootMap.map(section);
if (map == nullptr) {
return rootMap.putMap(section);
}
return *map;
}
auto subsection = section.substr(offset, index);
auto map = rootMap.map(subsection);
if (map == nullptr) {
rootMap = rootMap.putMap(subsection);
} else {
rootMap = *map;
}
offset = index+1;
} while (true);
}
void readSection(const std::string& section, dynamic::Map& map) {
while (hasNext()) {
skipWhitespace();
if (!hasNext()) {
@@ -36,43 +62,31 @@ class Reader : BasicParser {
if (c == '[') {
std::string name = parseName();
pos++;
readSection(name);
readSection(name, getSection(name));
return;
}
pos--;
std::string name = section+"."+parseName();
std::string name = parseName();
expect('=');
c = peek();
if (is_digit(c)) {
auto num = parseNumber(1);
if (handler.has(name)) {
handler.setValue(name, num);
}
map.put(name, parseNumber(1));
} else if (c == '-' || c == '+') {
int sign = c == '-' ? -1 : 1;
pos++;
auto num = parseNumber(sign);
if (handler.has(name)) {
handler.setValue(name, num);
}
map.put(name, parseNumber(sign));
} else if (is_identifier_start(c)) {
std::string identifier = parseName();
if (handler.has(name)) {
if (identifier == "true" || identifier == "false") {
bool flag = identifier == "true";
handler.setValue(name, flag);
} else if (identifier == "inf") {
handler.setValue(name, INFINITY);
} else if (identifier == "nan") {
handler.setValue(name, NAN);
}
if (identifier == "true" || identifier == "false") {
map.put(name, identifier == "true");
} else if (identifier == "inf") {
map.put(name, INFINITY);
} else if (identifier == "nan") {
map.put(name, NAN);
}
} else if (c == '"' || c == '\'') {
pos++;
std::string str = parseString(c);
if (handler.has(name)) {
handler.setValue(name, str);
}
map.put(name, parseString(c));
} else {
throw error("feature is not supported");
}
@@ -81,29 +95,60 @@ class Reader : BasicParser {
}
public:
Reader(
SettingsHandler& handler,
TomlReader(
std::string_view file,
std::string_view source)
: BasicParser(file, source), handler(handler) {
: BasicParser(file, source) {
root = dynamic::create_map();
}
void read() {
dynamic::Map_sptr read() {
skipWhitespace();
if (!hasNext()) {
return;
return root;
}
readSection("");
readSection("", *root);
return root;
}
};
dynamic::Map_sptr toml::parse(std::string_view file, std::string_view source) {
return TomlReader(file, source).read();
}
void toml::parse(
SettingsHandler& handler,
const std::string& file,
const std::string& source
SettingsHandler& handler, std::string_view file, std::string_view source
) {
Reader reader(handler, file, source);
reader.read();
auto map = parse(file, source);
for (auto& entry : map->values) {
const auto& sectionName = entry.first;
auto sectionMap = std::get_if<dynamic::Map_sptr>(&entry.second);
if (sectionMap == nullptr) {
continue;
}
for (auto& sectionEntry : (*sectionMap)->values) {
const auto& name = sectionEntry.first;
auto& value = sectionEntry.second;
auto fullname = sectionName+"."+name;
if (handler.has(fullname)) {
handler.setValue(fullname, value);
}
}
}
}
std::string toml::stringify(dynamic::Map& root) {
std::stringstream ss;
for (auto& sectionEntry : root.values) {
ss << "[" << sectionEntry.first << "]\n";
auto sectionMap = std::get_if<dynamic::Map_sptr>(&sectionEntry.second);
for (auto& entry : (*sectionMap)->values) {
ss << entry.first << " = ";
ss << entry.second << "\n";
}
ss << "\n";
}
return ss.str();
}
std::string toml::stringify(SettingsHandler& handler) {