4#include "absl/strings/str_format.h"
15 return absl::FailedPreconditionError(
"ROM must be loaded");
19 formatter.
AddField(
"size", absl::StrFormat(
"0x%X", rom->
size()));
20 formatter.
AddField(
"size_bytes",
static_cast<int>(rom->
size()));
22 return absl::OkStatus();
29 return absl::FailedPreconditionError(
"ROM must be loaded");
33 std::vector<std::string> validation_results;
37 validation_results.push_back(
"checksum: PASSED");
39 validation_results.push_back(
"checksum: FAILED");
44 if (rom->
title() ==
"THE LEGEND OF ZELDA") {
45 validation_results.push_back(
"header: PASSED");
47 validation_results.push_back(
"header: FAILED (Invalid title: " + rom->
title() +
")");
51 formatter.
AddField(
"validation_passed", all_ok);
52 std::string results_str;
53 for (
const auto& result : validation_results) {
54 if (!results_str.empty()) results_str +=
"; ";
55 results_str += result;
57 formatter.
AddField(
"results", results_str);
59 return absl::OkStatus();
65 auto rom_a_opt = parser.
GetString(
"rom_a");
66 auto rom_b_opt = parser.
GetString(
"rom_b");
68 if (!rom_a_opt.has_value()) {
69 return absl::InvalidArgumentError(
"Missing required argument: rom_a");
71 if (!rom_b_opt.has_value()) {
72 return absl::InvalidArgumentError(
"Missing required argument: rom_b");
75 std::string rom_a_path = rom_a_opt.value();
76 std::string rom_b_path = rom_b_opt.value();
91 formatter.
AddField(
"size_match",
false);
92 formatter.
AddField(
"size_a",
static_cast<int>(rom_a.
size()));
93 formatter.
AddField(
"size_b",
static_cast<int>(rom_b.
size()));
94 return absl::OkStatus();
98 std::vector<std::string> diff_details;
100 for (
size_t i = 0; i < rom_a.
size(); ++i) {
103 if (differences <= 10) {
104 diff_details.push_back(absl::StrFormat(
"0x%08X: 0x%02X vs 0x%02X",
110 formatter.
AddField(
"identical", differences == 0);
111 formatter.
AddField(
"differences_count", differences);
112 if (!diff_details.empty()) {
113 std::string diff_str;
114 for (
const auto& diff : diff_details) {
115 if (!diff_str.empty()) diff_str +=
"; ";
118 formatter.
AddField(
"differences", diff_str);
121 return absl::OkStatus();
127 auto rom_opt = parser.
GetString(
"rom_file");
128 auto golden_opt = parser.
GetString(
"golden_file");
130 if (!rom_opt.has_value()) {
131 return absl::InvalidArgumentError(
"Missing required argument: rom_file");
133 if (!golden_opt.has_value()) {
134 return absl::InvalidArgumentError(
"Missing required argument: golden_file");
137 std::string rom_path = rom_opt.value();
138 std::string golden_path = golden_opt.value();
146 std::ofstream file(golden_path, std::ios::binary);
147 if (!file.is_open()) {
148 return absl::NotFoundError(
"Could not open file for writing: " + golden_path);
151 file.write(
reinterpret_cast<const char*
>(source_rom.
vector().data()), source_rom.
size());
153 formatter.
AddField(
"status",
"success");
154 formatter.
AddField(
"golden_file", golden_path);
155 formatter.
AddField(
"source_file", rom_path);
156 formatter.
AddField(
"size",
static_cast<int>(source_rom.
size()));
158 return absl::OkStatus();
The Rom class is used to load, save, and modify Rom data.
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
absl::Status Execute(Rom *rom, const resources::ArgumentParser &parser, resources::OutputFormatter &formatter) override
Execute the command business logic.
Utility for parsing common CLI argument patterns.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
Main namespace for the application.
static RomLoadOptions CliDefaults()