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

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

Ajout du command executor pour trace de contour - Olivier 19/12/2001

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