source: Sophya/trunk/SophyaPI/PIext/piacmd.cc@ 2236

Last change on this file since 2236 was 2236, checked in by ansari, 23 years ago

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

File size: 47.4 KB
RevLine 
[293]1#include "piacmd.h"
[165]2#include <stdio.h>
3#include <stdlib.h>
[349]4#include <ctype.h>
[165]5#include <math.h>
6
[293]7#include "basexecut.h"
[165]8
[293]9#include "pdlmgr.h"
[165]10#include "ctimer.h"
[2214]11#include "strutil.h"
[2215]12#include "strutilxx.h"
[293]13// #include "dlftypes.h"
[165]14
[293]15#include "pistdimgapp.h"
[165]16#include "nobjmgr.h"
[361]17#include "piafitting.h"
[463]18#include "pawexecut.h"
[1224]19#include "cxxexecutor.h"
[1251]20#include "cxxexecwin.h"
[1828]21#include "contmodex.h"
[1920]22#include "flowmodex.h"
[165]23
[293]24#include PISTDWDG_H
25#include PILIST_H
[165]26
[293]27// ------------------------------------------------------------
[349]28// Gestion d'une fenetre d'aide interactive
29// Classe PIAHelpWind
[293]30// ------------------------------------------------------------
[165]31
[293]32class PIAHelpWind : public PIWindow {
33public :
34 PIAHelpWind(PIStdImgApp* par, PIACmd* piacmd);
35 virtual ~PIAHelpWind();
[330]36 virtual void Show();
[293]37 virtual void Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
[330]38 inline void AddHelpGroup(const char * hgrp, int gid)
39 { hgrpom->AppendItem(hgrp, 20000+gid); }
40 inline void ClearHelpList()
41 { mNitem=0; hitemlist->DeleteAllItems(); }
[293]42 inline void AddHelpItem(const char * hitem)
[330]43 { mNitem++; hitemlist->AppendItem(hitem, 100+mNitem); }
[293]44protected :
45 PIStdImgApp* dap;
46 PIACmd* piac;
47 int mNitem;
48 PIList* hitemlist;
[330]49 PIOptMenu* hgrpom;
[293]50 PIButton * mBut;
51 PILabel * mLab;
52 PIText* mTxt;
53};
[165]54
[293]55/* --Methode-- */
56PIAHelpWind::PIAHelpWind(PIStdImgApp *par, PIACmd* piacmd)
57 : PIWindow((PIMsgHandler *)par, "Help-PIApp", PIWK_normal, 400, 300, 100, 350)
58{
59dap = par;
60piac = piacmd;
61mNitem = 0;
[330]62SetMsg(77);
[165]63
[293]64int bsx, bsy;
65int tsx, tsy;
66int spx, spy;
67PIApplicationPrefCompSize(bsx, bsy);
68spx = bsx/6; spy = bsy/6;
69tsx = 10*bsx+2*spx; tsy = 7*bsy+3*spy;
70SetSize(tsx,tsy);
[330]71hgrpom = new PIOptMenu(this, "hgrpoptmen", bsx*2.0, bsy, spx/2, spy);
72hgrpom->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
73hitemlist = new PIList(this, "hitemlist", bsx*2.0, tsy-3*spy-bsy, spx/2, 2*spy+bsy);
[293]74hitemlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
75// hitemlist->SetBorderWidth(2);
[324]76mTxt = new PIText(this, "helptext", true, true, bsx*8.0, 6*bsy, bsx*2.0+1.5*spx, spy);
77// mTxt->SetMutiLineMode(true);
[293]78mTxt->SetTextEditable(false);
79mTxt->SetText("");
80mTxt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
81mLab = new PILabel(this, "helpitem", bsx*4, bsy, bsx*2.5+2*spx, tsy-spy-bsy);
82mLab->SetBorderWidth(1);
83mLab->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
84mLab->SetLabel("");
[330]85mBut = new PIButton(this, "Close", 70, bsx, bsy, tsx-bsx*1.5-spx, tsy-spy-bsy);
[293]86mBut->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
87}
[165]88
89/* --Methode-- */
[293]90PIAHelpWind::~PIAHelpWind()
91{
[330]92delete hgrpom;
[293]93delete hitemlist;
94delete mTxt;
95delete mLab;
96delete mBut;
97}
98
99/* --Methode-- */
100void PIAHelpWind::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
101{
102PIMessage um = UserMsg(msg);
[330]103if (((um == 77) && (ModMsg(msg) == PIMsg_Close)) || (um == 70) ) {
[293]104 Hide();
105 return;
106 }
[330]107else if ( (um >= 20000) && (sender == hgrpom)) { // Selection de groupe de Help
108 mTxt->SetText("");
109 mLab->SetLabel("");
110 piac->UpdateHelpList(this, um-20000);
111}
112else if ( (um > 100) && (sender == hitemlist) && (ModMsg(msg) == PIMsg_Select) ) {
[293]113 string s = hitemlist->GetSelectionStr();
114 mTxt->SetText(piac->GetUsage(s));
115 mLab->SetLabel(s);
116 }
117}
118
[330]119/* --Methode-- */
120void PIAHelpWind::Show()
121{
122hgrpom->SetValue(20000); // Groupe All
123mTxt->SetText("");
124mLab->SetLabel("");
125piac->UpdateHelpList(this, 0);
126PIWindow::Show();
127}
[293]128
[349]129// ------------------------------------------------------------
130// Bloc de commandes (Foreach, ...)
131// Classe PIACmdBloc
132// ------------------------------------------------------------
133
134class PIACmdBloc {
135public:
[1262]136 enum BType { BT_None, BT_ForeachList, BT_ForeachInt, BT_ForeachFloat };
137
[1562]138 PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args);
[1262]139 ~PIACmdBloc();
[349]140 inline PIACmdBloc* Parent() { return(parent); }
[1262]141 inline bool CheckOK() { return blkok; }
[349]142 inline void AddLine(string& line)
143 { lines.push_back(line); bloclineid.push_back(lines.size()); }
[2215]144 void AddLine(string& line, string& kw);
[349]145 inline void AddBloc(PIACmdBloc* blk)
146 { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
147 PIACmdBloc* Execute();
[2215]148 inline int& TestLevel() { return testlevel; }
[2236]149 inline int& LoopLevel() { return looplevel; }
150 inline bool CheckBloc()
151 { return ((testlevel == 0)&&(looplevel == 0)&&(!scrdef)); }
152
[349]153protected:
154 PIACmd* piacmd;
155 PIACmdBloc* parent;
[1262]156 bool blkok; // true -> block OK
157 BType typ; // foreach , integer loop, float loop, test
[349]158 string varname;
159 vector<string> strlist;
160 vector<string> lines;
161 vector<PIACmdBloc *> blocs;
162 vector<int> bloclineid;
163 int i1,i2,di;
164 float f1,f2,df;
[2215]165 int testlevel; // niveau d'imbrication des if
[2236]166 int looplevel; // niveau d'imbrication des for/foreach
167 bool scrdef; // true -> commande defscript ds for/foreach
[349]168};
169
170/* --Methode-- */
[1562]171PIACmdBloc::PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args)
[349]172{
173piacmd = piac;
174parent = par;
[1262]175blkok = false;
176typ = BT_None;
[349]177i1 = 0; i2 = -1; di = 1;
178f1 = 0.; f2 = -1.; df = 1.;
[2236]179testlevel = looplevel = 0;
180scrdef = false;
181
[349]182if ((args.size() < 2) || !isalpha((int)args[0][0]) ) return;
[1562]183if ((kw != "foreach") && (kw != "for")) return;
184varname = args[0]; // $CHECK$ Variable name should be checked
185//if (isalpha((int)args[1][0]) ) { This is a foreach bloc with string list
186if (kw == "foreach" ) { // This is a foreach bloc with string list
[2215]187 if ((args[1] != "(") || (args[args.size()-1] != ")") ) return;
188 for(int kk=2; kk<args.size()-1; kk++) strlist.push_back(args[kk]);
[1262]189 typ = BT_ForeachList;
[1276]190 blkok = true;
[349]191 }
192else { // This is an integer or float loop
193 size_t l = args[1].length();
194 size_t p = args[1].find(':');
195 size_t pp = args[1].find('.');
196 bool fl = (pp < l) ? true : false; // Float loop or integer loop
197 if (p >= l) return; // Syntaxe error
198 string a1 = args[1].substr(0, p);
199 string aa = args[1].substr(p+1);
200 p = aa.find(':');
201 string a2, a3;
202 bool hasa3 = false;
203 if (p < aa.length() ) {
204 a2 = aa.substr(0,p);
205 a3 = aa.substr(p+1);
206 hasa3 = true;
207 }
208 else a2 = aa;
209 if (fl) {
[1262]210 typ = BT_ForeachFloat;
[1276]211 blkok = true;
[349]212 f1 = atof(a1.c_str());
213 f2 = atof(a2.c_str());
214 if (hasa3) df = atof(a3.c_str());
215 else df = 1.;
216 }
217 else {
[1262]218 typ = BT_ForeachInt;
[1276]219 blkok = true;
[349]220 i1 = atoi(a1.c_str());
221 i2 = atoi(a2.c_str());
222 if (hasa3) di = atoi(a3.c_str());
223 else di = 1;
224 }
225 }
226}
227
228/* --Methode-- */
229PIACmdBloc::~PIACmdBloc()
230{
231for(int k=0; k<blocs.size(); k++) delete blocs[k];
232}
233
234/* --Methode-- */
[2215]235void PIACmdBloc::AddLine(string& line, string& kw)
236{
237 AddLine(line);
238 if (kw == "if") testlevel++;
239 else if (kw == "endif") testlevel--;
[2236]240 else if ((kw == "for") || (kw == "foreach")) looplevel++;
241 else if (kw == "end") looplevel--;
242 else if (kw == "defscript") scrdef = true;
[2215]243}
244
245/* --Methode-- */
[349]246PIACmdBloc* PIACmdBloc::Execute()
247{
248// cout << " DBG * PIACmdBloc::Execute() " << typ << " - " << bloclineid.size() <<
249// " I1,I2=" << i1 << " , " << i2 << " , " << di << endl;
250string cmd;
251int k=0;
252int kj=0;
253int kk=0;
254char buff[32];
[2215]255int rcc = 0;
256
[1262]257if (typ == BT_ForeachList) // foreach string loop
[349]258 for(k=0; k<strlist.size(); k++) {
[1565]259 cmd = "set " + varname + " '" + strlist[k] + "'";
[349]260 piacmd->Interpret(cmd);
261 for(kj=0; kj<bloclineid.size(); kj++) {
262 kk = bloclineid[kj];
[2215]263 if (kk > 0) {
264 rcc = piacmd->Interpret(lines[kk-1]);
265 if (rcc == 77766) break;
266 }
[349]267 else blocs[-kk-1]->Execute();
[2215]268 }
269 if (rcc == 77766) break;
[349]270 }
[1262]271else if (typ == BT_ForeachInt) // Integer loop
[349]272 for(int i=i1; i<i2; i+=di) {
273 k++;
274 if (++k > 9999) {
275 cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
276 break;
277 }
278 sprintf(buff, " %d", i);
279 cmd = "set " + varname + buff;
280 piacmd->Interpret(cmd);
281 for(kj=0; kj<bloclineid.size(); kj++) {
282 kk = bloclineid[kj];
[2215]283 if (kk > 0) {
284 rcc = piacmd->Interpret(lines[kk-1]);
285 if (rcc == 77766) break;
286 }
[349]287 else blocs[-kk-1]->Execute();
[2215]288 }
289 if (rcc == 77766) break;
[349]290 }
[1262]291else if (typ == BT_ForeachFloat) // float loop
[349]292 for(float f=f1; f<f2; f+=df) {
293 k++;
294 if (++k > 9999) {
295 cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
296 break;
297 }
298 sprintf(buff, " %g", f);
299 cmd = "set " + varname + buff;
300 piacmd->Interpret(cmd);
301 for(kj=0; kj<bloclineid.size(); kj++) {
302 kk = bloclineid[kj];
[2215]303 if (kk > 0) {
304 rcc = piacmd->Interpret(lines[kk-1]);
305 if (rcc == 77766) break;
306 }
[349]307 else blocs[-kk-1]->Execute();
[2215]308 }
309 if (rcc == 77766) break;
[349]310 }
311
312return(parent);
313}
314
[2236]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
[2214]322class PIACmdScript {
323public:
[2236]324 PIACmdScript(PIACmd* piac, string const& name, string const& comm);
[2214]325 virtual ~PIACmdScript();
[2236]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
[2214]347};
348
[2236]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}
388
[349]389// ------------------------------------------------------------
390// Classe PIACmd
391// ------------------------------------------------------------
392
[293]393static PIACmd* curpiacmd = NULL;
394/* --Methode-- */
[165]395PIACmd::PIACmd(NamedObjMgr* omg, PIStdImgApp* app)
396{
[293]397mObjMgr = omg;
[165]398mImgApp = app;
399system("cp history.pic hisold.pic");
400hist.open("history.pic");
[349]401histon = true;
[165]402trace = false; timing = false;
403gltimer = NULL;
[349]404felevel = 0;
[2215]405
[1276]406mulinecmd = "";
407mulinefg = false;
[2236]408curscript = NULL;
[293]409
[2215]410CmdBlks.push(NULL);
411list<char> xtx;
412TestsStack.push(xtx);
413curtestresult = true;
414
[330]415cmdhgrp["All"] = 0;
416cmdgrpid = 1;
417cmdhgrp["Commands"] = 1;
[293]418helpwin = new PIAHelpWind(app, this);
[330]419helpwin->AddHelpGroup("All", 0);
420helpwin->AddHelpGroup("Commands", 1);
[293]421
422string kw = "piacmd";
423string usage;
424usage = ">>> (piacmd) Interpreter's keywords : \n";
[349]425usage += " > set varname string # To set a variable, $varname \n";
426usage += " > get newvarname varname # To set a newvariable, equal to $varname \n";
[333]427usage += " > setol varname patt # Fills varname with object list \n";
[293]428usage += " > unset varname # clear variable definition \n";
[333]429usage += " > echo string # output string \n";
[353]430usage += " > alias name string # define a command alias \n";
431usage += " > readstdin varname # reads a line from stdin into $varname \n";
[349]432usage += " > foreach varname string-list # Loop \n";
[1562]433usage += " > for varname i1:i2[:di] # Integer loop \n";
434usage += " > for varname f1:f2[:df] # Float loop \n";
[349]435usage += " > end # end loops \n";
[1565]436usage += " > if test then # Conditional test : a == != < > <= >= b \n";
437usage += " > else # Conditional \n";
438usage += " > endif # End of conditional if bloc \n";
439usage += " > break # Delete (clears) all test and loop blocs \n";
440usage += " > return # Stops command execution from a file \n";
[2236]441usage += " > defscript endscript # Command script definition \n";
[353]442usage += " > listvars # List of variable names and values \n";
443usage += " > listalias # List of alias names and values \n";
444usage += " > listcommands # List of all known commands \n";
[2236]445usage += " > listscripts # List of all known scripts \n";
446usage += " > clearcript # Clear a script definition \n";
[353]447usage += " > exec filename # Execute commands from file \n";
[293]448usage += " > help <command_name> # <command_name> usage info \n";
449usage += " > helpwindow # Displays help window \n";
[349]450usage += " > timingon timingoff traceon traceoff \n";
[330]451string grp = "Commands";
452RegisterHelp(kw, usage, grp);
[293]453
[2203]454kw = "shell execute";
455usage = "> shell command_string # Execute shell command\n";
456usage += "> cshell command_string # Execute cshell command\n";
457usage += "---Exemples:\n";
458usage += " > shell ls\n";
459usage += " > cshell echo '$LD_LIBRARY_PATH'; map2cl -h; ls\n";
460usage += " > shell myfile.csh [arg1] [arg2] [...]\n";
461usage += " (where the first line of \"myfile.csh\" is \"#!/bin/csh\")\n";
462RegisterHelp(kw, usage, grp);
463
[293]464basexec = new PIABaseExecutor(this, omg, app);
[361]465fitexec = new PIAFitter(this, app);
[463]466pawexec = new PAWExecutor(this, app);
[1251]467CxxExecutor * cxxe = new CxxExecutor(this, app);
468cxxexec = cxxe;
[1828]469
470ContModExecutor *cntxx = new ContModExecutor(this, app);//_OP_
471cntexec = cntxx; //_OP_
[1920]472FlowModExecutor *flwxx = new FlowModExecutor(this, app);//_OP_
473flwexec = flwxx; //_OP_
[1828]474
[1251]475cxxoptwin = new CxxOptionWind(app, cxxe);
476cxxexwin = new CxxExecWind(app, cxxe);
477
[293]478AddInterpreter(this);
479curcmdi = this;
[165]480}
481
482/* --Methode-- */
483PIACmd::~PIACmd()
484{
485hist.close();
486if (gltimer) { delete gltimer; gltimer = NULL; }
[293]487Modmap::iterator it;
488for(it = modmap.begin(); it != modmap.end(); it++) {
489 string name = (*it).first + "_end";
490 DlModuleInitEndFunction fend = (*it).second->GetFunction(name);
491 if (fend) fend();
492 delete (*it).second;
493 }
[2236]494
495for(ScriptList::iterator sit = mScripts.begin();
496 sit != mScripts.end(); sit++) delete (*sit).second;
497
[293]498delete helpwin;
[1251]499delete cxxexwin;
500delete cxxoptwin;
[293]501if (curpiacmd == this) curpiacmd = NULL;
[361]502delete basexec;
503delete fitexec;
[463]504delete pawexec;
[1224]505delete cxxexec;
[165]506}
507
508/* --Methode-- */
[293]509PIACmd* PIACmd::GetInterpreter()
[165]510{
[293]511return(curpiacmd);
512}
[165]513
[293]514/* --Methode-- */
515string PIACmd::Name()
516{
517return("piacmd");
518}
[165]519
[293]520/* --Methode-- */
[330]521void PIACmd::RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, string grp)
[293]522{
[330]523if (!ce) {
524 RegisterHelp(keyw, usage, grp);
525 return;
526 }
527int gid = CheckHelpGrp(grp);
[293]528cmdex cme;
[330]529cme.group = gid;
[293]530cme.us = usage;
531cme.cex = ce;
532cmdexmap[keyw] = cme;
533}
534
535/* --Methode-- */
[330]536void PIACmd::RegisterHelp(string& keyw, string& usage, string& grp)
537{
538int gid = CheckHelpGrp(grp);
539cmdex cme;
540cme.group = gid;
541cme.us = usage;
542cme.cex = NULL;
543helpexmap[keyw] = cme;
544}
545
546/* --Methode-- */
547int PIACmd::CheckHelpGrp(string& grp)
548{
549int gid=0;
550CmdHGroup::iterator it = cmdhgrp.find(grp);
551if (it == cmdhgrp.end()) {
552 cmdgrpid++; gid = cmdgrpid;
553 cmdhgrp[grp] = gid;
554 helpwin->AddHelpGroup(grp.c_str(), gid);
555 }
556else gid = (*it).second;
557return(gid);
558}
559
560/* --Methode-- */
561void PIACmd::UpdateHelpList(PIAHelpWind* hw, int gid)
562{
563helpwin->ClearHelpList();
564CmdExmap::iterator it;
565for(it = helpexmap.begin(); it != helpexmap.end(); it++) {
566 if ( (gid != 0) && ((*it).second.group != gid) ) continue;
567 helpwin->AddHelpItem((*it).first.c_str());
568 }
569for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
570 if ( (gid != 0) && ((*it).second.group != gid) ) continue;
571 helpwin->AddHelpItem((*it).first.c_str());
572 }
573}
574
575/* --Methode-- */
[293]576void PIACmd::LoadModule(string& fnameso, string& name)
577{
578PDynLinkMgr * dynlink = new PDynLinkMgr(fnameso, false);
579if (dynlink == NULL) {
580 cerr << "PIACmd/LoadModule_Error: Pb opening SO " << fnameso << endl;
581 return;
[165]582 }
[293]583string fname = name + "_init";
584DlModuleInitEndFunction finit = dynlink->GetFunction(fname);
585if (!finit) {
586 cerr << "PIACmd/LoadModule_Error: Pb linking " << fname << endl;
587 return;
[165]588 }
[293]589cout << "PIACmd/LoadModule_Info: Initialisation module" << name
590 << " " << fname << "() ..." << endl;
591finit();
592modmap[name] = dynlink;
593return;
594}
[165]595
[293]596/* --Methode-- */
597void PIACmd::AddInterpreter(CmdInterpreter * cl)
598{
599if (!cl) return;
[349]600interpmap[cl->Name()] = cl;}
[165]601
602/* --Methode-- */
[293]603void PIACmd::SelInterpreter(string& name)
[165]604{
[293]605InterpMap::iterator it = interpmap.find(name);
606if (it == interpmap.end()) return;
607curcmdi = (*it).second;
608}
[165]609
[293]610
611
[357]612/* Fonction */
[368]613static string GetStringFrStdin(PIACmd* piac)
[357]614{
[368]615PIStdImgApp* piapp = piac->GetImgApp();
616if (piapp) {
617 PIBaseWdg* wdg = piapp->CurrentBaseWdg();
618 if (wdg) wdg->Refresh();
[357]619#ifndef __mac__
[368]620 /* On vide le buffer X-Window */
[374]621 XSync(PIXDisplay(),False);
[357]622#endif
[368]623}
[357]624char buff[128];
625fgets(buff, 128, stdin);
626buff[127] = '\0';
627return((string)buff);
628}
629
[293]630/* --Methode-- */
631int PIACmd::Interpret(string& s)
632{
[333]633int rc = 0;
[1262]634NamedObjMgr omg;
[2236]635ScriptList::iterator sit;
[165]636
[1262]637// On saute de commandes vides
638size_t l;
[349]639l = s.length();
640if (l < 1) return(0);
[165]641
[349]642// On enregistre les commandes
643if (histon) hist << s << endl;
644
[1262]645if (s[0] == '#') return(0); // si c'est un commentaire
[349]646
[1276]647// Logique de gestion des lignes suite
648// un \ en derniere position indique la presence d'une ligne suite
[1539]649size_t lnb = s.find_last_not_of(' ');
650if (s[lnb] == '\\' ) { // Lignes suite ...
[1276]651 mulinefg = true;
[1539]652 mulinecmd += s.substr(0,lnb);
[1276]653 mImgApp->GetConsole()->SetPrompt("...? ");
654 return(0);
655}
[165]656
[1276]657if (mulinefg) { // Il y avait des lignes suite
658 s = mulinecmd + s;
659 mulinecmd = "";
660 mulinefg = false;
[2215]661 const char * rprompt = (CmdBlks.empty()) ? "Cmd> " : "for...? ";
[1276]662 mImgApp->GetConsole()->SetPrompt(rprompt);
663}
664
[1262]665// Removing leading blanks
[1276]666size_t p,q;
[1262]667
668p=s.find_first_not_of(" \t");
669if (p < l) s = s.substr(p);
670
[349]671// >>>> Substitution d'alias (1er mot)
[2214]672CmdStrList::iterator it;
[449]673p = 0;
674q = s.find_first_of(" \t");
675l = s.length();
676string w1 = (q < l) ? s.substr(p,q-p) : s.substr(p);
677it = mAliases.find(w1);
678if (it != mAliases.end()) {
679 s = (q < l) ? ((*it).second + s.substr(q)) : (*it).second ;
680 l = s.length();
681 p=s.find_first_not_of(" \t");
682 if (p < l) s = s.substr(p);
[349]683 p = 0;
684 q = s.find_first_of(" ");
685 }
686
687// >>>> Separating keyword
[1262]688string toks,kw;
[165]689if (q < l)
690 { kw = s.substr(p,q-p); toks = s.substr(q, l-q); }
691else { kw = s.substr(p,l-p); toks = ""; }
692
[1562]693// les mot-cle end else endif doivent etre le seul mot de la ligne
[2236]694if ( (kw == "end") || (kw == "else") || (kw == "endif") || (kw == "endscript") ) {
[1562]695 size_t ltk = toks.length();
696 if (toks.find_first_not_of(" \t") < ltk) {
[2236]697 cerr << "PIACmd::Interpret()/syntax error near end else endif endscript \n"
[1562]698 << "line: " << s << endl;
699 return(1);
700 }
701}
702
[2236]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}
[1562]733// On verifie si nous sommes dans un bloc (for , foreach)
[2215]734if (CmdBlks.top() != NULL) { // On est dans un bloc
[1562]735 if ( (kw == "for") || (kw == "foreach")) felevel++;
736 else if (kw == "end") felevel--;
737 if (felevel == 0) { // Il faut executer le bloc
[2215]738 PIACmdBloc* curb = CmdBlks.top();
739 CmdBlks.top() = curb->Parent();
[1562]740 mImgApp->GetConsole()->SetPrompt("Cmd> ");
[2236]741 if (!curb->CheckBloc()) {
[2215]742 cerr << "PIACmd::Interpret()/syntax error - unbalenced if ... endif"
743 << " within for/foreach bloc ! " << endl;
744 delete curb;
745 return(2);
746 }
[349]747 // cout << " *DBG* Executing bloc " << endl;
[1562]748 bool ohv = histon;
749 histon = false;
[2215]750 if (curtestresult) {
751 // We push also PIACmdBloc and testresult on the stack
752 CmdBlks.push(NULL);
753 list<char> xtx;
754 TestsStack.push(xtx);
755 curb->Execute();
756 // And PIACmdBloc and TestResult from the corresponding stacks
757 PopStack(false);
758 }
759 delete curb;
[1562]760 histon = ohv;
761 }
[2215]762 else CmdBlks.top()->AddLine(s, kw);
[1562]763 return(0);
764}
[1565]765else if (kw == "end") {
766 cerr << "PIACmd::Interpret()/syntax error - end outside for/foreach bloc \n"
767 << "line: " << s << endl;
768 return(1);
769}
[1562]770
771// Sommes-nous dans un bloc de test if then else
[2215]772if (TestsStack.top().size() > 0) { // Nous sommes ds un bloc if
[1565]773 if (kw == "else") {
774 if ((*tresit) & 2) {
775 cerr << "PIACmd::Interpret()/syntax error - multiple else in if bloc \n"
776 << "line: " << s << endl;
777 return(1);
778 }
779 else {
[1570]780 const char * npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
[2215]781 if ((*tresit)&1) curtestresult = false;
[1565]782 mImgApp->GetConsole()->SetPrompt(npr);
783 (*tresit) |= 2;
784 return(0);
785 }
786 }
787 else if (kw == "endif") {
788 list<char>::iterator dbit = tresit;
[1562]789 tresit--;
[2215]790 TestsStack.top().erase(dbit);
[1570]791 const char * npr = "Cmd> ";
[2215]792 if (TestsStack.top().size() > 1) {
793 curtestresult = true;
794 list<char>::iterator it;
795 for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
796 // Si on n'est pas ds le else et le if est faux
797 if ( !((*it)&2) && !((*it)&1) ) curtestresult = false;
798 // Si on est ds else et le if etait vrai !
799 if ( ((*it)&2) && ((*it)&1) ) curtestresult = false;
800 if (!curtestresult) break;
801 }
802
[1565]803 if (!((*tresit)&2))
804 npr = ((*tresit)&1) ? "if-T> " : "if-F> ";
805 else
806 npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
807 }
[2215]808 else curtestresult = true;
[1565]809 mImgApp->GetConsole()->SetPrompt(npr);
[349]810 return(0);
811 }
[1565]812}
813else if ((kw == "else") || (kw == "endif")) {
814 cerr << "PIACmd::Interpret()/syntax error - else,endif outside if bloc \n"
815 << "line: " << s << endl;
816 return(1);
[1562]817}
[349]818
[1565]819bool fgcont = true;
[2215]820if (TestsStack.top().size() > 0) { // Resultat de if ou else
[1565]821 list<char>::iterator it;
[2215]822 for(it=TestsStack.top().begin(); it!=TestsStack.top().end(); it++) {
[1565]823 // Si on n'est pas ds le else et le if est faux
824 if ( !((*it)&2) && !((*it)&1) ) fgcont = false;
825 // Si on est ds else et le if etait vrai !
826 if ( ((*it)&2) && ((*it)&1) ) fgcont = false;
827 if (!fgcont) break;
828 }
829}
830
831if ((!fgcont) && (kw != "if")) return(0);
832
833
[2215]834// Les mots cles break et return peuvent de sortir de boucles/scripts/execfile
835if (kw == "break") return(77766);
836else if (kw == "return") return(77777);
837
[1262]838// Nous ne sommes donc pas dans un bloc .... Substitution de variables
[1276]839string s2;
840int rcs ;
[1262]841// Execution de code C++
842
[2236]843if (kw == "@@") {
[1262]844 CxxExecutor * cxxe = dynamic_cast<CxxExecutor *>(cxxexec);
845 if (cxxe == NULL) {
846 cerr << "PIACmd::Interpret() - BUG !!! Not a CxxExecutor " << endl;
847 return(99);
848 }
[2236]849 return(cxxe->ExecuteCXX(s.substr(2)));
[1262]850}
851
852
[1276]853rcs = SubstituteVars(s, s2);
854if (rcs) return(rcs);
[1262]855
856// >>>> Separating keyword and tokens
857vector<string> tokens;
[2236]858/*
[1262]859q = s2.find(' ');
860l = s2.length();
861if (q < l)
862 { kw = s2.substr(0,q); toks = s2.substr(q, l-q); }
863else { kw = s2; toks = ""; }
864
865q = 0;
866while (q < l) {
867 p = toks.find_first_not_of(" \t",q+1); // au debut d'un token
868 if (p>=l) break;
[1276]869 if ( (toks[p] == '\'') || (toks[p] == '"') ) {
870 q = toks.find(toks[p],p+1);
871 if (q>=l) {
[1565]872 cerr << "PIACmd::Interpret()/Syntax Error - Unbalenced quotes " << toks[p] << '.' << endl;
[1276]873 return(2);
874 }
875 p++;
876 }
877 else {
878 q = toks.find_first_of(" \t",p); // la fin du token;
879 }
[1262]880 string token = toks.substr(p,q-p);
881 tokens.push_back(token);
882 }
[2236]883*/
884/* decoupage en mots */
885LineToWords(s2, kw, tokens, toks, true);
[1562]886// Si c'est un for/foreach, on cree un nouveau bloc
887if ((kw == "foreach") || (kw == "for")) {
[1262]888 // cout << " *DBG* We got a foreach... " << endl;
[2215]889 PIACmdBloc* bloc = new PIACmdBloc(this, CmdBlks.top(), kw, tokens);
[1262]890 if (!bloc->CheckOK()) {
[1565]891 cerr << "PIACmd::Interpret() for/foreach syntax Error ! " << endl;
[1262]892 delete bloc;
[1565]893 return(1);
[1262]894 }
895 felevel++;
[2215]896 if (CmdBlks.top()) CmdBlks.top()->AddBloc(bloc);
[1562]897 else mImgApp->GetConsole()->SetPrompt("for...> ");
[2215]898 CmdBlks.top() = bloc;
[1262]899 // cout << " *DBG* New Bloc created ... " << endl;
900 return(0);
901 }
[1565]902else if (kw == "if") { // Un test if
903 bool restst = true;
904 int rct = EvaluateTest(tokens, s, restst);
905 if (rct) {
906 cerr << "PIACmd::Interpret() if syntax Error ! " << endl;
907 return(1);
908 }
909 char res_tst = (restst) ? 1 : 0;
[2215]910 TestsStack.top().push_back(res_tst);
911 if (TestsStack.top().size() == 1) tresit = TestsStack.top().begin();
[1562]912 else tresit++;
[1570]913 const char * npr = (restst) ? "if-T> " : "if-F> ";
[1565]914 mImgApp->GetConsole()->SetPrompt(npr);
[1562]915}
[2236]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}
[1262]944// cout << "PIACmd::Do() DBG KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
945// for(int ii=0; ii<tokens.size(); ii++)
946// cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
947
948}
949
[2236]950
[1262]951/* --Methode-- */
[2236]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);
987}
988
989/* --Methode-- */
[1262]990int PIACmd::SubstituteVars(string & s, string & s2)
991// Variable substitution
992{
[2214]993NamedObjMgr& omg = *mObjMgr;
[1262]994
[2215]995int iarr = -1; // index d'element de tableau
996size_t p,q,q2,q3,l;
[1262]997
998s2="";
[349]999p = 0;
1000l = s.length();
[2214]1001string vn, vv;
[349]1002while (p < l) {
1003 q = s.find('$',p);
[1276]1004 if (q > l) break;
1005 q2 = s.find('\'',p);
1006 if ((q2 < l) && (q2 < q)) { // On saute la chaine delimitee par ' '
1007 q2 = s.find('\'',q2+1);
1008 if (q2 >= l) {
1009 cerr << " Syntax error - Unbalenced quotes !!! " << endl;
1010 return(1);
1011 }
1012 s2 += s.substr(p, q2-p+1);
1013 p = q2+1; continue;
1014 }
[349]1015 // cout << "DBG: " << s2 << " p= " << p << " q= " << q << " L= " << l << endl;
1016 if ((q>0) && (s[q-1] == '\\')) { // Escape character \$
1017 s2 += (s.substr(p,q-1-p) + '$') ; p = q+1;
1018 continue;
1019 }
1020 if (q >= l-1) {
[1276]1021 cerr << " Syntax error - line ending with $ !!! " << endl;
1022 return(2);
[349]1023 }
1024 vn = "";
1025 if ( s[q+1] == '{' ) { // Variable in the form ${name}
1026 q2 = s.find('}',q+1);
1027 if (q2 >= l) {
[1276]1028 cerr << " Syntax error - Unbalenced brace {} !!! " << endl;
1029 return(3);
[349]1030 }
1031 vn = s.substr(q+2,q2-q-2);
1032 q2++;
[2215]1033 }
1034 else if ( s[q+1] == '(' ) { // Variable in the form $(name)
1035 q2 = s.find(')',q+1);
1036 if (q2 >= l) {
1037 cerr << " Syntax error - Unbalenced parenthesis () !!! " << endl;
1038 return(3);
1039 }
1040 vn = s.substr(q+2,q2-q-2);
1041 q2++;
1042 }
[349]1043 else if ( s[q+1] == '[' ) { // Variable in the form $[varname] -> This is $$varname
1044 q2 = s.find(']',q+1);
1045 if (q2 >= l) {
[1276]1046 cerr << " Syntax error - Unbalenced brace [] !!! " << endl;
1047 return(4);
[349]1048 }
1049 vn = s.substr(q+2,q2-q-2);
[2214]1050 if (!GetVar(vn, vv)) return(5);
1051 vn = vv;
[349]1052 q2++;
1053 }
1054 else {
[1562]1055 q2 = s.find_first_of(" .:+-*/,[](){}&|!$\"'",q+1);
[349]1056 if (q2 > l) q2 = l;
[2215]1057 q3 = q2;
[349]1058 vn = s.substr(q+1, q2-q-1);
[2215]1059 // Si variable de type $varname[index] : element de tableau
1060 if ((q2 < l) && (s[q2] == '[') ) {
1061 q3 = s.find_first_of("]",q2+1);
1062 string sia = s.substr(q2+1, q3-q2-1);
[2218]1063 if (sia.length() < 1) {
1064 cerr << " Syntax error - in $varname[index] : $"
1065 << vn << "[" << sia <<"]" << endl;
1066 return(4);
1067 }
1068 if (isalpha(sia[0])) {
1069 string sia2;
1070 if (!GetVar(sia, sia2) || (sia2.length() < 1)) {
1071 cerr << " Syntax error - in $varname[index] : $"
1072 << vn << "[" << sia <<"]" << endl;
1073 return(4);
1074 }
1075 sia = sia2;
1076 }
[2215]1077 int rcdia = ctoi(sia.c_str(), &iarr);
1078 if (rcdia < 0) {
1079 cerr << " Syntax error - in $varname[iarr] : $"
1080 << vn << "[" << sia <<"]" << endl;
1081 return(4);
1082 }
[349]1083 }
[2215]1084 }
[2214]1085 if (!GetVar(vn, vv)) return(5);
[2215]1086 if (iarr < 0) {
1087 s2 += (s.substr(p, q-p) + vv);
1088 p = q2;
1089 }
1090 else {
1091 vector<string> vs;
1092 FillVStringFrString(vv, vs);
1093 if (iarr >= vs.size()) {
1094 cerr << " Substitution error - word index out of range in "
1095 << "$varname[iarr] : $" << vn << "[" << iarr <<"]" << endl;
1096 return(4);
1097 }
1098 else s2 += (s.substr(p, q-p) + vs[iarr]);
1099 p = q3+1;
1100 }
1101}
[349]1102if (p < l) s2 += s.substr(p);
1103
1104p = s2.find_first_not_of(" \t");
1105if (p < l) s2 = s2.substr(p);
1106
[1262]1107return(0);
1108}
[349]1109
[1262]1110/* --Methode-- */
[2214]1111bool PIACmd::GetVar(string & vn, string & vv)
1112{
1113NamedObjMgr& omg = *mObjMgr;
1114if (vn.length() < 1) {
1115 cerr << " PIACmd::SubstituteVar/Error: length(varname=" << vn << ")<1 !" << endl;
1116 vv = ""; return(false);
1117}
1118// Variable de type $# $0 $1 ... (argument de .pic ou de script)
1119int ka = 0;
1120if (vn == "#") {
1121 if (ArgsStack.empty()) {
1122 cerr << " PIACmd::SubstituteVar/Error: ArgsStack empty ! "
1123 << " ($" << vn << ")" << endl;
[2218]1124 vv = ""; return(false);
[2214]1125 }
1126 char buff[32];
1127 long an = ArgsStack.top().size();
1128 sprintf(buff,"%ld", an);
[2218]1129 vv = buff; return(true);
[2214]1130}
1131else if (ctoi(vn.c_str(), &ka) > 0) { // $0 $1 $2 ...
1132 if (ArgsStack.empty()) {
1133 cerr << " PIACmd::SubstituteVar/Error: ArgsStack empty ! "
1134 << " ($" << vn << ")" << endl;
1135 vv = ""; return(false);
1136 }
1137 if ( (ka < 0) || (ka >= ArgsStack.top().size()) ) {
1138 cerr << " PIACmd::SubstituteVar/Error: Undefined variable ! "
1139 << " ($" << vn << ")" << endl;
1140 vv = ""; return(false);
1141 }
[2218]1142 vv = ArgsStack.top()[ka]; return(true);
[2214]1143}
[2218]1144else if (vn[0] == '#') { // Variable de type $#vname --> size(vname)
1145 vn = vn.substr(1);
1146 if (!omg.HasVar(vn) ) {
1147 cerr << " PIACmd::SubstituteVarError: Undefined variable "
1148 << vn << " ! " << endl;
1149 vv = ""; return(false);
1150 }
1151 vn = omg.GetVar(vn);
1152 vector<string> vs;
1153 FillVStringFrString(vn, vs);
1154 char buff[32];
1155 sprintf(buff,"%d", (int)vs.size());
1156 vv = buff; return(true);
1157 }
[2214]1158else { // variable ordinaire geree par NamedObjMgr
1159 if ( (!omg.HasVar(vn)) ) {
1160 cerr << " PIACmd::SubstituteVarError: Undefined variable "
1161 << vn << " ! " << endl;
[2218]1162 vv = ""; return(false);
[2214]1163 }
[2218]1164 vv = omg.GetVar(vn); return(true);
[2214]1165}
1166
[2218]1167return(false);
[2214]1168}
1169
1170/* --Methode-- */
[1565]1171int PIACmd::EvaluateTest(vector<string> & args, string & line, bool & res)
[1562]1172{
[1565]1173 res = true;
[2215]1174 if ((args.size() != 6) || (args[5] != "then") ||
1175 (args[0] != "(") || (args[4] != ")") ) return(1);
1176 if (args[2] == "==") res = (args[1] == args[3]);
1177 else if (args[2] == "!=") res = (args[1] != args[3]);
1178 else if (args[2] == "<")
1179 res = (atof(args[1].c_str()) < atof(args[3].c_str()));
1180 else if (args[2] == ">")
1181 res = (atof(args[1].c_str()) > atof(args[3].c_str()));
1182 else if (args[2] == "<=")
1183 res = (atof(args[1].c_str()) <= atof(args[3].c_str()));
1184 else if (args[2] == ">=")
1185 res = (atof(args[1].c_str()) >= atof(args[3].c_str()));
[1565]1186 else return(2);
1187 return(0);
[1562]1188}
1189
[2236]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
[1562]1195/* --Methode-- */
[2236]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
1250/* --Methode-- */
[2215]1251void PIACmd::PushStack(vector<string>& args)
1252{
1253 // We push the argument list (args) on the stack
1254 ArgsStack.push(args);
1255 // We push also PIACmdBloc and testresult on the stack
1256 CmdBlks.push(NULL);
1257 list<char> xtx;
1258 TestsStack.push(xtx);
1259
1260}
1261
1262/* --Methode-- */
1263void PIACmd::PopStack(bool psta)
1264{
1265 // We remove the argument list (args) from the stack
1266 if (psta) ArgsStack.pop();
1267 // And PIACmdBloc and TestResult from the corresponding stacks
1268 PIACmdBloc* curb = CmdBlks.top();
1269 while (curb != NULL) {
1270 PIACmdBloc* parb = curb->Parent();
1271 delete curb; curb = parb;
1272 }
1273 CmdBlks.pop();
1274 TestsStack.pop();
1275}
1276
1277/* --Methode-- */
[1262]1278int PIACmd::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
1279{
1280int rc = 0;
1281NamedObjMgr omg;
[349]1282
[165]1283// >>>>>>>>>>> Commande d'interpreteur
[1262]1284if (kw == "helpwindow") ShowHelpWindow();
[293]1285else if (kw == "help") {
[330]1286 if (tokens.size() > 0) cout << GetUsage(tokens[0]) << endl;
[293]1287 else {
[330]1288 string kwh = "piacmd";
1289 cout << GetUsage(kwh) << endl;
[293]1290 }
[165]1291 }
1292
1293else if (kw == "set") {
[293]1294 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: set varname string" << endl; return(0); }
[349]1295 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
1296 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
1297 return(0);
1298 }
[1276]1299 // string xx = tokens[1];
1300 // for (int kk=2; kk<tokens.size(); kk++) xx += (' ' + tokens[kk] );
1301 omg.SetVar(tokens[0], tokens[1]);
[165]1302 }
[349]1303
1304else if (kw == "getvar") {
1305 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: getvar newvarname varname" << endl; return(0); }
[1262]1306 if (!omg.HasVar(tokens[1])) {
[349]1307 cerr << "Error - No " << tokens[1] << " Variable " << endl;
1308 return(0);
1309 }
1310 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
1311 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
1312 return(0);
1313 }
[1262]1314 omg.SetVar(tokens[0], omg.GetVar(tokens[1]) );
[349]1315 }
1316
1317else if (kw == "alias") {
1318 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: alias aliasname string" << endl; return(0); }
1319 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
1320 cerr << "PIACmd::Interpret()/Error alias name should start with alphabetic" << endl;
1321 return(0);
1322 }
1323 string xx = tokens[1];
1324 for (int kk=2; kk<tokens.size(); kk++) xx += (' ' + tokens[kk]);
1325 mAliases[tokens[0]] = xx;
1326 }
1327
[333]1328else if (kw == "setol") {
1329 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: setol varname objnamepattern" << endl; return(0); }
[349]1330 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
1331 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
1332 return(0);
1333 }
[333]1334 vector<string> ol;
[349]1335 mObjMgr->GetObjList(tokens[1], ol);
1336 string vol;
1337 if (ol.size() < 1) vol = "";
1338 else {
1339 vol = ol[0];
1340 for (int kk=1; kk<ol.size(); kk++) vol += (' ' + ol[kk]);
1341 }
[1262]1342 omg.SetVar(tokens[0], vol);
[333]1343 }
[293]1344else if (kw == "unset") {
1345 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: unset varname" << endl; return(0); }
[1262]1346 if (omg.HasVar(tokens[0])) omg.DeleteVar(tokens[0]) ;
[293]1347 else cerr << "PIACmd::Interpret() No variable with name " << tokens[0] << endl;
[165]1348 }
[333]1349else if (kw == "echo") {
[1276]1350 for (int ii=0; ii<tokens.size(); ii++)
1351 cout << tokens[ii] << " " ;
[333]1352 cout << endl;
[1276]1353 }
[353]1354else if (kw == "readstdin") {
1355 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: readstdin varname" << endl; return(0); }
1356 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
1357 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
1358 return(0);
1359 }
[357]1360 mImgApp->GetConsole()->AddStr(">>> Reading From StdIn \n", PIVA_Magenta);
1361 cout << tokens[0] << " ? " << endl;
[1262]1362 omg.SetVar(tokens[0], GetStringFrStdin(this) );
[353]1363 }
1364
[165]1365else if (kw == "listvars") {
[293]1366 cout << "PIACmd::Interpret() Variable List , VarName = Value \n";
[1262]1367 DVList& varlist = omg.GetVarList();
1368 DVList::ValList::const_iterator it;
1369 string value;
1370 for(it = varlist.Begin(); it != varlist.End(); it++) {
[1291]1371#ifdef SANS_EVOLPLANCK
1372 MuTyV mtv = (*it).second;
1373 value = (string)(mtv);
1374#else
[1262]1375 value = (string)((*it).second.elval);
[1291]1376#endif
[1262]1377 cout << (*it).first << " = " << value << "\n";
1378 }
[165]1379 cout << endl;
1380 }
[353]1381else if (kw == "listalias") {
1382 cout << "PIACmd::Interpret() Alias List , AliasName = Value \n";
[2214]1383 CmdStrList::iterator it;
[353]1384 for(it = mAliases.begin(); it != mAliases.end(); it++)
1385 cout << (*it).first << " = " << (*it).second << "\n";
1386 cout << endl;
1387 }
1388else if (kw == "listcommands") {
[2236]1389 cout << "---- PIACmd::Interpret() Command List ----- \n";
[293]1390 CmdExmap::iterator it;
1391 int kc = 0;
1392 for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
1393 cout << (*it).first << " ";
1394 kc++;
1395 if (kc >= 5) { cout << "\n"; kc = 0; }
1396 }
1397 cout << endl;
1398 }
[2236]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}
[293]1423else if (kw == "traceon") { cout << "PIACmd::Interpret() -> Trace ON mode " << endl; trace = true; }
1424else if (kw == "traceoff") { cout << "PIACmd::Interpret() -> Trace OFF mode " << endl; trace = false; }
[165]1425else if (kw == "timingon") {
[293]1426 cout << "PIACmd::Interpret() -> Timing ON mode " << endl;
1427 if (gltimer) delete gltimer; gltimer = new Timer("PIA-CmdInterpreter "); timing = true;
1428 }
[165]1429else if (kw == "timingoff") {
[293]1430 cout << "PIACmd::Interpret() -> Timing OFF mode " << endl;
1431 if (gltimer) delete gltimer; gltimer = NULL; timing = false;
1432 }
[165]1433else if (kw == "exec") {
[293]1434 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: exec filename" << endl; return(0); }
[349]1435 ExecFile(tokens[0], tokens);
[165]1436 }
1437else if (kw == "shell") {
[293]1438 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: shell cmdline" << endl; return(0); }
[1276]1439 string cmd;
1440 for (int ii=0; ii<tokens.size(); ii++)
1441 cmd += (tokens[ii] + ' ');
1442 system(cmd.c_str());
[165]1443 }
[2203]1444else if (kw == "cshell") {
1445 if(tokens.size()<1) {cout<<"PIACmd::Interpret() Usage: cshell cmdline"<<endl; return(0);}
1446 string cmd="";
1447 for(int ii=0;ii<tokens.size();ii++) cmd+=(tokens[ii]+' ');
1448 CShellExecute(cmd);
1449 }
[1276]1450
[293]1451// Execution d'une commande enregistree
[1268]1452else rc = ExecuteCommand(kw, tokens, toks);
[165]1453
1454if (timing) gltimer->Split();
[333]1455return(rc);
[165]1456}
1457
[333]1458/* --Methode-- */
[2236]1459int PIACmd::ParseLineExecute(string& line, bool qw)
1460 // Si qw == true, on decoupe entre '' ou "" ou espaces
[333]1461{
[1262]1462vector<string> tokens;
[2236]1463string kw, toks;
[333]1464if (line.length() < 1) return(0);
[2236]1465LineToWords(line, kw, tokens, toks, qw);
[1268]1466return(ExecuteCommand(kw, tokens, toks));
[333]1467}
1468
[165]1469/* --Methode-- */
[1268]1470int PIACmd::ExecuteCommand(string& keyw, vector<string>& args, string& toks)
[333]1471{
1472 int rc = -1;
1473 CmdExmap::iterator it = cmdexmap.find(keyw);
1474 if (it == cmdexmap.end()) cout << "No such command : " << keyw << " ! " << endl;
1475 else {
[1268]1476 if ((*it).second.cex) rc = (*it).second.cex->Execute(keyw, args, toks);
[333]1477 else cout << "Dont know how to execute " << keyw << " ? " << endl;
1478 }
1479 return(rc);
1480}
1481
1482/* --Methode-- */
[349]1483int PIACmd::ExecFile(string& file, vector<string>& args)
[165]1484{
[293]1485char line_buff[512];
1486FILE *fip;
[165]1487
[293]1488if ( (fip = fopen(file.c_str(),"r")) == NULL ) {
[384]1489 if (file.find('.') >= file.length()) {
1490 cout << "PIACmd::Exec(): Error opening file " << file << endl;
1491 file += ".pic";
1492 cout << " Trying file " << file << endl;
1493 fip = fopen(file.c_str(),"r");
1494 }
1495 }
1496
1497if(fip == NULL) {
[293]1498 cerr << "PIACmd::Exec() Error opening file " << file << endl;
1499 hist << "##! PIACmd::Exec() Error opening file " << file << endl;
1500 return(0);
[165]1501 }
[349]1502
1503// hist << "### Executing commands from " << file << endl;
1504
[2215]1505PushStack(args);
[293]1506if (trace) {
1507 mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
1508 mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
1509 mImgApp->GetConsole()->AddStr("\n", PIVA_Magenta);
1510 }
[165]1511
[1562]1512bool ohv = histon;
[349]1513histon = false;
[293]1514while (fgets(line_buff,511,fip) != NULL)
1515 {
1516 if (trace) mImgApp->GetConsole()->AddStr(line_buff, PIVA_Magenta);
1517 line_buff[strlen(line_buff)-1] = '\0'; /* LF/CR de la fin */
1518 string line(line_buff);
[1565]1519 if (Interpret(line) == 77777) break;
[165]1520 }
[1562]1521histon = ohv;
[349]1522
1523// hist << "### End of Exec( " << file << " ) " << endl;
[293]1524if (trace) {
1525 mImgApp->GetConsole()->AddStr("### End of Exec( ", PIVA_Magenta);
1526 mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
1527 mImgApp->GetConsole()->AddStr(" ) \n", PIVA_Magenta);
[165]1528 }
1529
[2215]1530PopStack(true);
[2214]1531
[165]1532return(0);
1533}
1534
[2203]1535/* --Methode-- */
1536int PIACmd::CShellExecute(string cmd)
1537{
1538 if(cmd.size()<=0) return -1;
[293]1539
[2203]1540 NamedObjMgr omg;
1541 string fname = omg.GetTmpDir(); fname += "cshell_exec_pia.csh";
1542
1543 string cmdrm = "rm -f " + fname;
1544 system(cmdrm.c_str());
1545
1546 FILE *fip = fopen(fname.c_str(),"w");
1547 if(fip==NULL) {
1548 cout << "PIACmd/CShellExecute_Error: fopen("<<fname<<") failed"<<endl;
1549 return -2;
1550 }
1551 fprintf(fip,"#!/bin/csh\n\n");
1552 fprintf(fip,"%s\n",cmd.c_str());
1553 fprintf(fip,"\nexit 0\n");
1554 fclose(fip);
1555
1556 cmd = "csh "; cmd += fname;
1557 system(cmd.c_str());
1558
1559 system(cmdrm.c_str());
1560
1561 return 0;
1562}
1563
[293]1564static string* videstr = NULL;
1565/* --Methode-- */
1566string& PIACmd::GetUsage(const string& kw)
[165]1567{
[330]1568bool fndok = false;
[293]1569CmdExmap::iterator it = cmdexmap.find(kw);
[330]1570if (it == cmdexmap.end()) {
1571 it = helpexmap.find(kw);
1572 if (it != helpexmap.end()) fndok = true;
[165]1573 }
[330]1574 else fndok = true;
1575if (fndok) return( (*it).second.us );
1576// Keyword pas trouve
1577if (videstr == NULL) videstr = new string("");
1578*videstr = "Nothing known about " + kw + " ?? ";
1579return(*videstr);
1580
[165]1581}
1582
[293]1583/* --Methode-- */
1584void PIACmd::ShowHelpWindow()
[165]1585{
[293]1586helpwin->Show();
[165]1587}
[357]1588
[463]1589/* --Methode-- */
[1251]1590void PIACmd::ShowCxxOptionWindow()
1591{
1592cxxoptwin->Show();
1593}
1594
1595/* --Methode-- */
1596void PIACmd::ShowCxxExecWindow()
1597{
1598cxxexwin->Show();
1599}
1600
1601/* --Methode-- */
[463]1602void PIACmd::HelptoLaTex(string const & fname)
1603{
1604FILE *fip;
1605if ((fip = fopen(fname.c_str(), "w")) == NULL) {
1606 cout << "PIACmd::HelptoLaTex_Error: fopen( " << fname << endl;
1607 return;
1608 }
[357]1609
[463]1610fputs("% ----- Liste des groupes de Help ----- \n",fip);
1611fputs("List of {\\bf piapp} on-line Help groups: \n", fip);
1612fputs("\\begin{itemize} \n",fip);
1613CmdHGroup::iterator it;
1614for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++)
[484]1615 fprintf(fip,"\\item {\\bf %s } (p. \\pageref{%s}) \n",
1616 (*it).first.c_str(), (*it).first.c_str());
[463]1617
1618fputs("\\end{itemize} \n",fip);
1619
[484]1620fputs("\\newpage \n",fip);
1621
1622CmdExmap::iterator ite;
1623fputs("% ----- Liste de toutes les commandes ----- \n",fip);
1624fputs("\\begin{center} \n ", fip);
1625fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Help items \\rule{2cm}{1mm} \n", fip);
1626fputs("\n \n \\vspace{5mm} \n",fip);
1627fputs("\\begin{tabular}{llllll} \n", fip);
1628int kt = 0;
1629for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
1630 fprintf(fip,"%s & p. \\pageref{%s} ", (*ite).first.c_str(), (*ite).first.c_str() );
1631 kt++;
1632 if (kt < 3) fputs(" & ", fip);
1633 else { fputs(" \\\\ \n", fip); kt = 0; }
1634 }
1635if (kt == 1) fputs(" & & & \\\\ \n", fip);
1636else if (kt == 2) fputs(" & \\\\ \n", fip);
1637fputs("\\end{tabular} \n", fip);
1638fputs("\\end{center} \n", fip);
1639fputs("\n \n \\vspace{1cm} \n",fip);
1640
1641fputs("\\begin{center} \n ", fip);
1642fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Commands \\rule{2cm}{1mm} \n", fip);
1643fputs("\n \n \\vspace{5mm} \n",fip);
1644fputs("\\begin{tabular}{llllll} \n", fip);
1645kt = 0;
1646for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
1647 fprintf(fip,"%s & p. \\pageref{%s} ", (*ite).first.c_str(), (*ite).first.c_str() );
1648 kt++;
1649 if (kt < 3) fputs(" & ", fip);
1650 else { fputs(" \\\\ \n", fip); kt = 0; }
1651 }
1652if (kt == 1) fputs(" & & & \\\\ \n", fip);
1653else if (kt == 2) fputs(" & \\\\ \n", fip);
1654fputs("\\end{tabular} \n", fip);
1655fputs("\\end{center} \n", fip);
1656// fputs("\\newline \n",fip);
1657
[463]1658fputs("% ----- Liste des commandes dans chaque groupe ----- \n",fip);
1659fputs("\\newpage \n",fip);
1660int gid;
1661for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
1662 gid = (*it).second;
1663 if (gid == 0) continue;
[484]1664 fprintf(fip,"\\subsection{%s} \\label{%s} \n",
1665 (*it).first.c_str(), (*it).first.c_str());
[463]1666 for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
1667 if ((*ite).second.group != gid) continue;
[484]1668 fprintf(fip,"{ \\Large $ \\star \\star \\star $ } Help item {\\bf \\Large %s } \\label{%s} \n",
1669 (*ite).first.c_str(), (*ite).first.c_str());
[463]1670 fputs("\\begin{verbatim} \n",fip);
1671 fprintf(fip,"%s\n", (*ite).second.us.c_str());
1672 fputs("\\end{verbatim} \n",fip);
1673 }
1674 for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
1675 if ((*ite).second.group != gid) continue;
[484]1676 fprintf(fip,"{ \\Large $ \\star \\star \\star $ } Command {\\bf \\Large %s } \\label{%s} \n",
1677 (*ite).first.c_str(), (*ite).first.c_str());
[463]1678 fputs("\\begin{verbatim} \n",fip);
1679 fprintf(fip,"%s\n", (*ite).second.us.c_str());
1680 fputs("\\end{verbatim} \n",fip);
1681 }
1682}
1683
1684fclose(fip);
1685return;
1686}
1687
1688
1689
Note: See TracBrowser for help on using the repository browser.