Files
dstalk/plugins/config/include/toml_parse.h
XiuChengWu f2da0f2ed4 Add metadata validation script and module documentation
- Introduced a new Python script `check_agents_metadata.py` for validating agent metadata, including YAML parsing, rating ranges, and cross-references.
- Added usage instructions and exit codes for the script.
- Created a new markdown file `模块目录和功能说明.md` to outline the directory structure and functionality of the modules.
- Added a text file `说明此文件不可AI修改.txt` to specify that certain files should not be modified by AI, including important information about the `dstalk` framework and its modules.
2026-05-31 00:00:58 +08:00

76 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* @file toml_parse.h
* @brief Lightweight single-header TOML parser (subset: flat key-value pairs).
* 轻量级单头文件 TOML 解析器(子集:扁平键值对)。
* Copyright (c) 2026 dstalk contributors. GPLv3.
*/
#pragma once
// 共享 TOML 解析器 —— 由 ConfigStore核心和 config 插件共同使用 / Shared TOML parser — used by both ConfigStore (core) and config plugin.
// W12.2: Extracted from config_store.cpp:23-61 and config_plugin.cpp:28-66
// to eliminate the 74-line code duplication (W11.2 audit Finding 1).
// Does NOT support: inline tables, arrays, multi-line strings, escape sequences.
// 不支持:内联表、数组、多行字符串、转义序列。
#include <string>
namespace dstalk {
namespace toml {
/// 解析 TOML 字符串,对每个键值对调用 on_kv(full_key, value) / Parse a TOML string, calling on_kv(full_key, value) for each key-value pair.
/// 支持 [section] 标题、key = "value" 键值对、# 注释、空行 / Supports [section] headers, key = "value" pairs, # comments, blank lines.
template<typename F>
inline void parse(const std::string& content, F&& on_kv)
{
std::string current_section;
size_t pos = 0;
while (pos < content.size()) {
// 去除左侧空白 / Trim left whitespace
while (pos < content.size() && (content[pos] == ' ' || content[pos] == '\t'))
pos++;
if (pos >= content.size()) break;
// 提取下一行 / Extract next line
size_t nl = content.find('\n', pos);
std::string line = (nl != std::string::npos)
? content.substr(pos, nl - pos) : content.substr(pos);
pos = (nl != std::string::npos) ? nl + 1 : content.size();
// 去除右侧空白(包括 \r / Trim right whitespace (including \r)
while (!line.empty() && (line.back() == '\r' || line.back() == ' '))
line.pop_back();
// 跳过空行和注释 / Skip empty lines and comments
if (line.empty() || line[0] == '#') continue;
// 节标题: [section_name] / Section header: [section_name]
if (line[0] == '[' && line.back() == ']') {
current_section = line.substr(1, line.size() - 2);
continue;
}
// 键 = 值 / Key = value
size_t eq = line.find('=');
if (eq == std::string::npos) continue;
std::string key = line.substr(0, eq);
while (!key.empty() && key.back() == ' ') key.pop_back();
if (key.empty()) continue;
std::string val = line.substr(eq + 1);
while (!val.empty() && (val.front() == ' ' || val.front() == '\t'))
val.erase(0, 1);
if (val.size() >= 2 && val.front() == '"' && val.back() == '"')
val = val.substr(1, val.size() - 2);
std::string full_key = current_section.empty()
? key : current_section + "." + key;
on_kv(full_key, val);
}
}
} // namespace toml
} // namespace dstalk