Changeset 2463 in Sophya for trunk/SophyaPI/PIext


Ignore:
Timestamp:
Nov 27, 2003, 12:01:56 AM (22 years ago)
Author:
ansari
Message:

Modification du code de PIACmd : La classe PIACmd herite maintenant de la classe Commander (de SysTools) - Reza 26/11/2003

Location:
trunk/SophyaPI/PIext
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/SophyaPI/PIext/piacmd.cc

    r2419 r2463  
    132132}
    133133
    134 // ------------------------------------------------------------
    135 //         Bloc de commandes (Foreach, ...)   
    136 //               Classe  PIACmdBloc   
    137 // ------------------------------------------------------------
    138 
    139 class PIACmdBloc {
    140 public:
    141   enum BType { BT_None, BT_ForeachList, BT_ForeachInt, BT_ForeachFloat };
    142 
    143   PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args);
    144   ~PIACmdBloc();
    145   inline PIACmdBloc*   Parent() { return(parent); }
    146   inline bool   CheckOK() { return blkok; }
    147   inline void   AddLine(string& line) 
    148     { lines.push_back(line); bloclineid.push_back(lines.size()); }
    149   void          AddLine(string& line, string& kw); 
    150   inline void   AddBloc(PIACmdBloc* blk) 
    151     { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
    152   PIACmdBloc*   Execute();
    153   inline int&   TestLevel()  { return testlevel; }
    154   inline int&   LoopLevel()  { return looplevel; }
    155   inline bool   CheckBloc()
    156     { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)); }
    157  
    158 protected:
    159   PIACmd* piacmd;
    160   PIACmdBloc* parent;
    161   bool blkok;        // true -> block OK
    162   BType typ;         // foreach , integer loop, float loop, test
    163   string varname;
    164   vector<string> strlist;
    165   vector<string> lines;
    166   vector<PIACmdBloc *> blocs;
    167   vector<int> bloclineid;
    168   int i1,i2,di;
    169   float f1,f2,df;
    170   int testlevel;   // niveau d'imbrication des if
    171   int looplevel;   // niveau d'imbrication des for/foreach
    172   bool scrdef;     // true -> commande defscript ds for/foreach
    173 };
    174 
    175 /* --Methode-- */
    176 PIACmdBloc::PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args)
    177 {
    178 piacmd = piac;
    179 parent = par;
    180 blkok = false;
    181 typ = BT_None;
    182 i1 = 0;  i2 = -1;  di = 1;
    183 f1 = 0.; f2 = -1.; df = 1.;
    184 testlevel = looplevel = 0;
    185 scrdef = false;
    186 
    187 if ((args.size() < 2) ||  !isalpha((int)args[0][0]) )  return;
    188 if ((kw != "foreach") && (kw != "for"))  return;
    189 varname = args[0];  // $CHECK$ Variable name should be checked
    190 //if (isalpha((int)args[1][0]) ) {  This is a foreach bloc with string list
    191 if (kw == "foreach" ) { // This is a foreach bloc with string list
    192   if ((args[1] != "(") || (args[args.size()-1] != ")") ) return;
    193   for(int kk=2; kk<args.size()-1; kk++) strlist.push_back(args[kk]);
    194   typ = BT_ForeachList;
    195   blkok = true;
    196   }
    197 else { // This is an integer or float loop
    198   size_t l = args[1].length();
    199   size_t p = args[1].find(':');
    200   size_t pp = args[1].find('.');
    201   bool fl = (pp < l) ? true : false;  // Float loop or integer loop
    202   if (p >= l) return;  // Syntaxe error
    203   string a1 = args[1].substr(0, p);
    204   string aa = args[1].substr(p+1);
    205   p = aa.find(':');
    206   string a2, a3;
    207   bool hasa3 = false;
    208   if (p < aa.length() ) {
    209     a2 = aa.substr(0,p);
    210     a3 = aa.substr(p+1);
    211     hasa3 = true;
    212     }
    213   else  a2 = aa;
    214   if (fl) {
    215     typ = BT_ForeachFloat;
    216     blkok = true;
    217     f1 = atof(a1.c_str());
    218     f2 = atof(a2.c_str());
    219     if (hasa3)  df = atof(a3.c_str());
    220     else df = 1.;
    221     }
    222   else {
    223     typ = BT_ForeachInt;
    224     blkok = true;
    225     i1 = atoi(a1.c_str());
    226     i2 = atoi(a2.c_str());
    227     if (hasa3)  di = atoi(a3.c_str());
    228     else di = 1;
    229     }
    230   }
    231 }
    232 
    233 /* --Methode-- */
    234 PIACmdBloc::~PIACmdBloc()
    235 {
    236 for(int k=0; k<blocs.size(); k++) delete blocs[k];
    237 }
    238 
    239 /* --Methode-- */
    240 void PIACmdBloc::AddLine(string& line, string& kw)
    241 {
    242   AddLine(line);
    243   if (kw == "if")  testlevel++;
    244   else if (kw == "endif")  testlevel--;
    245   else if ((kw == "for") || (kw == "foreach"))  looplevel++;
    246   else if (kw == "end")  looplevel--;
    247   else if (kw == "defscript")  scrdef = true;
    248 }
    249 
    250 /* --Methode-- */
    251 PIACmdBloc* PIACmdBloc::Execute()
    252 {
    253 // cout << " DBG * PIACmdBloc::Execute() " << typ << " - " << bloclineid.size() <<
    254 //      " I1,I2=" << i1 << " , " << i2 << " , " << di << endl;
    255 string cmd;
    256 int k=0;
    257 int kj=0;
    258 int kk=0;
    259 char buff[32];
    260 int rcc = 0;
    261 
    262 if (typ == BT_ForeachList)   // foreach string loop
    263   for(k=0; k<strlist.size(); k++) {
    264     cmd = "set " + varname + " '" + strlist[k] + "'";
    265     piacmd->Interpret(cmd);
    266     for(kj=0; kj<bloclineid.size(); kj++) {
    267       kk = bloclineid[kj];
    268       if (kk > 0)  {
    269         rcc = piacmd->Interpret(lines[kk-1]);
    270         if (rcc == 77766)  break;
    271       }
    272       else blocs[-kk-1]->Execute();
    273     }
    274     if (rcc == 77766)  break;
    275   }
    276 else if (typ == BT_ForeachInt)  // Integer loop
    277   for(int i=i1; i<i2; i+=di) {
    278     k++;
    279     if (++k > 9999) {
    280       cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
    281       break;
    282       }
    283     sprintf(buff, " %d", i);
    284     cmd = "set " + varname + buff;
    285     piacmd->Interpret(cmd);
    286     for(kj=0; kj<bloclineid.size(); kj++) {
    287       kk = bloclineid[kj];
    288       if (kk > 0)  {
    289         rcc = piacmd->Interpret(lines[kk-1]);
    290         if (rcc == 77766)  break;
    291       }
    292       else blocs[-kk-1]->Execute();
    293     }
    294     if (rcc == 77766)  break;
    295   }
    296 else if (typ == BT_ForeachFloat)  // float loop
    297   for(float f=f1; f<f2; f+=df) {
    298     k++;
    299     if (++k > 9999) {
    300       cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
    301       break;
    302       }
    303     sprintf(buff, " %g", f);
    304     cmd = "set " + varname + buff;
    305     piacmd->Interpret(cmd);
    306     for(kj=0; kj<bloclineid.size(); kj++) {
    307       kk = bloclineid[kj];
    308       if (kk > 0)  {
    309         rcc = piacmd->Interpret(lines[kk-1]);
    310         if (rcc == 77766)  break;
    311       }
    312       else blocs[-kk-1]->Execute();
    313     }
    314     if (rcc == 77766)  break;
    315   }
    316 
    317 return(parent);
    318 }
    319 
    320 // ---------------------------------------------------------------
    321 //                  Classe PIACmdScript
    322 //   Definition et execution d'un script de PIACmd
    323 //   script : Une liste de commande PIACmd - Lors de l'execution,
    324 //   les variables-argument $# $0 $1 sont definies.
    325 // ---------------------------------------------------------------
    326 
    327 class PIACmdScript {
    328 public:
    329   PIACmdScript(PIACmd* piac, string const& name, string const& comm);
    330   virtual ~PIACmdScript();
    331 
    332   void          AddLine(string& line, string& kw); 
    333   virtual int   Execute(vector<string>& args);
    334 
    335   inline string& Name() { return mName; }
    336   inline string& Comment() { return mComm; }
    337   inline int&   TestLevel()  { return testlevel; }
    338   inline int&   LoopLevel()  { return looplevel; }
    339   inline bool   CheckScript()
    340     { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)&&fgok); }
    341 
    342 protected:
    343   PIACmd* piacmd;
    344   string mName;
    345   string mComm;
    346   vector<string> lines;
    347   int testlevel;   // niveau d'imbrication des if
    348   int looplevel;   // niveau d'imbrication des for/foreach
    349   bool scrdef;     // true -> commande defscript ds for/foreach
    350   bool fgok;       // Script name OK
    351  
    352 };
    353 
    354 /* --Methode-- */
    355 PIACmdScript::PIACmdScript(PIACmd* piac, string const& name,
    356                            string const& comm)
    357 {
    358 piacmd = piac;
    359 testlevel = looplevel = 0;
    360 scrdef = false;
    361 mName = name;
    362 if (!isalpha(name[0]))  fgok = false;
    363 else fgok = true;
    364 mComm = comm;
    365 }
    366 
    367 /* --Methode-- */
    368 PIACmdScript::~PIACmdScript()
    369 {
    370 }
    371 
    372 /* --Methode-- */
    373 void PIACmdScript::AddLine(string& line, string& kw)
    374 {
    375   if (kw == "if")  testlevel++;
    376   else if (kw == "endif")  testlevel--;
    377   else if ((kw == "for") || (kw == "foreach"))  looplevel++;
    378   else if (kw == "end")  looplevel--;
    379   else if (kw == "defscript")  scrdef = true;
    380   lines.push_back(line);
    381 }
    382 
    383 /* --Methode-- */
    384 int PIACmdScript::Execute(vector<string>& args)
    385 {
    386   if (!CheckScript()) return(-1);
    387   cout << " PIACmdScript::Execute() - Executing script " << Name() << endl;
    388   for(int k=0; k<lines.size(); k++) {
    389     if (piacmd->Interpret(lines[k]) == 77777) break;
    390   }
    391   return(0);
    392 }
    393134
    394135// ------------------------------------------------------------
     
    396137// ------------------------------------------------------------
    397138
    398 static PIACmd* curpiacmd = NULL;
     139// static PIACmd* curpiacmd = NULL;
    399140/* --Methode-- */
    400141PIACmd::PIACmd(NamedObjMgr* omg, PIStdImgApp* app)
     142  : Commander()
    401143{
    402144mObjMgr = omg;
    403145mImgApp = app;
    404 system("cp history.pic hisold.pic");
    405 hist.open("history.pic");
    406 histon = true;
    407 trace = false;   timing = false;
    408 gltimer = NULL;
    409 felevel = 0;
    410 
    411 mulinecmd = "";
    412 mulinefg = false;
    413 spromptmul = "Cmd> ";
    414 if (mImgApp) mImgApp->GetConsole()->SetPrompt(spromptmul);
    415 curscript = NULL;
    416 
    417 CmdBlks.push(NULL);
    418 list<char> xtx;
    419 TestsStack.push(xtx);
    420 curtestresult = true;
    421 
    422 cmdhgrp["All"] = 0;
    423 cmdgrpid = 1;
    424 cmdhgrp["PIACmd"] = 1;
     146
     147//MOVE if (mImgApp) mImgApp->GetConsole()->SetPrompt(spromptmul);
     148//?? cmdhgrp["All"] = 0;
     149//?? cmdgrpid = 1;
     150//?? cmdhgrp["PIACmd"] = 1;
    425151helpwin = new PIAHelpWind(app, this);
    426152helpwin->AddHelpGroup("All", 0);
    427 helpwin->AddHelpGroup("PIACmd", 1);
    428 
    429 string kw = "Interpreter";
    430 string usage;
    431 usage = ">>> (piacmd) Interpreter's keywords : \n";
    432 usage += "  > set varname string   # To set a variable, $varname \n";
    433 usage += "  > get newvarname varname # To set a newvariable, equal to $varname \n";
    434 usage += "  > setol varname patt     # Fills varname with object list \n";
    435 usage += "  > unset varname          # clear variable definition \n";
    436 usage += "  > rpneval varname RPNExpression # Reverse Polish Notation evaluation \n";
    437 usage += "  > varname = 'string string ...' # To set a variable, $varname  \n";
    438 usage += "  > varname = RPNExpression # RPN evaluation / result -> varname \n";
    439 usage += "  > echo string            # output string \n";
    440 usage += "  > echo2file filename string # Append the string to the specified file \n";
    441 usage += "  > alias name string      # define a command alias \n";
    442 usage += "  > readstdin varname      # reads a line from stdin into $varname \n";
    443 usage += "  > foreach varname ( string-list ) # Loop \n";
    444 usage += "  > for varname i1:i2[:di]      # Integer loop  \n";
    445 usage += "  > for varname f1:f2[:df]      # Float loop  \n";
    446 usage += "  > end                         # end loops \n";
    447 usage += "  > if ( test ) then  # Conditional test : a == != < > <= >= b \n";
    448 usage += "  > else          # Conditional  \n";
    449 usage += "  > endif         # End of conditional if bloc \n";
    450 usage += "  > break         # Delete (clears) all test and loop blocs \n";
    451 usage += "  > return        # Stops command execution from a file \n";
    452 usage += "  > defscript endscript # Command script definition \n";
    453 usage += "  > listvars      # List of variable names and values \n";
    454 usage += "  > listalias     # List of alias names and values \n";
    455 usage += "  > listcommands  # List of all known commands \n";
    456 usage += "  > listscripts   # List of all known scripts \n";
    457 usage += "  > clearcript    # Clear a script definition \n";
    458 usage += "  > exec filename # Execute commands from file \n";
    459 usage += "  > help <command_name>  # <command_name> usage info \n";
    460 usage += "  > helpwindow           # Displays help window \n";
    461 usage += "  > timingon  timingoff traceon  traceoff \n";
     153// helpwin->AddHelpGroup("PIACmd", 1);
     154
     155string kw = "exitpiapp";
    462156string grp = "PIACmd";
    463 RegisterHelp(kw, usage, grp);
    464 
    465 kw = "RPNEvaluator";
    466 usage = " Reverse Polish Notation (HP calculator like) expression evaluation \n";
    467 usage += "  >> Stack: \n";
    468 usage += "     ... (4) (3) z=(2) y=(1) x=(0)=Stack.Top() \n";
    469 usage += "  >> Examples:  \n";
    470 usage += "  - sin(PI/6): pi 6 / sin \n";
    471 usage += "  - 1*2*...*5: 1 2 3 4 5 product \n";
    472 usage += "  - x=x+y: x = $x $y * \n";
    473 usage += "  >>> Stack operations : \n";
    474 usage += "      print x<>y pop push (duplicate x) \n";
    475 usage += "  >>> Constants (Cst pushed to stack): \n";
    476 usage += "      pi e \n";
    477 usage += "  >>> Arithmetic operators (x,y) --> x@y \n";
    478 usage += "      + - * / % ( (int)y % (int)x )\n";
    479 usage += "  >>> F(X): x --> F(x) \n";
    480 usage += "      chs sqrt sq log log10 exp  \n";
    481 usage += "      fabs  floor ceil \n";
    482 usage += "      cos sin tan acos asin atan deg2rad rad2deg \n";
    483 usage += "  >>> F(X,Y): (x,y) --> F(x,y) \n";
    484 usage += "      pow atan2 \n";
    485 usage += "  >>> F(): random number generators \n";
    486 usage += "      rand (flat 0..1) norand (normal/gaussian) \n";
    487 usage += "  >>> Stack sum/product/mean/sigma/sigma^2 \n";
    488 usage += "      sum product mean sigma sigma2 sigmean (y->sigma x->mean) \n";
    489 RegisterHelp(kw, usage, grp);
    490 
    491 kw = "autoiniranf";
    492 usage  = "> Automatic random number generator initialisation\n";
    493 usage += "   by Auto_Ini_Ranf(int lp) \n";
    494 usage += "   Usage: autoiniranf";
     157string usage = "To end the piapp session ";
    495158RegisterCommand(kw, usage, NULL, grp);
    496 
    497 kw = "shell execute";
    498 usage  = "> shell  command_string  # Execute  shell command\n";
    499 usage += "> cshell command_string  # Execute cshell command\n";
    500 usage += "---Examples:\n";
    501 usage += "  > shell ls\n";
    502 usage += "  > cshell echo '$LD_LIBRARY_PATH'; map2cl -h; ls\n";
    503 usage += "  > shell myfile.csh [arg1] [arg2] [...]\n";
    504 usage += "    (where the first line of \"myfile.csh\" is \"#!/bin/csh\")\n";
    505 RegisterCommand(kw, usage, NULL, grp);
    506 
    507 kw = "exitpiapp";
    508 usage = "To end the piapp session (Interpreter's command)";
     159kw = "helpwindow";
     160usage = "To display the Help window ";
    509161RegisterCommand(kw, usage, NULL, grp);
    510162
     
    523175cxxexwin  = new  CxxExecWind(app, cxxe);
    524176
    525 AddInterpreter(this);
    526 curcmdi = this;
    527177}
    528178
     
    530180PIACmd::~PIACmd()
    531181{
    532 hist.close();
    533 if (gltimer) { delete gltimer;  gltimer = NULL; }
    534 Modmap::iterator it;
    535 for(it = modmap.begin(); it != modmap.end(); it++) {
    536   string name = (*it).first + "_end";
    537   DlModuleInitEndFunction fend = (*it).second->GetFunction(name);
    538   if (fend) fend();
    539   delete (*it).second;
    540   }
    541 
    542 for(ScriptList::iterator sit = mScripts.begin();
    543     sit != mScripts.end(); sit++) delete (*sit).second;
    544182 
    545183delete helpwin;
    546184delete cxxexwin;
    547185delete cxxoptwin;
    548 if (curpiacmd == this)  curpiacmd = NULL;
    549186delete basexec;
    550187delete fitexec;
     
    553190}
    554191
    555 /* --Methode-- */
    556 PIACmd* PIACmd::GetInterpreter()
    557 {
    558 return(curpiacmd);
    559 }
    560 
    561 /* --Methode-- */
    562 string PIACmd::Name()
    563 {
    564 return("piacmd");
    565 }
    566 
    567 /* --Methode-- */
    568 void PIACmd::RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, string grp)
    569 {
    570 if (!ce) {
    571   RegisterHelp(keyw, usage, grp);
    572   return;
    573   }
    574 int gid = CheckHelpGrp(grp);
    575 cmdex cme;
    576 cme.group = gid;
    577 cme.us = usage;
    578 cme.cex = ce;
    579 cmdexmap[keyw] = cme;
    580 }
    581 
    582 /* --Methode-- */
    583 void PIACmd::RegisterHelp(string& keyw, string& usage, string& grp)
    584 {
    585 int gid = CheckHelpGrp(grp);
    586 cmdex cme;
    587 cme.group = gid;
    588 cme.us = usage;
    589 cme.cex = NULL;
    590 helpexmap[keyw] = cme;
    591 }
    592192
    593193/* --Methode-- */
     
    619219  }
    620220}
    621 
    622 /* --Methode-- */
    623 void PIACmd::LoadModule(string& fnameso, string& name)
    624 {
    625 PDynLinkMgr * dynlink = new PDynLinkMgr(fnameso, false);
    626 if (dynlink == NULL) {
    627   cerr << "PIACmd/LoadModule_Error: Pb opening SO " << fnameso << endl;
    628   return;
    629   }
    630 string fname = name + "_init";
    631 DlModuleInitEndFunction finit = dynlink->GetFunction(fname);
    632 if (!finit) {
    633   cerr << "PIACmd/LoadModule_Error: Pb linking " << fname << endl;
    634   return;
    635   }
    636 cout << "PIACmd/LoadModule_Info: Initialisation module" << name
    637      << "  " << fname << "() ..." << endl;
    638 finit();
    639 modmap[name] = dynlink;
    640 return;
    641 }
    642 
    643 /* --Methode-- */
    644 void PIACmd::AddInterpreter(CmdInterpreter * cl)
    645 {
    646 if (!cl) return;
    647 interpmap[cl->Name()] = cl;}
    648 
    649 /* --Methode-- */
    650 void PIACmd::SelInterpreter(string& name)
    651 {
    652 InterpMap::iterator it = interpmap.find(name);
    653 if (it == interpmap.end())   return;
    654 curcmdi = (*it).second;
    655 }
    656 
    657221
    658222
     
    675239}
    676240
    677 /* --Methode-- */
    678 int PIACmd::Interpret(string& s)
     241
     242/* --Methode-- */
     243int PIACmd::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
    679244{
    680245int rc = 0;
    681246NamedObjMgr omg;
    682 ScriptList::iterator sit;
    683 
    684 // On saute de commandes vides
    685 size_t l;
    686 l = s.length();
    687 if (!mulinefg && (l < 1))  return(0);
    688 
    689 // On enregistre les commandes
    690 if (histon) hist << s << endl;   
    691 
    692 if (s[0] == '#') return(0); // si c'est un commentaire
    693 
    694 // Logique de gestion des lignes suite
    695 // un \ en derniere position indique la presence d'une ligne suite
    696 size_t lnb = s.find_last_not_of(' ');
    697 if (s[lnb] == '\\' ) { // Lignes suite ...
    698   mulinecmd += s.substr(0,lnb);
    699   if (!mulinefg) {
    700     spromptmul = mImgApp->GetConsole()->GetPrompt();
    701     mImgApp->GetConsole()->SetPrompt("...? ");
    702     mulinefg = true;
    703   }
    704   return(0);
    705 }
    706 
    707 if (mulinefg) {  // Il y avait des lignes suite
    708   s = mulinecmd + s;
    709   mulinecmd = "";
    710   mulinefg = false;
    711   mImgApp->GetConsole()->SetPrompt(spromptmul);
    712 }
    713 
    714 // Removing leading blanks
    715 size_t p,q;
    716 
    717 p=s.find_first_not_of(" \t");
    718 if (p < l) s = s.substr(p);
    719 
    720 // >>>> Substitution d'alias (1er mot)
    721 CmdStrList::iterator it;
    722 p = 0;
    723 q = s.find_first_of(" \t");
    724 l = s.length();
    725 string w1 =  (q < l) ? s.substr(p,q-p) : s.substr(p);
    726 it = mAliases.find(w1);
    727 if (it != mAliases.end())  {
    728   s =  (q < l) ? ((*it).second + s.substr(q)) : (*it).second ;
    729   l = s.length();
    730   p=s.find_first_not_of(" \t");
    731   if (p < l) s = s.substr(p);
    732   p = 0;
    733   q = s.find_first_of(" ");
    734   }
    735 
    736 // >>>> Separating keyword
    737 string toks,kw;
    738 if (q < l)
    739   {  kw = s.substr(p,q-p);  toks = s.substr(q, l-q); }
    740 else { kw = s.substr(p,l-p);  toks = ""; }
    741 
    742 // les mot-cle end else endif doivent etre le seul mot de la ligne
    743 if ( (kw == "end") || (kw == "else") || (kw == "endif") || (kw == "endscript") ) {
    744   size_t ltk = toks.length();
    745   if (toks.find_first_not_of(" \t") < ltk) {
    746     cerr << "PIACmd::Interpret()/syntax error near end else endif endscript \n"
    747          << "line: " << s << endl;
    748     return(1);
    749   }
    750 }
    751 
    752 // On verifie si on est en train de definir un script
    753 if (curscript) {
    754   if (kw == "endscript") {
    755     if (curscript->CheckScript()) {
    756       sit = mScripts.find(curscript->Name());
    757       if (sit != mScripts.end()) {
    758         cout << "PIACmd::Interpret() replacing script "
    759              << curscript->Name() << endl;
    760         PIACmdScript* scr = mScripts[curscript->Name()];
    761         mScripts.erase(sit);
    762         delete scr;
    763       }
    764       cout << "PIACmd::Interpret() Script " << curscript->Name()
    765            << " defined successfully" << endl;
    766       mScripts[curscript->Name()] = curscript;
    767       mImgApp->GetConsole()->SetPrompt("Cmd> ");
    768       curscript = NULL;
    769       return(0);
    770     }
    771     else {
    772       cout << "PIACmd::Interpret() Error in Script " << curscript->Name()
    773            << " definition " << endl;
    774       mImgApp->GetConsole()->SetPrompt("Cmd> ");
    775       curscript = NULL;
    776       return(2);
    777     }
    778   }
    779   else curscript->AddLine(s, kw);
    780   return(0);
    781 }
    782 // On verifie si nous sommes dans un bloc (for , foreach)
    783 if (CmdBlks.top() != NULL)  { // On est dans un bloc
    784   if ( (kw == "for") || (kw == "foreach")) felevel++;
    785   else if (kw == "end") felevel--;
    786   if (felevel == 0) { // Il faut executer le bloc
    787     PIACmdBloc* curb = CmdBlks.top();
    788     CmdBlks.top() = curb->Parent();
    789     mImgApp->GetConsole()->SetPrompt("Cmd> ");
    790     if (!curb->CheckBloc()) {
    791       cerr << "PIACmd::Interpret()/syntax error - unbalenced if ... endif"
    792            << " within for/foreach bloc ! " << endl;
    793       delete curb;
    794       return(2); 
    795     }
    796        //       cout << " *DBG* Executing bloc " << endl;
    797     bool ohv = histon;
    798     histon = false;
    799     if (curtestresult) {
    800       // We push also PIACmdBloc and testresult on the stack
    801       CmdBlks.push(NULL);
    802       list<char> xtx;
    803       TestsStack.push(xtx);
    804       curb->Execute();
    805       // And PIACmdBloc and TestResult from the corresponding stacks
    806       PopStack(false);
    807     }
    808     delete curb;
    809     histon = ohv;
    810   }
    811   else CmdBlks.top()->AddLine(s, kw);
    812   return(0);
    813 }
    814 else if (kw == "end") {
    815   cerr << "PIACmd::Interpret()/syntax error - end outside for/foreach bloc \n"
    816        << "line: " << s << endl;
    817   return(1); 
    818 }
    819 
    820 // Sommes-nous dans un bloc de test if then else
    821 if (TestsStack.top().size() > 0) {  // Nous sommes ds un bloc if
    822   if (kw == "else") {
    823     if ((*tresit) & 2) {
    824       cerr << "PIACmd::Interpret()/syntax error - multiple else in if bloc \n"
    825            << "line: " << s << endl;
    826       return(1);
    827     }
    828     else {
    829       const char * npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
    830       if ((*tresit)&1)  curtestresult = false;
    831       mImgApp->GetConsole()->SetPrompt(npr);
    832       (*tresit) |= 2;
    833       return(0);
    834     }
    835   }
    836   else if (kw == "endif") {
    837     list<char>::iterator dbit = tresit;
    838     tresit--;
    839     TestsStack.top().erase(dbit);
    840     const char * npr = "Cmd> ";
    841     if (TestsStack.top().size() > 1) {
    842       curtestresult = true;
    843       list<char>::iterator it;
    844       for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
    845         // Si on n'est pas ds le else et le if est faux
    846         if ( !((*it)&2) && !((*it)&1) ) curtestresult = false;
    847         // Si on est ds else et le if etait vrai !
    848         if ( ((*it)&2) && ((*it)&1) )  curtestresult = false;
    849         if (!curtestresult)  break;
    850       }
    851      
    852       if (!((*tresit)&2))
    853         npr = ((*tresit)&1) ? "if-T> " : "if-F> ";
    854       else
    855         npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
    856     }
    857     else curtestresult = true;
    858     mImgApp->GetConsole()->SetPrompt(npr);
    859     return(0);
    860   }
    861 }
    862 else if ((kw == "else") || (kw == "endif")) {
    863   cerr << "PIACmd::Interpret()/syntax error - else,endif outside if bloc \n"
    864        << "line: " << s << endl;
    865   return(1); 
    866 }
    867 
    868 bool fgcont = true;
    869 if (TestsStack.top().size() > 0) { // Resultat de if ou else
    870   list<char>::iterator it;
    871   for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
    872     // Si on n'est pas ds le else et le if est faux
    873     if ( !((*it)&2) && !((*it)&1) )  fgcont = false;
    874     // Si on est ds else et le if etait vrai !
    875     if ( ((*it)&2) && ((*it)&1) )  fgcont = false;
    876     if (!fgcont)  break;
    877   }
    878 }
    879 
    880 if ((!fgcont) && (kw != "if"))  return(0);
    881 
    882 
    883 // Les mots cles break et return peuvent de sortir de boucles/scripts/execfile
    884 if (kw == "break") return(77766);
    885 else if (kw == "return")  return(77777);
    886 
    887 // Nous ne sommes donc pas dans un bloc ....  Substitution de variables
    888 string s2;
    889 int rcs ;
    890 // Execution de code C++
    891 
    892 if (kw == "@@") {
    893   CxxExecutor * cxxe = dynamic_cast<CxxExecutor *>(cxxexec);
    894   if (cxxe == NULL) {
    895     cerr << "PIACmd::Interpret() - BUG !!! Not a CxxExecutor " << endl;
    896     return(99);
    897   }
    898   return(cxxe->ExecuteCXX(s.substr(2)));
    899 }
    900 
    901 
    902 rcs = SubstituteVars(s, s2);
    903 if (rcs) {
    904   cerr << "PIACmd::Interpret()/syntax error in SubstituteVars() \n"
    905        << "line: " << s << endl;
    906   return(rcs);
    907 }
    908 // >>>> Separating keyword and tokens
    909 vector<string> tokens;
    910 /* decoupage en mots */
    911 LineToWords(s2, kw, tokens, toks, true);
    912 
    913 // Si c'est un for/foreach, on cree un nouveau bloc
    914 if ((kw == "foreach") || (kw == "for")) {
    915   //     cout << " *DBG* We got a foreach... " << endl;
    916   PIACmdBloc* bloc = new PIACmdBloc(this, CmdBlks.top(), kw, tokens);
    917   if (!bloc->CheckOK()) {
    918     cerr << "PIACmd::Interpret() for/foreach syntax Error ! " << endl;
    919     delete bloc;
    920     return(1);
    921     }
    922   felevel++;
    923   if (CmdBlks.top())  CmdBlks.top()->AddBloc(bloc);
    924   else  mImgApp->GetConsole()->SetPrompt("for...> ");
    925   CmdBlks.top() = bloc;
    926   //  cout << " *DBG* New Bloc created ... " << endl;
    927   return(0);
    928   }
    929 else if (kw == "if") {  // Un test if
    930   bool restst = true;
    931   int rct = EvaluateTest(tokens, s, restst);
    932   if (rct) {
    933     cerr << "PIACmd::Interpret() if syntax Error ! " << "line: " << s << endl;
    934     return(1);
    935   }
    936   char res_tst = (restst) ? 1 : 0;
    937   TestsStack.top().push_back(res_tst);
    938   if (TestsStack.top().size() == 1) tresit = TestsStack.top().begin();
    939   else tresit++;
    940   const char * npr = (restst) ? "if-T> " : "if-F> ";
    941   mImgApp->GetConsole()->SetPrompt(npr);
    942 }
    943 else if ((tokens.size() > 0) && (tokens[0] == "=")) { 
    944   // x = RPNExpression (Evaluation d'expression RPN)
    945   tokens[0] = kw;
    946   int rcev = EvalRPNExpr(tokens, s);
    947   if (rcev) {
    948     cerr << "PIACmd::Interpret() evaluation (RPN) syntax Error ! " << "line: " << s << endl;
    949     return(1);
    950   }
    951   return(0);
    952 }
    953 else if (kw == "defscript") {  // definition de script
    954   if (tokens.size() > 0) {
    955     if (tokens.size() < 2)  tokens.push_back("");
    956     curscript = new PIACmdScript(this, tokens[0], tokens[1]);
    957     mImgApp->GetConsole()->SetPrompt("Script...> ");
    958     return(0);
    959   }
    960   else {
    961     cerr << "PIACmd::Interpret() No script name in defscript" << "line: " << s << endl;
    962     return(1);
    963   }
    964 }
    965 else {
    966   //  Si c'est le nom d'un script
    967   sit = mScripts.find(kw);
    968   if (sit != mScripts.end()) {
    969     bool ohv = histon;
    970     histon = false;
    971     tokens.insert(tokens.begin(), kw);
    972     PushStack(tokens);
    973     (*sit).second->Execute(tokens);
    974     PopStack(true);
    975     histon = ohv;
    976   }
    977   //  Execution de commandes
    978   else rc = ExecuteCommandLine(kw, tokens, toks);
    979   return(rc);
    980 
    981 // cout << "PIACmd::Do() DBG  KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
    982 //  for(int ii=0; ii<tokens.size(); ii++)
    983 //  cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
    984 
    985 return(0);
    986 }
    987 
    988 
    989 /* --Methode-- */
    990 int PIACmd::LineToWords(string& line, string& kw, vector<string>& tokens,
    991                         string& toks, bool uq)
    992 {
    993 if (line.length() < 1)  return(0);
    994 int nw = 1;
    995 size_t p = line.find_first_not_of(" ");
    996 line = line.substr(p);
    997 p = 0;
    998 size_t q = line.find_first_of(" ");
    999 size_t l = line.length();
    1000 
    1001 if (q < l)
    1002   {  kw = line.substr(p,q-p);  toks = line.substr(q, l-q); }
    1003 else { kw = line.substr(p,l-p);  toks = ""; }
    1004 
    1005 q = 0;
    1006 while (q < l)  {
    1007   p = toks.find_first_not_of(" \t",q+1); // au debut d'un token
    1008   if (p>=l) break;
    1009   if ( uq && ((toks[p] == '\'') || (toks[p] == '"')) ) {
    1010     q = toks.find(toks[p],p+1);
    1011     if (q>=l)  {
    1012       cerr << "PIACmd::LineToWords/Syntax Error - Unbalenced quotes " << toks[p] << '.' << endl;
    1013       return(-1);
    1014     }
    1015     p++;
    1016   }
    1017   else {
    1018     q = toks.find_first_of(" \t",p); // la fin du token;
    1019   }
    1020   string token = toks.substr(p,q-p);
    1021   tokens.push_back(token);  nw++;
    1022   }
    1023 
    1024 return(nw);
    1025 }
    1026 
    1027 /* --Methode-- */
    1028 int PIACmd::SubstituteVars(string & s, string & s2)
    1029 //  Variable substitution 
    1030 {
    1031 NamedObjMgr& omg = *mObjMgr;
    1032 
    1033 int iarr = -1;  // index d'element de tableau
    1034 size_t p,q,q2,q3,l;
    1035 
    1036 s2="";
    1037 p = 0;
    1038 l = s.length();
    1039 string vn, vv;
    1040 while (p < l) {
    1041   iarr = -1;
    1042   q = s.find('$',p);
    1043   if (q > l) break;
    1044   q2 = s.find('\'',p);
    1045   if ((q2 < l) && (q2 < q)) {  // On saute la chaine delimitee par ' '
    1046     q2 = s.find('\'',q2+1);
    1047     if (q2 >= l) {
    1048       cerr << " Syntax error - Unbalenced  quotes !!! " << endl;
    1049       return(1);
    1050       }
    1051     s2 += s.substr(p, q2-p+1);
    1052     p = q2+1;  continue; 
    1053   }
    1054   //  cout << "DBG: " << s2 << " p= " << p << " q= " << q << " L= " << l << endl;
    1055   if ((q>0) && (s[q-1] == '\\')) {   // Escape character \$
    1056      s2 += (s.substr(p,q-1-p) + '$') ; p = q+1;
    1057      continue;
    1058      }
    1059   if (q >= l-1) {
    1060       cerr << " Syntax error - line ending with $ !!! " << endl;
    1061       return(2);
    1062       }
    1063   vn = "";
    1064   if ( s[q+1] == '{' ) {  // Variable in the form ${name}
    1065     q2 = s.find('}',q+1);
    1066     if (q2 >= l) {
    1067       cerr << " Syntax error -  Unbalenced  brace {} !!! " << endl;
    1068       return(3);
    1069       }
    1070     vn = s.substr(q+2,q2-q-2);
    1071     q2++;
    1072   }
    1073   else if ( s[q+1] == '(' ) {  // Variable in the form $(name)
    1074     q2 = s.find(')',q+1);
    1075     if (q2 >= l) {
    1076       cerr << " Syntax error -  Unbalenced  parenthesis () !!! " << endl;
    1077       return(3);
    1078       }
    1079     vn = s.substr(q+2,q2-q-2);
    1080     q2++;
    1081   }
    1082   else if ( s[q+1] == '[' ) {  // Variable in the form $[varname]  -> This is $$varname
    1083     q2 = s.find(']',q+1);
    1084     if (q2 >= l) {
    1085       cerr << " Syntax error - Unbalenced  brace [] !!! " << endl;
    1086       return(4);
    1087       }
    1088     vn = s.substr(q+2,q2-q-2);
    1089     if (!GetVar(vn, vv)) return(5);
    1090     vn = vv;
    1091     q2++;
    1092     }
    1093   else {
    1094     q2 = s.find_first_of(" .:+-*/,[](){}&|!$\"'",q+1);
    1095     if (q2 > l) q2 = l;
    1096     q3 = q2;
    1097     vn = s.substr(q+1, q2-q-1);
    1098     // Si variable de type $varname[index] : element de tableau
    1099     if ((q2 < l) && (s[q2] == '[') ) {
    1100       q3 = s.find_first_of("]",q2+1);
    1101       string sia = s.substr(q2+1, q3-q2-1);
    1102       if (sia.length() < 1) {
    1103         cerr << " Syntax error - in $varname[index] : $" 
    1104              << vn << "[" << sia <<"]" << endl;
    1105         return(4);
    1106       }
    1107       if (isalpha(sia[0])) {
    1108         string sia2;
    1109         if (!GetVar(sia, sia2) || (sia2.length() < 1)) {
    1110           cerr << " Syntax error - in $varname[index] : $" 
    1111                << vn << "[" << sia <<"]" << endl;
    1112         return(4);       
    1113         }
    1114         sia = sia2;
    1115       }
    1116       int rcdia = ctoi(sia.c_str(), &iarr);
    1117       if (rcdia < 0) {
    1118         cerr << " Syntax error - in $varname[iarr] : $"
    1119              << vn << "[" << sia <<"]" << endl;
    1120         return(4);
    1121       }
    1122     }
    1123   }
    1124   if (!GetVar(vn, vv)) return(5);
    1125   if (iarr < 0) {
    1126     s2 += (s.substr(p, q-p) + vv);
    1127     p = q2;
    1128   }
    1129   else {
    1130     vector<string> vs;
    1131     FillVStringFrString(vv, vs);
    1132     if (iarr >= vs.size()) {
    1133       cerr << " Substitution error - word index out of range in "
    1134            << "$varname[iarr] : $" << vn << "[" << iarr <<"]" << endl;
    1135       return(4);
    1136     }
    1137     else s2 += (s.substr(p, q-p) + vs[iarr]);
    1138     p = q3+1;
    1139   }
    1140 }
    1141 if (p < l) s2 += s.substr(p);
    1142 
    1143 p = s2.find_first_not_of(" \t");
    1144 if (p < l) s2 = s2.substr(p);
    1145 
    1146 return(0);
    1147 }
    1148 
    1149 /* --Methode-- */
    1150 bool PIACmd::GetVar(string & vn, string & vv)
    1151 {
    1152 NamedObjMgr& omg = *mObjMgr;
    1153 if (vn.length() < 1) {
    1154   cerr << " PIACmd::SubstituteVar/Error: length(varname=" << vn << ")<1 !" << endl;
    1155   vv = "";    return(false);
    1156 }
    1157 // Variable de type $# $0 $1 ... (argument de .pic ou de script)
    1158 int ka = 0;
    1159 if (vn == "#") {
    1160   if (ArgsStack.empty()) {
    1161     cerr << " PIACmd::SubstituteVar/Error: ArgsStack empty ! "
    1162          << " ($" << vn << ")" << endl;
    1163     vv = "";  return(false);
    1164   }
    1165   char buff[32];
    1166   long an = ArgsStack.top().size();
    1167   sprintf(buff,"%ld", an);
    1168   vv = buff;  return(true);
    1169 }
    1170 else if (ctoi(vn.c_str(), &ka) > 0) {  // $0 $1 $2 ...
    1171   if (ArgsStack.empty()) {
    1172     cerr << " PIACmd::SubstituteVar/Error: ArgsStack empty ! "
    1173          << " ($" << vn << ")" << endl;
    1174     vv = ""; return(false);
    1175   }
    1176   if ( (ka < 0) || (ka >= ArgsStack.top().size()) ) {
    1177     cerr << " PIACmd::SubstituteVar/Error: Undefined variable ! "
    1178          << " ($" << vn << ")" << endl;
    1179     vv = ""; return(false);
    1180   }
    1181   vv = ArgsStack.top()[ka];  return(true);
    1182 }
    1183 else if (vn[0] == '#') {  // Variable de type $#vname --> size(vname)
    1184   vn = vn.substr(1);
    1185   if (!omg.HasVar(vn) ) {
    1186     cerr << " PIACmd::SubstituteVarError: Undefined variable "
    1187          << vn << " ! " << endl;
    1188     vv = "";  return(false);
    1189   }
    1190   vn = omg.GetVar(vn);
    1191   vector<string> vs;
    1192   FillVStringFrString(vn, vs);
    1193   char buff[32];
    1194   sprintf(buff,"%d", (int)vs.size());
    1195   vv = buff; return(true);
    1196   }
    1197 else {  // variable ordinaire geree par NamedObjMgr
    1198   if ( (!omg.HasVar(vn)) )  {
    1199     cerr << " PIACmd::SubstituteVarError: Undefined variable "
    1200          << vn << " ! " << endl;
    1201     vv = "";  return(false);
    1202   }
    1203   vv = omg.GetVar(vn);  return(true);
    1204 }
    1205 
    1206 return(false);
    1207 }
    1208 
    1209 /* --Methode-- */
    1210 int PIACmd::EvaluateTest(vector<string> & args, string & line, bool & res)
    1211 {
    1212   res = true;
    1213   if ((args.size() != 6) || (args[5] != "then") ||
    1214       (args[0] != "(") || (args[4] != ")") ) return(1);
    1215   if (args[2] == "==") res = (args[1] == args[3]);
    1216   else if (args[2] == "!=") res = (args[1] != args[3]);
    1217   else if (args[2] == "<")
    1218     res = (atof(args[1].c_str()) < atof(args[3].c_str()));
    1219   else if (args[2] == ">")
    1220     res = (atof(args[1].c_str()) > atof(args[3].c_str()));
    1221   else if (args[2] == "<=")
    1222     res = (atof(args[1].c_str()) <= atof(args[3].c_str()));
    1223   else if (args[2] == ">=")
    1224     res = (atof(args[1].c_str()) >= atof(args[3].c_str()));
    1225   else return(2);
    1226   return(0);
    1227 }
    1228 
    1229 /* Operations sur le stack RPN */
    1230 inline bool Check_myRPNStack_(stack<double>& s, double& x, string& line)
    1231 {
    1232   if (s.empty()) {
    1233     cerr << "PIACmd::EvalRPNExpr: syntax error / empty RPN stack " << line << endl;
    1234     return true;
    1235   }
    1236   else x = s.top();
    1237   return false;
    1238 }
    1239 inline bool Check_myRPNStack_(stack<double>& s, double& x, double& y, string& line)
    1240 {
    1241   if (s.size() < 2) {
    1242     cerr << "PIACmd::EvalRPNExpr: syntax error / RPN stack size < 2  " << line << endl;
    1243     return true;
    1244   } 
    1245  else {
    1246    x = s.top(); s.pop(); y = s.top();
    1247  }
    1248   return false;
    1249 }
    1250 
    1251 inline void Print_myRPNStack_(stack<double> s)
    1252 {
    1253   if (s.empty())
    1254     cout << "PIACmd::EvalRPNExpr/PrintStack: Empty stack " << endl;
    1255   else {
    1256     int k = 0;
    1257     cout << "PIACmd::EvalRPNExpr/PrintStack: Size()= " << s.size() << endl;
    1258     while( !s.empty() ) {
    1259       cout << "    " << k << ":  " << s.top() << "  ";
    1260       if (k == 0)  cout << " (x) " << endl;
    1261       else if (k == 1) cout << " (y) " << endl;
    1262       else if (k == 2) cout << " (z) " << endl;
    1263       else cout << endl;
    1264       s.pop(); k++;
    1265     }
    1266   }
    1267  
    1268 }
    1269 
    1270 int Sum_RPNStack_(stack<double>& s, double& sx, double& sx2, string& line)
    1271 {
    1272   sx = sx2 = 0.;
    1273   int nn = 0;
    1274   double x = 0.;
    1275   while( !s.empty() ) {
    1276     x = s.top(); s.pop();
    1277     sx += x; sx2 += x*x;
    1278     nn++;
    1279   }
    1280   return(nn); 
    1281 }
    1282 
    1283 int Product_RPNStack_(stack<double>& s, double& px, string& line)
    1284 {
    1285   px = 1.;
    1286   int nn = 0;
    1287   double x = 0.;
    1288   while( !s.empty() ) {
    1289     x = s.top(); s.pop();
    1290     px *= x;  nn++;
    1291   }
    1292   return(nn); 
    1293 }
    1294  
    1295 /* --Methode-- */
    1296 int PIACmd::EvalRPNExpr(vector<string> & args, string & line)
    1297 {
    1298   NamedObjMgr& omg = *mObjMgr;
    1299  
    1300   if (args.size() < 2) {
    1301     cerr << "PIACmd::EvalRPNExpr: syntax error / missing arguments " << line << endl;
    1302     return(1);
    1303   }
    1304   else if (args.size() == 2) {
    1305     omg.SetVar(args[0], args[1]);
    1306     return(0);
    1307   }
    1308 
    1309   double x,y;
    1310   x = y = 0.;
    1311   stack<double> rpnstack;  // Stack des operations en RPN
    1312   for(int k=1; k<args.size(); k++) {
    1313     // Les 4 operations de base + - * /
    1314     if (args[k] == "+") {
    1315       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1316       rpnstack.top() = y+x;
    1317     }
    1318     else if (args[k] == "-") {
    1319       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1320       rpnstack.top() = y-x;
    1321     }
    1322     else if (args[k] == "*") {
    1323       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1324       rpnstack.top() = y*x;
    1325     }
    1326     else if (args[k] == "/") {
    1327       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1328       rpnstack.top() = y/x;
    1329     }
    1330     else if (args[k] == "%") {
    1331       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1332       rpnstack.top() = (int)y % (int)x;
    1333     }
    1334     // Les constantes : e , pi
    1335     else if (args[k] == "e") {
    1336       rpnstack.push(M_E);
    1337     }
    1338     else if (args[k] == "pi") {
    1339       rpnstack.push(M_PI);
    1340     }
    1341     // Les fonctions usuelles a 1 argument f(x)
    1342     else if (args[k] == "cos") {
    1343       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1344       rpnstack.top() = cos(x);
    1345     }
    1346     else if (args[k] == "sin") {
    1347       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1348       rpnstack.top() = sin(x);
    1349     }
    1350     else if (args[k] == "tan") {
    1351       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1352       rpnstack.top() = tan(x);
    1353     }
    1354     else if (args[k] == "acos") {
    1355       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1356       rpnstack.top() = acos(x);
    1357     }
    1358     else if (args[k] == "asin") {
    1359       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1360       rpnstack.top() = asin(x);
    1361     }
    1362     else if (args[k] == "atan") {
    1363       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1364       rpnstack.top() = atan(x);
    1365     }
    1366     else if (args[k] == "chs") {
    1367       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1368       rpnstack.top() = -x;
    1369     }
    1370     else if (args[k] == "sqrt") {
    1371       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1372       rpnstack.top() = sqrt(x);
    1373     }
    1374     else if (args[k] == "sq") {  // x^2
    1375       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1376       rpnstack.top() = x*x;
    1377     }
    1378     else if (args[k] == "log") {
    1379       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1380       rpnstack.top() = log(x);
    1381     }
    1382     else if (args[k] == "log10") {
    1383       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1384       rpnstack.top() = log10(x);
    1385     }
    1386     else if (args[k] == "exp") {
    1387       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1388       rpnstack.top() = exp(x);
    1389     }
    1390     else if (args[k] == "fabs") {
    1391       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1392       rpnstack.top() = fabs(x);
    1393     }
    1394     else if (args[k] == "floor") {
    1395       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1396       rpnstack.top() = floor(x);
    1397     }
    1398     else if (args[k] == "ceil") {
    1399       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1400       rpnstack.top() = ceil(x);
    1401     }
    1402     // trunc et nint vire - ca ne compile pas sous linux - Reza 01/2003
    1403     else if (args[k] == "deg2rad") {
    1404       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1405       rpnstack.top() = x*M_PI/180.;
    1406     }
    1407     else if (args[k] == "rad2deg") {
    1408       if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1409       rpnstack.top() = x*180./M_PI;
    1410     }
    1411     // Les fonctions usuelles a 2 argument f(x,y)
    1412     else if (args[k] == "pow") {
    1413       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1414       rpnstack.top() = pow(y,x);
    1415     }
    1416     else if (args[k] == "atan2") {
    1417       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1418       rpnstack.top() = atan2(x,y);
    1419     }
    1420     // generateur aleatoire
    1421     else if (args[k] == "rand") {
    1422       double rnd = drand01();
    1423       rpnstack.push(rnd);
    1424     }
    1425     else if (args[k] == "norand") {
    1426       double rnd = GauRnd(0., 1.);
    1427       rpnstack.push(rnd);
    1428     }
    1429     // Fonction a N arguments  - Somme, produit, etc ...
    1430     else if ((args[k] == "sum") || (args[k] == "mean") || (args[k] == "sigmean") ||
    1431              (args[k] == "sigma") || (args[k] == "sigma2") ) {
    1432       double sx, sx2;
    1433       int nn = Sum_RPNStack_(rpnstack, sx, sx2, line);
    1434       if (args[k] == "sum") rpnstack.push(sx);
    1435       else {
    1436         if (nn == 0) {
    1437           cerr << "PIACmd::EvalRPNExpr: mean/sigma error- RPN stack empty: "
    1438                << line << endl;
    1439           return(1);
    1440         }
    1441         double fnn = nn;
    1442         if ((args[k] == "sigma") || (args[k] == "sigmean"))
    1443           rpnstack.push(sqrt(sx2/fnn-(x*x/(fnn*fnn))));
    1444         else if ((args[k] == "mean") || (args[k] == "sigmean"))  rpnstack.push(sx/fnn);
    1445         else rpnstack.push(sx2/fnn-(x*x/(fnn*fnn)));
    1446       }
    1447     }
    1448     else if (args[k] == "product") {
    1449       double px;
    1450       int nn = Product_RPNStack_(rpnstack, px, line);
    1451       if (nn == 0) {
    1452         cerr << "PIACmd::EvalRPNExpr: product error- RPN stack empty: "
    1453              << line << endl;
    1454         return(1);
    1455       }
    1456       rpnstack.push(px);
    1457     }
    1458     // Fonctions de manipulation de stack
    1459     else if (args[k] == "print") {
    1460       Print_myRPNStack_(rpnstack);
    1461     }
    1462     else if (args[k] == "x<>y") {
    1463       if ( Check_myRPNStack_(rpnstack, x, y, line) ) return(1);
    1464       rpnstack.top() = x;  rpnstack.push(y);
    1465     }
    1466     else if (args[k] == "pop") {
    1467       rpnstack.pop();
    1468     }
    1469     else if (args[k] == "push") {
    1470       if (rpnstack.empty()) rpnstack.push(0.);
    1471       else rpnstack.push(rpnstack.top());
    1472     }
    1473     // On met un nombre sur le stack
    1474     else {
    1475       char * esptr;
    1476       x = strtod(args[k].c_str(), &esptr);
    1477       //      if (ctof(args[k].c_str(),&x) < 0) {
    1478       if (esptr == args[k].c_str()) {
    1479         cerr << "PIACmd::EvalRPNExpr: syntax error near " << args[k]
    1480              << " in expression: \n" << line << endl;
    1481         return(2);
    1482       }
    1483       rpnstack.push(x);
    1484     }
    1485 
    1486   }
    1487 
    1488   if ( Check_myRPNStack_(rpnstack, x, line) ) return(1);
    1489   char buff[64];
    1490   sprintf(buff, "%g", x);
    1491   string res = buff;
    1492   omg.SetVar(args[0], res);
    1493   return(0);
    1494 }
    1495 
    1496 /* --Methode-- */
    1497 void PIACmd::PushStack(vector<string>& args)
    1498 {
    1499   // We push the argument list (args) on the stack
    1500   ArgsStack.push(args);
    1501   // We push also PIACmdBloc and testresult on the stack
    1502   CmdBlks.push(NULL);
    1503   list<char> xtx;
    1504   TestsStack.push(xtx);
    1505 
    1506 }
    1507 
    1508 /* --Methode-- */
    1509 void PIACmd::PopStack(bool psta)
    1510 {
    1511   // We remove the argument list (args) from the stack
    1512   if (psta) ArgsStack.pop();
    1513   // And PIACmdBloc and TestResult from the corresponding stacks
    1514   PIACmdBloc* curb = CmdBlks.top();
    1515   while (curb != NULL) {
    1516     PIACmdBloc* parb = curb->Parent();
    1517     delete curb;  curb = parb;
    1518   }
    1519   CmdBlks.pop();
    1520   TestsStack.pop();
    1521 }
    1522 
    1523 /* --Methode-- */
    1524 int PIACmd::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
    1525 {
    1526 int rc = 0;
    1527 NamedObjMgr omg;
    1528247
    1529248// >>>>>>>>>>> Commande d'interpreteur
    1530249if (kw == "helpwindow") ShowHelpWindow();
    1531 else if (kw == "help") {
    1532   if (tokens.size() > 0) cout << GetUsage(tokens[0]) << endl;
    1533   else { 
    1534     string kwh = "piacmd";
    1535     cout << GetUsage(kwh) << endl;
    1536     }
    1537   }
    1538 
    1539 else if (kw == "set") {
    1540   if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: set varname string" << endl;  return(0); }
    1541   if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
    1542     cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
    1543     return(0);
    1544     }
    1545   //  string xx = tokens[1];
    1546   //  for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk] );
    1547   omg.SetVar(tokens[0], tokens[1]);
    1548   }
    1549 
    1550 else if (kw == "getvar") {
    1551   if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: getvar newvarname varname" << endl;  return(0); }
    1552   if (!omg.HasVar(tokens[1])) {
    1553     cerr << "Error - No " << tokens[1] << " Variable " << endl;
    1554     return(0);
    1555     }
    1556   if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
    1557     cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
    1558     return(0);
    1559     }
    1560   omg.SetVar(tokens[0], omg.GetVar(tokens[1]) );
    1561   }
    1562 
    1563 else if (kw == "alias") {
    1564   if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: alias aliasname string" << endl;  return(0); }
    1565   if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
    1566     cerr << "PIACmd::Interpret()/Error alias name should start with alphabetic" << endl;
    1567     return(0);
    1568     }
    1569   string xx = tokens[1];
    1570   for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk]);
    1571   mAliases[tokens[0]] = xx;
    1572   }
    1573 
    1574 else if (kw == "setol") {
    1575   if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: setol varname objnamepattern" << endl;  return(0); }
    1576   if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
    1577     cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
    1578     return(0);
    1579     }
    1580   vector<string> ol;
    1581   mObjMgr->GetObjList(tokens[1], ol);
    1582   string vol;
    1583   if (ol.size() < 1) vol = "";
    1584   else {
    1585      vol = ol[0];
    1586     for (int kk=1; kk<ol.size(); kk++)  vol += (' ' + ol[kk]);
    1587     }
    1588   omg.SetVar(tokens[0], vol);
    1589   }
    1590 else if (kw == "unset") {
    1591   if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: unset varname" << endl;  return(0); }
    1592   if (omg.HasVar(tokens[0])) omg.DeleteVar(tokens[0]) ;
    1593   else cerr << "PIACmd::Interpret() No variable with name " << tokens[0] << endl;
    1594   }
    1595  else if (kw == "rpneval") {  // Evaluation d'expression en notation polonaise inverse
    1596   return(EvalRPNExpr(tokens, toks));
    1597 }
    1598 else if (kw == "echo") {
    1599   for (int ii=0; ii<tokens.size(); ii++)
    1600     cout << tokens[ii] << " " ;
    1601   cout << endl;
    1602  }
    1603 else if (kw == "echo2file") {
    1604   if (tokens.size() < 1) {
    1605     cout << "PIACmd::Interpret() Usage: echo2file filename [string ] " << endl; 
    1606     return(0);
    1607   }
    1608   ofstream ofs(tokens[0].c_str(), ios::app);
    1609   for (int ii=1; ii<tokens.size(); ii++)
    1610     ofs << tokens[ii] << " " ;
    1611   ofs << endl;
    1612  }
    1613 else if (kw == "readstdin") {
    1614   if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: readstdin varname" << endl;  return(0); }
    1615   if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
    1616     cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
    1617     return(0);
    1618     }
    1619   mImgApp->GetConsole()->AddStr(">>> Reading From StdIn \n", PIVA_Magenta);
    1620   cout << tokens[0] << " ? " << endl;
    1621   omg.SetVar(tokens[0], GetStringFrStdin(this) );
    1622   }
    1623 
    1624 else if (kw == "listvars") {
    1625   cout << "PIACmd::Interpret()  Variable List , VarName = Value \n";
    1626   DVList& varlist = omg.GetVarList();
    1627   DVList::ValList::const_iterator it;
    1628   string value;
    1629   for(it = varlist.Begin(); it != varlist.End(); it++) {
    1630 #ifdef SANS_EVOLPLANCK
    1631     MuTyV mtv = (*it).second;
    1632     value = (string)(mtv);
    1633 #else
    1634     value = (string)((*it).second.elval);
    1635 #endif
    1636     cout << (*it).first << " = " <<  value << "\n";
    1637     }
    1638   cout << endl;
    1639   }
    1640 else if (kw == "listalias") {
    1641   cout << "PIACmd::Interpret()  Alias List , AliasName = Value \n";
    1642   CmdStrList::iterator it;
    1643   for(it = mAliases.begin(); it != mAliases.end(); it++) 
    1644     cout << (*it).first << " = " <<  (*it).second << "\n";
    1645   cout << endl;
    1646   }
    1647 else if (kw == "listcommands") {
    1648   cout << "---- PIACmd::Interpret() Command List ----- \n";
    1649   CmdExmap::iterator it;
    1650   int kc = 0;
    1651   for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
    1652     cout << (*it).first << "  ";
    1653     kc++;
    1654     if (kc >= 5) { cout << "\n"; kc = 0; }
    1655     }
    1656   cout << endl;
    1657   }
    1658 else if (kw == "listscripts") {
    1659   cout << "---- PIACmd::Interpret() Script List ----- \n";
    1660   for(ScriptList::iterator sit = mScripts.begin();
    1661       sit != mScripts.end(); sit++)
    1662     cout << " Script: " << (*sit).second->Name() << " - "
    1663          << (*sit).second->Comment() << endl;
    1664 }
    1665 else if (kw == "clearscript") {
    1666   if (tokens.size() < 1) {
    1667     cout << "PIACmd::Interpret() Usage: clearscript scriptname" << endl; 
    1668     return(0);
    1669   }
    1670   ScriptList::iterator sit = mScripts.find(tokens[0]);
    1671   if (sit == mScripts.end()) {
    1672     cout << "PIACmd::Interpret() No script with name" << tokens[0] << endl;
    1673     return(0);
    1674   }
    1675   else {
    1676     delete (*sit).second;
    1677     mScripts.erase(sit);
    1678     cout << "PIACmd::Interpret() script " << tokens[0] << " cleared" << endl;
    1679     return(0);
    1680   }
    1681 }
    1682 else if (kw == "traceon")  { cout << "PIACmd::Interpret()  -> Trace ON mode " << endl; trace = true; }
    1683 else if (kw == "traceoff") { cout << "PIACmd::Interpret()  -> Trace OFF mode " << endl; trace = false; }
    1684 else if (kw == "timingon") {
    1685   cout << "PIACmd::Interpret()  -> Timing ON mode " << endl;
    1686   if (gltimer)   delete gltimer;   gltimer = new Timer("PIA-CmdInterpreter ");   timing = true;
    1687   }
    1688 else if (kw == "timingoff") {
    1689   cout << "PIACmd::Interpret()  -> Timing OFF mode " << endl;
    1690   if (gltimer)  delete gltimer;  gltimer = NULL;  timing = false;
    1691   }
    1692 else if (kw == "exec") {
    1693   if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: exec filename" << endl;  return(0); }
    1694   ExecFile(tokens[0], tokens);
    1695   }
    1696 else if (kw == "autoiniranf") {
    1697   Auto_Ini_Ranf(1);
    1698   return(0);
    1699 }
    1700250// ----> Sortie d'application
    1701251else if (kw == "exitpiapp") {
     
    1703253  return(0);
    1704254}
    1705 else if (kw == "shell") {
    1706   if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: shell cmdline" << endl;  return(0); }
    1707   string cmd;
    1708   for (int ii=0; ii<tokens.size(); ii++)
    1709     cmd += (tokens[ii] + ' ');
    1710   system(cmd.c_str());
    1711   }
    1712 else if (kw == "cshell") {
    1713   if(tokens.size()<1) {cout<<"PIACmd::Interpret() Usage: cshell cmdline"<<endl; return(0);}
    1714   string cmd="";
    1715   for(int ii=0;ii<tokens.size();ii++) cmd+=(tokens[ii]+' ');
    1716   CShellExecute(cmd);
    1717   }
    1718 
    1719 //  Execution d'une commande enregistree
    1720 else rc = ExecuteCommand(kw, tokens, toks);
    1721 
    1722 if (timing)  gltimer->Split();
    1723 return(rc);
    1724 }
    1725 
    1726 /* --Methode-- */
    1727 int PIACmd::ParseLineExecute(string& line, bool qw)
    1728   // Si qw == true, on decoupe entre '' ou "" ou espaces
    1729 {
    1730 vector<string> tokens;
    1731 string kw, toks;
    1732 if (line.length() < 1)  return(0);
    1733 LineToWords(line, kw, tokens, toks, qw);
    1734 return(ExecuteCommand(kw, tokens, toks)); 
    1735 }
    1736 
    1737 /* --Methode-- */
    1738 int PIACmd::ExecuteCommand(string& keyw, vector<string>& args, string& toks)
    1739 {
    1740   int rc = -1;
    1741   CmdExmap::iterator it = cmdexmap.find(keyw);
    1742   if (it == cmdexmap.end())  cout << "No such command : " << keyw << " ! " << endl;
    1743   else {
    1744     if ((*it).second.cex) rc = (*it).second.cex->Execute(keyw, args, toks);
    1745     else cout << "Dont know how to execute " << keyw << " ? " << endl;
    1746     }
    1747   return(rc);
    1748 }
    1749 
    1750 /* --Methode-- */
    1751 int PIACmd::ExecFile(string& file, vector<string>& args)
    1752 {
    1753 char line_buff[512];
    1754 FILE *fip;
    1755 
    1756 if ( (fip = fopen(file.c_str(),"r")) == NULL ) {
    1757   if (file.find('.') >= file.length()) {
    1758     cout << "PIACmd::Exec(): Error opening file " << file << endl;
    1759     file += ".pic";
    1760     cout << "                Trying file " << file << endl;
    1761     fip = fopen(file.c_str(),"r");
    1762     }
    1763   }
    1764 
    1765 if(fip == NULL) {
    1766   cerr << "PIACmd::Exec() Error opening file " << file << endl;
    1767   hist << "##! PIACmd::Exec() Error opening file " << file << endl;
    1768   return(0);
    1769   }
    1770 
    1771 // hist << "### Executing commands from " << file << endl;
    1772 
    1773 PushStack(args);
    1774 if (trace) {
    1775   mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
    1776   mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
    1777   mImgApp->GetConsole()->AddStr("\n", PIVA_Magenta);
    1778   }
    1779 
    1780 bool ohv = histon;
    1781 histon = false;
    1782 while (fgets(line_buff,511,fip) != NULL)
    1783   {
    1784   if (trace) mImgApp->GetConsole()->AddStr(line_buff, PIVA_Magenta);
    1785   line_buff[strlen(line_buff)-1] = '\0';   /*  LF/CR de la fin */
    1786   string line(line_buff);
    1787   if (Interpret(line) == 77777) break;
    1788   }
    1789 histon = ohv;
    1790 
    1791 // hist << "### End of Exec( " << file << " ) " << endl;
    1792 if (trace) {
    1793   mImgApp->GetConsole()->AddStr("### End of Exec( ", PIVA_Magenta);
    1794   mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
    1795   mImgApp->GetConsole()->AddStr(" ) \n", PIVA_Magenta);
    1796   }
    1797 
    1798 PopStack(true);
    1799 
    1800 return(0);
    1801 }
    1802 
    1803 /* --Methode-- */
    1804 int PIACmd::CShellExecute(string cmd)
    1805 {
    1806  if(cmd.size()<=0) return -1;
    1807 
    1808  NamedObjMgr omg;
    1809  string fname = omg.GetTmpDir(); fname += "cshell_exec_pia.csh";
    1810 
    1811  string cmdrm = "rm -f " + fname;
    1812  system(cmdrm.c_str());
    1813 
    1814  FILE *fip = fopen(fname.c_str(),"w");
    1815  if(fip==NULL)   {
    1816    cout << "PIACmd/CShellExecute_Error: fopen("<<fname<<") failed"<<endl;
    1817    return -2;
    1818  }
    1819  fprintf(fip,"#!/bin/csh\n\n");
    1820  fprintf(fip,"%s\n",cmd.c_str());
    1821  fprintf(fip,"\nexit 0\n");
    1822  fclose(fip);
    1823 
    1824  cmd = "csh "; cmd += fname;
    1825  system(cmd.c_str());
    1826 
    1827  system(cmdrm.c_str());
    1828 
    1829  return 0;
    1830 }
    1831 
    1832 static string* videstr = NULL;
    1833 /* --Methode-- */
    1834 string& PIACmd::GetUsage(const string& kw)
    1835 {
    1836 bool fndok = false;
    1837 CmdExmap::iterator it = cmdexmap.find(kw);
    1838 if (it == cmdexmap.end()) {
    1839   it = helpexmap.find(kw);
    1840   if (it != helpexmap.end())  fndok = true;
    1841   }
    1842   else  fndok = true;
    1843 if (fndok)   return( (*it).second.us );
    1844 // Keyword pas trouve
    1845 if (videstr == NULL) videstr = new string("");
    1846 *videstr =  "Nothing known about " + kw + " ?? ";
    1847 return(*videstr);
    1848  
    1849 }
     255else return Commander::ExecuteCommandLine(kw, tokens, toks);
     256
     257}
     258
    1850259
    1851260/* --Methode-- */
     
    1867276}
    1868277
    1869 /*  Les definitions suivantes doivent se trouver ds l'en-tete du fichier LaTeX
    1870   \newcommand{\piacommand}[1]{
    1871     \framebox{\bf \Large #1 } \index{#1} % (Command)
    1872   }
    1873 
    1874   \newcommand{\piahelpitem}[1]{
    1875     \framebox{\bf \Large #1 } \index{#1} (Help item)
    1876   }
    1877 
    1878   \newcommand{\myppageref}[1]{ (p. \pageref{#1} ) }
    1879 */
    1880 
    1881 // Fonction qui remplace tout caractere non alphanumerique en Z
    1882 static void check_latex_reflabel(string & prl)
    1883 {
    1884   for(int k=0; k<prl.length(); k++)
    1885     if (! isalnum(prl[k]) )  prl[k] = 'Z';
    1886 }
    1887 // Fonction qui remplace _ en \_
    1888 static string check_latex_underscore(string const & mot)
    1889 {
    1890   string rs;
    1891   for(int k=0; k<mot.length(); k++) {
    1892     if (mot[k] == '_') rs += "\\_";
    1893     else rs += mot[k];
    1894   }
    1895   return rs;
    1896 }
    1897 
    1898 /* --Methode-- */
    1899 void PIACmd::HelptoLaTeX(string const & fname)
    1900 {
    1901 FILE *fip;
    1902 if ((fip = fopen(fname.c_str(), "w")) == NULL)   {
    1903   cout << "PIACmd::HelptoLaTex_Error: fopen( " << fname << endl;
    1904   return;
    1905   }
    1906 
    1907 fputs("% ----- Liste des groupes de Help ----- \n",fip);
    1908 fputs("List of {\\bf piapp} on-line Help groups: \n", fip);
    1909 fputs("\\begin{itemize} \n",fip);
    1910 string prl;
    1911 string mol;
    1912 CmdHGroup::iterator it;
    1913 for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
    1914   if ((*it).first == "All") continue;
    1915   prl = (*it).first;  check_latex_reflabel(prl);
    1916   mol = check_latex_underscore((*it).first);
    1917   fprintf(fip,"\\item {\\bf %s }  (p. \\pageref{%s}) \n",
    1918           mol.c_str(), prl.c_str());
    1919 }
    1920 
    1921 fputs("\\end{itemize} \n",fip);
    1922 
    1923 fputs("\\vspace*{10mm} \n",fip);
    1924 
    1925 CmdExmap::iterator ite;
    1926 fputs("% ----- Liste de toutes les commandes et help item ----- \n",fip);
    1927 fputs("\\vspace{5mm} \n",fip);
    1928 // fputs("\\begin{table}[h!] \n", fip);
    1929 fputs("\\begin{center} \n ", fip);
    1930 fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Help items \\rule{2cm}{1mm} \\\\ \n", fip);
    1931 fputs("\\vspace{3mm} \n",fip);
    1932 fputs("\\begin{tabular}{llllll}  \n", fip);
    1933 int kt = 0;
    1934 for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
    1935   prl = (*ite).first;  check_latex_reflabel(prl);
    1936   mol = check_latex_underscore((*ite).first);
    1937   fprintf(fip,"%s & p. \\pageref{%s} ", mol.c_str(),  prl.c_str() );
    1938   kt++;
    1939   if (kt < 3) fputs(" & ", fip);
    1940   else  { fputs(" \\\\  \n", fip);  kt = 0; }
    1941   }
    1942 if (kt == 1) fputs("  &  &  &   \\\\  \n", fip);
    1943 else if (kt == 2)  fputs("  &   \\\\  \n", fip);
    1944 fputs("\\end{tabular} \n", fip);
    1945 fputs("\\end{center} \n", fip);
    1946 //fputs("\\end{table} \n", fip);
    1947 fputs("\\newpage  \n",fip);
    1948 
    1949 int gid;
    1950 for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
    1951   gid = (*it).second;
    1952   if (gid == 0)  continue;
    1953   //  fputs("\\begin{table}[h!] \n",fip);
    1954   fputs("\\vspace{6mm} \n",fip);
    1955   fputs("\\begin{center} \n ", fip);
    1956   fprintf(fip, "\\rule{2cm}{1mm} \\makebox[60mm]{{ \\bf %s } help group} \\rule{2cm}{1mm} \\\\ \n",
    1957           (*it).first.c_str());
    1958   fputs("\\vspace{3mm} \n",fip);
    1959   fputs("\\begin{tabular}{llllll} \n", fip);
    1960   kt = 0;
    1961   for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
    1962     if ((*ite).second.group != gid)  continue;
    1963     prl = (*ite).first;  check_latex_reflabel(prl);
    1964     mol = check_latex_underscore((*ite).first);
    1965     fprintf(fip,"%s & p. \\pageref{%s} ", mol.c_str(),  prl.c_str() );
    1966     kt++;
    1967     if (kt < 3) fputs(" & ", fip);
    1968     else  { fputs(" \\\\  \n", fip);  kt = 0; }
    1969   }
    1970   for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
    1971     if ((*ite).second.group != gid)  continue;
    1972     prl = (*ite).first;  check_latex_reflabel(prl);
    1973     mol = check_latex_underscore((*ite).first);
    1974     fprintf(fip,"%s & p. \\pageref{%s} ", mol.c_str(),  prl.c_str() );
    1975     kt++;
    1976     if (kt < 3) fputs(" & ", fip);
    1977     else  { fputs(" \\\\  \n", fip);  kt = 0; }
    1978   }
    1979   if (kt == 1) fputs("  &  &  &   \\\\  \n", fip);
    1980   else if (kt == 2)  fputs("  &   \\\\  \n", fip);
    1981   fputs("\\end{tabular} \n", fip);
    1982   fputs("\\end{center} \n", fip);
    1983   //  fputs("\\end{table} \n",fip);
    1984   //  fputs("\\vspace{5mm} \n",fip);
    1985 }
    1986 // fputs("\\newline \n",fip);
    1987 
    1988 fputs("% ----- Liste des commandes dans chaque groupe ----- \n",fip);
    1989 fputs("\\newpage \n",fip);
    1990 
    1991 for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
    1992   gid = (*it).second;
    1993   if (gid == 0)  continue;
    1994   prl = (*it).first;  check_latex_reflabel(prl);
    1995   fprintf(fip,"\\subsection{%s} \\label{%s} \n",
    1996           (*it).first.c_str(), prl.c_str());
    1997   fprintf(fip,"\\noindent \n");
    1998   for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
    1999     if ((*ite).second.group != gid)  continue;
    2000     prl = (*ite).first;  check_latex_reflabel(prl);
    2001     mol = check_latex_underscore((*ite).first);
    2002     fprintf(fip,"\\piahelpitem{%s} \\label{%s} \n",
    2003             mol.c_str(), prl.c_str());
    2004     fputs("\\begin{verbatim} \n",fip);
    2005     fprintf(fip,"%s\n", (*ite).second.us.c_str());
    2006     fputs("\\end{verbatim} \n",fip);
    2007     }
    2008   for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
    2009     if ((*ite).second.group != gid)  continue;
    2010     prl = (*ite).first;  check_latex_reflabel(prl);
    2011     mol = check_latex_underscore((*ite).first);
    2012     fprintf(fip,"\\piacommand{%s} \\label{%s} \n",
    2013             mol.c_str(), prl.c_str());
    2014     fputs("\\begin{verbatim} \n",fip);
    2015     fprintf(fip,"%s\n", (*ite).second.us.c_str());
    2016     fputs("\\end{verbatim} \n",fip);
    2017     }
    2018 }
    2019 
    2020 fclose(fip);
    2021 return;
    2022 }
    2023 
    2024 
    2025 
     278/* --Methode-- */
     279void PIACmd::SetCurrentPrompt(const char* pr)
     280{
     281  Commander::SetCurrentPrompt(pr);
     282  if (mImgApp) mImgApp->GetConsole()->SetPrompt(pr);
     283}
     284
     285/* --Methode-- */
     286void PIACmd::ShowMessage(const char * msg, int att)
     287{
     288  char va = (att == 0) ? 0 : PIVA_Magenta;
     289  if (mImgApp) mImgApp->GetConsole()->AddStr(msg, va);
     290}
  • trunk/SophyaPI/PIext/piacmd.h

    r2322 r2463  
    88
    99#include "machdefs.h"
    10 #include <iostream>
    11 #include <fstream>
     10#include "commander.h"
    1211#include <string>
    1312#include <vector>
    14 #include <list>
    15 #include <stack>
    16 #include <map>
    17 #include <functional>
    1813
    1914#include "dlftypes.h"
    20 #include "pdlmgr.h"
    21 #include "ctimer.h"
    22 
    23 // Classe definissant l'interface pour un executeur de commande
    24 class CmdExecutor {
    25 public:
    26   virtual       ~CmdExecutor() {} ;
    27   // keyw : Le mot cle associe , args: Arguments de la commande
    28   virtual int   Execute(string& keyw, vector<string>& args, string& toks)=0;
    29 };
    30 
    31 // Classe definissant l'interface pour un interpreteur de commande
    32 class CmdInterpreter {
    33 public:
    34   virtual               ~CmdInterpreter() {} ;
    35   virtual string        Name()=0;
    36   virtual int           Interpret(string& line)=0;
    37 };
    38 
    39 
    4015
    4116// Forward declaration of some classes ...
    4217class NamedObjMgr;
    4318class PIStdImgApp;
    44 #ifdef SANS_EVOLPLANCK
    45 class Timer;
    46 #else
    47 namespace SOPHYA {
    48 class Timer;
    49 }
    50 #endif
    5119
    5220class PIAHelpWind;   // Fenetre d'aide en ligne
    5321class CxxExecWind;   // Fenetre pour CxxExecutor
    5422class CxxOptionWind; // Option de CxxExecutor
    55 
    56 class PIACmdBloc;    // Bloc de type foreach / for de l'interpreteur PIACmd
    57 class PIACmdScript;  // Script de commandes defini ds l'interpreteur PIACmd
    5823
    5924// ---------------------------------------------------------------------
     
    6429
    6530
    66 class PIACmd : public CmdInterpreter  {
     31class PIACmd : public Commander  {
    6732public:
    68   static PIACmd*        GetInterpreter();
     33  //  static PIACmd*    GetInterpreter();
    6934
    7035                        PIACmd(NamedObjMgr* omg, PIStdImgApp* app);
    7136  virtual               ~PIACmd();
    72   virtual string        Name();
    7337
    74   virtual void          RegisterCommand(string& keyw, string& usage, CmdExecutor * ce,
    75                                         string grp="Commands");
    76   virtual void          RegisterHelp(string& keyw, string& usage, string& grp);
    77   virtual void          LoadModule(string& fnameso, string& name);
    7838
    79   virtual void          AddInterpreter(CmdInterpreter * cl);
    80   virtual void          SelInterpreter(string& name);
     39  virtual int            ExecuteCommandLine(string & kw, vector<string> & tokens,
     40                                            string & toks);
     41  void                   ShowHelpWindow();
     42  void                   ShowCxxOptionWindow();
     43  void                   ShowCxxExecWindow();
    8144
    82   virtual int           Interpret(string& line);
    83   virtual int           ParseLineExecute(string& line, bool qw=true);
    84   virtual int           ExecuteCommand(string& keyw, vector<string>& args, string& toks);
    85   virtual int           ExecFile(string& file, vector<string>& args);
    86   virtual int           CShellExecute(string cmd);
    87   virtual string&       GetUsage(const string& kw);
     45    //  inline  CmdInterpreter* CurrentInterpreter() { return(curcmdi); }
    8846
    89           void          ShowHelpWindow();
    90           void          ShowCxxOptionWindow();
    91           void          ShowCxxExecWindow();
    92 
    93   virtual void          HelptoLaTeX(string const & flnm);
    94 
    95   inline  CmdInterpreter* CurrentInterpreter() { return(curcmdi); }
    9647  inline  CmdExecutor*    BaseExecutor()  { return(basexec); }
    9748  inline  CmdExecutor*    ContExecutor()  { return(cntexec); } //_OP_
     
    10152  virtual void          UpdateHelpList(PIAHelpWind* hw, int gid);
    10253
    103 //   Utilitaire pour decoupage en mot
    104   static  int   LineToWords(string& line, string& kw, vector<string>& tokens,
    105                             string& toks, bool uq=true);
    10654protected:
    10755  virtual int   CheckHelpGrp(string& grp);
    108   int           ExecuteCommandLine(string & keyw, vector<string> & args,
    109                                    string & toks);
    11056
    111   int           SubstituteVars(string & s, string & s2); 
    112   int           EvaluateTest(vector<string> & args,
    113                              string & line, bool & res);
    114   int           EvalRPNExpr(vector<string> & args, string & line);
    115 
    116   bool          GetVar(string & vn, string & vv);
    117   void          PushStack(vector<string> & args);
    118   void          PopStack(bool psta=true);
     57  virtual void  SetCurrentPrompt(const char* pr);
     58  virtual void  ShowMessage(const char * msg, int att);
    11959
    12060  NamedObjMgr* mObjMgr;
    12161  PIStdImgApp* mImgApp;
    12262
    123   CmdInterpreter* curcmdi;
    12463  CmdExecutor* basexec;  // basic command executor
    12564  CmdExecutor* fitexec;  // Fit command executor
     
    13069  CmdExecutor *flwexec; // flow chart executor _OP_
    13170 
    132 // Pour enregistrer la liste de commandes et leurs executeurs et le help
    133   struct cmdex {int group; string us; CmdExecutor * cex; } ;
    134   typedef map<string, int, less<string> > CmdHGroup;   // Liste des groupes de commandes
    135   CmdHGroup cmdhgrp;
    136   int cmdgrpid;                                     // Numero de groupe courant
    137   typedef map<string, cmdex, less<string> > CmdExmap;
    138   CmdExmap cmdexmap;
    139   CmdExmap helpexmap;                               // Pour les helps sans commande
    140 
    141 // Pour garder la liste des modules
    142   typedef map<string, PDynLinkMgr* , less<string> > Modmap;
    143   Modmap modmap;
    144 
    145 // Pour garder la liste des interpreteur
    146   typedef map<string, CmdInterpreter*, less<string> > InterpMap;
    147   InterpMap interpmap;
    148  
    149 //  Pour stocker les scripts definis ds l'interpreteur
    150   typedef map<string, PIACmdScript*, less<string> > ScriptList;
    151   ScriptList mScripts;  // Liste des scripts
    152   PIACmdScript* curscript; // Script en cours de definition
    153 
    154 //  Pour stocker les alias definies par l'interpreteur
    155   typedef map<string, string, less<string> > CmdStrList;
    156   CmdStrList mAliases;  // Liste des alias
    157 
    158 // Le stack pour les arguments des .pic et des scripts
    159   stack< vector<string> > ArgsStack;
    160 
    161   stack< PIACmdBloc * > CmdBlks;  // Bloc de commande courant (foreach, ...)
    162   int felevel;                    // foreach-for level
    163   stack< list<char> > TestsStack; // Stack des resultats de test
    164   list<char>::iterator tresit;       // Test courant
    165   bool curtestresult;             // Resultat courant des tests
    166 
    167   bool mulinefg;            // Bloc multi-lignes (ligne suite)
    168   string mulinecmd;         // Commande multi-lignes
    169   string spromptmul;        // Prompt console avant multi-ligne
    170 
    171   ofstream hist;       //  History file
    172   bool histon;        //  True ->  history file
    173   bool trace;          // Trace flag
    174   bool timing;         // Display CPU Time
    175   Timer* gltimer;      // pour Display CPU Time
    176 
    17771// Fenetre d'aide interactive
    17872  PIAHelpWind* helpwin;
Note: See TracChangeset for help on using the changeset viewer.