Changeset 2671 in Sophya for trunk/SophyaLib/SysTools
- Timestamp:
- Apr 18, 2005, 5:34:31 PM (20 years ago)
- Location:
- trunk/SophyaLib/SysTools
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/SophyaLib/SysTools/commander.cc
r2615 r2671 12 12 #include "rpneval.h" 13 13 #include "srandgen.h" 14 #include "zthread.h" 14 15 15 16 … … 331 332 } 332 333 334 335 // ------------------------------------------------------------ 336 // Classe CommandExeThr 337 // ------------------------------------------------------------ 338 /*! 339 \internal 340 \class SOPHYA::CommandExeThr 341 \ingroup SysTools 342 Class for internal use by class Commander for command execution in separate threads. 343 */ 344 class CommandExeThr : public ZThread { 345 public: 346 CommandExeThr(uint_8 id, CmdExecutor * cmdex, string& keyw, 347 vector<string>& args, string& toks); 348 virtual void run(); 349 inline uint_8 Id() { return _id; } 350 inline bool IfDone() { return _fgdone; } 351 inline string& Tokens() { return _toks; } 352 inline string& Keyword() { return _keyw; } 353 protected: 354 uint_8 _id; 355 CmdExecutor * _cmdex; 356 string _keyw, _toks; 357 vector<string> _args; 358 bool _fgdone; 359 }; 360 361 /* --Methode-- */ 362 CommandExeThr::CommandExeThr(uint_8 id, CmdExecutor * cmdex, string& keyw, 363 vector<string>& args, string& toks) 364 { 365 _id = id; 366 _cmdex = cmdex; 367 _keyw = keyw; 368 if (args.size() > 1) 369 for(size_t k=0; k<args.size()-1; k++) _args.push_back(args[k]); 370 _toks = toks; 371 for(size_t k=_toks.size()-1; k>0; k--) 372 if (_toks[k] == '&') { _toks[k] = ' '; break; } 373 _fgdone = false; 374 } 375 376 /* --Methode-- */ 377 void CommandExeThr::run() 378 { 379 int rc = _cmdex->Execute(_keyw, _args, _toks); 380 _fgdone = true; 381 setRC(rc); 382 } 383 333 384 // ------------------------------------------------------------ 334 385 // Classe Commander … … 345 396 to applications. 346 397 347 Although the in sterpreter has many limitations compared to398 Although the interpreter has many limitations compared to 348 399 c-shell, or Tcl , it provides some interesting possibilities: 349 400 … … 400 451 curtestresult = true; 401 452 453 // Pour la numerotation et l'identification des threads 454 ThrId = 0; 455 402 456 // Numero de help-groupe courant - Le premier groupe ajoute aura un gid = 1 403 457 // gid = 0 n'existe pas : c'est le groupe de toutes les commandes … … 411 465 string usage; 412 466 usage = ">>> (Commander) Interpreter's keywords : \n"; 413 usage += " > set varname string # To set a variable, $varname \n";467 usage += " > set varname string # To set a variable, $varname \n"; 414 468 usage += " > unset varname # clear variable definition \n"; 415 469 usage += " > rpneval varname RPNExpression # Reverse Polish Notation evaluation \n"; … … 436 490 usage += " > listscripts # List of all known scripts \n"; 437 491 usage += " > clearcript # Clear a script definition \n"; 492 usage += " > thrlist # List of command execution threads (& as the last character) \n"; 493 usage += " > clearthrlist # Removes finished threads from the list \n"; 494 usage += " > cancelthr Id # Cancel a given thread (ThrId=id) \n"; 495 usage += " > waitthr # Waits until all active threads have finished (join()) \n"; 438 496 usage += " > exec filename # Execute commands from file \n"; 439 497 usage += " > help <command_name> # <command_name> usage info \n"; … … 475 533 RegisterCommand(kw, usage, NULL, grp); 476 534 535 kw = "CExpEvaluator"; 536 usage = "> Evaluation of C-like expression (used in V = C-like-Expression) \n"; 537 usage += " >>> Arithmetic operators, parenthesis ( + - * / ) \n"; 538 usage += " >>> Functions : sqrt fabs floor hypot \n"; 539 usage += " ... exp log log10 pow ; sinh cosh tanh \n"; 540 usage += " ... sin cos tan asin acos atan atan2 \n"; 541 usage += " ... rand01() randpm1() gaurand() \n"; 542 usage += " >>> Constants : Pi = M_PI E = M_E \n"; 543 usage += " Example: x = 5.*(2.+sin(0.3*Pi))"; 544 RegisterCommand(kw, usage, NULL, grp); 545 477 546 kw = "shell execute"; 478 547 usage = "> shell command_string # Execute shell command\n"; … … 656 725 /* --Methode-- */ 657 726 /*! 658 \brief Method which has to be invoked to interpret a gi evcommand line or string.727 \brief Method which has to be invoked to interpret a given command line or string. 659 728 */ 660 729 int Commander::Interpret(string& s) … … 662 731 int rc = 0; 663 732 ScriptList::iterator sit; 733 734 // Si le flag d'arret d'execution a ete positionne on returne avec le code 735 // de BREAKEXECUTION 736 if (fgexebrk) { 737 cout << " ===> Commander::Interpret() - STOP Execution (CMD_BREAKEXE_RC)" << endl; 738 fgexebrk = false; return CMD_BREAKEXE_RC; 739 } 664 740 665 741 // On saute de commandes vides … … 769 845 // On verifie si nous sommes dans un bloc (for , foreach) 770 846 if (CmdBlks.top() != NULL) { // On est dans un bloc 771 if ( (kw == "for") || (kw == "foreach") ) felevel++;847 if ( (kw == "for") || (kw == "foreach") || (kw == "forinfile") ) felevel++; 772 848 else if (kw == "end") felevel--; 773 849 if (felevel == 0) { // Il faut executer le bloc … … 777 853 if (!curb->CheckBloc()) { 778 854 cerr << "Commander::Interpret()/syntax error - unbalenced if ... endif" 779 << " within for/foreach bloc ! " << endl;855 << " within for/foreach/forinfile bloc ! " << endl; 780 856 delete curb; 781 857 _xstatus = 93; … … 803 879 } 804 880 else if (kw == "end") { 805 cerr << "Commander::Interpret()/syntax error - end outside for/foreach bloc \n"881 cerr << "Commander::Interpret()/syntax error - end outside for/foreach/forinfile bloc \n" 806 882 << "line: " << s << endl; 807 883 _xstatus = 94; … … 1001 1077 1002 1078 return(0); 1079 } 1080 1081 void Commander::StopExecution() 1082 { 1083 fgexebrk = true; 1003 1084 } 1004 1085 … … 1762 1843 } 1763 1844 } 1845 //--------------------------------------------- 1846 //--- Commandes de gestion des threads ------ 1847 //--------------------------------------------- 1848 else if (kw == "thrlist") { 1849 ListThreads(); 1850 return(0); 1851 } 1852 else if (kw == "cancelthr") { 1853 if (tokens.size() < 1) { cout << "Commander::Interpret() Usage: cancelthr thrid" << endl; return(0); } 1854 uint_8 id = atol(tokens[0].c_str()); 1855 CancelThr(id); 1856 return (0); 1857 } 1858 else if (kw == "waitthr") { 1859 WaitThreads(); 1860 return (0); 1861 } 1862 else if (kw == "cleanthrlist") { 1863 CleanThrList(); 1864 return (0); 1865 } 1866 1764 1867 else if (kw == "traceon") { cout << "Commander::Interpret() -> Trace ON mode " << endl; trace = true; } 1765 1868 else if (kw == "traceoff") { cout << "Commander::Interpret() -> Trace OFF mode " << endl; trace = false; } … … 1820 1923 if (it == cmdexmap.end()) cout << "No such command : " << keyw << " ! " << endl; 1821 1924 else { 1822 if ((*it).second.cex) rc = (*it).second.cex->Execute(keyw, args, toks); 1925 if ((*it).second.cex) { 1926 // Doit-on l'executer sous forme de thread separe ? 1927 if ((args.size()>0) && (args[args.size()-1] == "&")) { 1928 ThrId++; 1929 CommandExeThr * thr = new CommandExeThr(ThrId, (*it).second.cex, keyw, args, toks); 1930 CmdThrExeList.push_back(thr); 1931 cout << " Commander::ExecuteCommand() : Thread execution of command " << keyw << endl; 1932 thr->start(); 1933 rc = 0; 1934 } 1935 else rc = (*it).second.cex->Execute(keyw, args, toks); 1936 } 1823 1937 else cout << "Dont know how to execute " << keyw << " ? " << endl; 1824 1938 } … … 1877 1991 1878 1992 return(0); 1993 } 1994 1995 /* --Methode-- */ 1996 void Commander::ListThreads() 1997 { 1998 cout << "---- Commander::ListThreads() List of separate execution threads NThread=" 1999 << CmdThrExeList.size() << " ----- " << endl; 2000 for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 2001 tit != CmdThrExeList.end(); tit++) { 2002 cout << "Id=" << (*tit)->Id(); 2003 if ( (*tit)->IfDone() ) cout << " Finished , Rc= " << (*tit)->getRC(); 2004 else cout << " Executing"; 2005 cout << " (Cmd= " << (*tit)->Keyword() << " " << (*tit)->Tokens() << " )" << endl; 2006 } 2007 } 2008 /* --Methode-- */ 2009 void Commander::CancelThr(uint_8 id) 2010 { 2011 for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 2012 tit != CmdThrExeList.end(); tit++) { 2013 if ((*tit)->Id() == id) { 2014 (*tit)->cancel(); 2015 cout << "Commander::CancelThr() Thread Id= " << id << " cancelled" << endl; 2016 return; 2017 } 2018 } 2019 cout << "Commander::CancelThr()/Error: No thread with Id= " << id << endl; 2020 } 2021 2022 /* --Methode-- */ 2023 void Commander::CleanThrList() 2024 { 2025 cout << "---- Commander::CleanThrList() Cleaning thrlist ----- \n"; 2026 list<CommandExeThr *> thrcopie; 2027 for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 2028 tit != CmdThrExeList.end(); tit++) { 2029 if ( (*tit)->IfDone() ) { 2030 cout << " Thread Id= " << (*tit)->Id() << " rc= " << (*tit)->getRC() << " Cleaned" << endl; 2031 delete (*tit); 2032 } 2033 else thrcopie.push_back((*tit)); 2034 } 2035 CmdThrExeList = thrcopie; 2036 cout << " ... " << CmdThrExeList.size() << " threads still active " << endl; 2037 } 2038 2039 /* --Methode-- */ 2040 void Commander::WaitThreads() 2041 { 2042 cout << "---- Commander::WaitThreads() Wait/Join command execution threads - NThread=" 2043 << CmdThrExeList.size() << " ----- " << endl; 2044 for(list<CommandExeThr *>::iterator tit = CmdThrExeList.begin(); 2045 tit != CmdThrExeList.end(); tit++) { 2046 try { 2047 if (! (*tit)->IfDone()) (*tit)->join(); 2048 } 2049 catch (std::exception & e) { 2050 cout << " Commander::WaitThreads()/Exception msg= " << e.what() << endl; 2051 } 2052 cout << " Joined thread Id= " << (*tit)->Id() << " rc= " << (*tit)->getRC() << endl; 2053 delete (*tit); 2054 } 2055 CmdThrExeList.erase(CmdThrExeList.begin(), CmdThrExeList.end()); 1879 2056 } 1880 2057 -
trunk/SophyaLib/SysTools/commander.h
r2598 r2671 59 59 class CommanderBloc; // Bloc de type foreach / for de l'interpreteur Commander 60 60 class CommanderScript; // Script de commandes defini ds l'interpreteur Commander 61 62 //! A simple command interpreter with c-shell like syntax with dynamic load capability. 61 class CommandExeThr; // Thread d'execution de commande 62 63 //! A simple command interpreter with c-shell like syntax and dynamic load capability. 63 64 64 65 class Commander : public CmdInterpreter { … … 85 86 86 87 virtual int Interpret(string& line); 88 virtual void StopExecution(); 87 89 88 90 virtual int ExecuteCommand(string& keyw, vector<string>& args, string& toks); … … 162 164 void PopStack(bool psta=true); 163 165 166 // Gestion des threads d'execution de commandes 167 void ListThreads(); 168 void CancelThr(uint_8 thrid); 169 void CleanThrList(); 170 void WaitThreads(); 171 172 // ------ Attributs et variables ------ 164 173 CmdInterpreter* curcmdi; 165 174 … … 180 189 CmdExmap helpexmap; // Pour les helps sans commande 181 190 191 // Pour garder la liste des threads d'execution de commande 192 list<CommandExeThr *> CmdThrExeList; 193 uint_8 ThrId; 194 182 195 // Pour garder la liste des modules 183 196 typedef map<string, PDynLinkMgr* , less<string> > Modmap; -
trunk/SophyaLib/SysTools/zthread.h
r2598 r2671 39 39 inline void setRC(int rc) { _rc = rc; } 40 40 //! Return the value of the return code for the thread object 41 inline int getRC( int rc) { return(_rc);41 inline int getRC() { return(_rc); 42 42 } 43 43 inline void setAction(ZThreadAction act, void * usp=NULL)
Note:
See TracChangeset
for help on using the changeset viewer.