62 lines
1.9 KiB
C++
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
|