Changeset 2236 in Sophya for trunk/SophyaPI/PIext


Ignore:
Timestamp:
Oct 30, 2002, 12:52:29 AM (23 years ago)
Author:
ansari
Message:

Ajout possibilite de definition de script ds PIACmd et evaluation d'expression @ x = ... - Reza 29/10/2002

Location:
trunk/SophyaPI/PIext
Files:
2 edited

Legend:

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

    r2218 r2236  
    147147  PIACmdBloc*   Execute();
    148148  inline int&   TestLevel()  { return testlevel; }
     149  inline int&   LoopLevel()  { return looplevel; }
     150  inline bool   CheckBloc()
     151    { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)); }
     152 
    149153protected:
    150154  PIACmd* piacmd;
     
    160164  float f1,f2,df;
    161165  int testlevel;   // niveau d'imbrication des if
     166  int looplevel;   // niveau d'imbrication des for/foreach
     167  bool scrdef;     // true -> commande defscript ds for/foreach
    162168};
    163169
     
    171177i1 = 0;  i2 = -1;  di = 1;
    172178f1 = 0.; f2 = -1.; df = 1.;
    173 testlevel = 0;
     179testlevel = looplevel = 0;
     180scrdef = false;
     181
    174182if ((args.size() < 2) ||  !isalpha((int)args[0][0]) )  return;
    175183if ((kw != "foreach") && (kw != "for"))  return;
     
    230238  if (kw == "if")  testlevel++;
    231239  else if (kw == "endif")  testlevel--;
     240  else if ((kw == "for") || (kw == "foreach"))  looplevel++;
     241  else if (kw == "end")  looplevel--;
     242  else if (kw == "defscript")  scrdef = true;
    232243}
    233244
     
    302313}
    303314
    304 // ------------------
    305 //  Classe PIACmdScript
    306 // ------------------
     315// ---------------------------------------------------------------
     316//                  Classe PIACmdScript
     317//   Definition et execution d'un script de PIACmd
     318//   script : Une liste de commande PIACmd - Lors de l'execution,
     319//   les variables-argument $# $0 $1 sont definies.
     320// ---------------------------------------------------------------
     321
    307322class PIACmdScript {
    308323public:
    309   PIACmdScript();
     324  PIACmdScript(PIACmd* piac, string const& name, string const& comm);
    310325  virtual ~PIACmdScript();
     326
     327  void          AddLine(string& line, string& kw); 
     328  virtual int   Execute(vector<string>& args);
     329
     330  inline string& Name() { return mName; }
     331  inline string& Comment() { return mComm; }
     332  inline int&   TestLevel()  { return testlevel; }
     333  inline int&   LoopLevel()  { return looplevel; }
     334  inline bool   CheckScript()
     335    { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)&&fgok); }
     336
     337protected:
     338  PIACmd* piacmd;
     339  string mName;
     340  string mComm;
     341  vector<string> lines;
     342  int testlevel;   // niveau d'imbrication des if
     343  int looplevel;   // niveau d'imbrication des for/foreach
     344  bool scrdef;     // true -> commande defscript ds for/foreach
     345  bool fgok;       // Script name OK
     346 
    311347};
     348
     349/* --Methode-- */
     350PIACmdScript::PIACmdScript(PIACmd* piac, string const& name,
     351                           string const& comm)
     352{
     353piacmd = piac;
     354testlevel = looplevel = 0;
     355scrdef = false;
     356mName = name;
     357if (!isalpha(name[0]))  fgok = false;
     358else fgok = true;
     359mComm = comm;
     360}
     361
     362/* --Methode-- */
     363PIACmdScript::~PIACmdScript()
     364{
     365}
     366
     367/* --Methode-- */
     368void PIACmdScript::AddLine(string& line, string& kw)
     369{
     370  if (kw == "if")  testlevel++;
     371  else if (kw == "endif")  testlevel--;
     372  else if ((kw == "for") || (kw == "foreach"))  looplevel++;
     373  else if (kw == "end")  looplevel--;
     374  else if (kw == "defscript")  scrdef = true;
     375  lines.push_back(line);
     376}
     377
     378/* --Methode-- */
     379int PIACmdScript::Execute(vector<string>& args)
     380{
     381  if (!CheckScript()) return(-1);
     382  cout << " PIACmdScript::Execute() - Executing script " << Name() << endl;
     383  for(int k=0; k<lines.size(); k++) {
     384    if (piacmd->Interpret(lines[k]) == 77777) break;
     385  }
     386  return(0);
     387}
    312388
    313389// ------------------------------------------------------------
     
    330406mulinecmd = "";
    331407mulinefg = false;
     408curscript = NULL;
    332409
    333410CmdBlks.push(NULL);
     
    362439usage += "  > break         # Delete (clears) all test and loop blocs \n";
    363440usage += "  > return        # Stops command execution from a file \n";
     441usage += "  > defscript endscript # Command script definition \n";
    364442usage += "  > listvars      # List of variable names and values \n";
    365443usage += "  > listalias     # List of alias names and values \n";
    366444usage += "  > listcommands  # List of all known commands \n";
     445usage += "  > listscripts   # List of all known scripts \n";
     446usage += "  > clearcript    # Clear a script definition \n";
    367447usage += "  > exec filename # Execute commands from file \n";
    368448usage += "  > help <command_name>  # <command_name> usage info \n";
     
    412492  delete (*it).second;
    413493  }
     494
     495for(ScriptList::iterator sit = mScripts.begin();
     496    sit != mScripts.end(); sit++) delete (*sit).second;
     497 
    414498delete helpwin;
    415499delete cxxexwin;
     
    549633int rc = 0;
    550634NamedObjMgr omg;
    551 
     635ScriptList::iterator sit;
    552636
    553637// On saute de commandes vides
     
    608692
    609693// les mot-cle end else endif doivent etre le seul mot de la ligne
    610 if ( (kw == "end") || (kw == "else") || (kw == "endif") ) {
     694if ( (kw == "end") || (kw == "else") || (kw == "endif") || (kw == "endscript") ) {
    611695  size_t ltk = toks.length();
    612696  if (toks.find_first_not_of(" \t") < ltk) {
    613     cerr << "PIACmd::Interpret()/syntax error near end else endif \n"
     697    cerr << "PIACmd::Interpret()/syntax error near end else endif endscript \n"
    614698         << "line: " << s << endl;
    615699    return(1);
     
    617701}
    618702
     703// On verifie si on est en train de definir un script
     704if (curscript) {
     705  if (kw == "endscript") {
     706    if (curscript->CheckScript()) {
     707      sit = mScripts.find(curscript->Name());
     708      if (sit != mScripts.end()) {
     709        cout << "PIACmd::Interpret() replacing script "
     710             << curscript->Name() << endl;
     711        PIACmdScript* scr = mScripts[curscript->Name()];
     712        mScripts.erase(sit);
     713        delete scr;
     714      }
     715      cout << "PIACmd::Interpret() Script " << curscript->Name()
     716           << " defined successfully" << endl;
     717      mScripts[curscript->Name()] = curscript;
     718      mImgApp->GetConsole()->SetPrompt("Cmd> ");
     719      curscript = NULL;
     720      return(0);
     721    }
     722    else {
     723      cout << "PIACmd::Interpret() Error in Script " << curscript->Name()
     724           << " definition " << endl;
     725      mImgApp->GetConsole()->SetPrompt("Cmd> ");
     726      curscript = NULL;
     727      return(2);
     728    }
     729  }
     730  else curscript->AddLine(s, kw);
     731  return(0);
     732}
    619733// On verifie si nous sommes dans un bloc (for , foreach)
    620734if (CmdBlks.top() != NULL)  { // On est dans un bloc
     
    625739    CmdBlks.top() = curb->Parent();
    626740    mImgApp->GetConsole()->SetPrompt("Cmd> ");
    627     if (curb->TestLevel() != 0) {
     741    if (!curb->CheckBloc()) {
    628742      cerr << "PIACmd::Interpret()/syntax error - unbalenced if ... endif"
    629743           << " within for/foreach bloc ! " << endl;
     
    727841// Execution de code C++
    728842
    729 if (s[0] == '@')   {
     843if (kw == "@@") {
    730844  CxxExecutor * cxxe = dynamic_cast<CxxExecutor *>(cxxexec);
    731845  if (cxxe == NULL) {
     
    733847    return(99);
    734848  }
    735   // Sans substitution des variables $
    736   if (s[1] == '@') return(cxxe->ExecuteCXX(s.substr(2)));
    737   else { // AVEC substitution des variables $
    738     rcs = SubstituteVars(s, s2);
    739     if (rcs) return(rcs);
    740     return(cxxe->ExecuteCXX(s2.substr(1)));   
    741   }
     849  return(cxxe->ExecuteCXX(s.substr(2)));
    742850}
    743851
     
    748856// >>>> Separating keyword and tokens
    749857vector<string> tokens;
    750 
     858/*
    751859q = s2.find(' ');
    752860l = s2.length();
     
    773881  tokens.push_back(token);
    774882  }
    775 
    776 
     883*/
     884/* decoupage en mots */
     885LineToWords(s2, kw, tokens, toks, true);
    777886// Si c'est un for/foreach, on cree un nouveau bloc
    778887if ((kw == "foreach") || (kw == "for")) {
     
    805914  mImgApp->GetConsole()->SetPrompt(npr);
    806915}
    807 //  Execution de commandes
    808 else rc = ExecuteCommandLine(kw, tokens, toks);
    809 return(rc);
    810 
     916else if (kw == "@") {  // Evaluation d'expression
     917  int rcev = EvalVarExpr(tokens, s);
     918  if (rcev) {
     919    cerr << "PIACmd::Interpret() evaluation syntax Error ! " << endl;
     920    return(1);
     921  }
     922  return(0);
     923}
     924else if (kw == "defscript") {  // definition de script
     925  curscript = new PIACmdScript(this, tokens[0], tokens[1]);
     926  mImgApp->GetConsole()->SetPrompt("Script...> ");
     927  return(0);
     928}
     929else {
     930  //  Si c'est le nom d'un script
     931  sit = mScripts.find(kw);
     932  if (sit != mScripts.end()) {
     933    bool ohv = histon;
     934    histon = false;
     935    PushStack(tokens);
     936    (*sit).second->Execute(tokens);
     937    PopStack(true);
     938    histon = ohv;
     939  }
     940  //  Execution de commandes
     941  else rc = ExecuteCommandLine(kw, tokens, toks);
     942  return(rc);
     943
    811944// cout << "PIACmd::Do() DBG  KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
    812945//  for(int ii=0; ii<tokens.size(); ii++)
    813946//  cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
    814947
     948}
     949
     950
     951/* --Methode-- */
     952int PIACmd::LineToWords(string& line, string& kw, vector<string>& tokens,
     953                        string& toks, bool uq)
     954{
     955if (line.length() < 1)  return(0);
     956int nw = 1;
     957size_t p = line.find_first_not_of(" ");
     958line = line.substr(p);
     959p = 0;
     960size_t q = line.find_first_of(" ");
     961size_t l = line.length();
     962
     963if (q < l)
     964  {  kw = line.substr(p,q-p);  toks = line.substr(q, l-q); }
     965else { kw = line.substr(p,l-p);  toks = ""; }
     966
     967q = 0;
     968while (q < l)  {
     969  p = toks.find_first_not_of(" \t",q+1); // au debut d'un token
     970  if (p>=l) break;
     971  if ( uq && ((toks[p] == '\'') || (toks[p] == '"')) ) {
     972    q = toks.find(toks[p],p+1);
     973    if (q>=l)  {
     974      cerr << "PIACmd::LineToWords/Syntax Error - Unbalenced quotes " << toks[p] << '.' << endl;
     975      return(-1);
     976    }
     977    p++;
     978  }
     979  else {
     980    q = toks.find_first_of(" \t",p); // la fin du token;
     981  }
     982  string token = toks.substr(p,q-p);
     983  tokens.push_back(token);  nw++;
     984  }
     985
     986return(nw);
    815987}
    816988
     
    10161188}
    10171189
     1190/* Verification la presence d'argument d'operation */
     1191#define _Check_EvalVarArg(j_) if (j_ >= args.size()) { \
     1192  cerr << "PIACmd::EvalVarExpr: syntax error " << line << endl; \
     1193  return(1); }
     1194 
     1195/* --Methode-- */
     1196int PIACmd::EvalVarExpr(vector<string> & args, string & line)
     1197{
     1198  if ((args.size() < 3) || (args[1] != "=") || !isalpha(args[0][0]) )  {
     1199    cerr << " PIACmd::EvalVarExpr: syntax error " << line << endl;
     1200    return(1);
     1201  }
     1202
     1203  double x = atof(args[2].c_str());
     1204  double y = 0.;
     1205  int k = 3;
     1206  while (k < args.size()) {
     1207    if (args[k] == "+") {
     1208      _Check_EvalVarArg(k+1);
     1209      y = atof(args[k+1].c_str());
     1210      x += y;  k += 2;
     1211    }
     1212    else if (args[k] == "-") {
     1213      _Check_EvalVarArg(k+1);
     1214      y = atof(args[k+1].c_str());
     1215      x -= y;  k += 2;
     1216    }
     1217    else if (args[k] == "*") {
     1218      _Check_EvalVarArg(k+1);
     1219      y = atof(args[k+1].c_str());
     1220      x *= y;  k += 2;
     1221    }
     1222    else if (args[k] == "/") {
     1223      _Check_EvalVarArg(k+1);
     1224      y = atof(args[k+1].c_str());
     1225      x /= y;  k += 2;
     1226    }
     1227    else if (args[k] == "//") {
     1228      _Check_EvalVarArg(k+1);
     1229      if (args[k+1] == "sin")  x = sin(x);
     1230      else if (args[k+1] == "cos")  x = cos(x);
     1231      else if (args[k+1] == "tan")  x = tan(x);
     1232      else if (args[k+1] == "asin")  x = asin(x);
     1233      else if (args[k+1] == "acos")  x = acos(x);
     1234      else if (args[k+1] == "atan")  x = atan(x);
     1235      else if (args[k+1] == "log")   x = log(x);
     1236      else if (args[k+1] == "log10") x = log10(x);
     1237      else if (args[k+1] == "exp")   x = exp(x);
     1238      k += 2;
     1239   }
     1240  }
     1241
     1242  NamedObjMgr& omg = *mObjMgr;
     1243  char buff[64];
     1244  sprintf(buff, "%g", x);
     1245  string vv = buff;
     1246  omg.SetVar(args[0], vv);
     1247  return(0);
     1248}
     1249
    10181250/* --Methode-- */
    10191251void PIACmd::PushStack(vector<string>& args)
     
    11551387  }
    11561388else if (kw == "listcommands") {
    1157   cout << "---- PIACmd::Interpret()  Command Variable List ----- \n";
     1389  cout << "---- PIACmd::Interpret() Command List ----- \n";
    11581390  CmdExmap::iterator it;
    11591391  int kc = 0;
     
    11651397  cout << endl;
    11661398  }
     1399else if (kw == "listscripts") {
     1400  cout << "---- PIACmd::Interpret() Script List ----- \n";
     1401  for(ScriptList::iterator sit = mScripts.begin();
     1402      sit != mScripts.end(); sit++)
     1403    cout << " Script: " << (*sit).second->Name() << " - "
     1404         << (*sit).second->Comment() << endl;
     1405}
     1406else if (kw == "clearscript") {
     1407  if (tokens.size() < 1) {
     1408    cout << "PIACmd::Interpret() Usage: clearscript scriptname" << endl; 
     1409    return(0);
     1410  }
     1411  ScriptList::iterator sit = mScripts.find(tokens[0]);
     1412  if (sit == mScripts.end()) {
     1413    cout << "PIACmd::Interpret() No script with name" << tokens[0] << endl;
     1414    return(0);
     1415  }
     1416  else {
     1417    delete (*sit).second;
     1418    mScripts.erase(sit);
     1419    cout << "PIACmd::Interpret() script " << tokens[0] << " cleared" << endl;
     1420    return(0);
     1421  }
     1422}
    11671423else if (kw == "traceon")  { cout << "PIACmd::Interpret()  -> Trace ON mode " << endl; trace = true; }
    11681424else if (kw == "traceoff") { cout << "PIACmd::Interpret()  -> Trace OFF mode " << endl; trace = false; }
     
    12011457
    12021458/* --Methode-- */
    1203 int PIACmd::ParseLineExecute(string& line)
     1459int PIACmd::ParseLineExecute(string& line, bool qw)
     1460  // Si qw == true, on decoupe entre '' ou "" ou espaces
    12041461{
    12051462vector<string> tokens;
    1206 
     1463string kw, toks;
    12071464if (line.length() < 1)  return(0);
    1208 
    1209 string toks,kw;
    1210 size_t p = line.find_first_not_of(" ");
    1211 line = line.substr(p);
    1212 p = 0;
    1213 size_t q = line.find_first_of(" ");
    1214 size_t l = line.length();
    1215 
    1216 if (q < l)
    1217   {  kw = line.substr(p,q-p);  toks = line.substr(q, l-q); }
    1218 else { kw = line.substr(p,l-p);  toks = ""; }
    1219 
    1220 q = 0;
    1221 while (q < l)  {
    1222   p = toks.find_first_not_of(" ",q+1); // au debut d'un token
    1223   if (p>=l) break;
    1224   q = toks.find_first_of(" ",p); // la fin du token;
    1225   string token = toks.substr(p,q-p);
    1226   tokens.push_back(token);
    1227   }
    1228 
     1465LineToWords(line, kw, tokens, toks, qw);
    12291466return(ExecuteCommand(kw, tokens, toks)); 
    12301467}
  • trunk/SophyaPI/PIext/piacmd.h

    r2215 r2236  
    8181
    8282  virtual int           Interpret(string& line);
    83   virtual int           ParseLineExecute(string& line);
     83  virtual int           ParseLineExecute(string& line, bool qw=true);
    8484  virtual int           ExecuteCommand(string& keyw, vector<string>& args, string& toks);
    8585  virtual int           ExecFile(string& file, vector<string>& args);
     
    101101  virtual void          UpdateHelpList(PIAHelpWind* hw, int gid);
    102102
     103//   Utilitaire pour decoupage en mot
     104  static  int   LineToWords(string& line, string& kw, vector<string>& tokens,
     105                            string& toks, bool uq=true);
    103106protected:
    104107  virtual int   CheckHelpGrp(string& grp);
     
    109112  int           EvaluateTest(vector<string> & args,
    110113                             string & line, bool & res);
     114  int           EvalVarExpr(vector<string> & args, string & line);
     115
    111116  bool          GetVar(string & vn, string & vv);
    112117  void          PushStack(vector<string> & args);
     
    145150  typedef map<string, PIACmdScript*, less<string> > ScriptList;
    146151  ScriptList mScripts;  // Liste des scripts
     152  PIACmdScript* curscript; // Script en cours de definition
    147153
    148154//  Pour stocker les alias definies par l'interpreteur
Note: See TracChangeset for help on using the changeset viewer.