1 | #include "piacmd.h"
|
---|
2 | #include <stdio.h>
|
---|
3 | #include <stdlib.h>
|
---|
4 | #include <math.h>
|
---|
5 |
|
---|
6 | #include "basexecut.h"
|
---|
7 |
|
---|
8 | #include "pdlmgr.h"
|
---|
9 | #include "ctimer.h"
|
---|
10 | // #include "dlftypes.h"
|
---|
11 |
|
---|
12 | #include "pistdimgapp.h"
|
---|
13 | #include "nobjmgr.h"
|
---|
14 |
|
---|
15 | #include PISTDWDG_H
|
---|
16 | #include PILIST_H
|
---|
17 |
|
---|
18 | // ------------------------------------------------------------
|
---|
19 | // Gestion d'une fenetre d'aide interactive
|
---|
20 | // ------------------------------------------------------------
|
---|
21 |
|
---|
22 | class PIAHelpWind : public PIWindow {
|
---|
23 | public :
|
---|
24 | PIAHelpWind(PIStdImgApp* par, PIACmd* piacmd);
|
---|
25 | virtual ~PIAHelpWind();
|
---|
26 | virtual void Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL);
|
---|
27 | inline void AddHelpItem(const char * hitem)
|
---|
28 | { mNitem++; hitemlist->AppendItem(hitem, 1000+mNitem); }
|
---|
29 | protected :
|
---|
30 | PIStdImgApp* dap;
|
---|
31 | PIACmd* piac;
|
---|
32 | int mNitem;
|
---|
33 | PIList* hitemlist;
|
---|
34 | PIButton * mBut;
|
---|
35 | PILabel * mLab;
|
---|
36 | PIText* mTxt;
|
---|
37 | };
|
---|
38 |
|
---|
39 | /* --Methode-- */
|
---|
40 | PIAHelpWind::PIAHelpWind(PIStdImgApp *par, PIACmd* piacmd)
|
---|
41 | : PIWindow((PIMsgHandler *)par, "Help-PIApp", PIWK_normal, 400, 300, 100, 350)
|
---|
42 | {
|
---|
43 | dap = par;
|
---|
44 | piac = piacmd;
|
---|
45 | mNitem = 0;
|
---|
46 | SetMsg(777);
|
---|
47 |
|
---|
48 | int bsx, bsy;
|
---|
49 | int tsx, tsy;
|
---|
50 | int spx, spy;
|
---|
51 | PIApplicationPrefCompSize(bsx, bsy);
|
---|
52 | spx = bsx/6; spy = bsy/6;
|
---|
53 | tsx = 10*bsx+2*spx; tsy = 7*bsy+3*spy;
|
---|
54 | SetSize(tsx,tsy);
|
---|
55 | hitemlist = new PIList(this, "hitemlist", bsx*2.0, tsy-2*spy, spx/2, spy);
|
---|
56 | hitemlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
|
---|
57 | // hitemlist->SetBorderWidth(2);
|
---|
58 | mTxt = new PIText(this, "helptext", true, true, bsx*8.0, 6*bsy, bsx*2.0+1.5*spx, spy);
|
---|
59 | // mTxt->SetMutiLineMode(true);
|
---|
60 | mTxt->SetTextEditable(false);
|
---|
61 | mTxt->SetText("");
|
---|
62 | mTxt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
|
---|
63 | mLab = new PILabel(this, "helpitem", bsx*4, bsy, bsx*2.5+2*spx, tsy-spy-bsy);
|
---|
64 | mLab->SetBorderWidth(1);
|
---|
65 | mLab->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
|
---|
66 | mLab->SetLabel("");
|
---|
67 | mBut = new PIButton(this, "Close", 700, bsx, bsy, tsx-bsx*1.5-spx, tsy-spy-bsy);
|
---|
68 | mBut->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
|
---|
69 | }
|
---|
70 |
|
---|
71 | /* --Methode-- */
|
---|
72 | PIAHelpWind::~PIAHelpWind()
|
---|
73 | {
|
---|
74 | delete hitemlist;
|
---|
75 | delete mTxt;
|
---|
76 | delete mLab;
|
---|
77 | delete mBut;
|
---|
78 | }
|
---|
79 |
|
---|
80 | /* --Methode-- */
|
---|
81 | void PIAHelpWind::Process(PIMessage msg, PIMsgHandler* sender, void* /*data*/)
|
---|
82 | {
|
---|
83 | PIMessage um = UserMsg(msg);
|
---|
84 | if (((um == 777) && (ModMsg(msg) == PIMsg_Close)) || (um == 700) ) {
|
---|
85 | Hide();
|
---|
86 | return;
|
---|
87 | }
|
---|
88 | else if ( (um > 1000) && (sender == hitemlist)) {
|
---|
89 | string s = hitemlist->GetSelectionStr();
|
---|
90 | mTxt->SetText(piac->GetUsage(s));
|
---|
91 | mLab->SetLabel(s);
|
---|
92 | }
|
---|
93 | }
|
---|
94 |
|
---|
95 |
|
---|
96 | static PIACmd* curpiacmd = NULL;
|
---|
97 | /* --Methode-- */
|
---|
98 | PIACmd::PIACmd(NamedObjMgr* omg, PIStdImgApp* app)
|
---|
99 | {
|
---|
100 | mObjMgr = omg;
|
---|
101 | mImgApp = app;
|
---|
102 | system("cp history.pic hisold.pic");
|
---|
103 | hist.open("history.pic");
|
---|
104 | trace = false; timing = false;
|
---|
105 | gltimer = NULL;
|
---|
106 |
|
---|
107 | helpwin = new PIAHelpWind(app, this);
|
---|
108 |
|
---|
109 | string kw = "piacmd";
|
---|
110 | string usage;
|
---|
111 | usage = ">>> (piacmd) Interpreter's keywords : \n";
|
---|
112 | usage += " timingon timingoff traceon traceoff \n";
|
---|
113 | usage += " set unset listvar listcommands exec shell \n";
|
---|
114 | usage += " > set varname 'string' # To set a variable, $varname \n";
|
---|
115 | usage += " > unset varname # clear variable definition \n";
|
---|
116 | usage += " > listvars # List of variable names and values \n";
|
---|
117 | usage += " > listcommands # List of all known commands \n";
|
---|
118 | usage += " > exec filename # Execute commands from file \n";
|
---|
119 | usage += " > shell comand_string # Execute shell command \n";
|
---|
120 | usage += " > help <command_name> # <command_name> usage info \n";
|
---|
121 | usage += " > helpwindow # Displays help window \n";
|
---|
122 | RegisterCommand(kw, usage, NULL);
|
---|
123 |
|
---|
124 | basexec = new PIABaseExecutor(this, omg, app);
|
---|
125 | AddInterpreter(this);
|
---|
126 | curcmdi = this;
|
---|
127 | }
|
---|
128 |
|
---|
129 | /* --Methode-- */
|
---|
130 | PIACmd::~PIACmd()
|
---|
131 | {
|
---|
132 | hist.close();
|
---|
133 | if (gltimer) { delete gltimer; gltimer = NULL; }
|
---|
134 | Modmap::iterator it;
|
---|
135 | for(it = modmap.begin(); it != modmap.end(); it++) {
|
---|
136 | string name = (*it).first + "_end";
|
---|
137 | DlModuleInitEndFunction fend = (*it).second->GetFunction(name);
|
---|
138 | if (fend) fend();
|
---|
139 | delete (*it).second;
|
---|
140 | }
|
---|
141 | delete helpwin;
|
---|
142 | if (curpiacmd == this) curpiacmd = NULL;
|
---|
143 | }
|
---|
144 |
|
---|
145 | /* --Methode-- */
|
---|
146 | PIACmd* PIACmd::GetInterpreter()
|
---|
147 | {
|
---|
148 | return(curpiacmd);
|
---|
149 | }
|
---|
150 |
|
---|
151 | /* --Methode-- */
|
---|
152 | string PIACmd::Name()
|
---|
153 | {
|
---|
154 | return("piacmd");
|
---|
155 | }
|
---|
156 |
|
---|
157 | /* --Methode-- */
|
---|
158 | void PIACmd::RegisterCommand(string& keyw, string& usage, CmdExecutor * ce)
|
---|
159 | {
|
---|
160 | // if (!ce) return;
|
---|
161 | cmdex cme;
|
---|
162 | cme.us = usage;
|
---|
163 | cme.cex = ce;
|
---|
164 | cmdexmap[keyw] = cme;
|
---|
165 | if (helpwin) helpwin->AddHelpItem(keyw.c_str());
|
---|
166 | }
|
---|
167 |
|
---|
168 | /* --Methode-- */
|
---|
169 | void PIACmd::LoadModule(string& fnameso, string& name)
|
---|
170 | {
|
---|
171 | PDynLinkMgr * dynlink = new PDynLinkMgr(fnameso, false);
|
---|
172 | if (dynlink == NULL) {
|
---|
173 | cerr << "PIACmd/LoadModule_Error: Pb opening SO " << fnameso << endl;
|
---|
174 | return;
|
---|
175 | }
|
---|
176 | string fname = name + "_init";
|
---|
177 | DlModuleInitEndFunction finit = dynlink->GetFunction(fname);
|
---|
178 | if (!finit) {
|
---|
179 | cerr << "PIACmd/LoadModule_Error: Pb linking " << fname << endl;
|
---|
180 | return;
|
---|
181 | }
|
---|
182 | cout << "PIACmd/LoadModule_Info: Initialisation module" << name
|
---|
183 | << " " << fname << "() ..." << endl;
|
---|
184 | finit();
|
---|
185 | modmap[name] = dynlink;
|
---|
186 | return;
|
---|
187 | }
|
---|
188 |
|
---|
189 | /* --Methode-- */
|
---|
190 | void PIACmd::AddInterpreter(CmdInterpreter * cl)
|
---|
191 | {
|
---|
192 | if (!cl) return;
|
---|
193 | interpmap[cl->Name()] = cl;
|
---|
194 | }
|
---|
195 |
|
---|
196 | /* --Methode-- */
|
---|
197 | void PIACmd::SelInterpreter(string& name)
|
---|
198 | {
|
---|
199 | InterpMap::iterator it = interpmap.find(name);
|
---|
200 | if (it == interpmap.end()) return;
|
---|
201 | curcmdi = (*it).second;
|
---|
202 | }
|
---|
203 |
|
---|
204 |
|
---|
205 | // Pour le decoupage des commandes en lignes
|
---|
206 | typedef vector<string> cmdtok;
|
---|
207 |
|
---|
208 | /* --Methode-- */
|
---|
209 | int PIACmd::Interpret(string& s)
|
---|
210 | {
|
---|
211 |
|
---|
212 | cmdtok tokens;
|
---|
213 | if (s.length() < 1) return(0);
|
---|
214 |
|
---|
215 | hist << s << endl; // On enregistre les commandes
|
---|
216 |
|
---|
217 | if (s[0] == '#') {
|
---|
218 | cout << "PIACmd::Interpret() Comment-Line:" << s << endl;
|
---|
219 | return(0);
|
---|
220 | }
|
---|
221 | string toks,kw;
|
---|
222 | size_t p = s.find_first_not_of(" ");
|
---|
223 | s = s.substr(p);
|
---|
224 | p = 0;
|
---|
225 | size_t q = s.find_first_of(" ");
|
---|
226 | size_t l = s.length();
|
---|
227 |
|
---|
228 | if (q < l)
|
---|
229 | { kw = s.substr(p,q-p); toks = s.substr(q, l-q); }
|
---|
230 | else { kw = s.substr(p,l-p); toks = ""; }
|
---|
231 |
|
---|
232 | q = 0;
|
---|
233 | while (q < l) {
|
---|
234 | p = toks.find_first_not_of(" ",q+1); // au debut d'un token
|
---|
235 | if (p>=l) break;
|
---|
236 | q = toks.find_first_of(" ",p); // la fin du token;
|
---|
237 | string token = toks.substr(p,q-p);
|
---|
238 | tokens.push_back(token);
|
---|
239 | }
|
---|
240 |
|
---|
241 | for(int k=0; k<tokens.size(); k++) { // On remplace les $varname par la valeur de la variable
|
---|
242 | if ((tokens[k])[0] != '$') continue;
|
---|
243 | CmdVarList::iterator it = mVars.find(tokens[k].substr(1));
|
---|
244 | if (it != mVars.end()) tokens[k] = (*it).second;
|
---|
245 | }
|
---|
246 |
|
---|
247 | // cout << "PIACmd::Do() DBG KeyW= " << kw << " NbArgs= " << tokens.size() << endl;
|
---|
248 | // for(int ii=0; ii<tokens.size(); ii++)
|
---|
249 | // cout << "arg[ " << ii << " ] : " << tokens[ii] << endl;
|
---|
250 |
|
---|
251 | // >>>>>>>>>>> Commande d'interpreteur
|
---|
252 | if (kw == "helpwindow") ShowHelpWindow();
|
---|
253 | else if (kw == "help") {
|
---|
254 | if (tokens.size() > 0) {
|
---|
255 | CmdExmap::iterator it = cmdexmap.find(tokens[0]);
|
---|
256 | if (it == cmdexmap.end()) cout << "Nothing known about " << tokens[0] << " ?? " << endl;
|
---|
257 | else cout << (*it).second.us << endl;
|
---|
258 | }
|
---|
259 | else {
|
---|
260 | cout << "\n -------- PIACmd::Interpret() ::::: Help ------------ \n";
|
---|
261 | cout << ">>> Interpreter's keywords : \n";
|
---|
262 | cout << " timingon timingoff traceon traceoff \n";
|
---|
263 | cout << " set unset listvar listcommands exec shell \n";
|
---|
264 | cout << " > set varname 'string' # To set a variable, $varname \n";
|
---|
265 | cout << " > unset varname # clear variable definition \n";
|
---|
266 | cout << " > listvars # List of variable names and values \n";
|
---|
267 | cout << " > listcommands # List of all known commands \n";
|
---|
268 | cout << " > exec filename # Execute commands from file \n";
|
---|
269 | cout << " > shell comand_string # Execute shell command \n";
|
---|
270 | cout << " > help <command_name> # <command_name> usage info \n";
|
---|
271 | cout << " > helpwindow # Displays help window \n" << endl;
|
---|
272 | }
|
---|
273 | }
|
---|
274 |
|
---|
275 |
|
---|
276 | else if (kw == "set") {
|
---|
277 | if (tokens.size() < 2) { cout << "PIACmd::Interpret() Usage: set varname string" << endl; return(0); }
|
---|
278 | mVars[tokens[0]] = tokens[1];
|
---|
279 | }
|
---|
280 | else if (kw == "unset") {
|
---|
281 | if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: unset varname" << endl; return(0); }
|
---|
282 | CmdVarList::iterator it = mVars.find(tokens[0]);
|
---|
283 | if (it != mVars.end()) mVars.erase(it);
|
---|
284 | else cerr << "PIACmd::Interpret() No variable with name " << tokens[0] << endl;
|
---|
285 | }
|
---|
286 | else if (kw == "listvars") {
|
---|
287 | cout << "PIACmd::Interpret() Variable List , VarName = Value \n";
|
---|
288 | CmdVarList::iterator it;
|
---|
289 | for(it = mVars.begin(); it != mVars.end(); it++)
|
---|
290 | cout << (*it).first << " = " << (*it).second << "\n";
|
---|
291 | cout << endl;
|
---|
292 | }
|
---|
293 | else if (kw == "listvars") {
|
---|
294 | cout << "---- PIACmd::Interpret() Command keyword List ----- \n";
|
---|
295 | CmdExmap::iterator it;
|
---|
296 | int kc = 0;
|
---|
297 | for(it = cmdexmap.begin(); it != cmdexmap.end(); it++) {
|
---|
298 | cout << (*it).first << " ";
|
---|
299 | kc++;
|
---|
300 | if (kc >= 5) { cout << "\n"; kc = 0; }
|
---|
301 | }
|
---|
302 | cout << endl;
|
---|
303 | }
|
---|
304 | else if (kw == "traceon") { cout << "PIACmd::Interpret() -> Trace ON mode " << endl; trace = true; }
|
---|
305 | else if (kw == "traceoff") { cout << "PIACmd::Interpret() -> Trace OFF mode " << endl; trace = false; }
|
---|
306 | else if (kw == "timingon") {
|
---|
307 | cout << "PIACmd::Interpret() -> Timing ON mode " << endl;
|
---|
308 | if (gltimer) delete gltimer; gltimer = new Timer("PIA-CmdInterpreter "); timing = true;
|
---|
309 | }
|
---|
310 | else if (kw == "timingoff") {
|
---|
311 | cout << "PIACmd::Interpret() -> Timing OFF mode " << endl;
|
---|
312 | if (gltimer) delete gltimer; gltimer = NULL; timing = false;
|
---|
313 | }
|
---|
314 | else if (kw == "exec") {
|
---|
315 | if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: exec filename" << endl; return(0); }
|
---|
316 | ExecFile(tokens[0]);
|
---|
317 | }
|
---|
318 | else if (kw == "shell") {
|
---|
319 | if (tokens.size() < 1) { cout << "PIACmd::Interpret() Usage: shell cmdline" << endl; return(0); }
|
---|
320 | system(toks.c_str());
|
---|
321 | }
|
---|
322 | // Execution d'une commande enregistree
|
---|
323 | else {
|
---|
324 | CmdExmap::iterator it = cmdexmap.find(kw);
|
---|
325 | if (it == cmdexmap.end()) cout << "No such command : " << kw << " ! " << endl;
|
---|
326 | else {
|
---|
327 | if ((*it).second.cex) (*it).second.cex->Execute(kw, tokens);
|
---|
328 | else cout << "Dont know how to execute " << kw << " ? " << endl;
|
---|
329 | }
|
---|
330 | }
|
---|
331 |
|
---|
332 | if (timing) gltimer->Split();
|
---|
333 | return(0);
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | /* --Methode-- */
|
---|
338 | int PIACmd::ExecFile(string& file)
|
---|
339 | {
|
---|
340 | char line_buff[512];
|
---|
341 | FILE *fip;
|
---|
342 |
|
---|
343 | if ( (fip = fopen(file.c_str(),"r")) == NULL ) {
|
---|
344 | cerr << "PIACmd::Exec() Error opening file " << file << endl;
|
---|
345 | hist << "##! PIACmd::Exec() Error opening file " << file << endl;
|
---|
346 | return(0);
|
---|
347 | }
|
---|
348 |
|
---|
349 | hist << "### Executing commands from " << file << endl;
|
---|
350 | if (trace) {
|
---|
351 | mImgApp->GetConsole()->AddStr("### Executing commands from ", PIVA_Magenta);
|
---|
352 | mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
|
---|
353 | mImgApp->GetConsole()->AddStr("\n", PIVA_Magenta);
|
---|
354 | }
|
---|
355 |
|
---|
356 | while (fgets(line_buff,511,fip) != NULL)
|
---|
357 | {
|
---|
358 | if (trace) mImgApp->GetConsole()->AddStr(line_buff, PIVA_Magenta);
|
---|
359 | line_buff[strlen(line_buff)-1] = '\0'; /* LF/CR de la fin */
|
---|
360 | string line(line_buff);
|
---|
361 | Interpret(line);
|
---|
362 | }
|
---|
363 | hist << "### End of Exec( " << file << " ) " << endl;
|
---|
364 | if (trace) {
|
---|
365 | mImgApp->GetConsole()->AddStr("### End of Exec( ", PIVA_Magenta);
|
---|
366 | mImgApp->GetConsole()->AddStr(file.c_str(), PIVA_Magenta);
|
---|
367 | mImgApp->GetConsole()->AddStr(" ) \n", PIVA_Magenta);
|
---|
368 | }
|
---|
369 |
|
---|
370 | return(0);
|
---|
371 | }
|
---|
372 |
|
---|
373 |
|
---|
374 | static string* videstr = NULL;
|
---|
375 | /* --Methode-- */
|
---|
376 | string& PIACmd::GetUsage(const string& kw)
|
---|
377 | {
|
---|
378 | CmdExmap::iterator it = cmdexmap.find(kw);
|
---|
379 | if (it == cmdexmap.end()) {
|
---|
380 | if (videstr == NULL) videstr = new string("");
|
---|
381 | return(*videstr);
|
---|
382 | }
|
---|
383 | else return( (*it).second.us );
|
---|
384 | }
|
---|
385 |
|
---|
386 | /* --Methode-- */
|
---|
387 | void PIACmd::ShowHelpWindow()
|
---|
388 | {
|
---|
389 | helpwin->Show();
|
---|
390 | }
|
---|