freepdfeditor/spike/common/SpikeRunner.cpp

62 lines
1.9 KiB
C++

// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2025 ai-ad4 and the FreePDFEditor contributors
#include "SpikeRunner.h"
#include <cstdio>
#include <cstdlib>
#include <string>
namespace freepdfeditor::spike {
namespace {
// Minimal hand-rolled JSON string escaper — avoids pulling a JSON lib into the
// spike harness, which must stay dependency-light so it builds first.
std::string esc(std::string s)
{
std::string out;
out.reserve(s.size() + 8);
for (char c : s) {
switch (c) {
case '"': out += "\\\""; break;
case '\\': out += "\\\\"; break;
case '\n': out += "\\n"; break;
case '\r': out += "\\r"; break;
case '\t': out += "\\t"; break;
default:
if (static_cast<unsigned char>(c) < 0x20) {
char buf[8];
std::snprintf(buf, sizeof(buf), "\\u%04x", c);
out += buf;
} else {
out += c;
}
}
}
return out;
}
} // namespace
int emit_json_report(const SpikeResult& r)
{
std::string samples;
for (std::size_t i = 0; i < r.failed_samples.size(); ++i) {
if (i) samples += ",";
samples += "\"" + esc(r.failed_samples[i]) + "\"";
}
std::printf(
"{\"spike\":\"%s\",\"name\":\"%s\",\"total\":%zu,\"passed\":%zu,"
"\"failed\":%zu,\"errored\":%zu,\"metric\":\"%s\",\"value\":%.6f,"
"\"target\":%.6f,\"gate_met\":%s,\"samples\":[%s],\"notes\":\"%s\"}\n",
r.spike.c_str(), r.name.c_str(),
r.total, r.passed, r.failed, r.errored,
r.metric_name.c_str(), r.metric_value, r.target,
r.gate_met ? "true" : "false",
samples.c_str(), esc(r.notes).c_str());
std::fflush(stdout);
return r.gate_met ? 0 : 1;
}
} // namespace freepdfeditor::spike