wvstreamsdebugger.cc

00001 #include "wvstreamsdebugger.h"
00002 #include "wvlinklist.h"
00003 
00004 
00005 static const int command_map_size = 16;
00006 
00007 DeclareWvList(WvStreamsDebugger);
00008 static WvStreamsDebuggerList *debuggers;
00009 
00010 
00011 WvStreamsDebugger::CommandMap *WvStreamsDebugger::commands;
00012 
00013 
00014 class WvStreamsDebuggerStaticInitCleanup
00015 {
00016 public:
00017     WvStreamsDebuggerStaticInitCleanup()
00018     {
00019         WvStreamsDebugger::add_command("help",
00020                 0, &WvStreamsDebugger::help_run_cb, 0);
00021     }
00022     ~WvStreamsDebuggerStaticInitCleanup()
00023     {
00024         assert(!debuggers || debuggers->isempty());
00025         
00026         if (WvStreamsDebugger::commands)
00027         {
00028             WvStreamsDebugger::CommandMap::Iter i(*WvStreamsDebugger::commands);
00029             for (i.rewind(); i.next(); )
00030                 delete i->data;
00031             WvStreamsDebugger::commands->zap();
00032             delete WvStreamsDebugger::commands;
00033             WvStreamsDebugger::commands = NULL;
00034         }
00035         
00036         if (debuggers)
00037         {
00038             delete debuggers;
00039             debuggers = NULL;
00040         }
00041     }
00042 };
00043 static WvStreamsDebuggerStaticInitCleanup ___;
00044 
00045 
00046 void *WvStreamsDebugger::get_command_data(WvStringParm cmd, Command *command)
00047 {
00048     if (command == NULL)
00049     {
00050         Command **pcommand = commands->find(cmd);
00051         if (!pcommand)
00052             return NULL;
00053         command = *pcommand;
00054     }
00055     
00056     void **pcd = (void **)command_data.find(cmd);
00057     void *cd;
00058     if (pcd == NULL)
00059     {
00060         // In case the command has been added since our constructor
00061         // was executed...
00062         
00063         if (!!command->init_cb)
00064             cd = command->init_cb(cmd);
00065         else
00066             cd = NULL;
00067             
00068         command_data.add(cmd, (char *)cd);
00069     }
00070     else
00071         cd = *pcd;
00072     
00073     return cd;
00074 }
00075 
00076 
00077 WvStreamsDebugger::WvStreamsDebugger() :
00078     command_data(command_map_size)
00079 {
00080     if (!debuggers)
00081         debuggers = new WvStreamsDebuggerList;
00082     debuggers->append(this, false);
00083     
00084     // Add command data for existing commands
00085     CommandMap::Iter i(*commands);
00086     for (i.rewind(); i.next(); )
00087         (void)get_command_data(i->key, i->data);
00088 }
00089 
00090 
00091 WvStreamsDebugger::~WvStreamsDebugger()
00092 {
00093     // Remove command data
00094     CommandDataMap::Iter i(command_data);
00095     for (i.rewind(); i.next(); )
00096     {
00097         WvString cmd = i->key;
00098         void *cd = i->data;
00099         
00100         Command *command = (*commands)[cmd];
00101         if (!!command->cleanup_cb)
00102             command->cleanup_cb(cmd, cd);
00103     }
00104     command_data.zap();
00105     
00106     debuggers->unlink(this);
00107 }
00108 
00109 
00110 WvString WvStreamsDebugger::run(WvStringParm cmd, WvStringList &args,
00111         ResultCallback result_cb)
00112 {
00113     Command **pcommand = commands->find(cmd);
00114     if (!pcommand)
00115         return "No such command";
00116     Command *command = *pcommand;
00117    
00118     return command->run_cb(cmd, args, result_cb, get_command_data(cmd, command));
00119 }
00120 
00121 
00122 bool WvStreamsDebugger::add_command(WvStringParm cmd,
00123         InitCallback init_cb,
00124         RunCallback run_cb,
00125         CleanupCallback cleanup_cb)
00126 {
00127     if (!commands)
00128         commands = new CommandMap(command_map_size);
00129         
00130     if (commands->exists(cmd))
00131         return false;
00132     Command *command = new Command(init_cb, run_cb, cleanup_cb);
00133     commands->add(cmd, command);
00134     return true;
00135 }
00136 
00137 
00138 bool WvStreamsDebugger::foreach(WvStringParm cmd, ForeachCallback foreach_cb)
00139 {
00140     Command **pcommand = commands->find(cmd);
00141     if (!pcommand)
00142         return false;
00143     Command *command = *pcommand;
00144     
00145     if (debuggers)
00146     {
00147         WvStreamsDebuggerList::Iter i(*debuggers);
00148         for (i.rewind(); i.next(); )
00149         {
00150             void *cd = i->get_command_data(cmd, command);
00151             foreach_cb(cmd, cd); 
00152         }
00153     }
00154     
00155     return true;
00156 }
00157 
00158 
00159 WvString WvStreamsDebugger::help_run_cb(WvStringParm cmd,
00160         WvStringList &args,
00161         ResultCallback result_cb, void *)
00162 {
00163     WvStringList cmd_list;
00164     cmd_list.append("Commands availible:");
00165     CommandMap::Iter i(*commands);
00166     for (i.rewind(); i.next(); )
00167         cmd_list.append(i->key);
00168     result_cb(cmd, cmd_list);
00169     return WvString::null;
00170 }

Generated on Thu Jan 24 16:50:57 2008 for WvStreams by  doxygen 1.5.4