yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
command_handler.cc
Go to the documentation of this file.
2
3#include <iostream>
4#include <optional>
5#include <utility>
6
7#include "absl/flags/declare.h"
8#include "absl/flags/flag.h"
10#include "util/macro.h"
11
12ABSL_DECLARE_FLAG(bool, sandbox);
13
14namespace yaze {
15namespace cli {
16namespace resources {
17
18absl::Status CommandHandler::Run(const std::vector<std::string>& args,
19 Rom* rom_context,
20 std::string* captured_output) {
21 // 1. Parse arguments
22 ArgumentParser parser(args);
23
24 // 2. Validate arguments
25 auto validation_status = ValidateArgs(parser);
26 if (!validation_status.ok()) {
27 std::cerr << "Error: " << validation_status.message() << "\n\n";
28 std::cerr << "Usage: " << GetUsage() << "\n";
29 return validation_status;
30 }
31
32 // 3. Get format string (output format). Some commands reuse --format for
33 // data formatting (hex/ascii/both). If so, fall back to default output.
34 std::string format_str =
35 parser.GetString("format").value_or(GetDefaultFormat());
36
37 // 4. Create output formatter
38 auto formatter_or = OutputFormatter::FromString(format_str);
39 if (!formatter_or.ok()) {
40 if (format_str == "hex" || format_str == "ascii" || format_str == "both" ||
41 format_str == "binary") {
43 } else {
44 return formatter_or.status();
45 }
46 }
47 OutputFormatter formatter = std::move(formatter_or.value());
48
49 // 5. Setup command context
51 config.external_rom_context = rom_context;
52 config.format = format_str;
53 config.verbose = parser.HasFlag("verbose");
54
55 // Check for --rom override
56 if (auto rom_path = parser.GetString("rom"); rom_path.has_value()) {
57 config.rom_path = *rom_path;
58 }
59
60 // Check for --symbols override
61 if (auto symbols_path = parser.GetString("symbols");
62 symbols_path.has_value()) {
63 config.symbols_path = *symbols_path;
64 }
65
66 // Optional project runtime context used to mirror editor feature/custom object
67 // behavior during CLI execution.
68 if (auto project_path = parser.GetString("project-context");
69 project_path.has_value()) {
70 config.project_context_path = *project_path;
71 }
72
73 // Check for --mock-rom flag
74 config.use_mock_rom = parser.HasFlag("mock-rom");
75
76 CommandContext context(config);
77
78 // 6. Get ROM (loads if needed) - only if command requires it
79 Rom* rom = nullptr;
80 std::optional<Rom> sandbox_rom;
81 bool sandbox_enabled = false;
82
83 // Set symbol provider regardless of ROM loading (it might load its own symbols)
85
86 if (RequiresRom()) {
87 ASSIGN_OR_RETURN(rom, context.GetRom());
88 SetRomContext(rom);
90
91 if (absl::GetFlag(FLAGS_sandbox) || parser.HasFlag("sandbox")) {
92 sandbox_enabled = true;
93 auto sandbox_or =
95 if (!sandbox_or.ok()) {
96 return sandbox_or.status();
97 }
98 sandbox_rom.emplace();
99 auto load_status =
100 sandbox_rom->LoadFromFile(sandbox_or->rom_path.string());
101 if (!load_status.ok()) {
102 return load_status;
103 }
104 rom = &*sandbox_rom;
105 SetRomContext(rom);
106 }
107
108 // 7. Ensure labels are loaded if required
109 if (RequiresLabels()) {
111 }
112 }
113
114 // 8. Begin output formatting
115 formatter.BeginObject(GetOutputTitle());
116
117 // 9. Execute command business logic
118 auto execute_status = Execute(rom, parser, formatter);
119 if (!execute_status.ok()) {
120 // Preserve structured output for failing commands so callers can inspect
121 // machine-readable diagnostics even when status is non-OK.
122 formatter.EndObject();
123 if (captured_output) {
124 *captured_output = formatter.GetOutput();
125 } else {
126 formatter.Print();
127 }
128 return execute_status;
129 }
130
131 if (sandbox_enabled && rom != nullptr && rom->dirty()) {
132 auto save_status = rom->SaveToFile({.save_new = false});
133 if (!save_status.ok()) {
134 return save_status;
135 }
136 }
137
138 // 10. Finalize and print output
139 formatter.EndObject();
140
141 if (captured_output) {
142 *captured_output = formatter.GetOutput();
143 } else {
144 formatter.Print();
145 }
146
147 return absl::OkStatus();
148}
149
151 Descriptor descriptor;
152 descriptor.display_name = GetName(); // Use GetName() for display.
153 descriptor.summary = "Command summary not provided.";
154 descriptor.todo_reference = "todo#unassigned";
155 return descriptor;
156}
157
158} // namespace resources
159} // namespace cli
160} // namespace yaze
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
absl::Status SaveToFile(const SaveSettings &settings)
Definition rom.cc:291
bool dirty() const
Definition rom.h:133
absl::StatusOr< SandboxMetadata > CreateSandbox(Rom &rom, absl::string_view description)
static RomSandboxManager & Instance()
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)
bool HasFlag(const std::string &name) const
Check if a flag is present.
Encapsulates common context for CLI command execution.
absl::StatusOr< Rom * > GetRom()
Get the ROM instance (loads if not already loaded)
absl::Status EnsureLabelsLoaded(Rom *rom)
Ensure resource labels are loaded.
project::YazeProject * GetProjectContext()
Returns loaded project context when –project-context was used.
emu::debug::SymbolProvider * GetSymbolProvider()
Get the SymbolProvider instance.
virtual bool RequiresLabels() const
Check if the command requires ROM labels.
virtual std::string GetUsage() const =0
Get the command usage string.
virtual std::string GetName() const =0
Get the command name.
virtual void SetRomContext(Rom *rom)
Set the ROM context for tools that need ROM access. Default implementation stores the ROM pointer for...
virtual absl::Status Execute(Rom *rom, const ArgumentParser &parser, OutputFormatter &formatter)=0
Execute the command business logic.
virtual void SetSymbolProvider(emu::debug::SymbolProvider *provider)
Set the SymbolProvider context.
absl::Status Run(const std::vector< std::string > &args, Rom *rom_context, std::string *captured_output=nullptr)
Execute the command.
virtual std::string GetOutputTitle() const
Get the output title for formatting.
virtual std::string GetDefaultFormat() const
Get the default output format ("json" or "text")
virtual bool RequiresRom() const
Check if the command requires a loaded ROM.
virtual void SetProjectContext(project::YazeProject *project)
Set the YazeProject context. Default implementation does nothing, override if tool needs project info...
virtual Descriptor Describe() const
Provide metadata for TUI/help summaries.
virtual absl::Status ValidateArgs(const ArgumentParser &parser)=0
Validate command arguments.
Utility for consistent output formatting across commands.
std::string GetOutput() const
Get the formatted output.
static absl::StatusOr< OutputFormatter > FromString(const std::string &format)
Create formatter from string ("json" or "text")
void BeginObject(const std::string &title="")
Start a JSON object or text section.
void EndObject()
End a JSON object or text section.
void Print() const
Print the formatted output to stdout.
ABSL_DECLARE_FLAG(bool, sandbox)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Definition macro.h:62
#define RETURN_IF_ERROR(expr)
Definition snes.cc:22
Configuration for command context.
std::optional< std::string > project_context_path
std::optional< std::string > symbols_path