Changeset 349 in Sophya for trunk/SophyaPI/PIext/piacmd.cc


Ignore:
Timestamp:
Aug 4, 1999, 3:37:31 PM (26 years ago)
Author:
ercodmgr
Message:

A/ ajout des blocs foreach et ameliorations gestion des variables ($x)
pour l'interpreteur piacmd.
B/ Ajout PIStdImgApp::AddText et corrections diverses

Reza 05/08/99

File:
1 edited

Legend:

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

    r335 r349  
    22#include <stdio.h>
    33#include <stdlib.h>
     4#include <ctype.h>
    45#include <math.h>
    56
     
    1718
    1819// ------------------------------------------------------------
    19 //         Gestion d'une fenetre d'aide interactive       
     20//         Gestion d'une fenetre d'aide interactive 
     21//                    Classe   PIAHelpWind   
    2022// ------------------------------------------------------------
    2123
     
    117119}
    118120
     121// ------------------------------------------------------------
     122//         Bloc de commandes (Foreach, ...)   
     123//               Classe  PIACmdBloc   
     124// ------------------------------------------------------------
     125
     126class PIACmdBloc {
     127public:
     128                PIACmdBloc(PIACmd* piac, PIACmdBloc* par, vector<string>& args);
     129                ~PIACmdBloc();
     130  inline PIACmdBloc*   Parent() { return(parent); }
     131  inline bool   CheckOK() { return((typ >= 0) ? true : false); }
     132  inline void   AddLine(string& line) 
     133    { lines.push_back(line); bloclineid.push_back(lines.size()); }
     134  inline void   AddBloc(PIACmdBloc* blk) 
     135    { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
     136  PIACmdBloc*   Execute();
     137protected:
     138  PIACmd* piacmd;
     139  PIACmdBloc* parent;
     140  int typ;           // 0 foreach , 1 integer loop, 2 float loop
     141  string varname;
     142  vector<string> strlist;
     143  vector<string> lines;
     144  vector<PIACmdBloc *> blocs;
     145  vector<int> bloclineid;
     146  int i1,i2,di;
     147  float f1,f2,df;
     148};
     149
     150/* --Methode-- */
     151PIACmdBloc::PIACmdBloc(PIACmd* piac, PIACmdBloc* par, vector<string>& args)
     152{
     153piacmd = piac;
     154parent = par;
     155typ = -1;
     156i1 = 0;  i2 = -1;  di = 1;
     157f1 = 0.; f2 = -1.; df = 1.;
     158if ((args.size() < 2) ||  !isalpha((int)args[0][0]) )  return;
     159varname = args[0];
     160if (isalpha((int)args[1][0]) ) { // This is a foreach-integer bloc
     161  for(int kk=1; kk<args.size(); kk++) strlist.push_back(args[kk]);
     162  typ = 0;
     163  }
     164else { // This is an integer or float loop
     165  size_t l = args[1].length();
     166  size_t p = args[1].find(':');
     167  size_t pp = args[1].find('.');
     168  bool fl = (pp < l) ? true : false;  // Float loop or integer loop
     169  if (p >= l) return;  // Syntaxe error
     170  string a1 = args[1].substr(0, p);
     171  string aa = args[1].substr(p+1);
     172  p = aa.find(':');
     173  string a2, a3;
     174  bool hasa3 = false;
     175  if (p < aa.length() ) {
     176    a2 = aa.substr(0,p);
     177    a3 = aa.substr(p+1);
     178    hasa3 = true;
     179    }
     180  else  a2 = aa;
     181  if (fl) {
     182    typ = 2;
     183    f1 = atof(a1.c_str());
     184    f2 = atof(a2.c_str());
     185    if (hasa3)  df = atof(a3.c_str());
     186    else df = 1.;
     187    }
     188  else {
     189    typ = 1;
     190    i1 = atoi(a1.c_str());
     191    i2 = atoi(a2.c_str());
     192    if (hasa3)  di = atoi(a3.c_str());
     193    else di = 1;
     194    }
     195  }
     196}
     197
     198/* --Methode-- */
     199PIACmdBloc::~PIACmdBloc()
     200{
     201for(int k=0; k<blocs.size(); k++) delete blocs[k];
     202}
     203
     204/* --Methode-- */
     205PIACmdBloc* PIACmdBloc::Execute()
     206{
     207// cout << " DBG * PIACmdBloc::Execute() " << typ << " - " << bloclineid.size() <<
     208//      " I1,I2=" << i1 << " , " << i2 << " , " << di << endl;
     209string cmd;
     210int k=0;
     211int kj=0;
     212int kk=0;
     213char buff[32];
     214if (typ == 0)   // foreach string loop
     215  for(k=0; k<strlist.size(); k++) {
     216    cmd = "set " + varname + " " + strlist[k];
     217    piacmd->Interpret(cmd);
     218    for(kj=0; kj<bloclineid.size(); kj++) {
     219      kk = bloclineid[kj];
     220      if (kk > 0)  piacmd->Interpret(lines[kk-1]);
     221      else blocs[-kk-1]->Execute();
     222      }
     223  }
     224else if (typ == 1)  // Integer loop
     225  for(int i=i1; i<i2; i+=di) {
     226    k++;
     227    if (++k > 9999) {
     228      cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
     229      break;
     230      }
     231    sprintf(buff, " %d", i);
     232    cmd = "set " + varname + buff;
     233    piacmd->Interpret(cmd);
     234    for(kj=0; kj<bloclineid.size(); kj++) {
     235      kk = bloclineid[kj];
     236      if (kk > 0)  piacmd->Interpret(lines[kk-1]);
     237      else blocs[-kk-1]->Execute();
     238      }
     239  }
     240else if (typ == 2)  // float loop
     241  for(float f=f1; f<f2; f+=df) {
     242    k++;
     243    if (++k > 9999) {
     244      cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
     245      break;
     246      }
     247    sprintf(buff, " %g", f);
     248    cmd = "set " + varname + buff;
     249    piacmd->Interpret(cmd);
     250    for(kj=0; kj<bloclineid.size(); kj++) {
     251      kk = bloclineid[kj];
     252      if (kk > 0)  piacmd->Interpret(lines[kk-1]);
     253      else blocs[-kk-1]->Execute();
     254      }
     255  }
     256
     257return(parent);
     258}
     259
     260// ------------------------------------------------------------
     261//         Classe PIACmd
     262// ------------------------------------------------------------
     263
    119264static PIACmd* curpiacmd = NULL;
    120265/* --Methode-- */
     
    125270system("cp history.pic hisold.pic");
    126271hist.open("history.pic");
     272histon = true;
    127273trace = false;   timing = false;
    128274gltimer = NULL;
     275curblk = NULL;
     276felevel = 0;
    129277
    130278cmdhgrp["All"] = 0;
     
    138286string usage;
    139287usage = ">>> (piacmd) Interpreter's keywords : \n";
    140 usage += "  timingon  timingoff traceon  traceoff \n";
    141 usage += "  set unset listvar listcommands exec shell \n";
    142 usage += "  > set varname 'string'   # To set a variable, $varname \n";
     288usage += "  > set varname string   # To set a variable, $varname \n";
     289usage += "  > get newvarname varname # To set a newvariable, equal to $varname \n";
    143290usage += "  > setol varname patt     # Fills varname with object list \n";
    144291usage += "  > unset varname          # clear variable definition \n";
    145292usage += "  > echo string            # output string \n";
     293usage += "  > foreach varname string-list # Loop \n";
     294usage += "  > foreach varname i1:i2[:di]  # Integer loop  \n";
     295usage += "  > foreach varname f1:f2[:df]  # Float loop  \n";
     296usage += "  > end                         # end loops \n";
    146297usage += "  > listvars   # List of variable names and values \n";
    147298usage += "  > listcommands # List of all known commands \n";
     
    150301usage += "  > help <command_name>  # <command_name> usage info \n";
    151302usage += "  > helpwindow           # Displays help window \n";
     303usage += "  > timingon  timingoff traceon  traceoff \n";
    152304string grp = "Commands";
    153305RegisterHelp(kw, usage, grp);
     
    266418{
    267419if (!cl) return;
    268 interpmap[cl->Name()] = cl;
    269 }
     420interpmap[cl->Name()] = cl;}
    270421
    271422/* --Methode-- */
     
    286437int rc = 0;
    287438cmdtok tokens;
    288 if (s.length() < 1)  return(0);
    289 
    290 hist << s << endl;   // On enregistre les commandes
    291 
    292 if (s[0] == '#') {
    293   cout << "PIACmd::Interpret() Comment-Line:" << s << endl;
    294   return(0);
    295   }
     439CmdVarList::iterator it;
     440
     441// Removing leading blanks
     442size_t p,q,q2,l;
     443l = s.length();
     444if (l < 1)  return(0);
     445if (s[0] == '#') return(0); // si c'est un commentaire
     446p=s.find_first_not_of(" \t");
     447if (p < l) s = s.substr(p);
     448// else return(0);
     449
     450// On enregistre les commandes
     451if (histon) hist << s << endl;   
     452
     453
    296454string toks,kw;
    297 size_t p = s.find_first_not_of(" ");
    298 s = s.substr(p);
    299 p = 0;
    300 size_t q = s.find_first_of(" ");
    301 size_t l = s.length();
    302 
     455
     456// >>>> Substitution d'alias (1er mot)
     457int als = 0;
     458while (als < 2) {
     459  p = s.find_first_not_of(" ");
     460  s = s.substr(p);
     461  p = 0;
     462  q = s.find_first_of(" ");
     463  l = s.length();
     464  string w1 =  (q < l) ? s.substr(p,q-p) : s.substr(p);
     465  it = mAliases.find(w1);
     466  if (it != mAliases.end())  s =  (*it).second + s.substr(q);
     467  else als++;
     468  als++;
     469  }
     470
     471// >>>> Separating keyword
    303472if (q < l)
    304473  {  kw = s.substr(p,q-p);  toks = s.substr(q, l-q); }
    305474else { kw = s.substr(p,l-p);  toks = ""; }
    306475
     476// On verifie si nous sommes dans un bloc
     477if ( (curblk != NULL) && (kw != "foreach") ) { // On est dans un bloc
     478  if (kw != "end")   { curblk->AddLine(s);  return(0); }
     479  else {
     480    PIACmdBloc* curb = curblk;
     481    curblk = curb->Parent();
     482    felevel--;
     483    if (curblk  == NULL) {
     484       mImgApp->GetConsole()->SetPrompt("Cmd> ");
     485       //       cout << " *DBG* Executing bloc " << endl;
     486       curb->Execute();
     487       }
     488    else  {
     489      char prompt[64];
     490      sprintf(prompt, "foreach-%d> ", felevel);
     491      mImgApp->GetConsole()->SetPrompt(prompt);
     492      }
     493    return(0);
     494    }
     495  }
     496
     497// Nous ne sommes donc pas dans un bloc ....   
     498
     499// >>>> Variable substitution 
     500string s2="";
     501p = 0;
     502l = s.length();
     503string vn;
     504while (p < l) {
     505  q = s.find('$',p);
     506  //  cout << "DBG: " << s2 << " p= " << p << " q= " << q << " L= " << l << endl;
     507  if (q > l) break;
     508  if ((q>0) && (s[q-1] == '\\')) {   // Escape character \$
     509     s2 += (s.substr(p,q-1-p) + '$') ; p = q+1;
     510     continue;
     511     }
     512  if (q >= l-1) {
     513      cerr << " Syntax error !!! " << endl;
     514      return(0);
     515      }
     516  vn = "";
     517  if ( s[q+1] == '{' ) {  // Variable in the form ${name}
     518    q2 = s.find('}',q+1);
     519    if (q2 >= l) {
     520      cerr << " Syntax error !!! " << endl;
     521      return(0);
     522      }
     523    vn = s.substr(q+2,q2-q-2);
     524    q2++;
     525    }
     526  else if ( s[q+1] == '[' ) {  // Variable in the form $[varname]  -> This is $$varname
     527    q2 = s.find(']',q+1);
     528    if (q2 >= l) {
     529      cerr << " Syntax error !!! " << endl;
     530      return(0);
     531      }
     532    vn = s.substr(q+2,q2-q-2);
     533    it =  mVars.find(vn); 
     534    if ( (vn.length() < 1) || (it == mVars.end()) ) {
     535      cerr << " Error: Undefined variable " << vn << " ! " << endl;
     536      return(0);
     537      }
     538    vn = mVars[vn];
     539    q2++;
     540    }
     541  else {
     542    q2 = s.find_first_of(" .:/,]()$",q+1);
     543    if (q2 > l) q2 = l;
     544    vn = s.substr(q+1, q2-q-1);
     545    }
     546  it =  mVars.find(vn); 
     547  if ( (vn.length() < 1) || (it == mVars.end()) ) {
     548    cerr << " Error: Undefined variable " << vn << " ! " << endl;
     549    return(0);
     550    }
     551  s2 += (s.substr(p, q-p) + (*it).second);
     552  p = q2;
     553  }
     554if (p < l) s2 += s.substr(p);
     555
     556p = s2.find_first_not_of(" \t");
     557if (p < l) s2 = s2.substr(p);
     558
     559
     560// >>>> Separating keyword and tokens
     561q = s2.find(' ');
     562l = s2.length();
     563if (q < l)
     564  {  kw = s2.substr(0,q);  toks = s2.substr(q, l-q); }
     565else { kw = s2;  toks = ""; }
     566
    307567q = 0;
    308568while (q < l)  {
    309   p = toks.find_first_not_of(" ",q+1); // au debut d'un token
     569  p = toks.find_first_not_of(" \t",q+1); // au debut d'un token
    310570  if (p>=l) break;
    311   q = toks.find_first_of(" ",p); // la fin du token;
     571  q = toks.find_first_of(" \t",p); // la fin du token;
    312572  string token = toks.substr(p,q-p);
    313573  tokens.push_back(token);
    314574  }
    315575
    316 for(int k=0; k<tokens.size(); k++) { // On remplace les $varname par la valeur de la variable
    317   if ((tokens[k])[0] != '$')  continue;
    318   CmdVarList::iterator it = mVars.find(tokens[k].substr(1));
    319   if (it != mVars.end())  tokens[k] = (*it).second;
    320   }
     576
     577// Si c'est un foreach, on cree un nouveau bloc
     578if (kw == "foreach") {
     579  //     cout << " *DBG* We got a foreach... " << endl;
     580  PIACmdBloc* bloc = new PIACmdBloc(this, curblk, tokens);
     581  if (!bloc->CheckOK()) {
     582    cerr << "foreach syntax Error ! " << endl;
     583    delete bloc;
     584    return(0);
     585    }
     586  felevel++;
     587  if (curblk)  curblk->AddBloc(bloc);
     588  else {
     589    char prompt[64];
     590    sprintf(prompt, "foreach-%d> ", felevel);
     591    mImgApp->GetConsole()->SetPrompt(prompt);
     592    }
     593  curblk = bloc;
     594  //  cout << " *DBG* New Bloc created ... " << endl;
     595  return(0);
     596  }
     597
    321598
    322599// cout << "PIACmd::Do() DBG  KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
     
    325602
    326603// >>>>>>>>>>> Commande d'interpreteur
    327 if (kw == "helpwindow") ShowHelpWindow();
     604else if (kw == "helpwindow") ShowHelpWindow();
    328605else if (kw == "help") {
    329606  if (tokens.size() > 0) cout << GetUsage(tokens[0]) << endl;
     
    336613else if (kw == "set") {
    337614  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: set varname string" << endl;  return(0); }
    338   string xx = "";
    339   for (int kk=1; kk<tokens.size(); kk++)  xx += (tokens[kk] + ' ');
     615  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
     616    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
     617    return(0);
     618    }
     619  string xx = tokens[1];
     620  for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk] );
    340621  mVars[tokens[0]] = xx;
    341622  }
     623
     624else if (kw == "getvar") {
     625  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: getvar newvarname varname" << endl;  return(0); }
     626  it = mVars.find(tokens[1]);
     627  if (it == mVars.end()) {
     628    cerr << "Error - No " << tokens[1] << " Variable " << endl;
     629    return(0);
     630    }
     631  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
     632    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
     633    return(0);
     634    }
     635  mVars[tokens[0]] = (*it).second;
     636  }
     637
     638else if (kw == "alias") {
     639  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: alias aliasname string" << endl;  return(0); }
     640  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
     641    cerr << "PIACmd::Interpret()/Error alias name should start with alphabetic" << endl;
     642    return(0);
     643    }
     644  string xx = tokens[1];
     645  for (int kk=2; kk<tokens.size(); kk++)  xx += (' ' + tokens[kk]);
     646  mAliases[tokens[0]] = xx;
     647  }
     648
    342649else if (kw == "setol") {
    343650  if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: setol varname objnamepattern" << endl;  return(0); }
     651  if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
     652    cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
     653    return(0);
     654    }
    344655  vector<string> ol;
    345   mObjMgr->GetObjList(tokens[1], ol);
    346   string vol = "";
    347   for (int kk=0; kk<ol.size(); kk++)  vol += (ol[kk] + ' ');
     656  mObjMgr->GetObjList(tokens[1], ol);
     657  string vol;
     658  if (ol.size() < 1) vol = "";
     659  else {
     660     vol = ol[0];
     661    for (int kk=1; kk<ol.size(); kk++)  vol += (' ' + ol[kk]);
     662    }
    348663  mVars[tokens[0]] = vol;
    349664  }
     
    388703else if (kw == "exec") {
    389704  if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: exec filename" << endl;  return(0); }
    390   ExecFile(tokens[0]);
     705  ExecFile(tokens[0], tokens);
    391706  }
    392707else if (kw == "shell") {
     
    444759
    445760/* --Methode-- */
    446 int PIACmd::ExecFile(string& file)
     761int PIACmd::ExecFile(string& file, vector<string>& args)
    447762{
    448763char line_buff[512];
     
    454769  return(0);
    455770  }
    456  
    457 hist << "### Executing commands from " << file << endl;
     771
     772// hist << "### Executing commands from " << file << endl;
     773
     774// Setting $0 ... $99 variables
     775int k;
     776CmdVarList::iterator it;
     777char buff[32];
     778// First, we clear all previous values
     779string vn="#";
     780it = mVars.find(vn);
     781if (it != mVars.end())  mVars.erase(it);
     782for(k=0; k<99; k++) {   
     783  sprintf(buff,"%d",k);
     784  vn = buff;
     785  it = mVars.find(vn);
     786  if (it != mVars.end())  mVars.erase(it);
     787  }
     788// We then set them
     789vn="#";
     790sprintf(buff,"%d",(int)args.size());
     791mVars[vn] = buff;
     792for(k=0; k<args.size(); k++) {   
     793  sprintf(buff,"%d",k);
     794  vn = buff;
     795  mVars[vn] = args[k];
     796  }
     797
    458798if (trace) {
    459799  mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
     
    462802  }
    463803
     804histon = false;
    464805while (fgets(line_buff,511,fip) != NULL)
    465806  {
     
    469810  Interpret(line);
    470811  }
    471 hist << "### End of Exec( " << file << " ) " << endl;
     812histon = false;
     813
     814// hist << "### End of Exec( " << file << " ) " << endl;
    472815if (trace) {
    473816  mImgApp->GetConsole()->AddStr("### End of Exec( ", PIVA_Magenta);
Note: See TracChangeset for help on using the changeset viewer.