openMSX
commands/TclArgParser.cc
Go to the documentation of this file.
1 #include "TclArgParser.hh"
2 #include "CommandException.hh"
3 #include "join.hh"
4 #include "ranges.hh"
5 #include "stl.hh"
6 #include "view.hh"
7 
8 namespace openmsx {
9 
10 std::vector<TclObject> parseTclArgs(Interpreter& interp, span<const TclObject> inArgs, span<const ArgsInfo> table)
11 {
12  std::vector<TclObject> outArgs;
13  outArgs.reserve(inArgs.size());
14 
15  while (!inArgs.empty()) {
16  auto arg = inArgs.front();
17  auto argStr = arg.getString();
18  inArgs = inArgs.subspan<1>();
19  if (argStr.starts_with('-')) {
20  if (argStr == "--") {
21  append(outArgs, inArgs);
22  break;
23  }
24  auto it = ranges::find_if(table, [&](const auto& info) { return info.name == argStr; });
25  if (it == table.end()) {
26  throw CommandException(
27  "Invalid option: '", argStr, "'. Must be one of ",
28  join(view::transform(table, [](auto& info) {
29  return strCat('\'', info.name, '\'');
30  }), ", "), '.');
31  }
32  auto consumed = it->func(interp, inArgs);
33  inArgs = inArgs.subspan(consumed);
34  } else {
35  outArgs.push_back(arg);
36  }
37  }
38 
39  return outArgs;
40 }
41 
42 } // namespace openmsx
auto transform(Range &&range, UnaryOp op)
Definition: view.hh:312
Definition: span.hh:34
auto find_if(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:113
void append(Result &)
Definition: stl.hh:354
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
std::string strCat(Ts &&...ts)
Definition: strCat.hh:577
detail::Joiner< Collection, Separator > join(Collection &&col, Separator &&sep)
Definition: join.hh:60
std::vector< TclObject > parseTclArgs(Interpreter &interp, span< const TclObject > inArgs, span< const ArgsInfo > table)