openMSX
InfoCommand.cc
Go to the documentation of this file.
1 #include "InfoCommand.hh"
2 #include "InfoTopic.hh"
3 #include "TclObject.hh"
5 #include "CliComm.hh"
6 #include "CommandException.hh"
7 #include "MSXMotherBoard.hh"
8 #include "KeyRange.hh"
9 #include "unreachable.hh"
10 #include <iostream>
11 #include <cassert>
12 
13 using std::string;
14 using std::vector;
15 
16 namespace openmsx {
17 
18 InfoCommand::InfoCommand(CommandController& commandController, const string& name)
19  : Command(commandController, name)
20 {
21 }
22 
24 {
25  assert(infoTopics.empty());
26 }
27 
29 {
30 #ifndef NDEBUG
31  if (infoTopics.find(name) != infoTopics.end()) {
32  std::cerr << "INTERNAL ERROR: already have a info topic with "
33  "name " << name << std::endl;
35  }
36 #endif
37  infoTopics[name] = &topic;
38 }
39 
41 {
42  (void)topic;
43  if (infoTopics.find(name) == infoTopics.end()) {
44  std::cerr << "INTERNAL ERROR: can't unregister topic with name "
45  "name " << name << ", not found!" << std::endl;
47  }
48  assert(infoTopics[name] == &topic);
49  infoTopics.erase(name);
50 }
51 
52 // Command
53 
54 void InfoCommand::execute(const vector<TclObject>& tokens,
55  TclObject& result)
56 {
57  switch (tokens.size()) {
58  case 1:
59  // list topics
60  for (auto& p : infoTopics) {
61  result.addListElement(p.first());
62  }
63  break;
64  default:
65  // show info about topic
66  assert(tokens.size() >= 2);
67  const auto& topic = tokens[1].getString();
68  auto it = infoTopics.find(topic);
69  if (it == infoTopics.end()) {
70  throw CommandException("No info on: " + topic);
71  }
72  it->second->execute(tokens, result);
73  break;
74  }
75 }
76 
77 string InfoCommand::help(const vector<string>& tokens) const
78 {
79  string result;
80  switch (tokens.size()) {
81  case 1:
82  // show help on info cmd
83  result = "Show info on a certain topic\n"
84  " info [topic] [...]\n";
85  break;
86  default:
87  // show help on a certain topic
88  assert(tokens.size() >= 2);
89  auto it = infoTopics.find(tokens[1]);
90  if (it == infoTopics.end()) {
91  throw CommandException("No info on: " + tokens[1]);
92  }
93  result = it->second->help(tokens);
94  break;
95  }
96  return result;
97 }
98 
99 void InfoCommand::tabCompletion(vector<string>& tokens) const
100 {
101  switch (tokens.size()) {
102  case 2: {
103  // complete topic
104  completeString(tokens, keys(infoTopics));
105  break;
106  }
107  default:
108  // show help on a certain topic
109  assert(tokens.size() >= 3);
110  auto it = infoTopics.find(tokens[1]);
111  if (it != infoTopics.end()) {
112  it->second->tabCompletion(tokens);
113  }
114  break;
115  }
116 }
117 
118 } // namespace openmsx