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

Last change on this file since 1920 was 1920, checked in by perderos, 24 years ago

1) ajout de commande pour trace de champ de vecteur
2) modif pour compil sous peida (pawexecut.cc) OP 06/03/2002

File size: 34.3 KB
Line 
1#include "piacmd.h"
2#include <stdio.h>
3#include <stdlib.h>
4#include <ctype.h>
5#include <math.h>
6
7#include "basexecut.h"
8
9#include "pdlmgr.h"
10#include "ctimer.h"
11// #include "dlftypes.h"
12
13#include "pistdimgapp.h"
14#include "nobjmgr.h"
15#include "piafitting.h"
16#include "pawexecut.h"
17#include "cxxexecutor.h"
18#include "cxxexecwin.h"
19#include "contmodex.h"
20#include "flowmodex.h"
21
22#include PISTDWDG_H
23#include PILIST_H
24
25// ------------------------------------------------------------
26// Gestion d'une fenetre d'aide interactive
27// Classe PIAHelpWind
28// ------------------------------------------------------------
29
30class PIAHelpWind : public PIWindow {
31public :
32 PIAHelpWind(PIStdImgApp* par, PIACmd* piacmd);
33 virtual ~PIAHelpWind();
34 virtual void Show();
35 virtual void Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
36 inline void AddHelpGroup(const char * hgrp, int gid)
37 { hgrpom->AppendItem(hgrp, 20000+gid); }
38 inline void ClearHelpList()
39 { mNitem=0; hitemlist->DeleteAllItems(); }
40 inline void AddHelpItem(const char * hitem)
41 { mNitem++; hitemlist->AppendItem(hitem, 100+mNitem); }
42protected :
43 PIStdImgApp* dap;
44 PIACmd* piac;
45 int mNitem;
46 PIList* hitemlist;
47 PIOptMenu* hgrpom;
48 PIButton * mBut;
49 PILabel * mLab;
50 PIText* mTxt;
51};
52
53/* --Methode-- */
54PIAHelpWind::PIAHelpWind(PIStdImgApp *par, PIACmd* piacmd)
55 : PIWindow((PIMsgHandler *)par, "Help-PIApp", PIWK_normal, 400, 300, 100, 350)
56{
57dap = par;
58piac = piacmd;
59mNitem = 0;
60SetMsg(77);
61
62int bsx, bsy;
63int tsx, tsy;
64int spx, spy;
65PIApplicationPrefCompSize(bsx, bsy);
66spx = bsx/6; spy = bsy/6;
67tsx = 10*bsx+2*spx; tsy = 7*bsy+3*spy;
68SetSize(tsx,tsy);
69hgrpom = new PIOptMenu(this, "hgrpoptmen", bsx*2.0, bsy, spx/2, spy);
70hgrpom->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
71hitemlist = new PIList(this, "hitemlist", bsx*2.0, tsy-3*spy-bsy, spx/2, 2*spy+bsy);
72hitemlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
73// hitemlist->SetBorderWidth(2);
74mTxt = new PIText(this, "helptext", true, true, bsx*8.0, 6*bsy, bsx*2.0+1.5*spx, spy);
75// mTxt->SetMutiLineMode(true);
76mTxt->SetTextEditable(false);
77mTxt->SetText("");
78mTxt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
79mLab = new PILabel(this, "helpitem", bsx*4, bsy, bsx*2.5+2*spx, tsy-spy-bsy);
80mLab->SetBorderWidth(1);
81mLab->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
82mLab->SetLabel("");
83mBut = new PIButton(this, "Close", 70, bsx, bsy, tsx-bsx*1.5-spx, tsy-spy-bsy);
84mBut->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
85}
86
87/* --Methode-- */
88PIAHelpWind::~PIAHelpWind()
89{
90delete hgrpom;
91delete hitemlist;
92delete mTxt;
93delete mLab;
94delete mBut;
95}
96
97/* --Methode-- */
98void PIAHelpWind::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
99{
100PIMessage um = UserMsg(msg);
101if (((um == 77) && (ModMsg(msg) == PIMsg_Close)) || (um == 70) ) {
102 Hide();
103 return;
104 }
105else if ( (um >= 20000) && (sender == hgrpom)) { // Selection de groupe de Help
106 mTxt->SetText("");
107 mLab->SetLabel("");
108 piac->UpdateHelpList(this, um-20000);
109}
110else if ( (um > 100) && (sender == hitemlist) && (ModMsg(msg) == PIMsg_Select) ) {
111 string s = hitemlist->GetSelectionStr();
112 mTxt->SetText(piac->GetUsage(s));
113 mLab->SetLabel(s);
114 }
115}
116
117/* --Methode-- */
118void PIAHelpWind::Show()
119{
120hgrpom->SetValue(20000); // Groupe All
121mTxt->SetText("");
122mLab->SetLabel("");
123piac->UpdateHelpList(this, 0);
124PIWindow::Show();
125}
126
127// ------------------------------------------------------------
128// Bloc de commandes (Foreach, ...)
129// Classe PIACmdBloc
130// ------------------------------------------------------------
131
132class PIACmdBloc {
133public:
134 enum BType { BT_None, BT_ForeachList, BT_ForeachInt, BT_ForeachFloat };
135
136 PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args);
137 ~PIACmdBloc();
138 inline PIACmdBloc* Parent() { return(parent); }
139 inline bool CheckOK() { return blkok; }
140 inline void AddLine(string& line)
141 { lines.push_back(line); bloclineid.push_back(lines.size()); }
142 inline void AddBloc(PIACmdBloc* blk)
143 { blocs.push_back(blk); bloclineid.push_back(-blocs.size()); }
144 PIACmdBloc* Execute();
145protected:
146 PIACmd* piacmd;
147 PIACmdBloc* parent;
148 bool blkok; // true -> block OK
149 BType typ; // foreach , integer loop, float loop, test
150 string varname;
151 vector<string> strlist;
152 vector<string> lines;
153 vector<PIACmdBloc *> blocs;
154 vector<int> bloclineid;
155 int i1,i2,di;
156 float f1,f2,df;
157};
158
159/* --Methode-- */
160PIACmdBloc::PIACmdBloc(PIACmd* piac, PIACmdBloc* par, string& kw, vector<string>& args)
161{
162piacmd = piac;
163parent = par;
164blkok = false;
165typ = BT_None;
166i1 = 0; i2 = -1; di = 1;
167f1 = 0.; f2 = -1.; df = 1.;
168if ((args.size() < 2) || !isalpha((int)args[0][0]) ) return;
169if ((kw != "foreach") && (kw != "for")) return;
170varname = args[0]; // $CHECK$ Variable name should be checked
171//if (isalpha((int)args[1][0]) ) { This is a foreach bloc with string list
172if (kw == "foreach" ) { // This is a foreach bloc with string list
173 for(int kk=1; kk<args.size(); kk++) strlist.push_back(args[kk]);
174 typ = BT_ForeachList;
175 blkok = true;
176 }
177else { // This is an integer or float loop
178 size_t l = args[1].length();
179 size_t p = args[1].find(':');
180 size_t pp = args[1].find('.');
181 bool fl = (pp < l) ? true : false; // Float loop or integer loop
182 if (p >= l) return; // Syntaxe error
183 string a1 = args[1].substr(0, p);
184 string aa = args[1].substr(p+1);
185 p = aa.find(':');
186 string a2, a3;
187 bool hasa3 = false;
188 if (p < aa.length() ) {
189 a2 = aa.substr(0,p);
190 a3 = aa.substr(p+1);
191 hasa3 = true;
192 }
193 else a2 = aa;
194 if (fl) {
195 typ = BT_ForeachFloat;
196 blkok = true;
197 f1 = atof(a1.c_str());
198 f2 = atof(a2.c_str());
199 if (hasa3) df = atof(a3.c_str());
200 else df = 1.;
201 }
202 else {
203 typ = BT_ForeachInt;
204 blkok = true;
205 i1 = atoi(a1.c_str());
206 i2 = atoi(a2.c_str());
207 if (hasa3) di = atoi(a3.c_str());
208 else di = 1;
209 }
210 }
211}
212
213/* --Methode-- */
214PIACmdBloc::~PIACmdBloc()
215{
216for(int k=0; k<blocs.size(); k++) delete blocs[k];
217}
218
219/* --Methode-- */
220PIACmdBloc* PIACmdBloc::Execute()
221{
222// cout << " DBG * PIACmdBloc::Execute() " << typ << " - " << bloclineid.size() <<
223// " I1,I2=" << i1 << " , " << i2 << " , " << di << endl;
224string cmd;
225int k=0;
226int kj=0;
227int kk=0;
228char buff[32];
229if (typ == BT_ForeachList) // foreach string loop
230 for(k=0; k<strlist.size(); k++) {
231 cmd = "set " + varname + " '" + strlist[k] + "'";
232 piacmd->Interpret(cmd);
233 for(kj=0; kj<bloclineid.size(); kj++) {
234 kk = bloclineid[kj];
235 if (kk > 0) piacmd->Interpret(lines[kk-1]);
236 else blocs[-kk-1]->Execute();
237 }
238 }
239else if (typ == BT_ForeachInt) // Integer loop
240 for(int i=i1; i<i2; i+=di) {
241 k++;
242 if (++k > 9999) {
243 cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
244 break;
245 }
246 sprintf(buff, " %d", i);
247 cmd = "set " + varname + buff;
248 piacmd->Interpret(cmd);
249 for(kj=0; kj<bloclineid.size(); kj++) {
250 kk = bloclineid[kj];
251 if (kk > 0) piacmd->Interpret(lines[kk-1]);
252 else blocs[-kk-1]->Execute();
253 }
254 }
255else if (typ == BT_ForeachFloat) // float loop
256 for(float f=f1; f<f2; f+=df) {
257 k++;
258 if (++k > 9999) {
259 cout << ">>> Maximum PIACmdBloc loop limit (9999) -> break " << endl;
260 break;
261 }
262 sprintf(buff, " %g", f);
263 cmd = "set " + varname + buff;
264 piacmd->Interpret(cmd);
265 for(kj=0; kj<bloclineid.size(); kj++) {
266 kk = bloclineid[kj];
267 if (kk > 0) piacmd->Interpret(lines[kk-1]);
268 else blocs[-kk-1]->Execute();
269 }
270 }
271
272return(parent);
273}
274
275// ------------------------------------------------------------
276// Classe PIACmd
277// ------------------------------------------------------------
278
279static PIACmd* curpiacmd = NULL;
280/* --Methode-- */
281PIACmd::PIACmd(NamedObjMgr* omg, PIStdImgApp* app)
282{
283mObjMgr = omg;
284mImgApp = app;
285system("cp history.pic hisold.pic");
286hist.open("history.pic");
287histon = true;
288trace = false; timing = false;
289gltimer = NULL;
290curblk = NULL;
291felevel = 0;
292mulinecmd = "";
293mulinefg = false;
294
295cmdhgrp["All"] = 0;
296cmdgrpid = 1;
297cmdhgrp["Commands"] = 1;
298helpwin = new PIAHelpWind(app, this);
299helpwin->AddHelpGroup("All", 0);
300helpwin->AddHelpGroup("Commands", 1);
301
302string kw = "piacmd";
303string usage;
304usage = ">>> (piacmd) Interpreter's keywords : \n";
305usage += " > set varname string # To set a variable, $varname \n";
306usage += " > get newvarname varname # To set a newvariable, equal to $varname \n";
307usage += " > setol varname patt # Fills varname with object list \n";
308usage += " > unset varname # clear variable definition \n";
309usage += " > echo string # output string \n";
310usage += " > alias name string # define a command alias \n";
311usage += " > readstdin varname # reads a line from stdin into $varname \n";
312usage += " > foreach varname string-list # Loop \n";
313usage += " > for varname i1:i2[:di] # Integer loop \n";
314usage += " > for varname f1:f2[:df] # Float loop \n";
315usage += " > end # end loops \n";
316usage += " > if test then # Conditional test : a == != < > <= >= b \n";
317usage += " > else # Conditional \n";
318usage += " > endif # End of conditional if bloc \n";
319usage += " > break # Delete (clears) all test and loop blocs \n";
320usage += " > return # Stops command execution from a file \n";
321usage += " > listvars # List of variable names and values \n";
322usage += " > listalias # List of alias names and values \n";
323usage += " > listcommands # List of all known commands \n";
324usage += " > exec filename # Execute commands from file \n";
325usage += " > shell comand_string # Execute shell command \n";
326usage += " > help <command_name> # <command_name> usage info \n";
327usage += " > helpwindow # Displays help window \n";
328usage += " > timingon timingoff traceon traceoff \n";
329string grp = "Commands";
330RegisterHelp(kw, usage, grp);
331
332basexec = new PIABaseExecutor(this, omg, app);
333fitexec = new PIAFitter(this, app);
334pawexec = new PAWExecutor(this, app);
335CxxExecutor * cxxe = new CxxExecutor(this, app);
336cxxexec = cxxe;
337
338ContModExecutor *cntxx = new ContModExecutor(this, app);//_OP_
339cntexec = cntxx; //_OP_
340FlowModExecutor *flwxx = new FlowModExecutor(this, app);//_OP_
341flwexec = flwxx; //_OP_
342
343cxxoptwin = new CxxOptionWind(app, cxxe);
344cxxexwin = new CxxExecWind(app, cxxe);
345
346AddInterpreter(this);
347curcmdi = this;
348}
349
350/* --Methode-- */
351PIACmd::~PIACmd()
352{
353hist.close();
354if (gltimer) { delete gltimer; gltimer = NULL; }
355Modmap::iterator it;
356for(it = modmap.begin(); it != modmap.end(); it++) {
357 string name = (*it).first + "_end";
358 DlModuleInitEndFunction fend = (*it).second->GetFunction(name);
359 if (fend) fend();
360 delete (*it).second;
361 }
362delete helpwin;
363delete cxxexwin;
364delete cxxoptwin;
365if (curpiacmd == this) curpiacmd = NULL;
366delete basexec;
367delete fitexec;
368delete pawexec;
369delete cxxexec;
370}
371
372/* --Methode-- */
373PIACmd* PIACmd::GetInterpreter()
374{
375return(curpiacmd);
376}
377
378/* --Methode-- */
379string PIACmd::Name()
380{
381return("piacmd");
382}
383
384/* --Methode-- */
385void PIACmd::RegisterCommand(string& keyw, string& usage, CmdExecutor * ce, string grp)
386{
387if (!ce) {
388 RegisterHelp(keyw, usage, grp);
389 return;
390 }
391int gid = CheckHelpGrp(grp);
392cmdex cme;
393cme.group = gid;
394cme.us = usage;
395cme.cex = ce;
396cmdexmap[keyw] = cme;
397}
398
399/* --Methode-- */
400void PIACmd::RegisterHelp(string& keyw, string& usage, string& grp)
401{
402int gid = CheckHelpGrp(grp);
403cmdex cme;
404cme.group = gid;
405cme.us = usage;
406cme.cex = NULL;
407helpexmap[keyw] = cme;
408}
409
410/* --Methode-- */
411int PIACmd::CheckHelpGrp(string& grp)
412{
413int gid=0;
414CmdHGroup::iterator it = cmdhgrp.find(grp);
415if (it == cmdhgrp.end()) {
416 cmdgrpid++; gid = cmdgrpid;
417 cmdhgrp[grp] = gid;
418 helpwin->AddHelpGroup(grp.c_str(), gid);
419 }
420else gid = (*it).second;
421return(gid);
422}
423
424/* --Methode-- */
425void PIACmd::UpdateHelpList(PIAHelpWind* hw, int gid)
426{
427helpwin->ClearHelpList();
428CmdExmap::iterator it;
429for(it = helpexmap.begin(); it != helpexmap.end(); it++) {
430 if ( (gid != 0) && ((*it).second.group != gid) ) continue;
431 helpwin->AddHelpItem((*it).first.c_str());
432 }
433for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
434 if ( (gid != 0) && ((*it).second.group != gid) ) continue;
435 helpwin->AddHelpItem((*it).first.c_str());
436 }
437}
438
439/* --Methode-- */
440void PIACmd::LoadModule(string& fnameso, string& name)
441{
442PDynLinkMgr * dynlink = new PDynLinkMgr(fnameso, false);
443if (dynlink == NULL) {
444 cerr << "PIACmd/LoadModule_Error: Pb opening SO " << fnameso << endl;
445 return;
446 }
447string fname = name + "_init";
448DlModuleInitEndFunction finit = dynlink->GetFunction(fname);
449if (!finit) {
450 cerr << "PIACmd/LoadModule_Error: Pb linking " << fname << endl;
451 return;
452 }
453cout << "PIACmd/LoadModule_Info: Initialisation module" << name
454 << " " << fname << "() ..." << endl;
455finit();
456modmap[name] = dynlink;
457return;
458}
459
460/* --Methode-- */
461void PIACmd::AddInterpreter(CmdInterpreter * cl)
462{
463if (!cl) return;
464interpmap[cl->Name()] = cl;}
465
466/* --Methode-- */
467void PIACmd::SelInterpreter(string& name)
468{
469InterpMap::iterator it = interpmap.find(name);
470if (it == interpmap.end()) return;
471curcmdi = (*it).second;
472}
473
474
475
476/* Fonction */
477static string GetStringFrStdin(PIACmd* piac)
478{
479PIStdImgApp* piapp = piac->GetImgApp();
480if (piapp) {
481 PIBaseWdg* wdg = piapp->CurrentBaseWdg();
482 if (wdg) wdg->Refresh();
483#ifndef __mac__
484 /* On vide le buffer X-Window */
485 XSync(PIXDisplay(),False);
486#endif
487}
488char buff[128];
489fgets(buff, 128, stdin);
490buff[127] = '\0';
491return((string)buff);
492}
493
494/* --Methode-- */
495int PIACmd::Interpret(string& s)
496{
497int rc = 0;
498NamedObjMgr omg;
499
500// On saute de commandes vides
501size_t l;
502l = s.length();
503if (l < 1) return(0);
504
505// On enregistre les commandes
506if (histon) hist << s << endl;
507
508if (s[0] == '#') return(0); // si c'est un commentaire
509
510// Logique de gestion des lignes suite
511// un \ en derniere position indique la presence d'une ligne suite
512size_t lnb = s.find_last_not_of(' ');
513if (s[lnb] == '\\' ) { // Lignes suite ...
514 mulinefg = true;
515 mulinecmd += s.substr(0,lnb);
516 mImgApp->GetConsole()->SetPrompt("...? ");
517 return(0);
518}
519
520if (mulinefg) { // Il y avait des lignes suite
521 s = mulinecmd + s;
522 mulinecmd = "";
523 mulinefg = false;
524 const char * rprompt = (curblk == NULL) ? "Cmd> " : "for...? ";
525 mImgApp->GetConsole()->SetPrompt(rprompt);
526}
527
528// Removing leading blanks
529size_t p,q;
530
531p=s.find_first_not_of(" \t");
532if (p < l) s = s.substr(p);
533
534// >>>> Substitution d'alias (1er mot)
535CmdVarList::iterator it;
536p = 0;
537q = s.find_first_of(" \t");
538l = s.length();
539string w1 = (q < l) ? s.substr(p,q-p) : s.substr(p);
540it = mAliases.find(w1);
541if (it != mAliases.end()) {
542 s = (q < l) ? ((*it).second + s.substr(q)) : (*it).second ;
543 l = s.length();
544 p=s.find_first_not_of(" \t");
545 if (p < l) s = s.substr(p);
546 p = 0;
547 q = s.find_first_of(" ");
548 }
549
550// >>>> Separating keyword
551string toks,kw;
552if (q < l)
553 { kw = s.substr(p,q-p); toks = s.substr(q, l-q); }
554else { kw = s.substr(p,l-p); toks = ""; }
555
556// les mot-cle end else endif doivent etre le seul mot de la ligne
557if ( (kw == "end") || (kw == "else") || (kw == "endif") ) {
558 size_t ltk = toks.length();
559 if (toks.find_first_not_of(" \t") < ltk) {
560 cerr << "PIACmd::Interpret()/syntax error near end else endif \n"
561 << "line: " << s << endl;
562 return(1);
563 }
564}
565
566if (kw == "break") {
567 PIACmdBloc* curb = curblk;
568 while (curb) {
569 PIACmdBloc* dblk = curb;
570 curb = curb->Parent();
571 delete dblk;
572 }
573 testresult.clear();
574 return(0);
575}
576else if (kw == "return") return(77777);
577
578// On verifie si nous sommes dans un bloc (for , foreach)
579if (curblk != NULL) { // On est dans un bloc
580 if ( (kw == "for") || (kw == "foreach")) felevel++;
581 else if (kw == "end") felevel--;
582 if (felevel == 0) { // Il faut executer le bloc
583 PIACmdBloc* curb = curblk;
584 curblk = curb->Parent();
585 mImgApp->GetConsole()->SetPrompt("Cmd> ");
586 // cout << " *DBG* Executing bloc " << endl;
587 bool ohv = histon;
588 histon = false;
589 curb->Execute();
590 histon = ohv;
591 }
592 else curblk->AddLine(s);
593 return(0);
594}
595else if (kw == "end") {
596 cerr << "PIACmd::Interpret()/syntax error - end outside for/foreach bloc \n"
597 << "line: " << s << endl;
598 return(1);
599}
600
601// Sommes-nous dans un bloc de test if then else
602if (testresult.size() > 0) { // Nous sommes ds un bloc if
603 if (kw == "else") {
604 if ((*tresit) & 2) {
605 cerr << "PIACmd::Interpret()/syntax error - multiple else in if bloc \n"
606 << "line: " << s << endl;
607 return(1);
608 }
609 else {
610 const char * npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
611 mImgApp->GetConsole()->SetPrompt(npr);
612 (*tresit) |= 2;
613 return(0);
614 }
615 }
616 else if (kw == "endif") {
617 list<char>::iterator dbit = tresit;
618 tresit--;
619 testresult.erase(dbit);
620 const char * npr = "Cmd> ";
621 if (testresult.size() > 1) {
622 if (!((*tresit)&2))
623 npr = ((*tresit)&1) ? "if-T> " : "if-F> ";
624 else
625 npr = ((*tresit)&1) ? "else-F> " : "else-T> ";
626 }
627 mImgApp->GetConsole()->SetPrompt(npr);
628 return(0);
629 }
630}
631else if ((kw == "else") || (kw == "endif")) {
632 cerr << "PIACmd::Interpret()/syntax error - else,endif outside if bloc \n"
633 << "line: " << s << endl;
634 return(1);
635}
636
637bool fgcont = true;
638if (testresult.size() > 0) { // Resultat de if ou else
639 list<char>::iterator it;
640 for(it=testresult.begin(); it!=testresult.end(); it++) {
641 // Si on n'est pas ds le else et le if est faux
642 if ( !((*it)&2) && !((*it)&1) ) fgcont = false;
643 // Si on est ds else et le if etait vrai !
644 if ( ((*it)&2) && ((*it)&1) ) fgcont = false;
645 if (!fgcont) break;
646 }
647}
648
649if ((!fgcont) && (kw != "if")) return(0);
650
651
652// Nous ne sommes donc pas dans un bloc .... Substitution de variables
653string s2;
654int rcs ;
655// Execution de code C++
656
657if (s[0] == '@') {
658 CxxExecutor * cxxe = dynamic_cast<CxxExecutor *>(cxxexec);
659 if (cxxe == NULL) {
660 cerr << "PIACmd::Interpret() - BUG !!! Not a CxxExecutor " << endl;
661 return(99);
662 }
663 // Sans substitution des variables $
664 if (s[1] == '@') return(cxxe->ExecuteCXX(s.substr(2)));
665 else { // AVEC substitution des variables $
666 rcs = SubstituteVars(s, s2);
667 if (rcs) return(rcs);
668 return(cxxe->ExecuteCXX(s2.substr(1)));
669 }
670}
671
672
673rcs = SubstituteVars(s, s2);
674if (rcs) return(rcs);
675
676// >>>> Separating keyword and tokens
677vector<string> tokens;
678
679q = s2.find(' ');
680l = s2.length();
681if (q < l)
682 { kw = s2.substr(0,q); toks = s2.substr(q, l-q); }
683else { kw = s2; toks = ""; }
684
685q = 0;
686while (q < l) {
687 p = toks.find_first_not_of(" \t",q+1); // au debut d'un token
688 if (p>=l) break;
689 if ( (toks[p] == '\'') || (toks[p] == '"') ) {
690 q = toks.find(toks[p],p+1);
691 if (q>=l) {
692 cerr << "PIACmd::Interpret()/Syntax Error - Unbalenced quotes " << toks[p] << '.' << endl;
693 return(2);
694 }
695 p++;
696 }
697 else {
698 q = toks.find_first_of(" \t",p); // la fin du token;
699 }
700 string token = toks.substr(p,q-p);
701 tokens.push_back(token);
702 }
703
704
705// Si c'est un for/foreach, on cree un nouveau bloc
706if ((kw == "foreach") || (kw == "for")) {
707 // cout << " *DBG* We got a foreach... " << endl;
708 PIACmdBloc* bloc = new PIACmdBloc(this, curblk, kw, tokens);
709 if (!bloc->CheckOK()) {
710 cerr << "PIACmd::Interpret() for/foreach syntax Error ! " << endl;
711 delete bloc;
712 return(1);
713 }
714 felevel++;
715 if (curblk) curblk->AddBloc(bloc);
716 else mImgApp->GetConsole()->SetPrompt("for...> ");
717 curblk = bloc;
718 // cout << " *DBG* New Bloc created ... " << endl;
719 return(0);
720 }
721else if (kw == "if") { // Un test if
722 bool restst = true;
723 int rct = EvaluateTest(tokens, s, restst);
724 if (rct) {
725 cerr << "PIACmd::Interpret() if syntax Error ! " << endl;
726 return(1);
727 }
728 char res_tst = (restst) ? 1 : 0;
729 testresult.push_back(res_tst);
730 if (testresult.size() == 1) tresit = testresult.begin();
731 else tresit++;
732 const char * npr = (restst) ? "if-T> " : "if-F> ";
733 mImgApp->GetConsole()->SetPrompt(npr);
734}
735// Execution de commandes
736else rc = ExecuteCommandLine(kw, tokens, toks);
737return(rc);
738
739// cout << "PIACmd::Do() DBG KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
740// for(int ii=0; ii<tokens.size(); ii++)
741// cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
742
743}
744
745/* --Methode-- */
746int PIACmd::SubstituteVars(string & s, string & s2)
747// Variable substitution
748{
749NamedObjMgr omg;
750
751size_t p,q,q2,l;
752
753s2="";
754p = 0;
755l = s.length();
756string vn;
757while (p < l) {
758 q = s.find('$',p);
759 if (q > l) break;
760 q2 = s.find('\'',p);
761 if ((q2 < l) && (q2 < q)) { // On saute la chaine delimitee par ' '
762 q2 = s.find('\'',q2+1);
763 if (q2 >= l) {
764 cerr << " Syntax error - Unbalenced quotes !!! " << endl;
765 return(1);
766 }
767 s2 += s.substr(p, q2-p+1);
768 p = q2+1; continue;
769 }
770 // cout << "DBG: " << s2 << " p= " << p << " q= " << q << " L= " << l << endl;
771 if ((q>0) && (s[q-1] == '\\')) { // Escape character \$
772 s2 += (s.substr(p,q-1-p) + '$') ; p = q+1;
773 continue;
774 }
775 if (q >= l-1) {
776 cerr << " Syntax error - line ending with $ !!! " << endl;
777 return(2);
778 }
779 vn = "";
780 if ( s[q+1] == '{' ) { // Variable in the form ${name}
781 q2 = s.find('}',q+1);
782 if (q2 >= l) {
783 cerr << " Syntax error - Unbalenced brace {} !!! " << endl;
784 return(3);
785 }
786 vn = s.substr(q+2,q2-q-2);
787 q2++;
788 }
789 else if ( s[q+1] == '[' ) { // Variable in the form $[varname] -> This is $$varname
790 q2 = s.find(']',q+1);
791 if (q2 >= l) {
792 cerr << " Syntax error - Unbalenced brace [] !!! " << endl;
793 return(4);
794 }
795 vn = s.substr(q+2,q2-q-2);
796 if ( (vn.length() < 1) || (!omg.HasVar(vn)) ) {
797 cerr << " Error: Undefined variable " << vn << " ! " << endl;
798 return(5);
799 }
800 vn = omg.GetVar(vn);
801 q2++;
802 }
803 else {
804 q2 = s.find_first_of(" .:+-*/,[](){}&|!$\"'",q+1);
805 if (q2 > l) q2 = l;
806 vn = s.substr(q+1, q2-q-1);
807 }
808 if ( (vn.length() < 1) || (!omg.HasVar(vn)) ) {
809 cerr << " Error: Undefined variable " << vn << " ! " << endl;
810 return(5);
811 }
812 s2 += (s.substr(p, q-p) + omg.GetVar(vn));
813 p = q2;
814 }
815if (p < l) s2 += s.substr(p);
816
817p = s2.find_first_not_of(" \t");
818if (p < l) s2 = s2.substr(p);
819
820return(0);
821}
822
823/* --Methode-- */
824int PIACmd::EvaluateTest(vector<string> & args, string & line, bool & res)
825{
826 res = true;
827 if ((args.size() < 4) || (args[3] != "then")) return(1);
828 if (args[1] == "==") res = (args[0] == args[2]);
829 else if (args[1] == "!=") res = (args[0] != args[2]);
830 else if (args[1] == "<")
831 res = (atof(args[0].c_str()) < atof(args[2].c_str()));
832 else if (args[1] == ">")
833 res = (atof(args[0].c_str()) > atof(args[2].c_str()));
834 else if (args[1] == "<=")
835 res = (atof(args[0].c_str()) <= atof(args[2].c_str()));
836 else if (args[1] == ">=")
837 res = (atof(args[0].c_str()) >= atof(args[2].c_str()));
838 else return(2);
839 return(0);
840}
841
842/* --Methode-- */
843int PIACmd::ExecuteCommandLine(string & kw, vector<string> & tokens, string & toks)
844{
845int rc = 0;
846NamedObjMgr omg;
847
848// >>>>>>>>>>> Commande d'interpreteur
849if (kw == "helpwindow") ShowHelpWindow();
850else if (kw == "help") {
851 if (tokens.size() > 0) cout << GetUsage(tokens[0]) << endl;
852 else {
853 string kwh = "piacmd";
854 cout << GetUsage(kwh) << endl;
855 }
856 }
857
858else if (kw == "set") {
859 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: set varname string" << endl; return(0); }
860 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
861 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
862 return(0);
863 }
864 // string xx = tokens[1];
865 // for (int kk=2; kk<tokens.size(); kk++) xx += (' ' + tokens[kk] );
866 omg.SetVar(tokens[0], tokens[1]);
867 }
868
869else if (kw == "getvar") {
870 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: getvar newvarname varname" << endl; return(0); }
871 if (!omg.HasVar(tokens[1])) {
872 cerr << "Error - No " << tokens[1] << " Variable " << endl;
873 return(0);
874 }
875 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
876 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
877 return(0);
878 }
879 omg.SetVar(tokens[0], omg.GetVar(tokens[1]) );
880 }
881
882else if (kw == "alias") {
883 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: alias aliasname string" << endl; return(0); }
884 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
885 cerr << "PIACmd::Interpret()/Error alias name should start with alphabetic" << endl;
886 return(0);
887 }
888 string xx = tokens[1];
889 for (int kk=2; kk<tokens.size(); kk++) xx += (' ' + tokens[kk]);
890 mAliases[tokens[0]] = xx;
891 }
892
893else if (kw == "setol") {
894 if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: setol varname objnamepattern" << endl; return(0); }
895 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
896 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
897 return(0);
898 }
899 vector<string> ol;
900 mObjMgr->GetObjList(tokens[1], ol);
901 string vol;
902 if (ol.size() < 1) vol = "";
903 else {
904 vol = ol[0];
905 for (int kk=1; kk<ol.size(); kk++) vol += (' ' + ol[kk]);
906 }
907 omg.SetVar(tokens[0], vol);
908 }
909else if (kw == "unset") {
910 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: unset varname" << endl; return(0); }
911 if (omg.HasVar(tokens[0])) omg.DeleteVar(tokens[0]) ;
912 else cerr << "PIACmd::Interpret() No variable with name " << tokens[0] << endl;
913 }
914else if (kw == "echo") {
915 for (int ii=0; ii<tokens.size(); ii++)
916 cout << tokens[ii] << " " ;
917 cout << endl;
918 }
919else if (kw == "readstdin") {
920 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: readstdin varname" << endl; return(0); }
921 if ((tokens[0].length() < 1) || !isalpha((int)tokens[0][0]) ) {
922 cerr << "PIACmd::Interpret()/Error Variable name should start with alphabetic" << endl;
923 return(0);
924 }
925 mImgApp->GetConsole()->AddStr(">>> Reading From StdIn \n", PIVA_Magenta);
926 cout << tokens[0] << " ? " << endl;
927 omg.SetVar(tokens[0], GetStringFrStdin(this) );
928 }
929
930else if (kw == "listvars") {
931 cout << "PIACmd::Interpret() Variable List , VarName = Value \n";
932 DVList& varlist = omg.GetVarList();
933 DVList::ValList::const_iterator it;
934 string value;
935 for(it = varlist.Begin(); it != varlist.End(); it++) {
936#ifdef SANS_EVOLPLANCK
937 MuTyV mtv = (*it).second;
938 value = (string)(mtv);
939#else
940 value = (string)((*it).second.elval);
941#endif
942 cout << (*it).first << " = " << value << "\n";
943 }
944 cout << endl;
945 }
946else if (kw == "listalias") {
947 cout << "PIACmd::Interpret() Alias List , AliasName = Value \n";
948 CmdVarList::iterator it;
949 for(it = mAliases.begin(); it != mAliases.end(); it++)
950 cout << (*it).first << " = " << (*it).second << "\n";
951 cout << endl;
952 }
953else if (kw == "listcommands") {
954 cout << "---- PIACmd::Interpret() Command Variable List ----- \n";
955 CmdExmap::iterator it;
956 int kc = 0;
957 for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
958 cout << (*it).first << " ";
959 kc++;
960 if (kc >= 5) { cout << "\n"; kc = 0; }
961 }
962 cout << endl;
963 }
964else if (kw == "traceon") { cout << "PIACmd::Interpret() -> Trace ON mode " << endl; trace = true; }
965else if (kw == "traceoff") { cout << "PIACmd::Interpret() -> Trace OFF mode " << endl; trace = false; }
966else if (kw == "timingon") {
967 cout << "PIACmd::Interpret() -> Timing ON mode " << endl;
968 if (gltimer) delete gltimer; gltimer = new Timer("PIA-CmdInterpreter "); timing = true;
969 }
970else if (kw == "timingoff") {
971 cout << "PIACmd::Interpret() -> Timing OFF mode " << endl;
972 if (gltimer) delete gltimer; gltimer = NULL; timing = false;
973 }
974else if (kw == "exec") {
975 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: exec filename" << endl; return(0); }
976 ExecFile(tokens[0], tokens);
977 }
978else if (kw == "shell") {
979 if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: shell cmdline" << endl; return(0); }
980 string cmd;
981 for (int ii=0; ii<tokens.size(); ii++)
982 cmd += (tokens[ii] + ' ');
983 system(cmd.c_str());
984 }
985
986// Execution d'une commande enregistree
987else rc = ExecuteCommand(kw, tokens, toks);
988
989if (timing) gltimer->Split();
990return(rc);
991}
992
993/* --Methode-- */
994int PIACmd::ParseLineExecute(string& line)
995{
996vector<string> tokens;
997
998if (line.length() < 1) return(0);
999
1000string toks,kw;
1001size_t p = line.find_first_not_of(" ");
1002line = line.substr(p);
1003p = 0;
1004size_t q = line.find_first_of(" ");
1005size_t l = line.length();
1006
1007if (q < l)
1008 { kw = line.substr(p,q-p); toks = line.substr(q, l-q); }
1009else { kw = line.substr(p,l-p); toks = ""; }
1010
1011q = 0;
1012while (q < l) {
1013 p = toks.find_first_not_of(" ",q+1); // au debut d'un token
1014 if (p>=l) break;
1015 q = toks.find_first_of(" ",p); // la fin du token;
1016 string token = toks.substr(p,q-p);
1017 tokens.push_back(token);
1018 }
1019
1020return(ExecuteCommand(kw, tokens, toks));
1021}
1022
1023/* --Methode-- */
1024int PIACmd::ExecuteCommand(string& keyw, vector<string>& args, string& toks)
1025{
1026 int rc = -1;
1027 CmdExmap::iterator it = cmdexmap.find(keyw);
1028 if (it == cmdexmap.end()) cout << "No such command : " << keyw << " ! " << endl;
1029 else {
1030 if ((*it).second.cex) rc = (*it).second.cex->Execute(keyw, args, toks);
1031 else cout << "Dont know how to execute " << keyw << " ? " << endl;
1032 }
1033 return(rc);
1034}
1035
1036/* --Methode-- */
1037int PIACmd::ExecFile(string& file, vector<string>& args)
1038{
1039char line_buff[512];
1040FILE *fip;
1041
1042if ( (fip = fopen(file.c_str(),"r")) == NULL ) {
1043 if (file.find('.') >= file.length()) {
1044 cout << "PIACmd::Exec(): Error opening file " << file << endl;
1045 file += ".pic";
1046 cout << " Trying file " << file << endl;
1047 fip = fopen(file.c_str(),"r");
1048 }
1049 }
1050
1051if(fip == NULL) {
1052 cerr << "PIACmd::Exec() Error opening file " << file << endl;
1053 hist << "##! PIACmd::Exec() Error opening file " << file << endl;
1054 return(0);
1055 }
1056
1057// hist << "### Executing commands from " << file << endl;
1058
1059// Setting $0 ... $99 variables
1060int k;
1061char buff[32];
1062// First, we clear all previous values
1063NamedObjMgr omg;
1064string vn="#";
1065omg.DeleteVar(vn);
1066for(k=0; k<99; k++) {
1067 sprintf(buff,"%d",k);
1068 vn = buff;
1069 omg.DeleteVar(vn);
1070 }
1071// We then set them
1072string vval;
1073vn="#";
1074sprintf(buff,"%d",(int)args.size());
1075omg.SetVar(vn, buff);
1076for(k=0; k<args.size(); k++) {
1077 sprintf(buff,"%d",k);
1078 vn = buff;
1079 omg.SetVar(vn, args[k]);
1080 }
1081
1082if (trace) {
1083 mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
1084 mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
1085 mImgApp->GetConsole()->AddStr("\n", PIVA_Magenta);
1086 }
1087
1088bool ohv = histon;
1089histon = false;
1090while (fgets(line_buff,511,fip) != NULL)
1091 {
1092 if (trace) mImgApp->GetConsole()->AddStr(line_buff, PIVA_Magenta);
1093 line_buff[strlen(line_buff)-1] = '\0'; /* LF/CR de la fin */
1094 string line(line_buff);
1095 if (Interpret(line) == 77777) break;
1096 }
1097histon = ohv;
1098
1099// hist << "### End of Exec( " << file << " ) " << endl;
1100if (trace) {
1101 mImgApp->GetConsole()->AddStr("### End of Exec( ", PIVA_Magenta);
1102 mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
1103 mImgApp->GetConsole()->AddStr(" ) \n", PIVA_Magenta);
1104 }
1105
1106return(0);
1107}
1108
1109
1110static string* videstr = NULL;
1111/* --Methode-- */
1112string& PIACmd::GetUsage(const string& kw)
1113{
1114bool fndok = false;
1115CmdExmap::iterator it = cmdexmap.find(kw);
1116if (it == cmdexmap.end()) {
1117 it = helpexmap.find(kw);
1118 if (it != helpexmap.end()) fndok = true;
1119 }
1120 else fndok = true;
1121if (fndok) return( (*it).second.us );
1122// Keyword pas trouve
1123if (videstr == NULL) videstr = new string("");
1124*videstr = "Nothing known about " + kw + " ?? ";
1125return(*videstr);
1126
1127}
1128
1129/* --Methode-- */
1130void PIACmd::ShowHelpWindow()
1131{
1132helpwin->Show();
1133}
1134
1135/* --Methode-- */
1136void PIACmd::ShowCxxOptionWindow()
1137{
1138cxxoptwin->Show();
1139}
1140
1141/* --Methode-- */
1142void PIACmd::ShowCxxExecWindow()
1143{
1144cxxexwin->Show();
1145}
1146
1147/* --Methode-- */
1148void PIACmd::HelptoLaTex(string const & fname)
1149{
1150FILE *fip;
1151if ((fip = fopen(fname.c_str(), "w")) == NULL) {
1152 cout << "PIACmd::HelptoLaTex_Error: fopen( " << fname << endl;
1153 return;
1154 }
1155
1156fputs("% ----- Liste des groupes de Help ----- \n",fip);
1157fputs("List of {\\bf piapp} on-line Help groups: \n", fip);
1158fputs("\\begin{itemize} \n",fip);
1159CmdHGroup::iterator it;
1160for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++)
1161 fprintf(fip,"\\item {\\bf %s } (p. \\pageref{%s}) \n",
1162 (*it).first.c_str(), (*it).first.c_str());
1163
1164fputs("\\end{itemize} \n",fip);
1165
1166fputs("\\newpage \n",fip);
1167
1168CmdExmap::iterator ite;
1169fputs("% ----- Liste de toutes les commandes ----- \n",fip);
1170fputs("\\begin{center} \n ", fip);
1171fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Help items \\rule{2cm}{1mm} \n", fip);
1172fputs("\n \n \\vspace{5mm} \n",fip);
1173fputs("\\begin{tabular}{llllll} \n", fip);
1174int kt = 0;
1175for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
1176 fprintf(fip,"%s & p. \\pageref{%s} ", (*ite).first.c_str(), (*ite).first.c_str() );
1177 kt++;
1178 if (kt < 3) fputs(" & ", fip);
1179 else { fputs(" \\\\ \n", fip); kt = 0; }
1180 }
1181if (kt == 1) fputs(" & & & \\\\ \n", fip);
1182else if (kt == 2) fputs(" & \\\\ \n", fip);
1183fputs("\\end{tabular} \n", fip);
1184fputs("\\end{center} \n", fip);
1185fputs("\n \n \\vspace{1cm} \n",fip);
1186
1187fputs("\\begin{center} \n ", fip);
1188fputs("\\rule{2cm}{1mm} List of {\\bf piapp} Commands \\rule{2cm}{1mm} \n", fip);
1189fputs("\n \n \\vspace{5mm} \n",fip);
1190fputs("\\begin{tabular}{llllll} \n", fip);
1191kt = 0;
1192for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
1193 fprintf(fip,"%s & p. \\pageref{%s} ", (*ite).first.c_str(), (*ite).first.c_str() );
1194 kt++;
1195 if (kt < 3) fputs(" & ", fip);
1196 else { fputs(" \\\\ \n", fip); kt = 0; }
1197 }
1198if (kt == 1) fputs(" & & & \\\\ \n", fip);
1199else if (kt == 2) fputs(" & \\\\ \n", fip);
1200fputs("\\end{tabular} \n", fip);
1201fputs("\\end{center} \n", fip);
1202// fputs("\\newline \n",fip);
1203
1204fputs("% ----- Liste des commandes dans chaque groupe ----- \n",fip);
1205fputs("\\newpage \n",fip);
1206int gid;
1207for(it = cmdhgrp.begin(); it != cmdhgrp.end(); it++) {
1208 gid = (*it).second;
1209 if (gid == 0) continue;
1210 fprintf(fip,"\\subsection{%s} \\label{%s} \n",
1211 (*it).first.c_str(), (*it).first.c_str());
1212 for(ite = helpexmap.begin(); ite != helpexmap.end(); ite++) {
1213 if ((*ite).second.group != gid) continue;
1214 fprintf(fip,"{ \\Large $ \\star \\star \\star $ } Help item {\\bf \\Large %s } \\label{%s} \n",
1215 (*ite).first.c_str(), (*ite).first.c_str());
1216 fputs("\\begin{verbatim} \n",fip);
1217 fprintf(fip,"%s\n", (*ite).second.us.c_str());
1218 fputs("\\end{verbatim} \n",fip);
1219 }
1220 for(ite = cmdexmap.begin(); ite != cmdexmap.end(); ite++) {
1221 if ((*ite).second.group != gid) continue;
1222 fprintf(fip,"{ \\Large $ \\star \\star \\star $ } Command {\\bf \\Large %s } \\label{%s} \n",
1223 (*ite).first.c_str(), (*ite).first.c_str());
1224 fputs("\\begin{verbatim} \n",fip);
1225 fprintf(fip,"%s\n", (*ite).second.us.c_str());
1226 fputs("\\end{verbatim} \n",fip);
1227 }
1228}
1229
1230fclose(fip);
1231return;
1232}
1233
1234
1235
Note: See TracBrowser for help on using the repository browser.