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