openMSX
InfoCommand.cc
Go to the documentation of this file.
1 #include "InfoCommand.hh"
2 #include "TclObject.hh"
3 #include "CommandException.hh"
4 #include "KeyRange.hh"
5 #include "unreachable.hh"
6 #include <iostream>
7 #include <cassert>
8 
9 using std::string;
10 using std::vector;
11 
12 namespace openmsx {
13 
14 InfoCommand::InfoCommand(CommandController& commandController_, const string& name_)
15  : Command(commandController_, name_)
16 {
17 }
18 
20 {
21  assert(infoTopics.empty());
22 }
23 
25 {
26 #ifndef NDEBUG
27  if (infoTopics.contains(topic.getName())) {
28  std::cerr << "INTERNAL ERROR: already have an info topic with "
29  "name " << topic.getName() << std::endl;
31  }
32 #endif
33  infoTopics.insert_noDuplicateCheck(&topic);
34 }
35 
37 {
38  if (!infoTopics.contains(topic.getName())) {
39  std::cerr << "INTERNAL ERROR: can't unregister topic with name "
40  << topic.getName() << ", not found!" << std::endl;
42  }
43  infoTopics.erase(topic.getName());
44 }
45 
46 // Command
47 
48 void InfoCommand::execute(array_ref<TclObject> tokens,
49  TclObject& result)
50 {
51  switch (tokens.size()) {
52  case 1:
53  // list topics
54  for (auto* t : infoTopics) {
55  result.addListElement(t->getName());
56  }
57  break;
58  default:
59  // show info about topic
60  assert(tokens.size() >= 2);
61  const auto& topic = tokens[1].getString();
62  auto it = infoTopics.find(topic);
63  if (it == end(infoTopics)) {
64  throw CommandException("No info on: " + topic);
65  }
66  (*it)->execute(tokens, result);
67  break;
68  }
69 }
70 
71 string InfoCommand::help(const vector<string>& tokens) const
72 {
73  string result;
74  switch (tokens.size()) {
75  case 1:
76  // show help on info cmd
77  result = "Show info on a certain topic\n"
78  " info [topic] [...]\n";
79  break;
80  default:
81  // show help on a certain topic
82  assert(tokens.size() >= 2);
83  auto it = infoTopics.find(tokens[1]);
84  if (it == end(infoTopics)) {
85  throw CommandException("No info on: " + tokens[1]);
86  }
87  result = (*it)->help(tokens);
88  break;
89  }
90  return result;
91 }
92 
93 void InfoCommand::tabCompletion(vector<string>& tokens) const
94 {
95  switch (tokens.size()) {
96  case 2: {
97  // complete topic
98  vector<string_ref> topics;
99  for (auto* t : infoTopics) {
100  topics.push_back(t->getName());
101  }
102  completeString(tokens, topics);
103  break;
104  }
105  default:
106  // show help on a certain topic
107  assert(tokens.size() >= 3);
108  auto it = infoTopics.find(tokens[1]);
109  if (it != end(infoTopics)) {
110  (*it)->tabCompletion(tokens);
111  }
112  break;
113  }
114 }
115 
116 } // namespace openmsx
void registerTopic(InfoTopic &topic)
Definition: InfoCommand.cc:24
string_ref::const_iterator end(const string_ref &x)
Definition: string_ref.hh:167
size_type size() const
Definition: array_ref.hh:61
const std::string & getName() const
Definition: Completer.hh:16
InfoCommand(CommandController &commandController, const std::string &name)
Definition: InfoCommand.cc:14
This class implements a subset of the proposal for std::array_ref (proposed for the next c++ standard...
Definition: array_ref.hh:19
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
static void completeString(std::vector< std::string > &tokens, ITER begin, ITER end, bool caseSensitive=true)
Definition: Completer.hh:105
void addListElement(string_ref element)
Definition: TclObject.cc:69
void unregisterTopic(InfoTopic &topic)
Definition: InfoCommand.cc:36
#define UNREACHABLE
Definition: unreachable.hh:35