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

Last change on this file since 1276 was 1276, checked in by ercodmgr, 25 years ago

Amelioration de la syntaxe de l'interpreteur, gestion de quotes, ligne suite
Commande linkff2 (2eme groupe de link, pour utilisation par CxxExecutor
Amelioration de la gestion de TMPDIR

Reza 2/11/2000

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