5#include "absl/flags/declare.h"
6#include "absl/flags/flag.h"
7#include "absl/strings/ascii.h"
8#include "absl/strings/match.h"
9#include "absl/strings/numbers.h"
10#include "absl/strings/str_format.h"
11#include "absl/strings/str_join.h"
30 return absl::OkStatus();
38 return absl::OkStatus();
49 return absl::OkStatus();
56 return absl::FailedPreconditionError(
57 absl::StrFormat(
"Failed to load ROM from '%s': %s",
62 return absl::OkStatus();
66 std::string rom_path = absl::GetFlag(FLAGS_rom);
67 if (!rom_path.empty()) {
70 return absl::FailedPreconditionError(
71 absl::StrFormat(
"Failed to load ROM from '%s': %s",
72 rom_path, status.message()));
76 return absl::OkStatus();
79 return absl::FailedPreconditionError(
80 "No ROM loaded. Use --rom=<path> or --mock-rom for testing.");
92 return absl::FailedPreconditionError(
"ROM not loaded");
100 return absl::FailedPreconditionError(
"ROM has no resource label manager");
108 if (labels_status.ok()) {
112 return labels_status;
116 return absl::OkStatus();
127 const std::string& name)
const {
128 std::string flag =
"--" + name;
129 std::string equals_form = flag +
"=";
131 for (
size_t i = 0; i <
args_.size(); ++i) {
132 const std::string& arg =
args_[i];
135 if (absl::StartsWith(arg, equals_form)) {
136 return arg.substr(equals_form.length());
140 if (arg == flag && i + 1 <
args_.size()) {
149 const std::string& name)
const {
155 if (!value.has_value()) {
156 return absl::NotFoundError(
157 absl::StrFormat(
"Argument '--%s' not found", name));
161 if (absl::StartsWith(*value,
"0x") || absl::StartsWith(*value,
"0X")) {
163 if (absl::SimpleHexAtoi(value->substr(2), &result)) {
166 return absl::InvalidArgumentError(
167 absl::StrFormat(
"Invalid hex integer for '--%s': %s", name, *value));
172 if (absl::SimpleAtoi(*value, &result)) {
176 return absl::InvalidArgumentError(
177 absl::StrFormat(
"Invalid integer for '--%s': %s", name, *value));
182 if (!value.has_value()) {
183 return absl::NotFoundError(
184 absl::StrFormat(
"Argument '--%s' not found", name));
188 std::string hex_str = *value;
189 if (absl::StartsWith(hex_str,
"0x") || absl::StartsWith(hex_str,
"0X")) {
190 hex_str = hex_str.substr(2);
194 if (absl::SimpleHexAtoi(hex_str, &result)) {
198 return absl::InvalidArgumentError(
199 absl::StrFormat(
"Invalid hex value for '--%s': %s", name, *value));
203 std::string flag =
"--" + name;
204 for (
const auto& arg :
args_) {
213 std::vector<std::string> positional;
214 for (
size_t i = 0; i <
args_.size(); ++i) {
215 const std::string& arg =
args_[i];
216 if (!absl::StartsWith(arg,
"--")) {
217 positional.push_back(arg);
218 }
else if (arg.find(
'=') == std::string::npos && i + 1 <
args_.size()) {
227 const std::vector<std::string>& required)
const {
228 std::vector<std::string> missing;
229 for (
const auto& arg : required) {
231 missing.push_back(
"--" + arg);
235 if (!missing.empty()) {
236 return absl::InvalidArgumentError(
237 absl::StrFormat(
"Missing required arguments: %s",
238 absl::StrJoin(missing,
", ")));
241 return absl::OkStatus();
249 const std::string& format) {
250 std::string lower = absl::AsciiStrToLower(format);
251 if (lower ==
"json") {
253 }
else if (lower ==
"text") {
256 return absl::InvalidArgumentError(
257 absl::StrFormat(
"Unknown format: %s (expected 'json' or 'text')",
267 }
else if (
IsText() && !title.empty()) {
268 buffer_ += absl::StrFormat(
"=== %s ===\n", title);
290 buffer_ += absl::StrFormat(
" %-20s : %s\n", key, value);
303 buffer_ += absl::StrFormat(
" %-20s : %d\n", key, value);
316 buffer_ += absl::StrFormat(
" %-20s : %llu\n", key, value);
328 value ?
"true" :
"false");
330 buffer_ += absl::StrFormat(
" %-20s : %s\n", key, value ?
"yes" :
"no");
344 buffer_ += absl::StrFormat(
" %-20s : 0x%0*X\n", key, width, value);
361 buffer_ += absl::StrFormat(
" %s:\n", key);
384 buffer_ += absl::StrFormat(
" - %s\n", item);
408 result.reserve(str.size() + 10);
412 case '"': result +=
"\\\"";
break;
413 case '\\': result +=
"\\\\";
break;
414 case '\b': result +=
"\\b";
break;
415 case '\f': result +=
"\\f";
break;
416 case '\n': result +=
"\\n";
break;
417 case '\r': result +=
"\\r";
break;
418 case '\t': result +=
"\\t";
break;
421 result += absl::StrFormat(
"\\u%04x",
static_cast<int>(c));
The Rom class is used to load, save, and modify Rom data.
absl::Status LoadFromFile(const std::string &filename, bool z3_load=true)
core::ResourceLabelManager * resource_label()
std::optional< std::string > FindArgValue(const std::string &name) const
std::vector< std::string > args_
ArgumentParser(const std::vector< std::string > &args)
std::vector< std::string > GetPositional() const
Get all remaining positional arguments.
std::optional< std::string > GetString(const std::string &name) const
Parse a named argument (e.g., –format=json or –format json)
bool HasFlag(const std::string &name) const
Check if a flag is present.
absl::Status RequireArgs(const std::vector< std::string > &required) const
Validate that required arguments are present.
absl::StatusOr< int > GetHex(const std::string &name) const
Parse a hex integer argument.
absl::StatusOr< int > GetInt(const std::string &name) const
Parse an integer argument (supports hex with 0x prefix)
absl::StatusOr< Rom * > GetRom()
Get the ROM instance (loads if not already loaded)
absl::Status EnsureLabelsLoaded(Rom *rom)
Ensure resource labels are loaded.
absl::Status Initialize()
Initialize the context and load ROM if needed.
CommandContext(const Config &config)
ABSL_DECLARE_FLAG(std::string, rom)
absl::Status InitializeMockRom(Rom &rom)
Initialize a mock ROM for testing without requiring an actual ROM file.
Main namespace for the application.
Configuration for command context.
std::optional< std::string > rom_path
Rom * external_rom_context
std::unordered_map< std::string, std::unordered_map< std::string, std::string > > labels_
Modern project structure with comprehensive settings consolidation.
std::unordered_map< std::string, std::unordered_map< std::string, std::string > > resource_labels
absl::Status InitializeEmbeddedLabels()