00001 #ifndef NO_GPL
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #else
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 #endif
00056
00057
00058 #include <rtt/Logger.hpp>
00059 #include <rtt/extras/MultiVector.hpp>
00060 #include <rtt/types/TypeStream.hpp>
00061 #include <rtt/types/Types.hpp>
00062 #include "TaskBrowser.hpp"
00063
00064 #include <rtt/scripting/TryCommand.hpp>
00065 #include <rtt/TaskContext.hpp>
00066 #include <rtt/plugin/PluginLoader.hpp>
00067 #include <rtt/scripting/parser-debug.hpp>
00068 #include <rtt/scripting/Parser.hpp>
00069 #include <rtt/scripting/parse_exception.hpp>
00070 #include <rtt/scripting/PeerParser.hpp>
00071 #include <rtt/scripting/Scripting.hpp>
00072 #include <rtt/plugin/PluginLoader.hpp>
00073 #include <rtt/internal/GlobalService.hpp>
00074 #include <rtt/types/GlobalsRepository.hpp>
00075 #include <boost/algorithm/string.hpp>
00076
00077 #include <iostream>
00078 #include <fstream>
00079 #include <sstream>
00080 #include <iomanip>
00081 #include <deque>
00082 #include <stdio.h>
00083 #include <algorithm>
00084
00085 #if defined(HAS_READLINE) && !defined(NO_GPL)
00086 # define USE_READLINE
00087 #endif
00088 #if defined(HAS_EDITLINE)
00089
00090 # define USE_READLINE
00091 # define USE_EDITLINE
00092 #endif
00093
00094 # if defined(_POSIX_VERSION) && defined(HAS_READLINE) && !defined(HAS_EDITLINE)
00095 # define USE_SIGNALS 1
00096 # endif
00097
00098
00099 #ifdef USE_READLINE
00100 # ifdef USE_EDITLINE
00101 # include <editline/readline.h>
00102 # include <editline/history.h>
00103 # else
00104 # include <readline/readline.h>
00105 # include <readline/history.h>
00106 # endif
00107 #endif
00108 #include <boost/bind.hpp>
00109 #include <boost/lambda/lambda.hpp>
00110
00111 #ifdef USE_SIGNALS
00112 #include <signal.h>
00113 #endif
00114
00115
00116 #if defined(USE_SIGNALS) && defined(OROCOS_TARGET_XENOMAI) && CONFIG_XENO_VERSION_MAJOR == 2 && CONFIG_XENO_VERSION_MINOR >= 5
00117 extern "C"
00118 int xeno_sigwinch_handler(int sig, siginfo_t *si, void *ctxt);
00119 #endif
00120 namespace OCL
00121 {
00122 using namespace boost;
00123 using namespace std;
00124 using namespace RTT;
00125 using namespace RTT::detail;
00126 #ifdef USE_READLINE
00127 std::vector<std::string> TaskBrowser::candidates;
00128 std::vector<std::string> TaskBrowser::completes;
00129 std::vector<std::string>::iterator TaskBrowser::complete_iter;
00130 std::string TaskBrowser::component;
00131 std::string TaskBrowser::component_found;
00132 std::string TaskBrowser::peerpath;
00133 std::string TaskBrowser::text;
00134 #endif
00135 RTT::TaskContext* TaskBrowser::taskcontext = 0;
00136 Service::shared_ptr TaskBrowser::taskobject;
00137 RTT::TaskContext* TaskBrowser::peer = 0;
00138 RTT::TaskContext* TaskBrowser::tb = 0;
00139 RTT::TaskContext* TaskBrowser::context = 0;
00140
00141 using boost::bind;
00142 using namespace RTT;
00143 using namespace std;
00144
00145 string TaskBrowser::red;
00146 string TaskBrowser::green;
00147 string TaskBrowser::blue;
00148 std::deque<TaskContext*> taskHistory;
00149 std::string TaskBrowser::prompt("> ");
00150 std::string TaskBrowser::coloron;
00151 std::string TaskBrowser::underline;
00152 std::string TaskBrowser::coloroff;
00153
00154
00158 static std::ostream&
00159 nl(std::ostream& __os)
00160 { return __os.put(__os.widen('\n')); }
00161
00162
00163 #if defined(USE_READLINE)
00164
00165
00166 #if defined(USE_SIGNALS)
00167
00168 void ctrl_c_catcher(int sig)
00169 {
00170 ::signal(sig, SIG_IGN);
00171 rl_free_line_state();
00172 ::signal(SIGINT, ctrl_c_catcher);
00173 }
00174
00175 void TaskBrowser::rl_sigwinch_handler(int sig, siginfo_t *si, void *ctxt) {
00176 #if defined(OROCOS_TARGET_XENOMAI) && CONFIG_XENO_VERSION_MAJOR == 2 && CONFIG_XENO_VERSION_MINOR >= 5
00177 if (xeno_sigwinch_handler(sig, si, ctxt) == 0)
00178 #endif
00179 rl_resize_terminal();
00180 }
00181 #endif // USE_SIGNALS
00182
00183 char *TaskBrowser::rl_gets ()
00184 {
00185
00186
00187 if (line_read)
00188 {
00189 #ifdef _WIN32
00190
00201 free(line_read);
00202 #else
00203 free (line_read);
00204 #endif
00205 line_read = 0;
00206 }
00207
00208
00209 std::string p;
00210 if ( !macrorecording ) {
00211 p = prompt;
00212 } else {
00213 p = "> ";
00214 }
00215 #if defined(USE_SIGNALS)
00216
00217 if (rl_set_signals() != 0)
00218 cerr << "Error setting signals !" <<endl;
00219 #endif
00220 line_read = readline ( p.c_str() );
00221
00222
00223
00224 if (line_read && *line_read) {
00225
00226 string s = line_read;
00227 if (s != "quit" && ! ( history_get( where_history() ) && s == string(history_get( where_history() )->line) ) ) {
00228
00229
00230 add_history (line_read);
00231 }
00232 }
00233 return (line_read);
00234 }
00235
00236 char* TaskBrowser::dupstr( const char *s )
00237 {
00238 char * rv;
00239
00240 rv = (char*) malloc( strlen( s ) + 1 );
00241 strncpy( rv, s, strlen(s) + 1 );
00242 return rv;
00243 }
00244
00245 char *TaskBrowser::command_generator( const char *_text, int state )
00246 {
00247
00248 if ( !state )
00249 {
00250
00251 text = _text;
00252
00253 completes.clear();
00254 find_completes();
00255 complete_iter = completes.begin();
00256 }
00257 else
00258 ++complete_iter;
00259
00260
00261 if ( complete_iter == completes.end() )
00262 return 0;
00263
00264 return dupstr( complete_iter->c_str() );
00265 }
00266
00271 void TaskBrowser::find_completes() {
00272 std::string::size_type pos;
00273 std::string::size_type startpos;
00274 std::string line( rl_line_buffer, rl_point );
00275
00276
00277 if ( line.find(std::string("cd ")) == 0 || line.find(std::string("ls ")) == 0) {
00278
00279
00280 pos = line.find(" ");
00281 startpos = line.find_last_of(". ");
00282
00283
00284 peer = taskcontext;
00285 if ( pos+1 != line.length() )
00286 peer = findPeer( line.substr(pos+1) );
00287
00288 if (!peer)
00289 return;
00290
00291 RTT::TaskContext::PeerList v = peer->getPeerList();
00292 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00293 std::string path;
00294 if ( !( pos+1 > startpos) )
00295 path = line.substr(pos+1, startpos - pos);
00296
00297 if ( *i == line.substr(startpos+1) )
00298 completes.push_back( path + *i + ".");
00299 else
00300 if ( startpos == std::string::npos || startpos+1 == line.length() || i->find( line.substr(startpos+1)) == 0 )
00301 completes.push_back( path + *i );
00302 }
00303
00304 if (line.find(std::string("cd ")) == 0)
00305 return;
00306
00307 v = peer->provides()->getProviderNames();
00308 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00309 std::string path;
00310 if ( !( pos+1 > startpos) )
00311 path = line.substr(pos+1, startpos - pos);
00312
00313 if ( *i == line.substr(startpos+1) )
00314 completes.push_back( path + *i + ".");
00315 else
00316 if ( startpos == std::string::npos || startpos+1 == line.length() || i->find( line.substr(startpos+1)) == 0 )
00317 completes.push_back( path + *i );
00318 }
00319 return;
00320 }
00321
00322
00323 if ( line.find(std::string(".")) == 0 ) {
00324
00325 std::vector<std::string> tbcoms;
00326 tbcoms.push_back(".loadProgram ");
00327 tbcoms.push_back(".unloadProgram ");
00328 tbcoms.push_back(".loadStateMachine ");
00329 tbcoms.push_back(".unloadStateMachine ");
00330 tbcoms.push_back(".light");
00331 tbcoms.push_back(".dark");
00332 tbcoms.push_back(".hex");
00333 tbcoms.push_back(".nohex");
00334 tbcoms.push_back(".nocolors");
00335 tbcoms.push_back(".connect");
00336 tbcoms.push_back(".record");
00337 tbcoms.push_back(".end");
00338 tbcoms.push_back(".cancel");
00339 tbcoms.push_back(".provide");
00340 tbcoms.push_back(".services");
00341 tbcoms.push_back(".typekits");
00342 tbcoms.push_back(".types");
00343
00344
00345 for( std::vector<std::string>::iterator it = tbcoms.begin();
00346 it != tbcoms.end();
00347 ++it)
00348 if ( it->find(line) == 0 )
00349 completes.push_back( *it );
00350 return;
00351 }
00352
00353 if ( line.find(std::string("list ")) == 0
00354 || line.find(std::string("trace ")) == 0
00355 || line.find(std::string("untrace ")) == 0) {
00356 stringstream ss( line.c_str() );
00357 string lcommand;
00358 ss >> lcommand;
00359 lcommand += ' ';
00360 std::vector<std::string> progs;
00361
00362 if ( context->provides()->hasService("scripting") ) {
00363
00364 progs = context->getProvider<Scripting>("scripting")->getProgramList();
00365
00366 for( std::vector<std::string>::iterator it = progs.begin();
00367 it != progs.end();
00368 ++it) {
00369 string res = lcommand + *it;
00370 if ( res.find(line) == 0 )
00371 completes.push_back( *it );
00372 }
00373 progs = context->getProvider<Scripting>("scripting")->getStateMachineList();
00374 for( std::vector<std::string>::iterator it = progs.begin();
00375 it != progs.end();
00376 ++it) {
00377 string res = lcommand + *it;
00378 if ( res.find(line) == 0 )
00379 completes.push_back( *it );
00380 }
00381 }
00382 return;
00383 }
00384
00385 startpos = text.find_last_of(",( ");
00386 if ( startpos == std::string::npos )
00387 startpos = 0;
00388
00389
00390 find_peers(startpos);
00391
00392
00393
00394
00395
00396
00397 std::string comp = component;
00398
00399
00400
00401
00402
00403 find_ops();
00404
00405
00406
00407 if ( line.empty() ) {
00408 completes.push_back("cd ");
00409 completes.push_back("cd ..");
00410 completes.push_back("ls");
00411 completes.push_back("help");
00412 completes.push_back("quit");
00413 completes.push_back("list");
00414 completes.push_back("trace");
00415 completes.push_back("untrace");
00416 if (taskcontext == context)
00417 completes.push_back("leave");
00418 else
00419 completes.push_back("enter");
00420
00421 }
00422
00423
00424 if ( !text.empty() ) {
00425 if ( std::string( "cd " ).find(text) == 0 )
00426 completes.push_back("cd ");
00427 if ( std::string( "ls" ).find(text) == 0 )
00428 completes.push_back("ls");
00429 if ( std::string( "cd .." ).find(text) == 0 )
00430 completes.push_back("cd ..");
00431 if ( std::string( "help" ).find(text) == 0 )
00432 completes.push_back("help");
00433 if ( std::string( "quit" ).find(text) == 0 )
00434 completes.push_back("quit");
00435 if ( std::string( "list " ).find(text) == 0 )
00436 completes.push_back("list ");
00437 if ( std::string( "trace " ).find(text) == 0 )
00438 completes.push_back("trace ");
00439 if ( std::string( "untrace " ).find(text) == 0 )
00440 completes.push_back("untrace ");
00441
00442 if (taskcontext == context && string("leave").find(text) == 0)
00443 completes.push_back("leave");
00444
00445 if (context == tb && string("enter").find(text) == 0)
00446 completes.push_back("enter");
00447 }
00448 }
00449
00450 void TaskBrowser::find_ops()
00451 {
00452
00453
00454 std::vector<std::string> attrs;
00455 attrs = taskobject->getAttributeNames();
00456 for (std::vector<std::string>::iterator i = attrs.begin(); i!= attrs.end(); ++i ) {
00457 if ( i->find( component ) == 0 )
00458 completes.push_back( peerpath + *i );
00459 }
00460
00461 std::vector<std::string> props;
00462 taskobject->properties()->list(props);
00463 for (std::vector<std::string>::iterator i = props.begin(); i!= props.end(); ++i ) {
00464 if ( i->find( component ) == 0 ) {
00465 completes.push_back( peerpath + *i );
00466 }
00467 }
00468
00469
00470 vector<string> comps = taskobject->getNames();
00471 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00472 if ( i->find( component ) == 0 )
00473 completes.push_back( peerpath + *i );
00474 }
00475
00476
00477 comps = Types()->getDottedTypes();
00478 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00479 if ( peerpath.empty() && i->find( component ) == 0 )
00480 completes.push_back( *i );
00481 }
00482
00483
00484 comps = GlobalsRepository::Instance()->getAttributeNames();
00485 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00486 if ( peerpath.empty() && i->find( component ) == 0 )
00487 completes.push_back( *i );
00488 }
00489
00490
00491 if ( taskobject == peer->provides() && peer == context) {
00492 comps = GlobalService::Instance()->getNames();
00493 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00494 if ( i->find( component ) == 0 )
00495 completes.push_back( peerpath + *i );
00496 }
00497 }
00498
00499
00500 bool try_deeper = false;
00501 try {
00502 Parser parser;
00503 DataSourceBase::shared_ptr result = parser.parseExpression( peerpath + component_found, context );
00504 if (result && !component.empty() ) {
00505 vector<string> members = result->getMemberNames();
00506 for (std::vector<std::string>::iterator i = members.begin(); i!= members.end(); ++i ) {
00507 if ( string( component_found + "." + *i ).find( component ) == 0 )
00508 completes.push_back( peerpath + component_found + "." + *i );
00509 if ( component_found + "." + *i == component )
00510 try_deeper = true;
00511 }
00512 }
00513 } catch(...) {}
00514
00515
00516
00517 if (try_deeper) {
00518 try {
00519 Parser parser;
00520 DataSourceBase::shared_ptr result = parser.parseExpression( peerpath + component, context );
00521 if (result && !component.empty() ) {
00522 vector<string> members = result->getMemberNames();
00523 for (std::vector<std::string>::iterator i = members.begin(); i!= members.end(); ++i ) {
00524 if (component_found + "." != component )
00525 completes.push_back( peerpath + component + "." + *i );
00526 }
00527 }
00528 } catch(...) {}
00529 }
00530 }
00531
00532 void TaskBrowser::find_peers( std::string::size_type startpos )
00533 {
00534 peerpath.clear();
00535 peer = context;
00536 taskobject = context->provides();
00537
00538 std::string to_parse = text.substr(startpos);
00539 startpos = 0;
00540 std::string::size_type endpos = 0;
00541
00542 component.clear();
00543 peerpath.clear();
00544
00545 while (endpos != std::string::npos )
00546 {
00547 bool itemfound = false;
00548 endpos = to_parse.find(".");
00549 if ( endpos == startpos ) {
00550 component.clear();
00551 break;
00552 }
00553 std::string item = to_parse.substr(startpos, endpos);
00554
00555 if ( taskobject->hasService( item ) ) {
00556 taskobject = peer->provides(item);
00557 itemfound = true;
00558 } else
00559 if ( peer->hasPeer( item ) ) {
00560 peer = peer->getPeer( item );
00561 taskobject = peer->provides();
00562 itemfound = true;
00563 } else if ( GlobalService::Instance()->hasService(item) ) {
00564 taskobject = GlobalService::Instance()->provides(item);
00565 itemfound = true;
00566 }
00567 if ( itemfound ) {
00568 peerpath += to_parse.substr(startpos, endpos) + ".";
00569 if ( endpos != std::string::npos )
00570 to_parse = to_parse.substr(endpos + 1);
00571 else
00572 to_parse.clear();
00573 startpos = 0;
00574 }
00575 else {
00576
00577
00578 component_found = to_parse.substr(startpos, to_parse.rfind("."));
00579
00580 component = to_parse.substr(startpos, std::string::npos);
00581 break;
00582 }
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594 RTT::TaskContext::PeerList v;
00595 if ( taskobject == peer->provides() ) {
00596
00597 v = peer->getPeerList();
00598 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00599 if ( i->find( component ) == 0 ) {
00600 completes.push_back( peerpath + *i );
00601 completes.push_back( peerpath + *i + "." );
00602
00603 }
00604 }
00605 }
00606
00607 v = taskobject->getProviderNames();
00608 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00609 if ( i->find( component ) == 0 ) {
00610 completes.push_back( peerpath + *i );
00611 if ( *i != "this" )
00612 completes.push_back( peerpath + *i + "." );
00613
00614 }
00615 }
00616
00617 if ( peer == context && taskobject == peer->provides() ) {
00618 v = GlobalService::Instance()->getProviderNames();
00619 for (RTT::TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00620 if ( i->find( component ) == 0 ) {
00621 completes.push_back( peerpath + *i );
00622 if ( *i != "this" )
00623 completes.push_back( peerpath + *i + "." );
00624
00625 }
00626 }
00627 }
00628 return;
00629 }
00630
00631 char ** TaskBrowser::orocos_hmi_completion ( const char *text, int start, int end )
00632 {
00633 char **matches;
00634 matches = ( char ** ) 0;
00635
00636 matches = rl_completion_matches ( text, &TaskBrowser::command_generator );
00637
00638 return ( matches );
00639 }
00640 #endif // USE_READLINE
00641
00642 TaskBrowser::TaskBrowser( RTT::TaskContext* _c )
00643 : RTT::TaskContext("TaskBrowser"),
00644 debug(0),
00645 line_read(0),
00646 lastc(0), storedname(""), storedline(-1),
00647 usehex(false),
00648 macrorecording(false)
00649 {
00650 tb = this;
00651 context = tb;
00652 this->switchTaskContext(_c);
00653 #ifdef USE_READLINE
00654
00655 #ifdef USE_SIGNALS
00656 rl_catch_sigwinch = 0;
00657 #endif
00658 rl_completion_append_character = '\0';
00659 rl_attempted_completion_function = &TaskBrowser::orocos_hmi_completion;
00660
00661 if ( read_history(".tb_history") != 0 ) {
00662 read_history("~/.tb_history");
00663 }
00664 #ifdef USE_SIGNALS
00665 struct sigaction sa;
00666 sa.sa_sigaction = &TaskBrowser::rl_sigwinch_handler;
00667 sa.sa_flags = SA_SIGINFO | SA_RESTART;
00668 sigemptyset( &sa.sa_mask );
00669 sigaction(SIGWINCH, &sa, 0);
00670 #endif // USE_SIGNALS
00671 #endif // USE_READLINE
00672
00673 this->setColorTheme( darkbg );
00674 this->enterTask();
00675 }
00676
00677 TaskBrowser::~TaskBrowser() {
00678 #ifdef USE_READLINE
00679 if (line_read)
00680 {
00681 free (line_read);
00682 }
00683 if ( write_history(".tb_history") != 0 ) {
00684 write_history("~/.tb_history");
00685 }
00686 #endif
00687 }
00688
00692 char getTaskStatusChar(RTT::TaskContext* t)
00693 {
00694 if (t->inFatalError())
00695 return 'F';
00696 if (t->inRunTimeError())
00697 return 'E';
00698 if (t->inException())
00699 return 'X';
00700 if (t->isRunning() )
00701 return 'R';
00702 if (t->isConfigured() )
00703 return 'S';
00704 return 'U';
00705 }
00706
00707 char getStateMachineStatusChar(RTT::TaskContext* t, string progname)
00708 {
00709 string ps = t->getProvider<Scripting>("scripting")->getStateMachineStatusStr(progname);
00710 return toupper(ps[0]);
00711 }
00712
00713 char getProgramStatusChar(RTT::TaskContext* t, string progname)
00714 {
00715 string ps = t->getProvider<Scripting>("scripting")->getProgramStatusStr(progname);
00716 return toupper(ps[0]);
00717 }
00718
00719 void str_trim(string& str, char to_trim)
00720 {
00721 string::size_type pos1 = str.find_first_not_of(to_trim);
00722 string::size_type pos2 = str.find_last_not_of(to_trim);
00723 str = str.substr(pos1 == string::npos ? 0 : pos1,
00724 pos2 == string::npos ? str.length() - 1 : pos2 - pos1 + 1);
00725 }
00726
00727
00732 void TaskBrowser::loop()
00733 {
00734 #ifdef USE_SIGNALS
00735
00736 ::signal( SIGINT, ctrl_c_catcher );
00737
00738 if(rl_catch_signals == 0)
00739 cerr << "Error: not catching signals !"<<endl;
00740 if (rl_set_signals() != 0)
00741 cerr << "Error setting signals !" <<endl;
00742 #endif
00743 cout << nl<<
00744 coloron <<
00745 " This console reader allows you to browse and manipulate TaskContexts."<<nl<<
00746 " You can type in an operation, expression, create or change variables."<<nl;
00747 cout <<" (type '"<<underline<<"help"<<coloroff<<coloron<<"' for instructions and '"
00748 <<underline<<"ls"<<coloroff<<coloron<<"' for context info)"<<nl<<nl;
00749 #ifdef USE_READLINE
00750 cout << " TAB completion and HISTORY is available ('bash' like)" <<nl<<nl;
00751 #else
00752 cout << " TAB completion and history is NOT available (LGPL-version)" <<nl<<nl;
00753 #endif
00754 cout << " Use '"<<underline<<"Ctrl-D"<<coloroff<<coloron<<"' or type '"<<underline<<"quit"<<coloroff<<coloron<<"' to exit this program." <<coloroff<<nl<<nl;
00755
00756 while (1) {
00757 try {
00758 if (!macrorecording) {
00759 if ( context == tb )
00760 cout << green << " Watching " <<coloroff;
00761
00762 char state = getTaskStatusChar(taskcontext);
00763
00764
00765
00766 prompt = taskcontext->getName() + " [" + state + "]> ";
00767
00768
00769 cout.flush();
00770
00771
00772 for (PTrace::iterator it = ptraces.begin(); it != ptraces.end(); ++it) {
00773 RTT::TaskContext* progpeer = it->first.first;
00774 int line = progpeer->getProvider<Scripting>("scripting")->getProgramLine(it->first.second);
00775 if ( line != it->second ) {
00776 it->second = line;
00777 printProgram( it->first.second, -1, progpeer );
00778 }
00779 }
00780
00781 for (PTrace::iterator it = straces.begin(); it != straces.end(); ++it) {
00782 RTT::TaskContext* progpeer = it->first.first;
00783 int line = progpeer->getProvider<Scripting>("scripting")->getStateMachineLine(it->first.second);
00784 if ( line != it->second ) {
00785 it->second = line;
00786 printProgram( it->first.second, -1, progpeer );
00787 }
00788 }
00789 }
00790
00791 checkPorts();
00792 #ifdef USE_SIGNALS
00793
00794 ::signal( SIGINT, ctrl_c_catcher );
00795 #endif
00796 std::string command;
00797
00798
00799 try {
00800 #ifdef USE_READLINE
00801 const char* const commandStr = rl_gets();
00802
00803 command = commandStr ? commandStr : "quit";
00804 #else
00805 cout << prompt;
00806 getline(cin,command);
00807 if (!cin)
00808 command = "quit";
00809 #endif
00810 } catch(std::exception& e) {
00811 cerr << "The command line reader throwed a std::exception: '"<< e.what()<<"'."<<endl;
00812 } catch (...) {
00813 cerr << "The command line reader throwed an exception." <<endlog();
00814 }
00815 str_trim( command, ' ');
00816 #ifdef USE_SIGNALS
00817 ::signal( SIGINT, SIG_DFL );
00818 #endif
00819 cout << coloroff;
00820 if ( command == "quit" ) {
00821
00822 cout << endl;
00823 return;
00824 } else if ( command == "help") {
00825 printHelp();
00826 } else if ( command.find("help ") == 0) {
00827 printHelp( command.substr(command.rfind(' ')));
00828 } else if ( command == "#debug") {
00829 debug = !debug;
00830 } else if ( command.find("list ") == 0 || command == "list" ) {
00831 browserAction(command);
00832 } else if ( command.find("trace ") == 0 || command == "trace" ) {
00833 browserAction(command);
00834 } else if ( command.find("untrace ") == 0 || command == "untrace" ) {
00835 browserAction(command);
00836 } else if ( command.find("ls") == 0 ) {
00837 std::string::size_type pos = command.find("ls")+2;
00838 command = std::string(command, pos, command.length());
00839 printInfo( command );
00840 } else if ( command == "" ) {
00841 } else if ( command.find("cd ..") == 0 ) {
00842 this->switchBack( );
00843 } else if ( command.find("enter") == 0 ) {
00844 this->enterTask();
00845 } else if ( command.find("leave") == 0 ) {
00846 this->leaveTask();
00847 } else if ( command.find("cd ") == 0 ) {
00848 std::string::size_type pos = command.find("cd")+2;
00849 command = std::string(command, pos, command.length());
00850 this->switchTaskContext( command );
00851 } else if ( command.find(".") == 0 ) {
00852 command = std::string(command, 1, command.length());
00853 this->browserAction( command );
00854 } else if ( macrorecording) {
00855 macrotext += command +'\n';
00856 } else {
00857 try {
00858 this->evalCommand( command );
00859 } catch(std::exception& e) {
00860 cerr << "The command '"<<command<<"' caused a std::exception: '"<< e.what()<<"' and could not be completed."<<endl;
00861 } catch(...){
00862 cerr << "The command '"<<command<<"' caused an unknown exception and could not be completed."<<endl;
00863 }
00864
00865
00866 storedline = -1;
00867 }
00868
00869 } catch(std::exception& e) {
00870 cerr << "Warning: The command caused a std::exception: '"<< e.what()<<"' in the TaskBrowser's loop() function."<<endl;
00871 } catch(...) {
00872 cerr << "Warning: The command caused an exception in the TaskBrowser's loop() function." << endl;
00873 }
00874 }
00875 }
00876
00877 void TaskBrowser::enterTask()
00878 {
00879 if ( context == taskcontext ) {
00880 log(Info) <<"Already in Task "<< taskcontext->getName()<<endlog();
00881 return;
00882 }
00883 context = taskcontext;
00884 log(Info) <<"Entering Task "<< taskcontext->getName()<<endlog();
00885 }
00886
00887 void TaskBrowser::leaveTask()
00888 {
00889 if ( context == tb ) {
00890 log(Info) <<"Already watching Task "<< taskcontext->getName()<<endlog();
00891 return;
00892 }
00893 context = tb;
00894 log(Info) <<"Watching Task "<< taskcontext->getName()<<endlog();
00895 }
00896
00897 void TaskBrowser::recordMacro(std::string name)
00898 {
00899 if (macrorecording) {
00900 log(Error)<< "Macro already active." <<endlog();
00901 return;
00902 }
00903 if (context->provides()->hasService("scripting") == false) {
00904 log(Error)<< "Can not create a macro in a TaskContext without scripting service." <<endlog();
00905 return;
00906 }
00907 if ( name.empty() ) {
00908 cerr << "Please specify a macro name." <<endl;
00909 return;
00910 } else {
00911 cout << "Recording macro "<< name <<endl;
00912 cout << "Use program scripting syntax (do, set,...) !" << endl <<endl;
00913 cout << "export function "<< name<<" {"<<endl;
00914 }
00915 macrorecording = true;
00916 macroname = name;
00917 }
00918
00919 void TaskBrowser::cancelMacro() {
00920 if (!macrorecording) {
00921 log(Warning)<< "Macro recording was not active." <<endlog();
00922 return;
00923 }
00924 cout << "Canceling macro "<< macroname <<endl;
00925 macrorecording = false;
00926 macrotext.clear();
00927 }
00928
00929 void TaskBrowser::endMacro() {
00930 if (!macrorecording) {
00931 log(Warning)<< "Macro recording was not active." <<endlog();
00932 return;
00933 }
00934 string fname = macroname + ".ops";
00935 macrorecording = false;
00936 cout << "}" <<endl;
00937 cout << "Saving file "<< fname <<endl;
00938 ofstream macrofile( fname.c_str() );
00939 macrofile << "/* TaskBrowser macro '"<<macroname<<"' */" <<endl<<endl;
00940 macrofile << "export function "<<macroname<<" {"<<endl;
00941 macrofile << macrotext.c_str();
00942 macrofile << "}"<<endl;
00943 macrotext.clear();
00944
00945 cout << "Loading file "<< fname <<endl;
00946 context->getProvider<Scripting>("Scripting")->loadPrograms(fname);
00947 }
00948
00949 void TaskBrowser::switchBack()
00950 {
00951 if ( taskHistory.size() == 0)
00952 return;
00953
00954 this->switchTaskContext( taskHistory.front(), false );
00955 lastc = 0;
00956 taskHistory.pop_front();
00957 }
00958
00959 void TaskBrowser::checkPorts()
00960 {
00961
00962
00963 DataFlowInterface::Ports ports;
00964 ports = this->ports()->getPorts();
00965 for( DataFlowInterface::Ports::iterator i=ports.begin(); i != ports.end(); ++i) {
00966
00967 base::PortInterface* p = *i;
00968 base::PortInterface* tcp = taskcontext->ports()->getPort( p->getName() );
00969 if ( p->connected() == false || tcp == 0 || tcp->connected() == false) {
00970 this->ports()->removePort( p->getName() );
00971 delete p;
00972 }
00973 }
00974 }
00975
00976 void TaskBrowser::setColorTheme(ColorTheme t)
00977 {
00978
00979 const char* dbg = "\033[01;";
00980 const char* wbg = "\033[02;";
00981
00982 const char* r = "31m";
00983 const char* g = "32m";
00984 const char* b = "34m";
00985 const char* con = "31m";
00986 const char* coff = "\33[0m";
00987 const char* und = "\33[4m";
00988
00989 switch (t)
00990 {
00991 case nocolors:
00992 green.clear();
00993 red.clear();
00994 blue.clear();
00995 coloron.clear();
00996 coloroff.clear();
00997 underline.clear();
00998 return;
00999 break;
01000 case darkbg:
01001 green = dbg;
01002 red = dbg;
01003 blue = dbg;
01004 coloron = dbg;
01005 coloroff = wbg;
01006 break;
01007 case whitebg:
01008 green = wbg;
01009 red = wbg;
01010 blue = wbg;
01011 coloron = wbg;
01012 coloroff = wbg;
01013 break;
01014 }
01015 green += g;
01016 red += r;
01017 blue += b;
01018 coloron += con;
01019 coloroff = coff;
01020 underline = und;
01021 }
01022
01023 void TaskBrowser::switchTaskContext(std::string& c) {
01024
01025 peer = taskcontext;
01026 if ( this->findPeer( c + "." ) == 0 ) {
01027 cerr << "No such peer: "<< c <<nl;
01028 return;
01029 }
01030
01031 if ( peer == taskcontext ) {
01032 cerr << "Already in "<< c <<nl;
01033 return;
01034 }
01035
01036 if ( peer == tb ) {
01037 cerr << "Can not switch to TaskBrowser." <<nl;
01038 return;
01039 }
01040
01041
01042 this->switchTaskContext( peer );
01043 }
01044
01045 void TaskBrowser::switchTaskContext(RTT::TaskContext* tc, bool store) {
01046
01047 if (taskHistory.size() == 20 )
01048 taskHistory.pop_back();
01049 if ( taskcontext && store)
01050 taskHistory.push_front( taskcontext );
01051
01052
01053 this->disconnect();
01054
01055
01056 DataFlowInterface::Ports tports = this->ports()->getPorts();
01057 for( DataFlowInterface::Ports::iterator i=tports.begin(); i != tports.end(); ++i) {
01058 this->ports()->removePort( (*i)->getName() );
01059 delete *i;
01060 }
01061
01062
01063 if ( context == taskcontext )
01064 context = tc;
01065 taskcontext = tc;
01066 lastc = 0;
01067
01068
01069 this->addPeer( taskcontext );
01070
01071
01072
01073 tports = taskcontext->ports()->getPorts();
01074 if ( !tports.empty() )
01075 cout <<nl << "TaskBrowser connects to all data ports of "<<taskcontext->getName()<<endl;
01076 for( DataFlowInterface::Ports::iterator i=tports.begin(); i != tports.end(); ++i) {
01077 if (this->ports()->getPort( (*i)->getName() ) == 0 )
01078 this->ports()->addPort( *(*i)->antiClone() );
01079 }
01080 RTT::connectPorts(this,taskcontext);
01081
01082
01083
01084 cerr << " Switched to : " << taskcontext->getName() <<endl;
01085
01086 }
01087
01088 RTT::TaskContext* TaskBrowser::findPeer(std::string c) {
01089
01090 std::string s( c );
01091
01092 our_pos_iter_t parsebegin( s.begin(), s.end(), "teststring" );
01093 our_pos_iter_t parseend;
01094
01095 CommonParser cp;
01096 scripting::PeerParser pp( peer, cp, true );
01097 bool skipref = true;
01098 try {
01099 parse( parsebegin, parseend, pp.parser(), SKIP_PARSER );
01100 }
01101 catch( ... )
01102 {
01103 log(Debug) <<"No such peer : "<< c <<endlog();
01104 return 0;
01105 }
01106 taskobject = pp.taskObject();
01107 assert(taskobject);
01108 peer = pp.peer();
01109 return pp.peer();
01110 }
01111
01112 void TaskBrowser::browserAction(std::string& act)
01113 {
01114 std::stringstream ss(act);
01115 std::string instr;
01116 ss >> instr;
01117
01118 if ( instr == "list" ) {
01119 if (context->provides()->hasService("scripting") == false) {
01120 log(Error)<< "Can not list a program in a TaskContext without scripting service." <<endlog();
01121 return;
01122 }
01123 int line;
01124 ss >> line;
01125 if (ss) {
01126 this->printProgram(line);
01127 return;
01128 }
01129 ss.clear();
01130 string arg;
01131 ss >> arg;
01132 if (ss) {
01133 ss.clear();
01134 ss >> line;
01135 if (ss) {
01136
01137 this->printProgram(arg, line);
01138 return;
01139 }
01140
01141 this->printProgram( arg );
01142 return;
01143 }
01144
01145 this->printProgram();
01146 return;
01147 }
01148
01149
01150
01151
01152 if ( instr == "trace") {
01153 if (context->provides()->hasService("scripting") == false) {
01154 log(Error)<< "Can not trace a program in a TaskContext without scripting service." <<endlog();
01155 return;
01156 }
01157
01158 string arg;
01159 ss >> arg;
01160 if (ss) {
01161 bool pi = context->getProvider<Scripting>("scripting")->hasProgram(arg);
01162 if (pi) {
01163 ptraces[make_pair(context, arg)] = context->getProvider<Scripting>("scripting")->getProgramLine(arg);
01164 this->printProgram( arg );
01165 return;
01166 }
01167 pi = context->getProvider<Scripting>("scripting")->hasStateMachine(arg);
01168 if (pi) {
01169 straces[make_pair(context, arg)] = context->getProvider<Scripting>("scripting")->getStateMachineLine(arg);
01170 this->printProgram( arg );
01171 return;
01172 }
01173 cerr <<"No such program or state machine: "<< arg <<endl;
01174 return;
01175 }
01176
01177
01178 std::vector<std::string> names;
01179 names = context->getProvider<Scripting>("scripting")->getProgramList();
01180 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01181 bool pi = context->getProvider<Scripting>("scripting")->hasProgram(arg);
01182 if (pi)
01183 ptraces[make_pair(context, arg)] = context->getProvider<Scripting>("scripting")->getProgramLine(arg);
01184 }
01185
01186 names = context->getProvider<Scripting>("scripting")->getStateMachineList();
01187 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01188 bool pi = context->getProvider<Scripting>("scripting")->hasStateMachine(arg);
01189 if (pi)
01190 straces[make_pair(context, arg)] = context->getProvider<Scripting>("scripting")->getStateMachineLine(arg);
01191 }
01192
01193 cerr << "Tracing all programs and state machines in "<< context->getName() << endl;
01194 return;
01195 }
01196
01197 if ( instr == "untrace") {
01198 if (context->provides()->hasService("scripting") == false) {
01199 log(Error)<< "Can not untrace a program in a TaskContext without scripting service." <<endlog();
01200 return;
01201 }
01202 string arg;
01203 ss >> arg;
01204 if (ss) {
01205 ptraces.erase( make_pair(context, arg) );
01206 straces.erase( make_pair(context, arg) );
01207 cerr <<"Untracing "<< arg <<" of "<< context->getName()<<endl;
01208 return;
01209 }
01210
01211 std::vector<std::string> names;
01212 names = context->getProvider<Scripting>("scripting")->getProgramList();
01213 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01214 bool pi = context->getProvider<Scripting>("scripting")->hasProgram(arg);
01215 if (pi)
01216 ptraces.erase(make_pair(context, arg));
01217 }
01218
01219 names = context->getProvider<Scripting>("scripting")->getStateMachineList();
01220 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01221 bool pi = context->getProvider<Scripting>("scripting")->hasStateMachine(arg);
01222 if (pi)
01223 straces.erase(make_pair(context, arg));
01224 }
01225
01226 cerr << "Untracing all programs and state machines of "<< context->getName() << endl;
01227 return;
01228 }
01229
01230 std::string arg;
01231 ss >> arg;
01232 if ( instr == "dark") {
01233 this->setColorTheme(darkbg);
01234 cout << nl << "Setting Color Theme for "+green+"dark"+coloroff+" backgrounds."<<endl;
01235 return;
01236 }
01237 if ( instr == "light") {
01238 this->setColorTheme(whitebg);
01239 cout << nl << "Setting Color Theme for "+green+"light"+coloroff+" backgrounds."<<endl;
01240 return;
01241 }
01242 if ( instr == "nocolors") {
01243 this->setColorTheme(nocolors);
01244 cout <<nl << "Disabling all colors"<<endl;
01245 return;
01246 }
01247 if ( instr == "record") {
01248 recordMacro( arg );
01249 return;
01250 }
01251 if ( instr == "cancel") {
01252 cancelMacro();
01253 return;
01254 }
01255 if ( instr == "end") {
01256 endMacro();
01257 return;
01258 }
01259 if ( instr == "hex") {
01260 usehex = true;
01261 cout << "Switching to hex notation for output (use .nohex to revert)." <<endl;
01262 return;
01263 }
01264 if ( instr == "nohex") {
01265 usehex = false;
01266 cout << "Turning off hex notation for output." <<endl;
01267 return;
01268 }
01269 if ( instr == "provide") {
01270 while ( ss ) {
01271 cout << "Trying to locate service '" << arg << "'..."<<endl;
01272 if ( PluginLoader::Instance()->loadService(arg, context) )
01273 cout << "Service '"<< arg << "' loaded in " << context->getName() << endl;
01274 else
01275 cout << "Service not found." <<endl;
01276 ss >> arg;
01277 }
01278 return;
01279 }
01280 if (instr == "services") {
01281 vector<string> names = PluginLoader::Instance()->listServices();
01282 cout << "Available Services: ";
01283 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01284 cout << " " << *it;
01285 }
01286 cout <<endl;
01287 return;
01288 }
01289 if (instr == "typekits") {
01290 vector<string> names = PluginLoader::Instance()->listTypekits();
01291 cout << "Available Typekits: ";
01292 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01293 cout << " " << *it;
01294 }
01295 cout <<endl;
01296 return;
01297 }
01298 if (instr == "types") {
01299 vector<string> names = TypeInfoRepository::Instance()->getDottedTypes();
01300 cout << "Available data types: ";
01301 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01302 cout << " " << *it;
01303 }
01304 cout <<endl;
01305 return;
01306 }
01307 cerr << "Unknown Browser Action : "<< act <<endl;
01308 cerr << "See 'help' for valid syntax."<<endl;
01309 }
01310
01311 void TaskBrowser::evaluate(std::string& comm) {
01312 this->evalCommand(comm);
01313 }
01314
01315 Service::shared_ptr TaskBrowser::stringToService(string const& names) {
01316 Service::shared_ptr serv;
01317 std::vector<std::string> strs;
01318 boost::split(strs, names, boost::is_any_of("."));
01319
01320 string component = strs.front();
01321 if (! context->hasPeer(component) && !context->provides()->hasService(component) ) {
01322 return serv;
01323 }
01324
01325 if ( context->hasPeer(component) )
01326 serv = context->getPeer(component)->provides();
01327 else if (context->provides()->hasService(component))
01328 serv = context->provides(component);
01329
01330
01331 strs.erase( strs.begin() );
01332
01333
01334 while ( !strs.empty() && serv) {
01335 serv = serv->getService( strs.front() );
01336 if (serv)
01337 strs.erase( strs.begin() );
01338 }
01339 return serv;
01340 }
01341
01342
01343
01344 bool TaskBrowser::printService( string name ) {
01345 bool result = false;
01346 Service::shared_ptr ops = stringToService(name);
01347 ServiceRequester* sr = 0;
01348
01349 if ( ops || GlobalService::Instance()->hasService( name ) )
01350 {
01351 if ( !ops )
01352 ops = GlobalService::Instance()->provides(name);
01353 sresult << nl << "Printing Interface of '"<< coloron << ops->getName() <<coloroff <<"' :"<<nl<<nl;
01354 vector<string> methods = ops->getNames();
01355 std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printOperation, this, _1, ops) );
01356 cout << sresult.str();
01357 sresult.str("");
01358 result = true;
01359 }
01360 if ( context->requires()->requiresService( name ) )
01361 {
01362 sr = context->requires(name);
01363 sresult << nl << "Requiring '"<< coloron << sr->getRequestName() <<coloroff <<"' with methods: ";
01364 vector<string> methods = sr->getOperationCallerNames();
01365 sresult << coloron;
01366 std::for_each( methods.begin(), methods.end(), sresult << lambda::_1 <<" " );
01367 cout << sresult.str() << coloroff << nl;
01368 sresult.str("");
01369 result = true;
01370 }
01371 return result;
01372 }
01373
01374 void TaskBrowser::evalCommand(std::string& comm )
01375 {
01376
01377 bool result = printService(comm);
01378
01379
01380
01381
01382
01383 if ( context->provides()->getValue( comm ) ) {
01384 if (debug)
01385 cerr << "Found value..."<<nl;
01386 this->printResult( context->provides()->getValue( comm )->getDataSource().get(), true );
01387 cout << sresult.str()<<nl;
01388 sresult.str("");
01389 return;
01390 }
01391
01392 if ( result ) {
01393 return;
01394 }
01395
01396
01397
01398
01399 scripting::Parser _parser( 0 );
01400
01401 if (debug)
01402 cerr << "Trying ValueStatement..."<<nl;
01403 try {
01404
01405 last_expr = _parser.parseValueStatement( comm, context );
01406
01407 if ( last_expr ) {
01408
01409 assert( comm.size() != 0 );
01410 if ( comm[ comm.size() - 1 ] != ';' ) {
01411 this->printResult( last_expr.get(), true );
01412 cout << sresult.str() << nl <<endl;
01413 sresult.str("");
01414 } else
01415 last_expr->evaluate();
01416 return;
01417 } else if (debug)
01418 cerr << "returned (null) !"<<nl;
01419
01420
01421 } catch ( fatal_semantic_parse_exception& pe ) {
01422
01423 if (debug)
01424 cerr << "fatal_semantic_parse_exception: ";
01425 cerr << pe.what() <<nl;
01426 return;
01427 } catch ( syntactic_parse_exception& pe ) {
01428
01429 if (debug)
01430 cerr << "syntactic_parse_exception: ";
01431 cerr << pe.what() <<nl;
01432 return;
01433 } catch ( parse_exception_parser_fail &pe )
01434 {
01435
01436 if (debug) {
01437 cerr << "Ignoring ValueStatement exception :"<<nl;
01438 cerr << pe.what() <<nl;
01439 }
01440 } catch ( parse_exception& pe ) {
01441
01442 if (debug)
01443 cerr << "parse_exception :";
01444 cerr << pe.what() <<nl;
01445 return;
01446 }
01447 if (debug)
01448 cerr << "Trying Expression..."<<nl;
01449 try {
01450
01451 last_expr = _parser.parseExpression( comm, context );
01452
01453 if ( last_expr ) {
01454
01455 assert( comm.size() != 0 );
01456 if ( comm[ comm.size() - 1 ] != ';' ) {
01457 this->printResult( last_expr.get(), true );
01458 cout << sresult.str() << nl << endl;
01459 sresult.str("");
01460 } else
01461 last_expr->evaluate();
01462 return;
01463 } else if (debug)
01464 cerr << "returned (null) !"<<nl;
01465 } catch ( syntactic_parse_exception& pe ) {
01466
01467 if (debug)
01468 cerr << "syntactic_parse_exception :";
01469 cerr << pe.what() <<nl;
01470 return;
01471 } catch ( fatal_semantic_parse_exception& pe ) {
01472
01473 if (debug)
01474 cerr << "fatal_semantic_parse_exception :";
01475 cerr << pe.what() <<nl;
01476 return;
01477 } catch ( parse_exception_parser_fail &pe )
01478 {
01479
01480 if (debug)
01481 cerr << "Ignoring Expression exception :"<<nl;
01482 cerr << pe.what() <<nl;
01483
01484 } catch ( parse_exception& pe ) {
01485
01486 if (debug)
01487 cerr << "Ignoring Expression parse_exception :"<<nl;
01488 cerr << pe.what() <<nl;
01489 }
01490 }
01491
01492 void TaskBrowser::printResult( base::DataSourceBase* ds, bool recurse) {
01493 std::string prompt(" = ");
01494
01495 sresult <<prompt<< setw(20)<<left;
01496 if ( ds )
01497 doPrint( ds, recurse );
01498 else
01499 sresult << "(null)";
01500 sresult << right;
01501 }
01502
01503 void TaskBrowser::doPrint( base::DataSourceBase::shared_ptr ds, bool recurse) {
01504 if (!ds) {
01505 sresult << "(null)";
01506 return;
01507 }
01508
01509
01510
01511
01512 ds->reset();
01513
01514 DataSource<RTT::PropertyBag>* dspbag = DataSource<RTT::PropertyBag>::narrow(ds.get());
01515 if (dspbag) {
01516 RTT::PropertyBag bag( dspbag->get() );
01517 if (!recurse) {
01518 int siz = bag.getProperties().size();
01519 int wdth = siz ? (20 - (siz / 10 + 1)) : 20;
01520 sresult <<setw(0)<< siz <<setw( wdth )<< " Properties";
01521 } else {
01522 if ( ! bag.empty() ) {
01523 sresult <<setw(0)<<nl;
01524 for( RTT::PropertyBag::iterator it= bag.getProperties().begin(); it!=bag.getProperties().end(); ++it) {
01525 sresult <<setw(14)<<right<< Types()->toDot( (*it)->getType() )<<" "<<coloron<<setw(14)<< (*it)->getName()<<coloroff;
01526 base::DataSourceBase::shared_ptr propds = (*it)->getDataSource();
01527 this->printResult( propds.get(), false );
01528 sresult <<" ("<<(*it)->getDescription()<<')' << nl;
01529 }
01530 } else {
01531 sresult <<prompt<<"(empty RTT::PropertyBag)";
01532 }
01533 }
01534 return;
01535 }
01536
01537
01538 base::DataSourceBase::shared_ptr dsb(ds);
01539 dsb->evaluate();
01540 if (dsb->getMemberNames().empty() || dsb->getTypeInfo()->isStreamable() ) {
01541 if (debug) cerr << "terminal item " << dsb->getTypeName() << nl;
01542 if (usehex)
01543 sresult << std::hex << dsb;
01544 else
01545 sresult << std::dec << dsb;
01546 } else {
01547 sresult << setw(0);
01548 sresult << "{";
01549 vector<string> names = dsb->getMemberNames();
01550 if ( find(names.begin(), names.end(), "capacity") != names.end() &&
01551 find(names.begin(), names.end(), "size") != names.end() ) {
01552
01553 DataSource<int>::shared_ptr seq_size = dynamic_pointer_cast<DataSource<int> >(dsb->getMember("size"));
01554 if (seq_size) {
01555 ValueDataSource<unsigned int>::shared_ptr index = new ValueDataSource<unsigned int>(0);
01556
01557 sresult << " [";
01558 for (int i=0; i != seq_size->get(); ++i) {
01559 index->set( i );
01560 if (i == 10) {
01561 sresult << "...("<< seq_size->get() - 10 <<" items omitted)...";
01562 break;
01563 } else {
01564 DataSourceBase::shared_ptr element = dsb->getMember(index, DataSourceBase::shared_ptr() );
01565 doPrint(element, true);
01566 if (i+1 != seq_size->get())
01567 sresult <<", ";
01568 }
01569 }
01570 sresult << " ], ";
01571 }
01572 }
01573 for(vector<string>::iterator it = names.begin(); it != names.end(); ) {
01574 sresult << *it << " = ";
01575 doPrint( dsb->getMember(*it), true);
01576 if (++it != names.end())
01577 sresult <<", ";
01578 }
01579 sresult <<" }";
01580 }
01581 }
01582
01583 struct comcol
01584 {
01585 const char* command;
01586 comcol(const char* c) :command(c) {}
01587 std::ostream& operator()( std::ostream& os ) const {
01588 os<<"'"<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<"'";
01589 return os;
01590 }
01591 };
01592
01593 struct keycol
01594 {
01595 const char* command;
01596 keycol(const char* c) :command(c) {}
01597 std::ostream& operator()( std::ostream& os )const {
01598 os<<"<"<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<">";
01599 return os;
01600 }
01601 };
01602
01603 struct titlecol
01604 {
01605 const char* command;
01606 titlecol(const char* c) :command(c) {}
01607 std::ostream& operator()( std::ostream& os ) const {
01608 os<<endl<<"["<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<"]";
01609 return os;
01610 }
01611 };
01612
01613 std::ostream& operator<<(std::ostream& os, comcol f ){
01614 return f(os);
01615 }
01616
01617 std::ostream& operator<<(std::ostream& os, keycol f ){
01618 return f(os);
01619 }
01620
01621 std::ostream& operator<<(std::ostream& os, titlecol f ){
01622 return f(os);
01623 }
01624
01625 void TaskBrowser::printHelp()
01626 {
01627 cout << coloroff;
01628 cout <<titlecol("Task Browsing")<<nl;
01629 cout << " To switch to another task, type "<<comcol("cd <path-to-taskname>")<<nl;
01630 cout << " and type "<<comcol("cd ..")<<" to go back to the previous task (History size is 20)."<<nl;
01631 cout << " Pressing "<<keycol("tab")<<" multiple times helps you to complete your command."<<nl;
01632 cout << " It is not mandatory to switch to a task to interact with it, you can type the"<<nl;
01633 cout << " peer-path to the task (dot-separated) and then type command or expression :"<<nl;
01634 cout << " PeerTask.OtherTask.FinalTask.countTo(3) [enter] "<<nl;
01635 cout << " Where 'countTo' is a method of 'FinalTask'."<<nl;
01636 cout << " The TaskBrowser starts by default 'In' the current component. In order to watch"<<nl;
01637 cout << " the TaskBrowser itself, type "<<comcol("leave")<<" You will notice that it"<<nl;
01638 cout << " has connected to the data ports of the visited component. Use "<<comcol("enter")<<" to enter"<<nl;
01639 cout << " the visited component again. The "<<comcol("cd")<<" command works transparantly in both"<<nl;
01640 cout << " modi."<<nl;
01641
01642 cout << " "<<titlecol("Task Context Info")<<nl;
01643 cout << " To see the contents of a task, type "<<comcol("ls")<<nl;
01644 cout << " For a detailed argument list (and helpful info) of the object's methods, "<<nl;
01645 cout <<" type the name of one of the listed task objects : " <<nl;
01646 cout <<" this [enter]" <<nl<<nl;
01647 cout <<" factor( int number ) : bool" <<nl;
01648 cout <<" Factor a value into its primes." <<nl;
01649 cout <<" number : The number to factor in primes." <<nl;
01650 cout <<" isRunning( ) : bool" <<nl;
01651 cout <<" Is this RTT::TaskContext started ?" <<nl;
01652 cout <<" loadProgram( const& std::string Filename ) : bool" <<nl;
01653 cout <<" Load an Orocos Program Script from a file." <<nl;
01654 cout <<" Filename : An ops file." <<nl;
01655 cout <<" ..."<<nl;
01656
01657 cout << " A status character shows the TaskState of a component."<<nl;
01658 cout << " 'E':RunTimeError, 'S':Stopped, 'R':Running, 'U':PreOperational (Unconfigured)"<<nl;
01659 cout << " 'X':Exception, 'F':FatalError" << nl;
01660
01661 cout <<titlecol("Expressions")<<nl;
01662 cout << " You can evaluate any script expression by merely typing it :"<<nl;
01663 cout << " 1+1 [enter]" <<nl;
01664 cout << " = 2" <<nl;
01665 cout << " or inspect the status of a program :"<<nl;
01666 cout << " myProgram.isRunning [enter]" <<nl;
01667 cout << " = false" <<nl;
01668 cout << " and display the contents of complex data types (vector, array,...) :"<<nl;
01669 cout << " array(6)" <<nl;
01670 cout << " = {0, 0, 0, 0, 0, 0}" <<nl;
01671
01672 cout <<titlecol("Changing Attributes and Properties")<<nl;
01673 cout << " To change the value of a Task's attribute, type "<<comcol("varname = <newvalue>")<<nl;
01674 cout << " If you provided a correct assignment, the browser will inform you of the success"<<nl;
01675 cout <<" with the set value." <<nl;
01676
01677 cout <<titlecol("Operations")<<nl;
01678 cout << " An Operation is sent or called (evaluated) "<<nl;
01679 cout << " immediately and print the result. An example could be :"<<nl;
01680 cout << " someTask.bar.getNumberOfBeers(\"Palm\") [enter] "<<nl;
01681 cout << " = 99" <<nl;
01682 cout << " You can ask help on an operation by using the 'help' command: "<<nl;
01683 cout << " help start"<<nl;
01684 cout << " start( ) : bool"<<nl;
01685 cout << " Start this TaskContext (= startHook() + updateHook() )." <<nl;
01686
01687 cout <<titlecol("Program and scripting::StateMachine Scripts")<<nl;
01688 cout << " To load a program script use the scripting service."<<nl;
01689 cout << " Use "<<comcol(".provide scripting")<< " to load the scripting service in a TaskContext."<<nl;
01690 cout << " You can use "<<comcol("ls progname")<<nl;
01691 cout << " to see the programs operations and variables. You can manipulate each one of these"<<nl;
01692 cout << " using the service object of the program."<<nl;
01693
01694 cout << " To print a program or state machine listing, use "<<comcol("list progname [linenumber]")<<nl;
01695 cout << " to list the contents of the current program lines being executed,"<<nl;
01696 cout << " or 10 lines before or after <linenumber>. When only "<<comcol("list [n]")<<nl;
01697 cout << " is typed, 20 lines of the last listed program are printed from line <n> on "<<nl;
01698 cout << " ( default : list next 20 lines after previous list )."<<nl;
01699
01700 cout << " To trace a program or state machine listing, use "<<comcol("trace [progname]")<<" this will"<<nl;
01701 cout << " cause the TaskBrowser to list the contents of a traced program,"<<nl;
01702 cout << " each time the line number of the traced program changes."<<nl;
01703 cout << " Disable tracing with "<<comcol("untrace [progname]")<<""<<nl;
01704 cout << " If no arguments are given to "<<comcol("trace")<<" and "<<comcol("untrace")<<", it applies to all programs."<<nl;
01705
01706 cout << " A status character shows which line is being executed."<<nl;
01707 cout << " For programs : 'E':Error, 'S':Stopped, 'R':Running, 'P':Paused"<<nl;
01708 cout << " For state machines : <the same as programs> + 'A':Active, 'I':Inactive"<<nl;
01709
01710 cout <<titlecol("Changing Colors")<<nl;
01711 cout << " You can inform the TaskBrowser of your background color by typing "<<comcol(".dark")<<nl;
01712 cout << " "<<comcol(".light")<<", or "<<comcol(".nocolors")<<" to increase readability."<<nl;
01713
01714 cout <<titlecol("Output Formatting")<<nl;
01715 cout << " Use the commands "<<comcol(".hex") << " or " << comcol(".nohex") << " to turn hexadecimal "<<nl;
01716 cout << " notation of integers on or off."<<nl;
01717
01718 cout <<titlecol("Macro Recording / RTT::Command line history")<<nl;
01719 cout << " You can browse the commandline history by using the up-arrow key or press "<<comcol("Ctrl r")<<nl;
01720 cout << " and a search term. Hit enter to execute the current searched command."<<nl;
01721 cout << " Macros can be recorded using the "<<comcol(".record 'macro-name'")<<" command."<<nl;
01722 cout << " You can cancel the recording by typing "<<comcol(".cancel")<<" ."<<nl;
01723 cout << " You can save and load the macro by typing "<<comcol(".end")<<" . The macro becomes"<<nl;
01724 cout << " available as a command with name 'macro-name' in the current TaskContext." << nl;
01725 cout << " While you enter the macro, it is not executed, as you must use scripting syntax which"<<nl;
01726 cout << " may use loop or conditional statements, variables etc."<<nl;
01727
01728 cout <<titlecol("Connecting Ports")<<nl;
01729 cout << " You can instruct the TaskBrowser to connect to the ports of the current Peer by"<<nl;
01730 cout << " typing "<<comcol(".connect [port-name]")<<", which will temporarily create connections"<<nl;
01731 cout << " to all ports if [port-name] is omitted or to the specified port otherwise."<<nl;
01732 cout << " The TaskBrowser disconnects these ports when it visits another component, but the"<<nl;
01733 cout << " created connection objects remain in place (this is more or less a bug)!"<<nl;
01734
01735 cout <<titlecol("Plugins, Typekits and Services")<<nl;
01736 cout << " Use "<<comcol(".provide [servicename]")<< " to load a service in a TaskContext."<<nl;
01737 cout << " For example, to add XML marshalling, type: "<<comcol(".provide marshalling")<< "."<<nl;
01738 cout << " Use "<<comcol(".services")<< " to get a list of available services."<<nl;
01739 cout << " Use "<<comcol(".typekits")<< " to get a list of available typekits."<<nl;
01740 cout << " Use "<<comcol(".types")<< " to get a list of available data types."<<nl;
01741 }
01742
01743 void TaskBrowser::printHelp( string helpstring ) {
01744 peer = context;
01745
01746 str_trim(helpstring, ' ');
01747 str_trim(helpstring, '.');
01748
01749 if ( printService(helpstring))
01750 return;
01751
01752 if ( findPeer( helpstring ) ) {
01753 try {
01754
01755 sresult << nl;
01756 if (helpstring.rfind('.') != string::npos )
01757 printOperation( helpstring.substr(helpstring.rfind('.')+1 ), taskobject );
01758 else
01759 printOperation( helpstring, taskobject );
01760 cout << sresult.str();
01761 } catch (...) {
01762 cerr<< " help: No such operation known: '"<< helpstring << "'"<<nl;
01763 }
01764 } else {
01765 cerr<< " help: No such operation known (peer not found): '"<< helpstring << "'"<<nl;
01766 }
01767 sresult.str("");
01768 }
01769
01770 void TaskBrowser::printProgram(const std::string& progname, int cl , RTT::TaskContext* progpeer ) {
01771 string ps;
01772 char s;
01773 stringstream txtss;
01774 int ln;
01775 int start;
01776 int end;
01777 bool found(false);
01778
01779 if (progpeer == 0 )
01780 progpeer = context;
01781
01782
01783 if ( progpeer->getProvider<Scripting>("scripting")->hasProgram( progname ) ) {
01784 s = getProgramStatusChar(progpeer, progname);
01785 txtss.str( progpeer->getProvider<Scripting>("scripting")->getProgramText(progname) );
01786 ln = progpeer->getProvider<Scripting>("scripting")->getProgramLine(progname);
01787 if ( cl < 0 ) cl = ln;
01788 start = cl < 10 ? 1 : cl - 10;
01789 end = cl + 10;
01790 this->listText( txtss, start, end, ln, s);
01791 found = true;
01792 }
01793
01794
01795 if ( progpeer->getProvider<Scripting>("scripting")->hasStateMachine( progname ) ) {
01796 s = getStateMachineStatusChar(progpeer, progname);
01797 txtss.str( progpeer->getProvider<Scripting>("scripting")->getStateMachineText(progname) );
01798 ln = progpeer->getProvider<Scripting>("scripting")->getStateMachineLine(progname);
01799 if ( cl < 0 ) cl = ln;
01800 start = cl <= 10 ? 1 : cl - 10;
01801 end = cl + 10;
01802 this->listText( txtss, start, end, ln, s);
01803 found = true;
01804 }
01805 if ( !found ) {
01806 cerr << "Error : No such program or state machine found : "<<progname;
01807 cerr << " in "<< progpeer->getName() <<"."<<endl;
01808 return;
01809 }
01810 storedname = progname;
01811 }
01812
01813 void TaskBrowser::printProgram(int cl ) {
01814 string ps;
01815 char s;
01816 stringstream txtss;
01817 int ln;
01818 int start;
01819 int end;
01820 bool found(false);
01821 if ( context->getProvider<Scripting>("scripting")->hasProgram( storedname ) ) {
01822 s = getProgramStatusChar(context, storedname);
01823 txtss.str( context->getProvider<Scripting>("scripting")->getProgramText(storedname) );
01824 ln = context->getProvider<Scripting>("scripting")->getProgramLine(storedname);
01825 if ( cl < 0 ) cl = storedline;
01826 if (storedline < 0 ) cl = ln -10;
01827 start = cl;
01828 end = cl + 20;
01829 this->listText( txtss, start, end, ln, s);
01830 found = true;
01831 }
01832 if ( context->getProvider<Scripting>("scripting")->hasStateMachine(storedname) ) {
01833 s = getStateMachineStatusChar(context, storedname);
01834 txtss.str( context->getProvider<Scripting>("scripting")->getStateMachineText(storedname) );
01835 ln = context->getProvider<Scripting>("scripting")->getStateMachineLine(storedname);
01836 if ( cl < 0 ) cl = storedline;
01837 if (storedline < 0 ) cl = ln -10;
01838 start = cl;
01839 end = cl+20;
01840 this->listText( txtss, start, end, ln, s);
01841 found = true;
01842 }
01843 if ( !found )
01844 cerr << "Error : No such program or state machine found : "<<storedname<<endl;
01845 }
01846
01847 void TaskBrowser::listText(stringstream& txtss,int start, int end, int ln, char s) {
01848 int curln = 1;
01849 string line;
01850 while ( start > 1 && curln != start ) {
01851 getline( txtss, line, '\n' );
01852 if ( ! txtss )
01853 break;
01854 ++curln;
01855 }
01856 while ( end > start && curln != end ) {
01857 getline( txtss, line, '\n' );
01858 if ( ! txtss )
01859 break;
01860 if ( curln == ln ) {
01861 cout << s<<'>';
01862 }
01863 else
01864 cout << " ";
01865 cout<< setw(int(log(double(end)))) <<right << curln<< left;
01866 cout << ' ' << line <<endl;
01867 ++curln;
01868 }
01869 storedline = curln;
01870 // done !
01871 }
01872
01873 void TaskBrowser::printInfo(const std::string& peerp)
01874 {
01875 // this sets this->peer to the peer given
01876 peer = context;
01877 if ( this->findPeer( peerp+"." ) == 0 ) {
01878 cerr << "No such peer or object: " << peerp << endl;
01879 return;
01880 }
01881
01882 if ( !peer || !peer->ready()) {
01883 cout << nl << " Connection to peer "+peerp+" lost (peer->ready() == false)." <<endlog();
01884 return;
01885 }
01886
01887 // sresult << *it << "["<<getTaskStatusChar(peer->getPeer(*it))<<"] ";
01888
01889
01890 if ( peer->provides() == taskobject )
01891 sresult <<nl<<" Listing TaskContext "<< green << peer->getName()<<coloroff << "["<<getTaskStatusChar(peer)<<"] :"<<nl;
01892 else
01893 sresult <<nl<<" Listing Service "<< green << taskobject->getName()<<coloroff<< "["<<getTaskStatusChar(peer)<<"] :"<<nl;
01894
01895 sresult <<nl<<" Configuration Properties: ";
01896 RTT::PropertyBag* bag = taskobject->properties();
01897 if ( bag && bag->size() != 0 ) {
01898 // Print Properties:
01899 for( RTT::PropertyBag::iterator it = bag->begin(); it != bag->end(); ++it) {
01900 base::DataSourceBase::shared_ptr pds = (*it)->getDataSource();
01901 sresult << nl << setw(11)<< right << Types()->toDot( (*it)->getType() )<< " "
01902 << coloron <<setw(14)<<left<< (*it)->getName() << coloroff;
01903 this->printResult( pds.get(), false ); // do not recurse
01904 sresult<<" ("<< (*it)->getDescription() <<')';
01905 }
01906 } else {
01907 sresult << "(none)";
01908 }
01909 sresult <<nl;
01910
01911 // Print "this" interface (without detail) and then list objects...
01912 sresult <<nl<< " Provided Interface:";
01913
01914 sresult <<nl<< " Attributes : ";
01915 std::vector<std::string> objlist = taskobject->getAttributeNames();
01916 if ( !objlist.empty() ) {
01917 sresult << nl;
01918 // Print Attributes:
01919 for( std::vector<std::string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
01920 base::DataSourceBase::shared_ptr pds = taskobject->getValue(*it)->getDataSource();
01921 sresult << setw(11)<< right << Types()->toDot( pds->getType() )<< " "
01922 << coloron <<setw( 14 )<<left<< *it << coloroff;
01923 this->printResult( pds.get(), false ); // do not recurse
01924 sresult <<nl;
01925 }
01926 } else {
01927 sresult << coloron << "(none)";
01928 }
01929
01930 sresult <<coloroff<<nl<< " Operations : "<<coloron;
01931 objlist = taskobject->getNames();
01932 if ( !objlist.empty() ) {
01933 std::copy(objlist.begin(), objlist.end(), std::ostream_iterator<std::string>(sresult, " "));
01934 } else {
01935 sresult << "(none)";
01936 }
01937 sresult << coloroff << nl;
01938
01939 sresult <<nl<< " Data Flow Ports: ";
01940 objlist = taskobject->getPortNames();
01941 if ( !objlist.empty() ) {
01942 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
01943 base::PortInterface* port = taskobject->getPort(*it);
01944 bool writer = dynamic_cast<OutputPortInterface*>(port) ? true : false;
01945 // Port type R/W
01946 sresult << nl << " " << ( !writer ?
01947 " In" : "Out");
01948 // Port data type + name
01949 if ( !port->connected() )
01950 sresult << "(U) " << setw(11)<<right<< Types()->toDot( port->getTypeInfo()->getTypeName() );
01951 else
01952 sresult << "(C) " << setw(11)<<right<< Types()->toDot( port->getTypeInfo()->getTypeName() );
01953 sresult << " "
01954 << coloron <<setw( 14 )<<left<< *it << coloroff;
01955
01956 InputPortInterface* iport = dynamic_cast<InputPortInterface*>(port);
01957 if (iport) {
01958 sresult << " <= ( use '"<< iport->getName() << ".read(sample)' to read a sample from this port)";
01959 }
01960 OutputPortInterface* oport = dynamic_cast<OutputPortInterface*>(port);
01961 if (oport) {
01962 if ( oport->keepsLastWrittenValue())
01963 sresult << " => " << oport->getDataSource();
01964 else
01965 sresult << " => (keepsLastWrittenValue() == false. Enable it for this port in order to see it in the TaskBrowser.)";
01966 }
01967 #if 0
01968 // only show if we're connected to it
01969 if (peer == taskcontext && peer->provides() == taskobject) {
01970
01971
01972 InputPortInterface* iport = dynamic_cast<InputPortInterface*>(ports()->getPort(port->getName()));
01973 if (iport) {
01974
01975 iport->getDataSource()->evaluate();
01976
01977 if ( peer == this)
01978 sresult << " <= " << DataSourceBase::shared_ptr( iport->getDataSource());
01979 else
01980 sresult << " => " << DataSourceBase::shared_ptr( iport->getDataSource());
01981 }
01982 OutputPortInterface* oport = dynamic_cast<OutputPortInterface*>(ports()->getPort(port->getName()));
01983 if (oport) {
01984
01985 DataSourceBase::shared_ptr ds = oport->getDataSource();
01986 if (ds) {
01987 if ( peer == this)
01988 sresult << " => " << ds;
01989 else
01990 sresult << " <= " << ds << " (sent from TaskBrowser)";
01991 } else {
01992 sresult << "(no last written value kept)";
01993 }
01994 }
01995 } else {
01996 sresult << "(TaskBrowser not connected to this port)";
01997 }
01998 #endif
01999
02000
02001
02002 }
02003 } else {
02004 sresult << "(none)";
02005 }
02006 sresult << coloroff << nl;
02007
02008 objlist = taskobject->getProviderNames();
02009 sresult <<nl<< " Services: "<<nl;
02010 if ( !objlist.empty() ) {
02011 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
02012 sresult <<coloron<< " " << setw(14) << *it <<coloroff<< " ( "<< taskobject->provides(*it)->doc() << " ) "<<nl;
02013 } else {
02014 sresult <<coloron<< "(none)" <<coloroff <<nl;
02015 }
02016
02017
02018 if ( peer->provides() == taskobject ) {
02019
02020 objlist = peer->requires()->getOperationCallerNames();
02021 sresult <<nl<< " Requires Operations :";
02022 if ( !objlist.empty() ) {
02023 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
02024 sresult <<coloron<< " " << *it <<coloroff << '[' << (peer->requires()->getOperationCaller(*it)->ready() ? "R]" : "!]");
02025 sresult << nl;
02026 } else {
02027 sresult <<coloron<< " (none)" <<coloroff <<nl;
02028 }
02029 objlist = peer->requires()->getRequesterNames();
02030 sresult << " Requests Services :";
02031 if ( !objlist.empty() ) {
02032 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
02033 sresult <<coloron<< " " << *it <<coloroff << '[' << (peer->requires(*it)->ready() ? "R]" : "!]");
02034 sresult << nl;
02035 } else {
02036 sresult <<coloron<< " (none)" <<coloroff <<nl;
02037 }
02038
02039 if (peer->provides()->hasService("scripting")) {
02040 objlist = peer->getProvider<Scripting>("scripting")->getProgramList();
02041 if ( !objlist.empty() ) {
02042 sresult << " Programs : "<<coloron;
02043 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
02044 sresult << *it << "["<<getProgramStatusChar(peer,*it)<<"] ";
02045 sresult << coloroff << nl;
02046 }
02047
02048 objlist = peer->getProvider<Scripting>("scripting")->getStateMachineList();
02049 if ( !objlist.empty() ) {
02050 sresult << " StateMachines: "<<coloron;
02051 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
02052 sresult << *it << "["<<getStateMachineStatusChar(peer,*it)<<"] ";
02053 sresult << coloroff << nl;
02054 }
02055 }
02056
02057
02058 if ( context == tb )
02059 sresult <<nl<< " "<<peer->getName()<<" Peers : "<<coloron;
02060 else
02061 sresult << nl <<" Peers : "<<coloron;
02062
02063 objlist = peer->getPeerList();
02064 if ( !objlist.empty() )
02065 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
02066 if( peer->getPeer(*it) )
02067 sresult << *it << "["<<getTaskStatusChar(peer->getPeer(*it))<<"] ";
02068 else
02069 sresult << *it << "[X] ";
02070 }
02071 else
02072 sresult << "(none)";
02073 }
02074 sresult <<coloroff<<nl;
02075 cout << sresult.str();
02076 sresult.str("");
02077 }
02078
02079 void TaskBrowser::printOperation( const std::string m, Service::shared_ptr the_ops )
02080 {
02081 std::vector<ArgumentDescription> args;
02082 Service::shared_ptr ops;
02083 try {
02084 args = the_ops->getArgumentList( m );
02085 ops = the_ops;
02086 } catch(...) {
02087 args = GlobalService::Instance()->getArgumentList( m );
02088 ops = GlobalService::Instance();
02089 }
02090 sresult <<" " << coloron << m << coloroff<< "( ";
02091 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it) {
02092 sresult << Types()->toDot( it->type ) <<" ";
02093 sresult << coloron << it->name << coloroff;
02094 if ( it+1 != args.end() )
02095 sresult << ", ";
02096 else
02097 sresult << " ";
02098 }
02099 sresult << ") : "<< Types()->toDot( ops->getResultType(m) )<<nl;
02100 sresult << " " << ops->getDescription( m )<<nl;
02101 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it)
02102 sresult <<" "<< it->name <<" : " << it->description << nl;
02103 }
02104
02105 }