Files
2026-11-08 16:15:49 +01:00

93 lines
2.6 KiB
C++

#include "yamlparser.h"
#include <QFile>
#include <QTextStream>
#include <vector>
YamlNode YamlParser::parseFile(const QString &filePath)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return YamlNode();
}
QTextStream in(&file);
return parseString(in.readAll());
}
YamlNode YamlParser::parseString(const QString &content)
{
YamlNode root;
QStringList lines = content.split('\n');
struct StackEntry {
int indent;
YamlNode *node;
};
std::vector<StackEntry> stack;
stack.push_back({-1, &root});
for (int i = 0; i < lines.size(); ++i) {
QString rawLine = lines[i];
// Strip comments
int commentIdx = rawLine.indexOf('#');
if (commentIdx != -1) {
rawLine = rawLine.left(commentIdx);
}
// Calculate leading indentation spaces (tabs expanded to 2 spaces)
int indent = 0;
int idx = 0;
while (idx < rawLine.length()) {
if (rawLine[idx] == ' ') {
indent++;
idx++;
} else if (rawLine[idx] == '\t') {
indent += 2;
idx++;
} else {
break;
}
}
QString trimmed = rawLine.trimmed();
if (trimmed.isEmpty()) continue;
// Pop stack until parent has smaller indent
while (stack.size() > 1 && stack.back().indent >= indent) {
stack.pop_back();
}
YamlNode *parent = stack.back().node;
// Check for list item: "- something"
if (trimmed.startsWith("- ")) {
QString itemVal = trimmed.mid(2).trimmed();
if ((itemVal.startsWith('"') && itemVal.endsWith('"')) || (itemVal.startsWith('\'') && itemVal.endsWith('\''))) {
itemVal = itemVal.mid(1, itemVal.length() - 2);
}
parent->listValues.append(itemVal);
continue;
}
// Check for key: value
int colonIdx = trimmed.indexOf(':');
if (colonIdx != -1) {
QString key = trimmed.left(colonIdx).trimmed();
QString val = trimmed.mid(colonIdx + 1).trimmed();
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith('\'') && val.endsWith('\''))) {
val = val.mid(1, val.length() - 2);
}
parent->children[key] = YamlNode();
YamlNode *newNode = &(parent->children[key]);
newNode->value = val;
stack.push_back({indent, newNode});
}
}
return root;
}