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