WvStreams
wvstreamsdebugger.cc
1 #include <set>
2 #include "wvstreamsdebugger.h"
3 #include "wvlinklist.h"
4 
5 using std::set;
6 
7 
8 static set<WvStreamsDebugger*> *debuggers;
9 
10 
11 WvStreamsDebugger::CommandMap *WvStreamsDebugger::commands;
12 
13 
15 {
16 public:
18  {
19  WvStreamsDebugger::add_command("help",
20  0, &WvStreamsDebugger::help_run_cb, 0);
21  }
23  {
24  assert(!debuggers || debuggers->empty());
25 
26  if (WvStreamsDebugger::commands)
27  {
28  delete WvStreamsDebugger::commands;
29  WvStreamsDebugger::commands = NULL;
30  }
31 
32  if (debuggers)
33  {
34  delete debuggers;
35  debuggers = NULL;
36  }
37  }
38 };
40 
41 
42 void *WvStreamsDebugger::get_command_data(WvStringParm cmd, Command *command)
43 {
44  if (command == NULL)
45  {
46  CommandMap::iterator it = commands->find(cmd);
47  if (it == commands->end())
48  return NULL;
49  command = &it->second;
50  }
51 
52  void *cd;
53  CommandDataMap::iterator it = command_data.find(cmd);
54  if (it == command_data.end())
55  {
56  // In case the command has been added since our constructor
57  // was executed...
58  if (command->init_cb)
59  cd = command->init_cb(cmd);
60  else
61  cd = NULL;
62 
63  command_data[cmd] = cd;
64  }
65  else
66  cd = it->second;
67 
68  return cd;
69 }
70 
71 
72 WvStreamsDebugger::WvStreamsDebugger()
73 {
74  if (!debuggers)
75  debuggers = new set<WvStreamsDebugger*>;
76  debuggers->insert(this);
77 
78  // Add command data for existing commands
79  CommandMap::iterator it;
80  for (it = commands->begin(); it != commands->end(); ++it)
81  get_command_data(it->first, &it->second);
82 }
83 
84 
85 WvStreamsDebugger::~WvStreamsDebugger()
86 {
87  // Remove command data
88  CommandDataMap::iterator it;
89  for (it = command_data.begin(); it != command_data.end(); ++it)
90  {
91  CommandMap::iterator it2 = commands->find(it->first);
92  if (it2 != commands->end() && it2->second.cleanup_cb)
93  it2->second.cleanup_cb(it->first, it->second);
94  }
95  command_data.clear();
96 
97  debuggers->erase(this);
98 }
99 
100 
101 WvString WvStreamsDebugger::run(WvStringParm cmd, WvStringList &args,
102  ResultCallback result_cb)
103 {
104  CommandMap::iterator it = commands->find(cmd);
105  if (it == commands->end())
106  return "No such command";
107  Command *command = &it->second;
108 
109  return command->run_cb(cmd, args, result_cb,
110  get_command_data(cmd, command));
111 }
112 
113 
114 bool WvStreamsDebugger::add_command(WvStringParm cmd,
115  InitCallback init_cb,
116  RunCallback run_cb,
117  CleanupCallback cleanup_cb)
118 {
119  if (!commands)
120  commands = new CommandMap;
121 
122  return commands->insert(
123  std::make_pair(cmd, Command(init_cb, run_cb, cleanup_cb))).second;
124 }
125 
126 
127 bool WvStreamsDebugger::foreach(WvStringParm cmd, ForeachCallback foreach_cb)
128 {
129  CommandMap::iterator it = commands->find(cmd);
130 
131  if (it == commands->end())
132  return false;
133 
134  if (debuggers)
135  {
136  set<WvStreamsDebugger*>::iterator it2;
137  for (it2 = debuggers->begin(); it2 != debuggers->end(); ++it2)
138  {
139  void *cd = (*it2)->get_command_data(cmd, &it->second);
140  foreach_cb(cmd, cd);
141  }
142  }
143 
144  return true;
145 }
146 
147 
148 WvString WvStreamsDebugger::help_run_cb(WvStringParm cmd,
149  WvStringList &args,
150  ResultCallback result_cb, void *)
151 {
152  WvStringList cmd_list;
153  cmd_list.append("Commands available:");
154  CommandMap::iterator it;
155  for (it = commands->begin(); it != commands->end(); ++it)
156  cmd_list.append(it->first);
157  result_cb(cmd, cmd_list);
158  return WvString::null;
159 }
WvString
WvString is an implementation of a simple and efficient printable-string class.
Definition: wvstring.h:329
WvStreamsDebuggerStaticInitCleanup
Definition: wvstreamsdebugger.cc:14
WvStringList
This is a WvList of WvStrings, and is a really handy way to parse strings.
Definition: wvstringlist.h:27