source: Sophya/trunk/SophyaPI/PIext/cxxexecutor.cc@ 1268

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

3ieme argument string& toks pour Execute et ExecuteCommand
preparation gestion TmpDir dans cxxexecutor
suppression de ExecuteCXX ds cxxexecutor et appels
possibilite d'ajouter des userfct.cc ds cxxexecutor

cmv 1/11/00

  • Property svn:executable set to *
File size: 16.4 KB
Line 
1#include "cxxexecutor.h"
2
3#include <typeinfo>
4
5#include "strutilxx.h"
6#include "dvlist.h"
7
8#include "nomgadapter.h"
9#include "pistdimgapp.h"
10
11
12/* --Methode-- */
13CxxExecutor::CxxExecutor(PIACmd *mpiac, PIStdImgApp* /* app */)
14 : mUserCodeFn(""), mUserFctFn(""), mCompOpt(""), mLinkOpt(""), mMyLibs("")
15 , mDefTmp(""), mDefRoot("cxx_spiapp"), mDefFunc("usercxx")
16{
17mIncList.resize(0);
18mCallArgs.resize(0);
19
20// Gestion des fichiers par default dans TmpDir
21//.... CMV a gerer mais pas forcement OK ... voir avec Rz
22//NamedObjMgr omg;
23//string tmpdir = omg.GetTmpDir();
24//if(tmpdir.size()>1) mDefTmp = tmpdir;
25
26// On enregistre les nouvelles commandes
27string hgrp = "CxxExecutorCmd";
28string usage,kw;
29
30kw = "c++exec";
31usage = "c++exec: Execute the following c++ user code\n";
32usage+= "Usage: c++exec c++ user code\n";
33usage+= "Warning: c++ user code can be found in \"TmpDir/"+mDefRoot+".h\"\n";
34usage+= " total generated code can be found in \"TmpDir/"+mDefRoot+".cc\"";
35mpiac->RegisterCommand(kw, usage, this, hgrp);
36
37kw = "c++execfrf";
38usage = "c++execfrf: Execute c++ user_code [user_function_code]\n";
39usage+= "Usage: c++execfrf fileuser.cc [fileuserfct.cc]\n";
40usage+= "Warning: total generated code can be found in \"TmpDir/"+mDefRoot+".cc\"";
41mpiac->RegisterCommand(kw, usage, this, hgrp);
42
43kw = "c++args";
44usage = "c++args: Define user function arguments for c++exec and c++execfrf\n";
45usage+= "Usage: c++args arg1 arg2 arg3 ...\n";
46usage+= " c++args -? : give current arguments\n";
47usage+= " c++args : reset current arguments";
48mpiac->RegisterCommand(kw, usage, this, hgrp);
49
50kw = "c++create";
51usage = "c++create: create a file to be used by spiapp\n";
52usage+= "Usage: c++create file.cc func c++ user code...\n";
53mpiac->RegisterCommand(kw, usage, this, hgrp);
54
55kw = "c++createfrf";
56usage = "c++createfrf: create a file \"file.cc\"to be used by spiapp\n";
57usage+= " with a user file code \"fileuser.cc\"\n";
58usage+= " and an optional user function code \"fileuserfct.cc\"\n";
59usage+= "Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]\n";
60mpiac->RegisterCommand(kw, usage, this, hgrp);
61
62kw = "c++compile";
63usage = "c++compile: compile a file (file.cc -> file.so)\n";
64usage+= "Usage: c++compile file\n";
65usage+= "Warning: give \"file\" or \"file.so\" to create \"file.so\" from \"file.cc\"\n";
66usage+= " : to be used before c++link";
67mpiac->RegisterCommand(kw, usage, this, hgrp);
68
69kw = "c++link";
70usage = "c++link: link function \"func\" in file.so to spiapp\n";
71usage+= "Usage: c++link file.so func";
72mpiac->RegisterCommand(kw, usage, this, hgrp);
73
74kw = "c++include";
75usage = "c++include: give personnal includes to be used\n";
76usage+= "Usage: c++include myinc1.h myinc2.h ...\n";
77usage+= " c++include -? : give current include files\n";
78usage+= " c++include : reset current include files\n";
79usage+= "Warning: to be used before c++create... c++exec...";
80mpiac->RegisterCommand(kw, usage, this, hgrp);
81
82kw = "c++compileopt";
83usage = "c++compileopt: give additionnal compile options\n";
84usage+= "Usage: c++compileopt -g -O5 -IMy_Inc_Dir ...\n";
85usage+= " c++compileopt -? : give current compile options\n";
86usage+= " c++compileopt : reset current compile options\n";
87usage+= "Warning: to be used before c++compile";
88mpiac->RegisterCommand(kw, usage, this, hgrp);
89
90kw = "c++linkopt";
91usage = "c++linkopt: give additionnal link options\n";
92usage+= "Usage: c++linkopt -g -O5 ...\n";
93usage+= " c++linkopt -? : give current link options\n";
94usage+= " c++linkopt : reset current link options\n";
95usage+= "Warning: to be used before c++compile";
96mpiac->RegisterCommand(kw, usage, this, hgrp);
97
98kw = "c++mylibs";
99usage = "c++mylibs: give additionnal libraries\n";
100usage+= "Usage: c++mylibs -LMy_Lib_Dir -lmylib1 -lmylib2 ...\n";
101usage+= " c++mylibs -? : give current additionnal libraries\n";
102usage+= " c++mylibs : reset current additionnal libraries\n";
103usage+= "Warning: to be used before c++compile";
104mpiac->RegisterCommand(kw, usage, this, hgrp);
105
106
107}
108
109/* --Methode-- */
110CxxExecutor::~CxxExecutor()
111{
112}
113
114/* --Methode-- */
115int CxxExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
116{
117int rc=0;
118if(kw == "c++exec") {
119 if(tokens.size()<1) {
120 cout<<"Usage: c++exec c++ user code"<<endl;
121 return(1);
122 }
123 rc = FillUserCode(toks,0); if(rc) return(1);
124 rc = CrFile(); if(rc) return(1);
125 rc = Compile(); if(rc) return(1);
126 rc = Link(); if(rc) return(1);
127 rc = Call(); if(rc) return(1);
128
129} else if(kw == "c++execfrf") {
130 if(tokens.size()<1) {
131 cout<<"Usage: c++execfrf fileuser.cc [fileuserfct.cc]"<<endl;
132 return(1);
133 }
134 if(tokens.size()>1) rc = FillUserCode(tokens[0],tokens[1]);
135 else rc = FillUserCode(tokens[0]);
136 if(rc) return(1);
137 rc = CrFile(); if(rc) return(1);
138 rc = Compile(); if(rc) return(1);
139 rc = Link(); if(rc) return(1);
140 rc = Call(); if(rc) return(1);
141
142} else if(kw == "c++args") {
143 if(tokens.size()==1) if(tokens[0]=="-?")
144 {cout<<"c++args "<<GetArgs()<<endl; return(0);}
145 FillArgs(tokens);
146
147} else if(kw == "c++create") {
148 if(tokens.size()<3) {
149 cout<<"Usage: c++create file.cc func c++ user code ..."<<endl;
150 return(1);
151 }
152 rc = FillUserCode(toks,2); if(rc) return(1);
153 rc = CrFile(tokens[0],tokens[1]); if(rc) return(1);
154
155} else if(kw == "c++createfrf") {
156 if(tokens.size()<3) {
157 cout<<"Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]"<<endl;
158 return(1);
159 }
160 if(tokens.size()>3) rc = FillUserCode(tokens[2],tokens[3]);
161 else rc = FillUserCode(tokens[2]);
162 if(rc) return(1);
163 rc = CrFile(tokens[0],tokens[1]); if(rc) return(1);
164
165} else if(kw == "c++compile") {
166 if(tokens.size()>=1) rc = Compile(tokens[0]);
167 else rc = Compile();
168 if(rc) return(1);
169
170} else if(kw == "c++link") {
171 if(tokens.size()>=2) rc = Link(tokens[0],tokens[1]);
172 else if(tokens.size()>=1) rc = Link(tokens[0]);
173 else rc = Link();
174 if(rc) return(1);
175
176} else if(kw == "c++include") {
177 if(tokens.size()==1) if(tokens[0]=="-?")
178 {cout<<"c++include "<<GetInclude()<<endl; return(0);}
179 FillInclude(tokens);
180
181} else if(kw == "c++compileopt") {
182 if(tokens.size()==1) if(tokens[0]=="-?")
183 {cout<<"c++compileopt "<<GetCompileOpt()<<endl; return(0);}
184 FillCompileOpt(tokens);
185
186} else if(kw == "c++linkopt") {
187 if(tokens.size()==1) if(tokens[0]=="-?")
188 {cout<<"c++linkopt "<<GetLinkOpt()<<endl; return(0);}
189 FillLinkOpt(tokens);
190
191} else if(kw == "c++mylibs") {
192 if(tokens.size()==1) if(tokens[0]=="-?")
193 {cout<<"c++mylibs "<<GetLinkLibs()<<endl; return(0);}
194 FillLinkLibs(tokens);
195}
196
197return(0);
198}
199
200/* --Methode-- */
201int CxxExecutor::CrFile(string cfilename,string func)
202{
203if(cfilename.size()<1) cfilename = mDefTmp + mDefRoot + ".cc";
204if(func.size()<1) func = mDefFunc;
205
206ofstream os(cfilename.c_str(),ios::out);
207if(!os)
208 {cout<<"CxxExecutor::CrFile: unable to open "<<cfilename<<endl;
209 return 1;}
210
211PutInclude(os);
212os<<endl;
213
214PutIncludeUser(os);
215os<<endl;
216
217os<<"//-------------------------------------------------//"<<endl;
218os<<"//------------- Fonctions utilisateur -------------//"<<endl;
219os<<"//-------------------------------------------------//"<<endl;
220if(mUserFctFn.size()>0) os<<"#include \""<<mUserFctFn<<"\""<<endl;
221os<<endl;
222
223
224os<<"extern \"C\" {"<<endl;
225os<<" int "<<func<<"( vector<string>& args );"<<endl;
226os<<"}"<<endl<<endl;
227os<<"int "<<func<<"( vector<string>& args )"<<endl;
228os<<"{"<<endl;
229os<<"// Some definitions to help using spiapp;"<<endl;
230os<<"NamedObjMgr omg;"<<endl;
231os<<"Services2NObjMgr& srvo = *omg.GetServiceObj();"<<endl;
232os<<endl;
233
234PutObject(os);
235os<<endl;
236
237PutVar(os);
238os<<endl;
239
240os<<"//--------------------------------------------//"<<endl;
241os<<"//------------- Code utilisateur -------------//"<<endl;
242os<<"//--------------------------------------------//"<<endl;
243os<<endl;
244os<<"#include \""<<mUserCodeFn<<"\""<<endl;
245os<<endl;
246
247os<<"return 0;"<<endl;
248os<<"}"<<endl;
249
250cout<<"File "<<cfilename<<" for function "<<func<<" created"<<endl;
251cout<<"User code is in file "<<mUserCodeFn<<" included in "<<cfilename<<endl;
252return 0;
253}
254
255/* --Methode-- */
256void CxxExecutor::PutInclude(ofstream& os)
257{
258os<<"#include \"machdefs.h\""<<endl
259 <<endl
260
261 <<"//---- System et stdc++ include files"<<endl
262 <<"#include <stdio.h>"<<endl
263 <<"#include <stdlib.h>"<<endl
264 <<"#include <math.h>"<<endl
265 <<"#include <ctype.h>"<<endl
266 <<"#include <string.h>"<<endl
267 <<"#include <iostream.h>"<<endl
268 <<"#include <fstream.h>"<<endl
269 <<"#include <complex>"<<endl
270 <<endl
271
272 <<"#include <typeinfo>"<<endl
273 <<"#include <string>"<<endl
274 <<"#include <vector>"<<endl
275 <<"#include <map>"<<endl
276 <<"#include <functional>"<<endl
277 <<"#include <list>"<<endl
278 <<endl
279
280 <<"//---- Sophya include files"<<endl
281 <<"#include \"systools.h\""<<endl
282 <<"#include \"ntools.h\""<<endl
283 <<"#include \"array.h\""<<endl
284 <<"#include \"histats.h\""<<endl
285 <<endl
286
287 <<"//---- Spiapp include files"<<endl
288 <<"#include \"nobjmgr.h\""<<endl
289 <<"#include \"servnobjm.h\""<<endl
290 <<endl
291
292 <<"#define KeepObj(obj) ___nomobj = #obj; omg.AddObj(obj,___nomobj);"<<endl
293 <<"#define KeepVar(var) ___nomobj = #var; omg.GetVarList().Get(___nomobj) = var ;"<<endl
294 <<endl;
295
296return;
297}
298
299/* --Methode-- */
300void CxxExecutor::PutIncludeUser(ofstream& os)
301{
302if(mIncList.size()<1) return;
303for(uint_4 i=0;i<mIncList.size();i++)
304 os<<"#include \""<<mIncList[i]<<"\""<<endl;
305}
306
307/* --Methode-- */
308void CxxExecutor::PutObject(ofstream& os)
309{
310NamedObjMgr omg;
311NObjMgrAdapter* objmgrad;
312vector<string> objlist;
313string patt = "*";
314omg.GetObjList(patt,objlist);
315int nobjs = objlist.size();
316
317os<<"//-------------- Object List --------------"<<endl;
318os<<"//Number of objects = "<<nobjs<<endl;
319os<<"string ___nomobj;"<<endl<<endl;
320if(nobjs<=0) return;
321
322string dir,nobj,stmp,obtype;
323for(int i=0;i<nobjs;i++) {
324 objmgrad = omg.GetObjAdapter(objlist[i]);
325 omg.ParseObjectName(objlist[i],dir,nobj);
326 obtype = objmgrad->GetDataObjType();
327 stmp = "___" + nobj;
328
329 os<<"___nomobj = \""<<nobj<<"\";"<<endl;
330 os<<obtype<<"* "<<stmp
331 <<" = dynamic_cast< "<<obtype<<" * >(omg.GetObj(___nomobj));"<<endl;
332 os<<"if("<<stmp<<"==NULL) throw NullPtrError"
333 <<"(\"CxxExecutor::PutObject: Non existing object "<<nobj
334 <<"... please update file\");"<<endl;
335 os<<obtype<<"& "<<nobj<<" = (*"<<stmp<<");"<<endl<<endl;
336}
337
338return;
339}
340
341/* --Methode-- */
342void CxxExecutor::PutVar(ofstream& os)
343{
344os<<"//-------------- Variable List --------------"<<endl;
345NamedObjMgr omg;
346DVList& varlist = omg.GetVarList();
347// varlist.Show(); varlist.Print();
348DVList::ValList::const_iterator it;
349for(it=varlist.Begin(); it!=varlist.End(); it++) {
350 string key = (*it).first;
351 if (isalpha(key[0]) ) {
352 os<<"___nomobj = \""<<key<<"\";"<<endl;
353 os<<"MuTyV & $"<<key<<" = omg.GetVarList().Get(___nomobj);"<<endl;
354 }
355}
356
357return;
358}
359
360/* --Methode-- */
361int CxxExecutor::FillUserCode(string& usercode,uint_4 first)
362// - first is the first position in the "string" where the code starts
363// User code is read from input. It is put into file "TmpDir/cxx_spiapp.h".
364{
365mUserCodeFn = "";
366mUserFctFn = "";
367
368// get the string part which is after word "first"
369string code = usercode;
370if(code.size()<=0) {cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
371 return 1;}
372size_t q;
373for(uint_4 i=0;i<=first;i++) {
374 q = code.find_first_not_of(" \t");
375 if(q>=code.size()) {code=""; break;}
376 code = code.substr(q);
377 if(i==first) break;
378 q = code.find_first_of(" \t");
379 if(q>=code.size()) {code=""; break;}
380 code = code.substr(q);
381}
382if(code.size()<=0)
383 {cout<<"CxxExecutor::FillUserCode: no user code after "<<first<<endl;
384 return 1;}
385
386// Fill the file with user code
387mUserCodeFn = mDefTmp + mDefRoot + ".h";
388ofstream os(mUserCodeFn.c_str(),ios::out);
389if(!os) {cout<<"CxxExecutor::FillUserCode: unable to open "
390 <<mUserCodeFn<<endl; mUserCodeFn = ""; return 1;}
391os<<" "<<code;
392cout<<"User code filled from standard input into "<<mUserCodeFn<<endl;
393return 0;
394}
395
396/* --Methode-- */
397int CxxExecutor::FillUserCode(string filename,string filefctname)
398// User code is read from "filename" an optionally from filefctname.
399{
400mUserCodeFn = filename;
401mUserFctFn = filefctname;
402cout<<"User code filled from file "<<filename<<endl;
403return 0;
404}
405
406/* --Methode-- */
407int CxxExecutor::Compile(string rootfilename)
408{
409if(rootfilename.size()<1) rootfilename = mDefRoot;
410cout<<"Compile: "<<rootfilename<<endl;
411int rc = 0;
412rc = CrMakefile();
413if(rc) return(1);
414string make = "";
415make += "make -f " + mDefRoot + "_Makefile";
416make += " CXXFLAGS=\"" + mCompOpt + "\"";
417make += " LDFLAGS=\"" + mLinkOpt + "\"";
418make += " MYLIBS=\"" + mMyLibs + "\"";
419make += " " + rootfilename;
420rc = system(make.c_str());
421if(rc)
422 {cout<<"CxxExecutor::Compile : \n"<<make<<" Failed"<<endl;
423 return 1000+rc;}
424return 0;
425}
426
427/* --Methode-- */
428int CxxExecutor::CrMakefile(void)
429{
430string makename = mDefTmp + mDefRoot + "_Makefile";
431ofstream os(makename.c_str(),ios::out);
432if(!os)
433 {cout<<"CxxExecutor::CrMakefile: unable to open file for Makefile"<<endl;
434 return 1;}
435//---------------------------------------------------------------------
436os<<"MODULEDECCXXFLAGS := -msg_quiet"<<endl;
437os<<"include $(DPCBASEREP)/Include/MakefileUser.h"<<endl;
438os<<"MYLIBS ="<<endl;
439os<<"LIBS = -L$(SLB) -lPI -lextsophya -lsophya -lm"<<endl;
440os<<"ifeq ($(MACHEROS),OSF1)"<<endl;
441os<<"LIBS := $(LIBS) -lfor"<<endl;
442os<<"endif"<<endl;
443os<<"ifeq ($(MACHEROS),Linux)"<<endl;
444os<<"LIBS := $(LIBS) -ldl -lf2c"<<endl;
445os<<"endif"<<endl;
446os<<"%.so:%.o"<<endl;
447os<<"%:%.cc"<<endl;
448os<<"%:%.o"<<endl;
449os<<"%.o:%.cc"<<endl;
450os<<"%.o:%.c"<<endl;
451os<<"%:%.c"<<endl;
452os<<endl;
453os<<".PRECIOUS: %.so"<<endl;
454os<<endl;
455os<<"%:%.so"<<endl;
456os<<"\t"<<"echo $@ \" made (.so) \""<<endl;
457os<<"%.so:%.o"<<endl;
458os<<"\t"<<"$(LINK.cc) -shared -o $@ $< $(LIBS) $(MYLIBS)"<<endl;
459os<<"%.o:%.cc"<<endl;
460os<<"\t"<<"$(COMPILE.cc) -o $@ $<"<<endl;
461os<<"%.o:%.c"<<endl;
462os<<"\t"<<"$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $<"<<endl;
463//---------------------------------------------------------------------
464return 0;
465}
466
467/* --Methode-- */
468int CxxExecutor::Link(string libname,string func)
469{
470if(libname.size()<1) libname = mDefTmp + mDefRoot + ".so";
471if(func.size()<1) func = mDefFunc;
472
473NamedObjMgr omg;
474PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
475string key("link");
476vector<string> arg; arg.push_back(libname); arg.push_back(func);
477string toks = libname + " " + func;
478int rc = mpiac->ExecuteCommand(key,arg,toks);
479cout<<"Link from "<<libname<<" for function "<<func
480 <<" (rc="<<rc<<")"<<endl;
481return 0;
482}
483
484/* --Methode-- */
485int CxxExecutor::Call(string func)
486{
487if(func.size()<1) func = mDefFunc;
488
489NamedObjMgr omg;
490PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
491string key("call");
492vector<string> arg; arg.push_back(func);
493string toks = func;
494if(mCallArgs.size()>0)
495 for(uint_4 i=0;i<mCallArgs.size();i++) arg.push_back(mCallArgs[i]);
496mpiac->ExecuteCommand(key,arg,toks);
497return 0;
498}
499
500/* --Methode-- */
501void CxxExecutor::FillArgs(vector<string>& args)
502{
503mCallArgs.resize(0);
504if(args.size()<1) return;
505for(uint_4 i=0;i<args.size();i++) mCallArgs.push_back(args[i]);
506}
507
508void CxxExecutor::FillArgs(string& args)
509{
510mCallArgs.resize(0);
511FillVStringFrString(args,mCallArgs,' ');
512}
513
514string CxxExecutor::GetArgs(void)
515{
516string dum = "";
517if(mCallArgs.size()<1) return dum;
518for(uint_4 i=0;i<mCallArgs.size();i++) dum += mCallArgs[i] + " ";
519return dum;
520}
521
522/* --Methode-- */
523void CxxExecutor::FillInclude(vector<string>& inc)
524{
525mIncList.resize(0);
526if(inc.size()<1) return;
527for(uint_4 i=0;i<inc.size();i++) mIncList.push_back(inc[i]);
528}
529
530void CxxExecutor::FillInclude(string& inc)
531{
532mIncList.resize(0);
533FillVStringFrString(inc,mIncList,' ');
534}
535
536string CxxExecutor::GetInclude(void)
537{
538string dum = "";
539if(mIncList.size()<1) return dum;
540for(uint_4 i=0;i<mIncList.size();i++) dum += mIncList[i] + " ";
541return dum;
542}
543
544/* --Methode-- */
545void CxxExecutor::FillCompileOpt(vector<string>& copt)
546{
547mCompOpt = "";
548if(copt.size()<1) return;
549for(uint_4 i=0;i<copt.size();i++) mCompOpt += copt[i] + " ";
550}
551
552void CxxExecutor::FillCompileOpt(string& copt)
553{
554mCompOpt = copt;
555}
556
557string CxxExecutor::GetCompileOpt(void)
558{
559return mCompOpt;
560}
561
562/* --Methode-- */
563void CxxExecutor::FillLinkOpt(vector<string>& lopt)
564{
565mLinkOpt = "";
566if(lopt.size()<1) return;
567for(uint_4 i=0;i<lopt.size();i++) mLinkOpt += lopt[i] + " ";
568}
569
570void CxxExecutor::FillLinkOpt(string& lopt)
571{
572mLinkOpt = lopt;
573}
574
575string CxxExecutor::GetLinkOpt(void)
576{
577return mLinkOpt;
578}
579
580/* --Methode-- */
581void CxxExecutor::FillLinkLibs(vector<string>& llibs)
582{
583mMyLibs = "";
584if(llibs.size()<1) return;
585for(uint_4 i=0;i<llibs.size();i++) mMyLibs += llibs[i] + " ";
586}
587
588void CxxExecutor::FillLinkLibs(string& llibs)
589{
590mMyLibs = llibs;
591}
592
593string CxxExecutor::GetLinkLibs(void)
594{
595return mMyLibs;
596}
Note: See TracBrowser for help on using the repository browser.