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