Skip to content

Commit 7d174bb

Browse files
committed
fix(bench): a bracketed engine option must survive the --engines list split
`--engines` 用逗号分隔 spec,而 bracket 选项之间也用逗号 —— 于是 `mcpp[a=1,b=2]=/path` 会先被列表切成 `mcpp[a=1` 和 `b=2]=/path` 两半, `make_engine` 收到的是碎片,报「unknown engine」,而 spec 本身完全合法。 分隔符相同,所以**得由切列表的那一侧认识方括号**。split() 加了一个深度计数; 对 `--variants` / `--scenarios` / `--allow-failed` 没有影响(它们不含方括号, 计数永远是 0)。 顺带把 registry 里那个多余的 `{}` 块拍平。
1 parent fce8460 commit 7d174bb

2 files changed

Lines changed: 30 additions & 19 deletions

File tree

bench/src/main.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,28 @@ bool listed(const std::vector<std::string>& names, std::string_view engine) {
7373
});
7474
}
7575

76+
// Splits a comma-separated list, IGNORING commas inside `[...]`.
77+
//
78+
// An engine spec may carry bracketed options (`mcpp[schedule=on]=/path`), and a
79+
// second option would be separated by a comma — which this function would
80+
// otherwise cut in half, handing `make_engine` the fragments `mcpp[a=1` and
81+
// `b=2]=/path` and reporting "unknown engine" for a perfectly valid spec. The
82+
// list separator and the option separator are the same character, so the list
83+
// splitter is the one that has to know about the brackets.
84+
//
85+
// Harmless for every other caller: `--variants`, `--scenarios` and
86+
// `--allow-failed` contain no brackets, so the depth counter never leaves zero.
7687
std::vector<std::string> split(std::string_view s, char sep = ',') {
7788
std::vector<std::string> parts;
78-
std::size_t start = 0;
79-
while (start <= s.size()) {
80-
const auto pos = s.find(sep, start);
81-
const auto end = (pos == std::string_view::npos) ? s.size() : pos;
82-
if (end > start) parts.emplace_back(s.substr(start, end - start));
83-
if (pos == std::string_view::npos) break;
84-
start = pos + 1;
89+
std::size_t start = 0, depth = 0;
90+
for (std::size_t i = 0; i <= s.size(); ++i) {
91+
if (i < s.size()) {
92+
if (s[i] == '[') { ++depth; continue; }
93+
if (s[i] == ']') { if (depth) --depth; continue; }
94+
if (s[i] != sep || depth) continue;
95+
}
96+
if (i > start) parts.emplace_back(s.substr(start, i - start));
97+
start = i + 1;
8598
}
8699
return parts;
87100
}

bench/src/registry.cppm

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,16 @@ inline std::unique_ptr<engines::Engine> make_engine(std::string_view spec) {
9191
program = anchor_program(std::string(spec.substr(eq + 1)));
9292
}
9393

94-
{
95-
for (std::size_t at = 0; at <= opts.size();) {
96-
const auto end = std::min(opts.find(',', at), opts.size());
97-
const auto item = std::string_view(opts).substr(at, end - at);
98-
at = end + 1;
99-
if (item.empty()) continue;
100-
const auto sep = item.find('=');
101-
if (sep == std::string_view::npos) return nullptr;
102-
auto mapped = engine_option(name, item.substr(0, sep), item.substr(sep + 1));
103-
if (!mapped) return nullptr; // unknown: reject loudly
104-
env.emplace(std::move(mapped->first), std::move(mapped->second));
105-
}
94+
for (std::size_t at = 0; at <= opts.size();) {
95+
const auto end = std::min(opts.find(',', at), opts.size());
96+
const auto item = std::string_view(opts).substr(at, end - at);
97+
at = end + 1;
98+
if (item.empty()) continue;
99+
const auto sep = item.find('=');
100+
if (sep == std::string_view::npos) return nullptr;
101+
auto mapped = engine_option(name, item.substr(0, sep), item.substr(sep + 1));
102+
if (!mapped) return nullptr; // unknown: reject loudly
103+
env.emplace(std::move(mapped->first), std::move(mapped->second));
106104
}
107105

108106
if (name == "mcpp")

0 commit comments

Comments
 (0)