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