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/MultiVector.hpp>
00060 #include <rtt/TypeStream.hpp>
00061 #include "TaskBrowser.hpp"
00062
00063 #include "rtt/TryCommand.hpp"
00064 #include <rtt/TaskContext.hpp>
00065 #include <rtt/scripting/parser-debug.hpp>
00066 #include <rtt/scripting/Parser.hpp>
00067 #include <rtt/scripting/ProgramLoader.hpp>
00068 #include <rtt/scripting/parse_exception.hpp>
00069 #include <rtt/scripting/PeerParser.hpp>
00070
00071 #include <iostream>
00072 #include <fstream>
00073 #include <sstream>
00074 #include <iomanip>
00075 #include <deque>
00076 #include <stdio.h>
00077 #ifndef NO_GPL
00078 #include <readline/readline.h>
00079 #include <readline/history.h>
00080 #endif
00081 #include <boost/bind.hpp>
00082 #include <boost/lambda/lambda.hpp>
00083
00084 #include <signal.h>
00085
00086 namespace OCL
00087 {
00088 using namespace RTT;
00089 using namespace RTT::detail;
00090 #ifndef NO_GPL
00091 std::vector<std::string> TaskBrowser::candidates;
00092 std::vector<std::string> TaskBrowser::completes;
00093 std::vector<std::string>::iterator TaskBrowser::complete_iter;
00094 std::string TaskBrowser::component;
00095 std::string TaskBrowser::peerpath;
00096 std::string TaskBrowser::text;
00097 #endif
00098 TaskContext* TaskBrowser::taskcontext = 0;
00099 OperationInterface* TaskBrowser::taskobject = 0;
00100 TaskContext* TaskBrowser::peer = 0;
00101 TaskContext* TaskBrowser::tb = 0;
00102 TaskContext* TaskBrowser::context = 0;
00103
00104 using boost::bind;
00105 using namespace RTT;
00106 using namespace std;
00107
00108 string TaskBrowser::red("\e[m\e[1;31m");
00109 string TaskBrowser::green("\e[m\e[1;32m");
00110 string TaskBrowser::blue("\e[m\e[1;34m");
00111
00115 static std::ostream&
00116 nl(std::ostream& __os)
00117 { return __os.put(__os.widen('\n')); }
00118
00119
00120 void ctrl_c_catcher(int sig)
00121 {
00122 ::signal(sig, SIG_IGN);
00123 #ifndef NO_GPL
00124
00125
00126
00127 rl_free_line_state();
00128
00129 #endif
00130 ::signal(SIGINT, ctrl_c_catcher);
00131 }
00132
00133 #ifndef NO_GPL
00134 char *TaskBrowser::rl_gets ()
00135 {
00136
00137
00138 if (line_read)
00139 {
00140 free (line_read);
00141 line_read = 0;
00142 }
00143
00144
00145 std::string p;
00146 if ( !macrorecording ) {
00147 p = prompt;
00148 } else {
00149 p = "> ";
00150 }
00151
00152 if (rl_set_signals() != 0)
00153 cerr << "Error setting signals !" <<endl;
00154 line_read = readline ( p.c_str() );
00155
00156
00157
00158 if (line_read && *line_read) {
00159
00160 string s = line_read;
00161 if (s != "quit")
00162 add_history (line_read);
00163 }
00164 return (line_read);
00165 }
00166
00167 char* TaskBrowser::dupstr( const char *s )
00168 {
00169 char * rv;
00170
00171 rv = (char*) malloc( strlen( s ) + 1 );
00172 strcpy( rv, s );
00173 return rv;
00174 }
00175
00176 char *TaskBrowser::command_generator( const char *_text, int state )
00177 {
00178
00179 if ( !state )
00180 {
00181
00182 text = _text;
00183
00184 completes.clear();
00185 find_completes();
00186 complete_iter = completes.begin();
00187 }
00188 else
00189 ++complete_iter;
00190
00191
00192 if ( complete_iter == completes.end() )
00193 return 0;
00194
00195 return dupstr( complete_iter->c_str() );
00196 }
00197
00202 void TaskBrowser::find_completes() {
00203 std::string::size_type pos;
00204 std::string::size_type startpos;
00205 std::string line( rl_line_buffer );
00206
00207
00208 if ( line.find(std::string("cd ")) == 0 || line.find(std::string("ls ")) == 0) {
00209
00210
00211 pos = line.find(" ");
00212 startpos = line.find_last_of(". ");
00213
00214
00215 peer = taskcontext;
00216 if ( pos+1 != line.length() )
00217 peer = findPeer( line.substr(pos+1) );
00218
00219
00220 TaskContext::PeerList v = peer->getPeerList();
00221 for (TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00222 std::string path;
00223 if ( !( pos+1 > startpos) )
00224 path = line.substr(pos+1, startpos - pos);
00225
00226 if ( *i == line.substr(startpos+1) )
00227 completes.push_back( path + *i + ".");
00228 else
00229 if ( startpos == std::string::npos || startpos+1 == line.length() || i->find( line.substr(startpos+1)) == 0 )
00230 completes.push_back( path + *i );
00231 }
00232
00233 if (line.find(std::string("cd ")) == 0)
00234 return;
00235
00236 v = peer->getObjectList();
00237 for (TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00238 std::string path;
00239 if ( !( pos+1 > startpos) )
00240 path = line.substr(pos+1, startpos - pos);
00241
00242 if ( *i == line.substr(startpos+1) )
00243 completes.push_back( path + *i + ".");
00244 else
00245 if ( startpos == std::string::npos || startpos+1 == line.length() || i->find( line.substr(startpos+1)) == 0 )
00246 completes.push_back( path + *i );
00247 }
00248 return;
00249 }
00250
00251
00252 if ( line.find(std::string(".")) == 0 ) {
00253
00254 std::vector<std::string> tbcoms;
00255 tbcoms.push_back(".loadProgram ");
00256 tbcoms.push_back(".unloadProgram ");
00257 tbcoms.push_back(".loadStateMachine ");
00258 tbcoms.push_back(".unloadStateMachine ");
00259 tbcoms.push_back(".light");
00260 tbcoms.push_back(".dark");
00261 tbcoms.push_back(".nocolors");
00262 tbcoms.push_back(".connect");
00263 tbcoms.push_back(".record");
00264 tbcoms.push_back(".end");
00265 tbcoms.push_back(".cancel");
00266
00267
00268 for( std::vector<std::string>::iterator it = tbcoms.begin();
00269 it != tbcoms.end();
00270 ++it)
00271 if ( it->find(line) == 0 )
00272 completes.push_back( *it );
00273 return;
00274 }
00275
00276 if ( line.find(std::string("list ")) == 0
00277 || line.find(std::string("trace ")) == 0
00278 || line.find(std::string("untrace ")) == 0) {
00279 stringstream ss( line.c_str() );
00280 string lcommand;
00281 ss >> lcommand;
00282 lcommand += ' ';
00283 std::vector<std::string> progs;
00284
00285
00286 progs = context->scripting()->getPrograms();
00287
00288 for( std::vector<std::string>::iterator it = progs.begin();
00289 it != progs.end();
00290 ++it) {
00291 string res = lcommand + *it;
00292 if ( res.find(line) == 0 )
00293 completes.push_back( *it );
00294 }
00295 progs = context->scripting()->getStateMachines();
00296 for( std::vector<std::string>::iterator it = progs.begin();
00297 it != progs.end();
00298 ++it) {
00299 string res = lcommand + *it;
00300 if ( res.find(line) == 0 )
00301 completes.push_back( *it );
00302 }
00303
00304 return;
00305 }
00306
00307 startpos = text.find_last_of(",( ");
00308 if ( startpos == std::string::npos )
00309 startpos = 0;
00310
00311
00312 find_peers(startpos);
00313
00314
00315
00316
00317
00318
00319 std::string comp = component;
00320
00321
00322
00323
00324
00325 find_ops();
00326
00327
00328
00329 if ( line.empty() ) {
00330 completes.push_back("cd ");
00331 completes.push_back("cd ..");
00332 completes.push_back("ls");
00333 completes.push_back("help");
00334 completes.push_back("quit");
00335 completes.push_back("list");
00336 completes.push_back("trace");
00337 completes.push_back("untrace");
00338 if (taskcontext == context)
00339 completes.push_back("leave");
00340 else
00341 completes.push_back("enter");
00342
00343 }
00344
00345
00346 if ( !text.empty() ) {
00347 if ( std::string( "cd " ).find(text) == 0 )
00348 completes.push_back("cd ");
00349 if ( std::string( "ls" ).find(text) == 0 )
00350 completes.push_back("ls");
00351 if ( std::string( "cd .." ).find(text) == 0 )
00352 completes.push_back("cd ..");
00353 if ( std::string( "help" ).find(text) == 0 )
00354 completes.push_back("help");
00355 if ( std::string( "quit" ).find(text) == 0 )
00356 completes.push_back("quit");
00357 if ( std::string( "list " ).find(text) == 0 )
00358 completes.push_back("list ");
00359 if ( std::string( "trace " ).find(text) == 0 )
00360 completes.push_back("trace ");
00361 if ( std::string( "untrace " ).find(text) == 0 )
00362 completes.push_back("untrace ");
00363
00364 if (taskcontext == context && string("leave").find(text) == 0)
00365 completes.push_back("leave");
00366
00367 if (context == tb && string("enter").find(text) == 0)
00368 completes.push_back("enter");
00369 }
00370 }
00371
00372 void TaskBrowser::find_ops()
00373 {
00374
00375
00376 std::vector<std::string> attrs;
00377 attrs = taskobject->attributes()->names();
00378 for (std::vector<std::string>::iterator i = attrs.begin(); i!= attrs.end(); ++i ) {
00379 if ( i->find( component ) == 0 && !component.empty() )
00380 completes.push_back( peerpath + *i );
00381 }
00382
00383 if (taskobject == peer && peer->properties() != 0 ) {
00384 std::vector<std::string> props;
00385 peer->properties()->list(props);
00386 for (std::vector<std::string>::iterator i = props.begin(); i!= props.end(); ++i ) {
00387 if ( i->find( component ) == 0 && !component.empty() ) {
00388 completes.push_back( peerpath + *i );
00389 }
00390 }
00391 }
00392
00393
00394 std::vector<std::string> comps;
00395 comps = taskobject->commands()->getNames();
00396 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00397 if ( i->find( component ) == 0 )
00398 completes.push_back( peerpath + *i );
00399 }
00400
00401 comps = taskobject->methods()->getNames();
00402 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00403 if ( i->find( component ) == 0 )
00404 completes.push_back( peerpath + *i );
00405 }
00406
00407 comps = taskobject->events()->getNames();
00408 for (std::vector<std::string>::iterator i = comps.begin(); i!= comps.end(); ++i ) {
00409 if ( i->find( component ) == 0 )
00410 completes.push_back( peerpath + *i );
00411 }
00412 }
00413
00414 void TaskBrowser::find_peers( std::string::size_type startpos )
00415 {
00416 peerpath.clear();
00417 peer = context;
00418 taskobject = context;
00419
00420 std::string to_parse = text.substr(startpos);
00421 startpos = 0;
00422 std::string::size_type endpos = 0;
00423
00424 component.clear();
00425 peerpath.clear();
00426 while (endpos != std::string::npos )
00427 {
00428 bool itemfound = false;
00429 endpos = to_parse.find(".");
00430 if ( endpos == startpos ) {
00431 component.clear();
00432 break;
00433 }
00434 std::string item = to_parse.substr(startpos, endpos);
00435
00436 if ( taskobject->getObject( item ) ) {
00437 taskobject = peer->getObject(item);
00438 itemfound = true;
00439 } else
00440 if ( peer->hasPeer( item ) ) {
00441 peer = peer->getPeer( item );
00442 taskobject = peer;
00443 itemfound = true;
00444 }
00445 if ( itemfound ) {
00446 peerpath += to_parse.substr(startpos, endpos) + ".";
00447 if ( endpos != std::string::npos )
00448 to_parse = to_parse.substr(endpos + 1);
00449 else
00450 to_parse.clear();
00451 startpos = 0;
00452 }
00453 else {
00454
00455
00456 component = item;
00457 break;
00458 }
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469 TaskContext::PeerList v;
00470 if ( taskobject == peer ) {
00471
00472 v = peer->getPeerList();
00473 for (TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00474 if ( i->find( component ) == 0 ) {
00475 completes.push_back( peerpath + *i );
00476 completes.push_back( peerpath + *i + "." );
00477
00478 }
00479 }
00480 }
00481
00482 v = taskobject->getObjectList();
00483 for (TaskContext::PeerList::iterator i = v.begin(); i != v.end(); ++i) {
00484 if ( i->find( component ) == 0 ) {
00485 completes.push_back( peerpath + *i );
00486 if ( *i != "this" )
00487 completes.push_back( peerpath + *i + "." );
00488
00489 }
00490 }
00491 return;
00492 }
00493
00494 char ** TaskBrowser::orocos_hmi_completion ( const char *text, int start, int end )
00495 {
00496 char **matches;
00497 matches = ( char ** ) 0;
00498
00499 matches = rl_completion_matches ( text, &TaskBrowser::command_generator );
00500
00501 return ( matches );
00502 }
00503 #endif // !NO_GPL
00504
00505 TaskBrowser::TaskBrowser( TaskContext* _c )
00506 : TaskContext("TaskBrowser"),
00507 command(0),
00508 debug(0),
00509 line_read(0),
00510 lastc(0), storedname(""), storedline(-1),
00511 macrorecording(false)
00512 {
00513 tb = this;
00514 context = tb;
00515 this->switchTaskContext(_c);
00516 #ifndef NO_GPL
00517 rl_completion_append_character = '\0';
00518 rl_attempted_completion_function = &TaskBrowser::orocos_hmi_completion;
00519
00520 if ( read_history(".tb_history") != 0 ) {
00521 read_history("~/.tb_history");
00522 }
00523 #endif
00524
00525 this->setColorTheme( darkbg );
00526 this->enterTask();
00527 }
00528
00529 TaskBrowser::~TaskBrowser() {
00530 #ifndef NO_GPL
00531 if (line_read)
00532 {
00533 free (line_read);
00534 }
00535 if ( write_history(".tb_history") != 0 ) {
00536 write_history("~/.tb_history");
00537 }
00538 #endif
00539 }
00540
00544 char getTaskStatusChar(TaskContext* t)
00545 {
00546 if (t->isRunning() )
00547 return 'R';
00548 if (t->isConfigured() )
00549 return 'S';
00550 return 'U';
00551 }
00552
00553 char getStateMachineStatusChar(TaskContext* t, string progname)
00554 {
00555 string ps = t->scripting()->getStateMachineStatus(progname);
00556 return toupper(ps[0]);
00557 }
00558
00559 char getProgramStatusChar(TaskContext* t, string progname)
00560 {
00561 string ps = t->scripting()->getProgramStatus(progname);
00562 return toupper(ps[0]);
00563 }
00564
00565 void str_trim(string& str, char to_trim)
00566 {
00567 string::size_type pos1 = str.find_first_not_of(to_trim);
00568 string::size_type pos2 = str.find_last_not_of(to_trim);
00569 str = str.substr(pos1 == string::npos ? 0 : pos1,
00570 pos2 == string::npos ? str.length() - 1 : pos2 - pos1 + 1);
00571 }
00572
00573
00578 void TaskBrowser::loop()
00579 {
00580 using boost::lambda::_1;
00581
00582
00583 ::signal( SIGINT, ctrl_c_catcher );
00584 #ifndef NO_GPL
00585
00586 if(rl_catch_signals == 0)
00587 cerr << "Error: not catching signals !"<<endl;
00588 if (rl_set_signals() != 0)
00589 cerr << "Error setting signals !" <<endl;
00590 #endif
00591 cout << nl<<
00592 coloron <<
00593 " This console reader allows you to browse and manipulate TaskContexts."<<nl<<
00594 " You can type in a command, event, method, expression or change variables."<<nl;
00595 cout <<" (type '"<<underline<<"help"<<coloroff<<coloron<<"' for instructions)"<<nl;
00596 #ifndef NO_GPL
00597 cout << " TAB completion and HISTORY is available ('bash' like)" <<coloroff<<nl<<nl;
00598 #else
00599 cout << " TAB completion and history is NOT available (LGPL-version)" <<coloroff<<nl<<nl;
00600 #endif
00601 while (1)
00602 {
00603 if (!macrorecording) {
00604 if ( context == tb )
00605 cout << green << " Watching " <<coloroff;
00606 else
00607 cout << red << " In " << coloroff;
00608
00609 char state = getTaskStatusChar(taskcontext);
00610
00611 cout << "Task "<<green<< taskcontext->getName() <<coloroff<< "["<< state <<"]. (Status of last Command : ";
00612 if ( command == 0 )
00613 cout << "none";
00614 else if ( command->done() )
00615 cout <<green + "done";
00616 else if ( command->valid() )
00617 cout << blue+"busy";
00618 else if ( command->executed() )
00619 cout << red+"fail";
00620 else if ( command->accepted() )
00621 cout << blue+"queued";
00622 cout << coloroff << " )";
00623
00624
00625 cout << endl;
00626
00627
00628 for (PTrace::iterator it = ptraces.begin(); it != ptraces.end(); ++it) {
00629 TaskContext* progpeer = it->first.first;
00630 int line = progpeer->scripting()->getProgramLine(it->first.second);
00631 if ( line != it->second ) {
00632 it->second = line;
00633 printProgram( it->first.second, -1, progpeer );
00634 }
00635 }
00636
00637 for (PTrace::iterator it = straces.begin(); it != straces.end(); ++it) {
00638 TaskContext* progpeer = it->first.first;
00639 int line = progpeer->scripting()->getStateMachineLine(it->first.second);
00640 if ( line != it->second ) {
00641 it->second = line;
00642 printProgram( it->first.second, -1, progpeer );
00643 }
00644 }
00645 }
00646
00647 checkPorts();
00648
00649 ::signal( SIGINT, ctrl_c_catcher );
00650 #ifndef NO_GPL
00651 std::string command( rl_gets() );
00652 #else
00653 std::string command;
00654 cout << prompt;
00655 cin >> command;
00656 #endif
00657 str_trim( command, ' ');
00658 ::signal( SIGINT, SIG_DFL );
00659 cout << coloroff;
00660 if ( command == "quit" ) {
00661
00662 cout << endl;
00663 return;
00664 } else if ( command == "help") {
00665 printHelp();
00666 } else if ( command == "#debug") {
00667 debug = !debug;
00668 } else if ( command.find("list ") == 0 || command == "list" ) {
00669 browserAction(command);
00670 } else if ( command.find("trace ") == 0 || command == "trace" ) {
00671 browserAction(command);
00672 } else if ( command.find("untrace ") == 0 || command == "untrace" ) {
00673 browserAction(command);
00674 } else if ( command.find("ls") == 0 ) {
00675 std::string::size_type pos = command.find("ls")+2;
00676 command = std::string(command, pos, command.length());
00677 printInfo( command );
00678 } else if ( command == "" ) {
00679 } else if ( command.find("cd ..") == 0 ) {
00680 this->switchBack( );
00681 } else if ( command.find("enter") == 0 ) {
00682 this->enterTask();
00683 } else if ( command.find("leave") == 0 ) {
00684 this->leaveTask();
00685 } else if ( command.find("cd ") == 0 ) {
00686 std::string::size_type pos = command.find("cd")+2;
00687 command = std::string(command, pos, command.length());
00688 this->switchTaskContext( command );
00689 } else if ( command.find(".") == 0 ) {
00690 command = std::string(command, 1, command.length());
00691 this->browserAction( command );
00692 } else if ( macrorecording) {
00693 macrotext += command +'\n';
00694 } else {
00695 try {
00696 this->evalCommand( command );
00697 } catch(...){
00698 cerr << "The command '"<<command<<"' caused an unknown exception and could not be completed."<<endl;
00699 }
00700
00701
00702 storedline = -1;
00703 }
00704 cout <<endl;
00705 }
00706 }
00707
00708 std::deque<TaskContext*> taskHistory;
00709 std::string TaskBrowser::prompt(" (type 'ls' for context info) :");
00710 std::string TaskBrowser::coloron("\e[m\e[1;31m");
00711 std::string TaskBrowser::underline("\e[4m");
00712 std::string TaskBrowser::coloroff("\e[m");
00713
00714 void TaskBrowser::enterTask()
00715 {
00716 if ( context == taskcontext ) {
00717 log(Info) <<"Already in Task "<< taskcontext->getName()<<endlog();
00718 return;
00719 }
00720 context = taskcontext;
00721 log(Info) <<"Entering Task "<< taskcontext->getName()<<endlog();
00722 }
00723
00724 void TaskBrowser::leaveTask()
00725 {
00726 if ( context == tb ) {
00727 log(Info) <<"Already watching Task "<< taskcontext->getName()<<endlog();
00728 return;
00729 }
00730 context = tb;
00731 log(Info) <<"Watching Task "<< taskcontext->getName()<<endlog();
00732 }
00733
00734 void TaskBrowser::recordMacro(std::string name)
00735 {
00736 if ( name.empty() ) {
00737 cerr << "Please specify a macro name." <<endl;
00738 return;
00739 } else {
00740 cout << "Recording macro "<< name <<endl;
00741 cout << "Use program scripting syntax (do, set,...) !" << endl <<endl;
00742 cout << "export function "<< name<<" {"<<endl;
00743 }
00744 macrorecording = true;
00745 macroname = name;
00746 }
00747
00748 void TaskBrowser::cancelMacro() {
00749 cout << "Canceling macro "<< macroname <<endl;
00750 macrorecording = false;
00751 }
00752
00753 void TaskBrowser::endMacro() {
00754 string fname = macroname + ".ops";
00755 macrorecording = false;
00756 cout << "}" <<endl;
00757 cout << "Saving file "<< fname <<endl;
00758 ofstream macrofile( fname.c_str() );
00759 macrofile << "/* TaskBrowser macro '"<<macroname<<"' */" <<endl<<endl;
00760 macrofile << "export function "<<macroname<<" {"<<endl;
00761 macrofile << macrotext.c_str();
00762 macrofile << "}"<<endl;
00763
00764 cout << "Loading file "<< fname <<endl;
00765 ProgramLoader loader;
00766 if ( loader.loadProgram( fname, context ) ) {
00767 cout << "Done."<<endl;
00768 } else
00769 cout << "Failed."<<endl;
00770 }
00771
00772 void TaskBrowser::switchBack()
00773 {
00774 if ( taskHistory.size() == 0)
00775 return;
00776 if ( !taskcontext->engine()->commands()->isProcessed( lastc ) ) {
00777 Logger::log()<<Logger::Warning
00778 << "Previous command was not yet processed by previous Processor." <<Logger::nl
00779 << " Can not track command status across tasks."<< endlog();
00780
00781 command = 0;
00782 } else {
00783 delete command;
00784 command = 0;
00785 }
00786
00787 this->switchTaskContext( taskHistory.front(), false );
00788 lastc = 0;
00789 taskHistory.pop_front();
00790 }
00791
00792 void TaskBrowser::checkPorts()
00793 {
00794
00795
00796 DataFlowInterface::Ports ports;
00797 ports = this->ports()->getPorts();
00798 for( DataFlowInterface::Ports::iterator i=ports.begin(); i != ports.end(); ++i) {
00799
00800 PortInterface* p = *i;
00801 PortInterface* tcp = taskcontext->ports()->getPort( p->getName() );
00802 if ( p->ready() == false || tcp == 0 || tcp->ready() == false) {
00803 this->ports()->removePort( p->getName() );
00804 delete p;
00805 }
00806 }
00807 }
00808
00809 void TaskBrowser::setColorTheme(ColorTheme t)
00810 {
00811
00812 const char* dbg = "\033[01;";
00813 const char* wbg = "\033[02;";
00814
00815 const char* r = "31m";
00816 const char* g = "32m";
00817 const char* b = "34m";
00818 const char* con = "31m";
00819 const char* coff = "\e[m";
00820 const char* und = "\e[4m";
00821
00822 switch (t)
00823 {
00824 case nocolors:
00825 green.clear();
00826 red.clear();
00827 blue.clear();
00828 coloron.clear();
00829 coloroff.clear();
00830 underline.clear();
00831 return;
00832 break;
00833 case darkbg:
00834 green = dbg;
00835 red = dbg;
00836 blue = dbg;
00837 coloron = dbg;
00838 break;
00839 case whitebg:
00840 green = wbg;
00841 red = wbg;
00842 blue = wbg;
00843 coloron = wbg;
00844 break;
00845 }
00846 green += g;
00847 red += r;
00848 blue += b;
00849 coloron += con;
00850 coloroff = coff;
00851 underline = und;
00852 }
00853
00854 void TaskBrowser::switchTaskContext(std::string& c) {
00855
00856 peer = taskcontext;
00857 if ( this->findPeer( c + "." ) == 0 ) {
00858 cerr << "No such peer: "<< c <<nl;
00859 return;
00860 }
00861
00862 if ( peer == taskcontext ) {
00863 cerr << "Already in "<< c <<nl;
00864 return;
00865 }
00866
00867 if ( peer == tb ) {
00868 cerr << "Can not switch to TaskBrowser." <<nl;
00869 return;
00870 }
00871
00872
00873 this->switchTaskContext( peer );
00874 }
00875
00876 void TaskBrowser::switchTaskContext(TaskContext* tc, bool store) {
00877
00878 if (taskHistory.size() == 20 )
00879 taskHistory.pop_back();
00880 if ( taskcontext && store)
00881 taskHistory.push_front( taskcontext );
00882
00883
00884
00885 if ( taskcontext && !taskcontext->engine()->commands()->isProcessed( lastc ) ) {
00886 Logger::log()<<Logger::Warning
00887 << "Previous command was not yet processed by previous Processor." <<Logger::nl
00888 << " Can not track command status across tasks."<< endlog();
00889
00890 command = 0;
00891 } else {
00892 delete command;
00893 command = 0;
00894 }
00895
00896
00897 this->disconnect();
00898
00899
00900 DataFlowInterface::Ports ports = this->ports()->getPorts();
00901 for( DataFlowInterface::Ports::iterator i=ports.begin(); i != ports.end(); ++i) {
00902 this->ports()->removePort( (*i)->getName() );
00903 delete *i;
00904 }
00905
00906
00907 if ( context == taskcontext )
00908 context = tc;
00909 taskcontext = tc;
00910 lastc = 0;
00911
00912
00913 this->addPeer( taskcontext );
00914
00915 cerr << " Switched to : " << taskcontext->getName() <<endl;
00916
00917 }
00918
00919 TaskContext* TaskBrowser::findPeer(std::string c) {
00920
00921 std::string s( c );
00922
00923 our_pos_iter_t parsebegin( s.begin(), s.end(), "teststring" );
00924 our_pos_iter_t parseend;
00925
00926 PeerParser pp( peer, true );
00927 try {
00928 parse( parsebegin, parseend, pp.parser(), SKIP_PARSER );
00929 }
00930 catch( ... )
00931 {
00932 log(Debug) <<"No such peer : "<< c <<endlog();
00933 return 0;
00934 }
00935 taskobject = pp.taskObject();
00936 assert(taskobject);
00937 peer = pp.peer();
00938 return pp.peer();
00939 }
00940
00941 void TaskBrowser::browserAction(std::string& act)
00942 {
00943 std::stringstream ss(act);
00944 std::string instr;
00945 ss >> instr;
00946
00947 if ( instr == "list" ) {
00948 int line;
00949 ss >> line;
00950 if (ss) {
00951 this->printProgram(line);
00952 return;
00953 }
00954 ss.clear();
00955 string arg;
00956 ss >> arg;
00957 if (ss) {
00958 ss.clear();
00959 ss >> line;
00960 if (ss) {
00961
00962 this->printProgram(arg, line);
00963 return;
00964 }
00965
00966 this->printProgram( arg );
00967 return;
00968 }
00969
00970 this->printProgram();
00971 return;
00972 }
00973
00974
00975
00976
00977 if ( instr == "trace") {
00978 string arg;
00979 ss >> arg;
00980 if (ss) {
00981 bool pi = context->scripting()->hasProgram(arg);
00982 if (pi) {
00983 ptraces[make_pair(context, arg)] = context->scripting()->getProgramLine(arg);
00984 this->printProgram( arg );
00985 return;
00986 }
00987 pi = context->scripting()->hasStateMachine(arg);
00988 if (pi) {
00989 straces[make_pair(context, arg)] = context->scripting()->getStateMachineLine(arg);
00990 this->printProgram( arg );
00991 return;
00992 }
00993 cerr <<"No such program or state machine: "<< arg <<endl;
00994 return;
00995 }
00996
00997
00998 std::vector<std::string> names;
00999 names = context->scripting()->getPrograms();
01000 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01001 bool pi = context->scripting()->hasProgram(arg);
01002 if (pi)
01003 ptraces[make_pair(context, arg)] = context->scripting()->getProgramLine(arg);
01004 }
01005
01006 names = context->scripting()->getStateMachines();
01007 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01008 bool pi = context->scripting()->hasStateMachine(arg);
01009 if (pi)
01010 straces[make_pair(context, arg)] = context->scripting()->getStateMachineLine(arg);
01011 }
01012
01013 cerr << "Tracing all programs and state machines in "<< context->getName() << endl;
01014 return;
01015 }
01016
01017 if ( instr == "untrace") {
01018 string arg;
01019 ss >> arg;
01020 if (ss) {
01021 ptraces.erase( make_pair(context, arg) );
01022 straces.erase( make_pair(context, arg) );
01023 cerr <<"Untracing "<< arg <<" of "<< context->getName()<<endl;
01024 return;
01025 }
01026
01027 std::vector<std::string> names;
01028 names = context->scripting()->getPrograms();
01029 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01030 bool pi = context->scripting()->hasProgram(arg);
01031 if (pi)
01032 ptraces.erase(make_pair(context, arg));
01033 }
01034
01035 names = context->scripting()->getStateMachines();
01036 for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
01037 bool pi = context->scripting()->hasStateMachine(arg);
01038 if (pi)
01039 straces.erase(make_pair(context, arg));
01040 }
01041
01042 cerr << "Untracing all programs and state machines of "<< context->getName() << endl;
01043 return;
01044 }
01045
01046 std::string arg;
01047 ss >> arg;
01048 ProgramLoader loader;
01049 if ( instr == "loadProgram") {
01050 if ( loader.loadProgram( arg, context ) )
01051 cout << "Done."<<endl;
01052 else
01053 cout << "Failed."<<endl;
01054 return;
01055 }
01056 if ( instr == "unloadProgram") {
01057 if ( loader.unloadProgram( arg, context ) )
01058 cout << "Done."<<endl;
01059 else
01060 cout << "Failed."<<endl;
01061 return;
01062 }
01063
01064 if ( instr == "loadStateMachine") {
01065 if ( loader.loadStateMachine( arg, context ) )
01066 cout << "Done."<<endl;
01067 else
01068 cout << "Failed."<<endl;
01069 return;
01070 }
01071 if ( instr == "unloadStateMachine") {
01072 if ( loader.unloadStateMachine( arg, context ) )
01073 cout << "Done."<<endl;
01074 else
01075 cout << "Failed."<<endl;
01076 return;
01077 }
01078 if ( instr == "dark") {
01079 this->setColorTheme(darkbg);
01080 cout << nl << "Setting Color Theme for "+green+"dark"+coloroff+" backgrounds."<<endl;
01081 return;
01082 }
01083 if ( instr == "light") {
01084 this->setColorTheme(whitebg);
01085 cout << nl << "Setting Color Theme for "+green+"light"+coloroff+" backgrounds."<<endl;
01086 return;
01087 }
01088 if ( instr == "nocolors") {
01089 this->setColorTheme(nocolors);
01090 cout <<nl << "Disabling all colors"<<endl;
01091 return;
01092 }
01093 if ( instr == "connect") {
01094 if (arg.empty() ) {
01095 cout <<nl << "TaskBrowser connects to all ports of "<<taskcontext->getName()<<endl;
01096
01097 DataFlowInterface::Ports ports = taskcontext->ports()->getPorts();
01098 for( DataFlowInterface::Ports::iterator i=ports.begin(); i != ports.end(); ++i) {
01099 if (this->ports()->getPort( (*i)->getName() ) == 0 )
01100 this->ports()->addPort( (*i)->antiClone() );
01101 }
01102 RTT::connectPorts(this,taskcontext);
01103 }
01104 else {
01105 cout <<nl << "TaskBrowser connects to port '"<<arg <<"' of "<<taskcontext->getName()<<endl;
01106
01107 DataFlowInterface::Ports ports = taskcontext->ports()->getPorts();
01108 for( DataFlowInterface::Ports::iterator i=ports.begin(); i != ports.end(); ++i) {
01109 if ( (*i)->getName() == arg && this->ports()->getPort( (*i)->getName() ) == 0 ) {
01110 this->ports()->addPort( (*i)->antiClone() );
01111 this->ports()->getPort( arg )->connectTo( *i );
01112 assert( this->ports()->getPort( arg )->connected() );
01113 return;
01114 }
01115 }
01116 }
01117 return;
01118 }
01119 if ( instr == "record") {
01120 recordMacro( arg );
01121 return;
01122 }
01123 if ( instr == "cancel") {
01124 cancelMacro();
01125 return;
01126 }
01127 if ( instr == "end") {
01128 endMacro();
01129 return;
01130 }
01131 cerr << "Unknown Browser Action : "<< act <<endl;
01132 cerr << "See 'help' for valid syntax."<<endl;
01133 }
01134
01135 void TaskBrowser::evaluate(std::string& comm) {
01136 this->evalCommand(comm);
01137 }
01138
01139 void TaskBrowser::evalCommand(std::string& comm )
01140 {
01141 cout << " Got :"<< comm <<nl;
01142
01143 OperationInterface* ops = context->getObject( comm );
01144 if ( ops )
01145 {
01146 sresult << nl << "Printing Interface of '"<< coloron << ops->getName() <<coloroff <<"' :"<<nl<<nl;
01147 std::vector<std::string> methods = ops->commands()->getNames();
01148 std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printCommand, this, _1, ops) );
01149 methods = ops->methods()->getNames();
01150 std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printMethod, this, _1, ops) );
01151 if (comm == "this") {
01152 methods = taskcontext->events()->getNames();
01153 std::for_each( methods.begin(), methods.end(), boost::bind(&TaskBrowser::printEvent, this, _1, taskcontext->events()) );
01154 }
01155 cout << sresult.str();
01156 sresult.str("");
01157
01158 }
01159
01160
01161
01162
01163 if ( context->attributes()->getValue( comm ) ) {
01164 this->printResult( context->attributes()->getValue( comm )->getDataSource().get(), true );
01165 cout << sresult.str();
01166 sresult.str("");
01167 return;
01168 }
01169
01170 if ( ops ) {
01171 return;
01172 }
01173
01174 Parser _parser;
01175
01176 if (debug)
01177 cerr << "Trying ValueChange..."<<nl;
01178 try {
01179
01180 DataSourceBase::shared_ptr ds = _parser.parseValueChange( comm, context );
01181
01182 if ( ds.get() != 0 ) {
01183 this->printResult( ds.get(), false );
01184 cout << sresult.str() << nl;
01185 sresult.str("");
01186 return;
01187 } else if (debug)
01188 cerr << "returned zero !"<<nl;
01189 } catch ( fatal_semantic_parse_exception& pe ) {
01190
01191 if (debug)
01192 cerr << "fatal_semantic_parse_exception: ";
01193 cerr << pe.what() <<nl;
01194 return;
01195 } catch ( syntactic_parse_exception& pe ) {
01196
01197 if (debug)
01198 cerr << "syntactic_parse_exception: ";
01199 cerr << pe.what() <<nl;
01200 return;
01201 } catch ( parse_exception_parser_fail &pe )
01202 {
01203
01204 if (debug) {
01205 cerr << "Ignoring ValueChange exception :"<<nl;
01206 cerr << pe.what() <<nl;
01207 }
01208 } catch ( parse_exception& pe ) {
01209
01210 if (debug)
01211 cerr << "parse_exception :";
01212 cerr << pe.what() <<nl;
01213 return;
01214 }
01215 if (debug)
01216 cerr << "Trying Expression..."<<nl;
01217 try {
01218
01219 DataSourceBase::shared_ptr ds = _parser.parseExpression( comm, context );
01220
01221 if ( ds.get() != 0 ) {
01222 this->printResult( ds.get(), true );
01223 cout << sresult.str() << nl;
01224 sresult.str("");
01225 return;
01226 } else if (debug)
01227 cerr << "returned zero !"<<nl;
01228 } catch ( syntactic_parse_exception& pe ) {
01229
01230 if (debug)
01231 cerr << "syntactic_parse_exception :";
01232 cerr << pe.what() <<nl;
01233 return;
01234 } catch ( fatal_semantic_parse_exception& pe ) {
01235
01236 if (debug)
01237 cerr << "fatal_semantic_parse_exception :";
01238 cerr << pe.what() <<nl;
01239 return;
01240 } catch ( parse_exception_parser_fail &pe )
01241 {
01242
01243 if (debug) {
01244 cerr << "Ignoring Expression exception :"<<nl;
01245 cerr << pe.what() <<nl;
01246 }
01247 } catch ( parse_exception& pe ) {
01248
01249 if (debug) {
01250 cerr << "Ignoring Expression parse_exception :"<<nl;
01251 cerr << pe.what() <<nl;
01252 }
01253 }
01254 if (debug)
01255 cerr << "Trying Command..."<<nl;
01256 try {
01257 CommandInterface* com = _parser.parseCommand( comm, context, true ).first;
01258
01259 if ( com && dynamic_cast<DispatchInterface*>(com) == 0 ) {
01260 string prompt =" = ";
01261 sresult <<prompt<< setw(20)<<left;
01262 sresult << com->execute() << right;
01263 cout << sresult.str();
01264 sresult.str("");
01265 delete com;
01266 return;
01267 }
01268 if ( command && !command->executed() ) {
01269 cerr << "Warning : previous command is not yet processed by Processor." <<nl;
01270 } else {
01271 delete command;
01272 }
01273 command = dynamic_cast<DispatchInterface*>(com);
01274 } catch ( parse_exception& pe ) {
01275 if (debug)
01276 cerr << "CommandParser parse_exception :"<<nl;
01277 cerr << pe.what() <<nl;
01278 return;
01279 } catch (...) {
01280 cerr << "Illegal Input."<<nl;
01281 return;
01282 }
01283
01284 if ( command == 0 ) {
01285 cerr << "Uncaught : Illegal command."<<nl;
01286 return;
01287 }
01288
01289 if ( command->dispatch() == false ) {
01290 cerr << "Command not accepted by "<<context->getName()<<"'s Processor !" << nl;
01291 delete command;
01292 command = 0;
01293 accepted = 0;
01294 }
01295 }
01296
01297 void TaskBrowser::printResult( DataSourceBase* ds, bool recurse) {
01298 std::string prompt(" = ");
01299
01300 sresult <<prompt<< setw(20)<<left;
01301 if ( ds )
01302 doPrint( ds, recurse );
01303 else
01304 sresult << "(null)";
01305 sresult << right;
01306 }
01307
01308 void TaskBrowser::doPrint( DataSourceBase* ds, bool recurse) {
01309
01310
01311
01312 ds->reset();
01313
01314 DataSource<PropertyBag>* dspbag = DataSource<PropertyBag>::narrow(ds);
01315 if (dspbag) {
01316 PropertyBag bag( dspbag->get() );
01317 if (!recurse) {
01318 int siz = bag.getProperties().size();
01319 int wdth = siz ? (20 - (siz / 10 + 1)) : 20;
01320 sresult <<setw(0)<< siz <<setw( wdth )<< " Properties";
01321 } else {
01322 if ( ! bag.empty() ) {
01323 sresult <<setw(0)<<nl;
01324 for( PropertyBag::iterator it= bag.getProperties().begin(); it!=bag.getProperties().end(); ++it) {
01325 sresult <<setw(14)<<right<<(*it)->getType()<<" "<<coloron<<setw(14)<< (*it)->getName()<<coloroff;
01326 DataSourceBase::shared_ptr propds = (*it)->getDataSource();
01327 this->printResult( propds.get(), false );
01328 sresult <<" ("<<(*it)->getDescription()<<')' << nl;
01329 }
01330 } else {
01331 sresult <<prompt<<"(empty PropertyBag)";
01332 }
01333 }
01334 return;
01335 }
01336
01337 DataSourceBase::shared_ptr dsb(ds);
01338 dsb->evaluate();
01339 sresult << dsb;
01340 }
01341
01342 struct comcol
01343 {
01344 const char* command;
01345 comcol(const char* c) :command(c) {}
01346 std::ostream& operator()( std::ostream& os ) const {
01347 os<<"'"<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<"'";
01348 return os;
01349 }
01350 };
01351
01352 struct keycol
01353 {
01354 const char* command;
01355 keycol(const char* c) :command(c) {}
01356 std::ostream& operator()( std::ostream& os )const {
01357 os<<"<"<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<">";
01358 return os;
01359 }
01360 };
01361
01362 struct titlecol
01363 {
01364 const char* command;
01365 titlecol(const char* c) :command(c) {}
01366 std::ostream& operator()( std::ostream& os ) const {
01367 os<<endl<<"["<< TaskBrowser::coloron<< TaskBrowser::underline << command << TaskBrowser::coloroff<<"]";
01368 return os;
01369 }
01370 };
01371
01372 std::ostream& operator<<(std::ostream& os, comcol f ){
01373 return f(os);
01374 }
01375
01376 std::ostream& operator<<(std::ostream& os, keycol f ){
01377 return f(os);
01378 }
01379
01380 std::ostream& operator<<(std::ostream& os, titlecol f ){
01381 return f(os);
01382 }
01383
01384 void TaskBrowser::printHelp()
01385 {
01386 cout << coloroff;
01387 cout <<titlecol("Task Browsing")<<nl;
01388 cout << " To switch to another task, type "<<comcol("cd <path-to-taskname>")<<nl;
01389 cout << " and type "<<comcol("cd ..")<<" to go back to the previous task (History size is 20)."<<nl;
01390 cout << " Pressing "<<keycol("tab")<<" multiple times helps you to complete your command."<<nl;
01391 cout << " It is not mandatory to switch to a task to interact with it, you can type the"<<nl;
01392 cout << " peer-path to the task (dot-separated) and then type command or expression :"<<nl;
01393 cout << " PeerTask.OtherTask.FinalTask.countTo(3) [enter] "<<nl;
01394 cout << " Where 'countTo' is a method of 'FinalTask'."<<nl;
01395 cout << " The TaskBrowser starts by default 'In' the current component. In order to watch"<<nl;
01396 cout << " the TaskBrowser itself, type "<<comcol("leave")<<" You will notice that it"<<nl;
01397 cout << " has connected to the data ports of the visited component. Use "<<comcol("enter")<<" to enter"<<nl;
01398 cout << " the visited component again. The "<<comcol("cd")<<" command works transparantly in both"<<nl;
01399 cout << " modi."<<nl;
01400
01401 cout << " "<<titlecol("Task Context Info")<<nl;
01402 cout << " To see the contents of a task, type "<<comcol("ls")<<nl;
01403 cout << " For a detailed argument list (and helpful info) of the object's methods, "<<nl;
01404 cout <<" type the name of one of the listed task objects : " <<nl;
01405 cout <<" this [enter]" <<nl<<nl;
01406 cout <<" Command : bool factor( int number )" <<nl;
01407 cout <<" Factor a value into its primes." <<nl;
01408 cout <<" number : The number to factor in primes." <<nl;
01409 cout <<" Method : bool isRunning( )" <<nl;
01410 cout <<" Is this TaskContext started ?" <<nl;
01411 cout <<" Method : bool loadProgram( const& std::string Filename )" <<nl;
01412 cout <<" Load an Orocos Program Script from a file." <<nl;
01413 cout <<" Filename : An ops file." <<nl;
01414 cout <<" ..."<<nl;
01415
01416 cout <<titlecol("Expressions")<<nl;
01417 cout << " You can evaluate any script expression by merely typing it :"<<nl;
01418 cout << " 1+1 [enter]" <<nl;
01419 cout << " = 2" <<nl;
01420 cout << " or inspect the status of a program :"<<nl;
01421 cout << " programs.myProgram.isRunning [enter]" <<nl;
01422 cout << " = false" <<nl;
01423 cout << " and display the contents of complex data types (vector, array,...) :"<<nl;
01424 cout << " array(6)" <<nl;
01425 cout << " = {0, 0, 0, 0, 0, 0}" <<nl;
01426
01427 cout <<titlecol("Changing Attributes and Properties")<<nl;
01428 cout << " To change the value of a Task's attribute, type "<<comcol("varname = <newvalue>")<<nl;
01429 cout << " If you provided a correct assignment, the browser will inform you of the success"<<nl;
01430 cout <<" with '= true'." <<nl;
01431
01432 cout <<titlecol("Commands")<<nl;
01433 cout << " A Command is 'sent' to a task, which will process it in its own context (thread)."<<nl;
01434 cout << " A command consists of an object, followed by a dot ('.'), the command "<<nl;
01435 cout << " name, followed by the parameters. An example could be :"<<nl;
01436 cout << " otherTask.bar.orderBeers(\"Palm\", 5) [enter] "<<nl;
01437 cout << " The prompt will inform you about the status of the last command you entered. "<<nl;
01438 cout << " It is allowed to enter a new command while the previous is still busy. "<<nl;
01439
01440 cout <<titlecol("Methods")<<nl;
01441 cout << " Methods 'look' the same as commands, but they are evaluated"<<nl;
01442 cout << " immediately and print the result. An example could be :"<<nl;
01443 cout << " someTask.bar.getNumberOfBeers(\"Palm\") [enter] "<<nl;
01444 cout << " = 99" <<nl;
01445
01446 cout <<titlecol("Events")<<nl;
01447 cout << " Events behave as methods, they are emitted immediately."<<nl;
01448 cout << " An example emitting an event :"<<nl;
01449 cout << " someTask.notifyUserState(\"Drunk\") [enter] "<<nl;
01450 cout << " = (void)" <<nl;
01451
01452 cout <<titlecol("Program and StateMachine Scripts")<<nl;
01453 cout << " To load a program script from local disc, type "<<comcol(".loadProgram <filename>")<<nl;
01454 cout << " To load a state machine script from local disc, type "<<comcol(".loadStateMachine <filename>")<<nl;
01455 cout << " ( notice the starting dot '.' )"<<nl;
01456 cout << " Likewise, "<<comcol(".loadProgram <ProgramName>")<<" and "<<comcol(".unloadStateMachine <StateMachineName>")<<nl;
01457 cout << " are available (notice it is the program's name, not the filename)."<<nl;
01458 cout << " You can use "<<comcol("ls progname")<<nl;
01459 cout << " to see the programs commands, methods and variables. You can manipulate each one of these,."<<nl;
01460 cout << " as if the program is a Task itself (see all items above)."<<nl;
01461
01462 cout << " To print a program or state machine listing, use "<<comcol("list progname [linenumber]")<<nl;
01463 cout << " to list the contents of the current program lines being executed,"<<nl;
01464 cout << " or 10 lines before or after <linenumber>. When only "<<comcol("list [n]")<<nl;
01465 cout << " is typed, 20 lines of the last listed program are printed from line <n> on "<<nl;
01466 cout << " ( default : list next 20 lines after previous list )."<<nl;
01467
01468 cout << " To trace a program or state machine listing, use "<<comcol("trace [progname]")<<" this will"<<nl;
01469 cout << " cause the TaskBrowser to list the contents of a traced program,"<<nl;
01470 cout << " each time the line number of the traced program changes."<<nl;
01471 cout << " Disable tracing with "<<comcol("untrace [progname]")<<""<<nl;
01472 cout << " If no arguments are given to "<<comcol("trace")<<" and "<<comcol("untrace")<<", it applies to all programs."<<nl;
01473
01474 cout << " A status character shows which line is being executed."<<nl;
01475 cout << " For programs : 'E':Error, 'S':Stopped, 'R':Running, 'P':Paused"<<nl;
01476 cout << " For state machines : <the same as programs> + 'A':Active, 'I':Inactive"<<nl;
01477
01478 cout <<titlecol("Changing Colors")<<nl;
01479 cout << " You can inform the TaskBrowser of your background color by typing "<<comcol(".dark")<<nl;
01480 cout << " "<<comcol(".light")<<", or "<<comcol(".nocolors")<<" to increase readability."<<nl;
01481
01482 cout <<titlecol("Macro Recording / Command line history")<<nl;
01483 cout << " You can browse the commandline history by using the up-arrow key or press "<<comcol("Ctrl r")<<nl;
01484 cout << " and a search term. Hit enter to execute the current searched command."<<nl;
01485 cout << " Macros can be recorded using the "<<comcol(".record 'macro-name'")<<" command."<<nl;
01486 cout << " You can cancel the recording by typing "<<comcol(".cancel")<<" ."<<nl;
01487 cout << " You can save and load the macro by typing "<<comcol(".end")<<" . The macro becomes"<<nl;
01488 cout << " available as a command with name 'macro-name' in the current TaskContext." << nl;
01489 cout << " While you enter the macro, it is not executed, as you must use scripting syntax which"<<nl;
01490 cout << " may use loop or conditional statements, variables etc."<<nl;
01491
01492 cout <<titlecol("Connecting Ports")<<nl;
01493 cout << " You can instruct the TaskBrowser to connect to the ports of the current Peer by"<<nl;
01494 cout << " typing "<<comcol(".connect [port-name]")<<", which will temporarily create connections"<<nl;
01495 cout << " to all ports if [port-name] is omitted or to the specified port otherwise."<<nl;
01496 cout << " The TaskBrowser disconnects these ports when it visits another component, but the"<<nl;
01497 cout << " created connection objects remain in place (this is more or less a bug)!"<<nl;
01498 }
01499
01500 void TaskBrowser::printProgram(const std::string& progname, int cl , TaskContext* progpeer ) {
01501 string ps;
01502 char s;
01503 stringstream txtss;
01504 int ln;
01505 int start;
01506 int end;
01507 bool found(false);
01508
01509 if (progpeer == 0 )
01510 progpeer = context;
01511
01512
01513 if ( progpeer->scripting()->hasProgram( progname ) ) {
01514 s = getProgramStatusChar(progpeer, progname);
01515 txtss.str( progpeer->scripting()->getProgramText(progname) );
01516 ln = progpeer->scripting()->getProgramLine(progname);
01517 if ( cl < 0 ) cl = ln;
01518 start = cl < 10 ? 1 : cl - 10;
01519 end = cl + 10;
01520 this->listText( txtss, start, end, ln, s);
01521 found = true;
01522 }
01523
01524
01525 if ( progpeer->scripting()->hasStateMachine( progname ) ) {
01526 s = getStateMachineStatusChar(progpeer, progname);
01527 txtss.str( progpeer->scripting()->getStateMachineText(progname) );
01528 ln = progpeer->scripting()->getStateMachineLine(progname);
01529 if ( cl < 0 ) cl = ln;
01530 start = cl <= 10 ? 1 : cl - 10;
01531 end = cl + 10;
01532 this->listText( txtss, start, end, ln, s);
01533 found = true;
01534 }
01535 if ( !found ) {
01536 cerr << "Error : No such program or state machine found : "<<progname;
01537 cerr << " in "<< progpeer->getName() <<"."<<endl;
01538 return;
01539 }
01540 storedname = progname;
01541 }
01542
01543 void TaskBrowser::printProgram(int cl ) {
01544 string ps;
01545 char s;
01546 stringstream txtss;
01547 int ln;
01548 int start;
01549 int end;
01550 bool found(false);
01551 if ( context->scripting()->hasProgram( storedname ) ) {
01552 s = getProgramStatusChar(context, storedname);
01553 txtss.str( context->scripting()->getProgramText(storedname) );
01554 ln = context->scripting()->getProgramLine(storedname);
01555 if ( cl < 0 ) cl = storedline;
01556 if (storedline < 0 ) cl = ln -10;
01557 start = cl;
01558 end = cl + 20;
01559 this->listText( txtss, start, end, ln, s);
01560 found = true;
01561 }
01562 if ( context->scripting()->hasStateMachine(storedname) ) {
01563 s = getStateMachineStatusChar(context, storedname);
01564 txtss.str( context->scripting()->getStateMachineText(storedname) );
01565 ln = context->scripting()->getStateMachineLine(storedname);
01566 if ( cl < 0 ) cl = storedline;
01567 if (storedline < 0 ) cl = ln -10;
01568 start = cl;
01569 end = cl+20;
01570 this->listText( txtss, start, end, ln, s);
01571 found = true;
01572 }
01573 if ( !found )
01574 cerr << "Error : No such program or state machine found : "<<storedname<<endl;
01575 }
01576
01577 void TaskBrowser::listText(stringstream& txtss,int start, int end, int ln, char s) {
01578 int curln = 1;
01579 string line;
01580 while ( start > 1 && curln != start ) {
01581 getline( txtss, line, '\n' );
01582 if ( ! txtss )
01583 break;
01584 ++curln;
01585 }
01586 while ( end > start && curln != end ) {
01587 getline( txtss, line, '\n' );
01588 if ( ! txtss )
01589 break;
01590 if ( curln == ln ) {
01591 cout << s<<'>';
01592 }
01593 else
01594 cout << " ";
01595 cout<< setw(int(log(double(end)))) <<right << curln<< left;
01596 cout << ' ' << line <<endl;
01597 ++curln;
01598 }
01599 storedline = curln;
01600 // done !
01601 }
01602
01603 void TaskBrowser::printInfo(const std::string& peerp)
01604 {
01605 // this sets this->peer to the peer given
01606 peer = context;
01607 if ( this->findPeer( peerp+"." ) == 0 ) {
01608 cerr << "No such peer or object: " << peerp << endl;
01609 return;
01610 }
01611
01612 if ( !peer || !peer->ready()) {
01613 cout << nl << " Connection to peer "+peerp+" lost (peer->ready() == false)." <<endlog();
01614 return;
01615 }
01616
01617 if ( peer == taskobject )
01618 sresult <<nl<<" Listing TaskContext "<< green << peer->getName()<<coloroff<< " :"<<nl;
01619 else
01620 sresult <<nl<<" Listing TaskObject "<< green << taskobject->getName()<<coloroff<< " :"<<nl;
01621
01622 // Only print Properties for TaskContexts
01623 if ( peer == taskobject ) {
01624 sresult <<nl<<" Configuration Properties: ";
01625 PropertyBag* bag = peer->properties();
01626 if ( bag && bag->size() != 0 ) {
01627 // Print Properties:
01628 for( PropertyBag::iterator it = bag->begin(); it != bag->end(); ++it) {
01629 DataSourceBase::shared_ptr pds = (*it)->getDataSource();
01630 sresult << nl << setw(11)<< right << (*it)->getType()<< " "
01631 << coloron <<setw(14)<<left<< (*it)->getName() << coloroff;
01632 this->printResult( pds.get(), false ); // do not recurse
01633 sresult<<" ("<< (*it)->getDescription() <<')';
01634 }
01635 } else {
01636 sresult << "(none)";
01637 }
01638 sresult <<nl;
01639 }
01640
01641 // Print "this" interface (without detail) and then list objects...
01642 sresult <<nl<< " Execution Interface:";
01643
01644 sresult <<nl<< " Attributes : ";
01645 std::vector<std::string> objlist = taskobject->attributes()->names();
01646 if ( !objlist.empty() ) {
01647 sresult << nl;
01648 // Print Attributes:
01649 for( std::vector<std::string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
01650 DataSourceBase::shared_ptr pds = taskobject->attributes()->getValue(*it)->getDataSource();
01651 sresult << setw(11)<< right << pds->getType()<< " "
01652 << coloron <<setw( 14 )<<left<< *it << coloroff;
01653 this->printResult( pds.get(), false ); // do not recurse
01654 sresult <<nl;
01655 }
01656 } else {
01657 sresult << coloron << "(none)";
01658 }
01659
01660 sresult <<coloroff<<nl<< " Methods : "<<coloron;
01661 objlist = taskobject->methods()->getNames();
01662 if ( !objlist.empty() ) {
01663 copy(objlist.begin(), objlist.end(), std::ostream_iterator<std::string>(sresult, " "));
01664 } else {
01665 sresult << "(none)";
01666 }
01667 sresult <<coloroff<<nl<< " Commands : "<<coloron;
01668 objlist = taskobject->commands()->getNames();
01669 if ( !objlist.empty() ) {
01670 copy(objlist.begin(), objlist.end(), std::ostream_iterator<std::string>(sresult, " "));
01671 } else {
01672 sresult << "(none)";
01673 }
01674 sresult <<coloroff<<nl<< " Events : "<<coloron;
01675 objlist = taskobject->events()->getEvents();
01676 if ( !objlist.empty() ) {
01677 copy(objlist.begin(), objlist.end(), std::ostream_iterator<std::string>(sresult, " "));
01678 } else {
01679 sresult << "(none)";
01680 }
01681 sresult << coloroff << nl;
01682
01683 if ( peer == taskobject ) {
01684 sresult <<nl<< " Data Flow Ports: ";
01685 objlist = peer->ports()->getPortNames();
01686 if ( !objlist.empty() ) {
01687 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
01688 PortInterface* port = peer->ports()->getPort(*it);
01689 PortInterface::PortType pt = port->getPortType();
01690 // Port type R/W
01691 sresult << nl << " " << (pt == PortInterface::ReadPort ?
01692 " R" : pt == PortInterface::WritePort ? " W" : "RW");
01693 // Port data type + name
01694 if ( !port->ready() || !port->connection() )
01695 sresult << "(U) " << setw(11)<<right<< port->getTypeInfo()->getTypeName();
01696 else
01697 sresult << "(C) " << setw(11)<<right<< port->getTypeInfo()->getTypeName();
01698 sresult << " "
01699 << coloron <<setw( 14 )<<left<< *it << coloroff;
01700 if ( port->ready() )
01701 sresult << " = " <<port->connection()->getDataSource();
01702 else {
01703 ConnectionInterface::shared_ptr c = port->createConnection();
01704 if ( c )
01705 sresult << " = " << c->getDataSource();
01706 }
01707 // Port description
01708 // if ( peer->getObject(*it) )
01709 // sresult << " ( "<< taskobject->getObject(*it)->getDescription() << " ) ";
01710 }
01711 } else {
01712 sresult << "(none)";
01713 }
01714 sresult << coloroff << nl;
01715 }
01716
01717 objlist = taskobject->getObjectList();
01718 sresult <<nl<< " Task Objects: "<<nl;
01719 if ( !objlist.empty() ) {
01720 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
01721 sresult <<coloron<< " " << setw(14) << *it <<coloroff<< " ( "<< taskobject->getObject(*it)->getDescription() << " ) "<<nl;
01722 } else {
01723 sresult <<coloron<< "(none)" <<coloroff <<nl;
01724 }
01725
01726 // TaskContext specific:
01727 if ( peer == taskobject ) {
01728
01729 objlist = peer->scripting()->getPrograms();
01730 if ( !objlist.empty() ) {
01731 sresult << " Programs : "<<coloron;
01732 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
01733 sresult << *it << "["<<getProgramStatusChar(peer,*it)<<"] ";
01734 sresult << coloroff << nl;
01735 }
01736
01737 objlist = peer->scripting()->getStateMachines();
01738 if ( !objlist.empty() ) {
01739 sresult << " StateMachines: "<<coloron;
01740 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it)
01741 sresult << *it << "["<<getStateMachineStatusChar(peer,*it)<<"] ";
01742 sresult << coloroff << nl;
01743 }
01744
01745 // if we are in the TB, display the peers of our connected task:
01746 if ( context == tb )
01747 sresult <<nl<< " "<<peer->getName()<<" Peers : "<<coloron;
01748 else
01749 sresult << nl <<" Peers : "<<coloron;
01750
01751 objlist = peer->getPeerList();
01752 if ( !objlist.empty() )
01753 for(vector<string>::iterator it = objlist.begin(); it != objlist.end(); ++it) {
01754 assert( peer->getPeer(*it) );
01755 sresult << *it << "["<<getTaskStatusChar(peer->getPeer(*it))<<"] ";
01756 }
01757 else
01758 sresult << "(none)";
01759 }
01760 sresult <<coloroff<<nl;
01761 cout << sresult.str();
01762 sresult.str("");
01763 }
01764
01765 void TaskBrowser::printCommand( const std::string m, OperationInterface* ops )
01766 {
01767 using boost::lambda::_1;
01768 std::vector<ArgumentDescription> args;
01769 args = ops->commands()->getArgumentList( m );
01770 sresult << " Command : bool " << coloron << m << coloroff<< "( ";
01771 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it) {
01772 sresult << it->type <<" ";
01773 sresult << coloron << it->name << coloroff;
01774 if ( it+1 != args.end() )
01775 sresult << ", ";
01776 else
01777 sresult << " ";
01778 }
01779 sresult << ")"<<nl;
01780 sresult << " " << ops->commands()->getDescription( m )<<nl;
01781 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it)
01782 sresult <<" "<< it->name <<" : " << it->description << nl;
01783 }
01784
01785 void TaskBrowser::printMethod( const std::string m, OperationInterface* ops )
01786 {
01787 std::vector<ArgumentDescription> args;
01788 args = ops->methods()->getArgumentList( m );
01789 sresult << " Method : "<< ops->methods()->getResultType(m)<<" " << coloron << m << coloroff<< "( ";
01790 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it) {
01791 sresult << it->type <<" ";
01792 sresult << coloron << it->name << coloroff;
01793 if ( it+1 != args.end() )
01794 sresult << ", ";
01795 else
01796 sresult << " ";
01797 }
01798 sresult << ")"<<nl;
01799 sresult << " " << ops->methods()->getDescription( m )<<nl;
01800 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it)
01801 sresult <<" "<< it->name <<" : " << it->description << nl;
01802 }
01803
01804 void TaskBrowser::printEvent( const std::string m, EventService* ops )
01805 {
01806 std::vector<ArgumentDescription> args;
01807 args = ops->getArgumentList( m );
01808 sresult << " Event : "<< ops->getResultType(m)<<" " << coloron << m << coloroff<< "( ";
01809 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it) {
01810 sresult << it->type <<" ";
01811 sresult << coloron << it->name << coloroff;
01812 if ( it+1 != args.end() )
01813 sresult << ", ";
01814 else
01815 sresult << " ";
01816 }
01817 sresult << ")"<<nl;
01818 sresult << " " << ops->getDescription( m )<<nl;
01819 for (std::vector<ArgumentDescription>::iterator it = args.begin(); it != args.end(); ++it)
01820 sresult <<" "<< it->name <<" : " << it->description << nl;
01821 }
01822
01823 }