openMSX
TclArgParser.hh
Go to the documentation of this file.
1 #ifndef TCLARGPARSER_HH
2 #define TCLARGPARSER_HH
3 
4 #include "CommandException.hh"
5 #include "TclObject.hh"
6 #include "span.hh"
7 #include <functional>
8 #include <optional>
9 #include <string_view>
10 #include <vector>
11 
12 namespace openmsx {
13 
14 namespace detail {
15  template<typename T> struct GetArg;
16 
17  template<> struct GetArg<bool> {
18  void operator()(Interpreter& interp, const TclObject& obj, bool& result) const {
19  result = obj.getBoolean(interp);
20  }
21  };
22  template<> struct GetArg<int> {
23  void operator()(Interpreter& interp, const TclObject& obj, int& result) const {
24  result = obj.getInt(interp);
25  }
26  };
27  template<> struct GetArg<double> {
28  void operator()(Interpreter& interp, const TclObject& obj, double& result) const {
29  result = obj.getDouble(interp);
30  }
31  };
32  template<> struct GetArg<std::string_view> {
33  void operator()(Interpreter& /*interp*/, const TclObject& obj, std::string_view& result) const {
34  result = obj.getString();
35  }
36  };
37  template<> struct GetArg<std::string> {
38  void operator()(Interpreter& /*interp*/, const TclObject& obj, std::string& result) const {
39  result = std::string(obj.getString());
40  }
41  };
42  template<> struct GetArg<TclObject> {
43  void operator()(Interpreter& /*interp*/, const TclObject& obj, TclObject& result) const {
44  result = obj;
45  }
46  };
47 
48  template<typename T> struct GetArg<std::optional<T>> {
49  void operator()(Interpreter& interp, const TclObject& obj, std::optional<T>& result) const {
50  T t;
51  GetArg<T>{}(interp, obj, t);
52  result = std::move(t);
53  }
54  };
55 
56  template<typename T> struct GetArg<std::vector<T>> {
57  void operator()(Interpreter& interp, const TclObject& obj, std::vector<T>& result) const {
58  result.emplace_back();
59  GetArg<T>{}(interp, obj, result.back());
60  }
61  };
62 }
63 
64 // A Tcl-argument-parser description is made out of ArgsInfo objects
65 struct ArgsInfo
66 {
67  std::string_view name;
68  std::function<unsigned(Interpreter&, span<const TclObject>)> func;
69 };
70 
71 // Parse a flag.
72 inline ArgsInfo flagArg(std::string_view name, bool& flag)
73 {
74  return {
75  name,
76  [&flag](Interpreter& /*interp*/, span<const TclObject> /*args*/) {
77  flag = true;
78  return 0;
79  }
80  };
81 }
82 
83 // Parse a value (like a flag but with associated value).
84 template<typename T>
85 ArgsInfo valueArg(std::string_view name, T& value)
86 {
87  return {
88  name,
89  [name, &value](Interpreter& interp, span<const TclObject> args) {
90  if (args.empty()) {
91  throw CommandException("missing argument for ", name);
92  }
93  detail::GetArg<T>{}(interp, args.front(), value);
94  return 1;
95  }
96  };
97 }
98 
99 // Parse the given 'inArgs' arguments.
100 // The recognized flags/values are described in 'table'.
101 // The result of this parser is the collection of non-flag arguments.
102 // See src/unittest/TclArgParser.cc for example usages.
103 std::vector<TclObject> parseTclArgs(Interpreter& interp, span<const TclObject> inArgs, span<const ArgsInfo> table);
104 
105 } // namespace openmsx
106 
107 #endif
void operator()(Interpreter &, const TclObject &obj, std::string &result) const
Definition: TclArgParser.hh:38
void operator()(Interpreter &interp, const TclObject &obj, std::vector< T > &result) const
Definition: TclArgParser.hh:57
std::string_view name
Definition: TclArgParser.hh:67
ArgsInfo flagArg(std::string_view name, bool &flag)
Definition: TclArgParser.hh:72
Definition: span.hh:34
STL namespace.
void operator()(Interpreter &, const TclObject &obj, TclObject &result) const
Definition: TclArgParser.hh:43
Definition: join.hh:10
void operator()(Interpreter &interp, const TclObject &obj, double &result) const
Definition: TclArgParser.hh:28
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
constexpr Table table
Definition: CPUCore.cc:263
void operator()(Interpreter &interp, const TclObject &obj, int &result) const
Definition: TclArgParser.hh:23
std::string_view getString() const
Definition: TclObject.cc:102
bool getBoolean(Interpreter &interp) const
Definition: TclObject.cc:82
void operator()(Interpreter &, const TclObject &obj, std::string_view &result) const
Definition: TclArgParser.hh:33
double getDouble(Interpreter &interp) const
Definition: TclObject.cc:92
int getInt(Interpreter &interp) const
Definition: TclObject.cc:72
void operator()(Interpreter &interp, const TclObject &obj, std::optional< T > &result) const
Definition: TclArgParser.hh:49
void operator()(Interpreter &interp, const TclObject &obj, bool &result) const
Definition: TclArgParser.hh:18
ArgsInfo valueArg(std::string_view name, T &value)
Definition: TclArgParser.hh:85
TclObject t
std::vector< TclObject > parseTclArgs(Interpreter &interp, span< const TclObject > inArgs, span< const ArgsInfo > table)