#include "cxxexecutor.h" #include #include "dvlist.h" #include "nomgadapter.h" #include "pistdimgapp.h" void FillVStringFrString(string s,vector& vs,char sep = ' '); /* --Methode-- */ CxxExecutor::CxxExecutor(PIACmd *mpiac, PIStdImgApp* /* app */) : mCompOpt(""), mLinkOpt(""), mMyLibs("") { mUserCode.resize(0); mIncList.resize(0); mCallArgs.resize(0); NamedObjMgr omg; // On enregistre les nouvelles commandes string hgrp = "CxxExecutorCmd"; string usage,kw; kw = "c++exec"; usage = "c++exec: Execute the following c++ user code\n"; usage+= "Usage: c++exec c++ user code"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++execfrf"; usage = "c++execfrf: Execute c++ user code contained in a file\n"; usage+= "Usage: c++execfrf fileuser.cc"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++args"; usage = "c++args: Define user function arguments\n"; usage+= "Usage: c++args arg1 arg2 arg3 ...\n"; usage+= " c++args -? : give current arguments\n"; usage+= " c++args : reset current arguments"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++create"; usage = "c++create: create a file to be used by spiapp\n"; usage+= "Usage: c++create file.cc func c++ user code...\n"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++createfrf"; usage = "c++createfrf: create a file \"file.cc\"to be used by spiapp\n"; usage+= " with a user file \"fileuser.cc\"\n"; usage+= "Usage: c++createfrf file.cc func fileuser.cc\n"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++compile"; usage = "c++compile: compile a file (file.cc -> file.so)\n"; usage+= "Usage: c++compile file\n"; usage+= "Warning: give \"file\" or \"file.so\" to create \"file.so\" from \"file.cc\"\n"; usage+= " : to be used before c++link"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++link"; usage = "c++link: link function \"func\" in file.so to spiapp\n"; usage+= "Usage: c++link file.so func"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++include"; usage = "c++include: give personnal includes to be used\n"; usage+= "Usage: c++include myinc1.h myinc2.h ...\n"; usage+= " c++include -? : give current include files\n"; usage+= " c++include : reset current include files\n"; usage+= "Warning: to be used before c++create... c++exec..."; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++compileopt"; usage = "c++compileopt: give additionnal compile options\n"; usage+= "Usage: c++compileopt -g -O5 -IMy_Inc_Dir ...\n"; usage+= " c++compileopt -? : give current compile options\n"; usage+= " c++compileopt : reset current compile options\n"; usage+= "Warning: to be used before c++compile"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++linkopt"; usage = "c++linkopt: give additionnal link options\n"; usage+= "Usage: c++linkopt -g -O5 ...\n"; usage+= " c++linkopt -? : give current link options\n"; usage+= " c++linkopt : reset current link options\n"; usage+= "Warning: to be used before c++compile"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++mylibs"; usage = "c++mylibs: give additionnal libraries\n"; usage+= "Usage: c++mylibs -LMy_Lib_Dir -lmylib1 -lmylib2 ...\n"; usage+= " c++mylibs -? : give current additionnal libraries\n"; usage+= " c++mylibs : reset current additionnal libraries\n"; usage+= "Warning: to be used before c++compile"; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++setvar"; usage = "c++setvar: Setting test variable \n"; usage+= "c++setvar varname varcontent "; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++getvar"; usage = "c++getvar: Getting test variable content\n"; usage+= "c++getvar varname "; mpiac->RegisterCommand(kw, usage, this, hgrp); kw = "c++varlist"; usage = "c++getvar: Printing test variable list\n"; usage+= "c++varlist "; mpiac->RegisterCommand(kw, usage, this, hgrp); } /* --Methode-- */ CxxExecutor::~CxxExecutor() { } /* --Methode-- */ int CxxExecutor::Execute(string& kw, vector& tokens) { int rc=0; if(kw == "c++exec" || kw == "c++execfrf") { if(tokens.size()<1) { cout<<"Usage: c++exec c++ user code"<=1) rc = Compile(tokens[0]); else rc = Compile(); if(rc) return(1); } else if(kw == "c++link") { if(tokens.size()>=2) rc = Link(tokens[0],tokens[1]); else if(tokens.size()>=1) rc = Link(tokens[0]); else rc = Link(); if(rc) return(1); } else if(kw == "c++include") { if(tokens.size()==1) if(tokens[0]=="-?") cout<<"c++include "<2) for(uint_4 i=2;i& args );"<& args )"<"<"<"<"<"<"<"<"<"<"<"<"<"<"< objlist; string patt = "*"; omg.GetObjList(patt,objlist); int nobjs = objlist.size(); os<<"//-------------- Object List --------------"<GetDataObjType(); stmp = "___" + nobj; os<<"___nomobj = \""<(omg.GetObj(___nomobj));"<& usercode,uint_4 first) // - first is the first position in the vector<> where the code starts { mUserCode.resize(0); uint_4 nus = usercode.size(); if(nus<=first) { cout<<"CxxExecutor::FillUserCode: no user code"<CmdInterpreter(); string key("link"); vector arg; arg.push_back(libname); arg.push_back(func); int rc = mpiac->ExecuteCommand(key,arg); cout<<"Link from "<CmdInterpreter(); string key("call"); vector arg; arg.push_back(func); if(mCallArgs.size()>0) for(int i=0;iExecuteCommand(key,arg); return 0; } /* --Methode-- */ void CxxExecutor::FillArgs(vector& args) { mCallArgs.resize(0); if(args.size()<1) return; for(uint_4 i=0;i& inc) { mIncList.resize(0); if(inc.size()<1) return; for(uint_4 i=0;i& copt) { mCompOpt = ""; if(copt.size()<1) return; for(uint_4 i=0;i& lopt) { mLinkOpt = ""; if(lopt.size()<1) return; for(uint_4 i=0;i& llibs) { mMyLibs = ""; if(llibs.size()<1) return; for(uint_4 i=0;i& usercode,uint_4 first) // - first is the first position in the vector<> where the code starts { mUserCode.resize(0); uint_4 nus = usercode.size(); if(nus<=first) { cout<<"CxxExecutor::FillUserCode: no user code"< tokens[0]="salut tokens[1]=ca tokens[2]=va" --> "salutcava" // - On contourne partiellement le pb en ajoutant un blanc en debut des tokens[] // identifies comme etant dans une chaine de caracteres (mais impossible de gerer // si il y a plusieurs blancs!): "salut ca va" -> "salut ca va" // **** Conclusion **** // Pour ecrire du code sophistique, le faire dans un fichier string dum = ""; bool lastchar = false; bool comment = false; for(uint_4 i=first;i ajouter un blanc if(j==0 && comment) dum += " "; // on arrive sur un " : debut ou fin commentaire? inactif (\")? if(str[j]=='"') { if(j==0) comment = (comment) ? false: true; else {if(str[j-1]!='\\') comment = (comment) ? false: true;} } dum += str[j]; if( i==nus-1 && j==lstr-1 ) lastchar = true; // On charge la string "dum" si : 1-/ on a un ";" // 2-/ c'est le dernier charactere if((str[j]==';' && !comment) || lastchar) {mUserCode.push_back(dum); dum = "";} } } cout<<"User code filled from standard input"<& vs,char sep) // Use string "s" to fill vector of strings "vs" // considering char "sep" as a separator. // Vector is filled from its end (no reset done). // Tp write a "sep" char, use \'sep' // Warning: separator "sep" could not be set to '\' // Ex: sep=' ': s="aaa bbb cc d " -> vs=(aaa,bbb,cc,d) // Ex: sep=';': s="aaa ;bbb; cc;d " -> vs=(aaa ,bbb, cc,d ) // Ex: sep=';': s=";aaa\;bbb;;;ccc;ddd" -> vs=(aaa;bbb,ccc,ddd) // Ex: sep=';': s=";aaa\;bbb;;;ccc;ddd\" -> vs=(aaa;bbb,ccc,ddd\) { uint_4 ls = s.size(); if(ls<=0 || sep=='\\') return; s += sep; // add a separator at the end const char* str = s.c_str(); ls = strlen(str); // str[ls-1]==sep cf ci-dessus string dum = ""; for(uint_4 i=0; i