WvStreams
wvstreamsdebugger.cc
1#include <set>
2#include "wvstreamsdebugger.h"
3#include "wvlinklist.h"
4
5using std::set;
6
7
8static set<WvStreamsDebugger*> *debuggers;
9
10
11WvStreamsDebugger::CommandMap *WvStreamsDebugger::commands;
12
13
15{
16public:
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
42void *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
72WvStreamsDebugger::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
85WvStreamsDebugger::~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
101WvString 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
114bool 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
127bool 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
148WvString 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}
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
Definition wvstring.h:94
This is a WvList of WvStrings, and is a really handy way to parse strings.
WvString is an implementation of a simple and efficient printable-string class.
Definition wvstring.h:330