136 absl::Span<const std::string> args) {
138 return absl::InvalidArgumentError(
"rom requires a subcommand");
140 for (
const RomSubcommand& subcommand : kRomSubcommands) {
141 if (args[0] == subcommand.name) {
143 .
command = absl::StrCat(
"rom-", subcommand.name),
144 .args = {args.begin() + 1, args.end()},
148 return absl::InvalidArgumentError(
149 absl::StrCat(
"Unknown rom subcommand: ", args[0]));
153 std::vector<absl::string_view> names;
154 names.reserve(std::size(kRomSubcommands));
155 for (
const RomSubcommand& subcommand : kRomSubcommands) {
156 names.push_back(subcommand.name);
170 absl::Span<const std::string> args) {
171 absl::StatusOr<DebugWords> parsed = ExtractDebugBackend(args);
173 return parsed.status();
175 const DebugBackend backend = parsed->backend;
176 const std::vector<std::string>& words = parsed->words;
178 return absl::InvalidArgumentError(
"debug requires a subcommand");
181 const std::string& topic = words[0];
182 std::vector<absl::string_view> actions;
183 for (
const DebugRoute& route : kDebugRoutes) {
184 if (!MatchesTopic(route, topic)) {
187 size_t consumed_words = 1;
188 if (!route.action.empty()) {
189 actions.push_back(route.action);
190 if (words.size() < 2 || words[1] != route.action) {
196 const absl::string_view command = backend == DebugBackend::kGrpc
198 : route.mesen_command;
199 if (command.empty()) {
200 return absl::FailedPreconditionError(absl::StrCat(
201 "debug ", topic,
" has no gRPC backend; use --backend=mesen"));
205 .
command = std::string(command),
206 .args = {words.begin() + consumed_words, words.end()},
208 if (backend == DebugBackend::kMesen && !route.mesen_extra_arg.empty()) {
209 invocation.args.emplace_back(route.mesen_extra_arg);
214 if (!actions.empty()) {
215 return absl::InvalidArgumentError(absl::StrCat(
216 "debug ", topic,
" requires one of: ", absl::StrJoin(actions,
", ")));
218 return absl::InvalidArgumentError(
219 absl::StrCat(
"Unknown debug subcommand: ", topic));