Index: trunk/SophyaPI/PIext/cxxexecutor.cc
===================================================================
--- trunk/SophyaPI/PIext/cxxexecutor.cc	(revision 1265)
+++ trunk/SophyaPI/PIext/cxxexecutor.cc	(revision 1268)
@@ -12,8 +12,15 @@
 /* --Methode-- */
 CxxExecutor::CxxExecutor(PIACmd *mpiac, PIStdImgApp* /* app */)
-  : mUserCodeFn(""), mCompOpt(""), mLinkOpt(""), mMyLibs("")
+  : mUserCodeFn(""), mUserFctFn(""), mCompOpt(""), mLinkOpt(""), mMyLibs("")
+  , mDefTmp(""), mDefRoot("cxx_spiapp"), mDefFunc("usercxx")
 {
 mIncList.resize(0);
 mCallArgs.resize(0);
+
+// Gestion des fichiers par default dans TmpDir 
+//.... CMV a gerer mais pas forcement OK ... voir avec Rz
+//NamedObjMgr omg;
+//string tmpdir = omg.GetTmpDir();
+//if(tmpdir.size()>1) mDefTmp = tmpdir;
 
 // On enregistre les nouvelles commandes 
@@ -24,12 +31,12 @@
 usage = "c++exec: Execute the following c++ user code\n";
 usage+= "Usage: c++exec c++ user code\n";
-usage+= "Warning: c++ user code can be found in \"cxx_spiapp.h\"\n";
-usage+= "         total generated code can be found in \"cxx_spiapp.cc\"";
+usage+= "Warning: c++ user code can be found in \"TmpDir/"+mDefRoot+".h\"\n";
+usage+= "         total generated code can be found in \"TmpDir/"+mDefRoot+".cc\"";
 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\n";
-usage+= "Warning: total generated code can be found in \"cxx_spiapp.cc\"";
+usage = "c++execfrf: Execute c++ user_code [user_function_code]\n";
+usage+= "Usage: c++execfrf fileuser.cc [fileuserfct.cc]\n";
+usage+= "Warning: total generated code can be found in \"TmpDir/"+mDefRoot+".cc\"";
 mpiac->RegisterCommand(kw, usage, this, hgrp);
 
@@ -48,6 +55,7 @@
 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";
+usage+= "              with a user file code \"fileuser.cc\"\n";
+usage+= "             and an optional user function code \"fileuserfct.cc\"\n";
+usage+= "Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]\n";
 mpiac->RegisterCommand(kw, usage, this, hgrp);
 
@@ -105,15 +113,25 @@
 
 /* --Methode-- */
-int CxxExecutor::Execute(string& kw, vector<string>& tokens)
+int CxxExecutor::Execute(string& kw, vector<string>& tokens, string& toks)
 {
 int rc=0;
-if(kw == "c++exec" || kw == "c++execfrf") {
+if(kw == "c++exec") {
   if(tokens.size()<1) {
     cout<<"Usage: c++exec c++ user code"<<endl;
-    cout<<"Usage: c++execfrf fileuser.cc"<<endl;
     return(1);
   }
-  if(kw == "c++exec")    rc = FillUserCode(tokens,0);
-  if(kw == "c++execfrf") rc = FillUserCode(tokens[0]);
+  rc = FillUserCode(toks,0); if(rc) return(1);
+  rc = CrFile();   if(rc) return(1);
+  rc = Compile();  if(rc) return(1);
+  rc = Link();     if(rc) return(1);
+  rc = Call();     if(rc) return(1);
+
+} else if(kw == "c++execfrf") {
+  if(tokens.size()<1) {
+    cout<<"Usage: c++execfrf fileuser.cc [fileuserfct.cc]"<<endl;
+    return(1);
+  }
+  if(tokens.size()>1) rc = FillUserCode(tokens[0],tokens[1]);
+    else              rc = FillUserCode(tokens[0]);
   if(rc) return(1);
   rc = CrFile();   if(rc) return(1);
@@ -132,13 +150,15 @@
     return(1);
   }
-  rc = FillUserCode(tokens,2);       if(rc) return(1);
+  rc = FillUserCode(toks,2);       if(rc) return(1);
   rc = CrFile(tokens[0],tokens[1]);  if(rc) return(1);
 
 } else if(kw == "c++createfrf") {
   if(tokens.size()<3) {
-    cout<<"Usage: c++createfrf file.cc func fileuser.cc"<<endl;
+    cout<<"Usage: c++createfrf file.cc func fileuser.cc [fileuserfct.cc]"<<endl;
     return(1);
   }
-  rc = FillUserCode(tokens[2]);     if(rc) return(1);
+  if(tokens.size()>3) rc = FillUserCode(tokens[2],tokens[3]);
+    else              rc = FillUserCode(tokens[2]);
+  if(rc) return(1);
   rc = CrFile(tokens[0],tokens[1]); if(rc) return(1);
 
@@ -173,30 +193,5 @@
     {cout<<"c++mylibs "<<GetLinkLibs()<<endl; return(0);}
   FillLinkLibs(tokens);
-
-
-//// A VIRER quand variable de objmanager OK  --> Pour Reza
-} else if(kw == "c++setvar") {
-  if(tokens.size()<2) {
-    cout<<" Usage: c++setvar varname varcontent "<<endl;
-    return(1);
-  }
-  string varcont = tokens[1];
-  if(tokens.size()>2) 
-    for(uint_4 i=2;i<tokens.size();i++) varcont += " " + tokens[i] ;
-  NamedObjMgr omg;
-  omg.SetVar(tokens[0], varcont);
-} else if(kw == "c++getvar") {
-  if(tokens.size()<1) {
-    cout<<" Usage: c++getvar varname "<<endl;
-    return(1);
-  }
-  NamedObjMgr omg;
-  cout<<"c++getvar("<<tokens[0]<<")="<<omg.GetVar(tokens[0])<<endl;
-}  else if(kw == "c++varlist") {
-  NamedObjMgr omg; 
-  cout<<omg.GetVarList();
-}
-//// A VIRER quand variable de objmanager OK  --> Pour Reza
-
+}
 
 return(0);
@@ -204,30 +199,9 @@
 
 /* --Methode-- */
-int CxxExecutor::ExecuteCxx(string const & code)
-{
-  int rc;
-
-  mUserCodeFn = "";
-  mUserCodeFn = "cxx_spiapp.h";
-  ofstream os(mUserCodeFn.c_str(),ios::out);
-  if(!os) {cout<<"CxxExecutor::ExecuteCxx(): unable to open "
-	       <<mUserCodeFn<<endl;  mUserCodeFn = ""; return 1;}
-  
-  os << code ;
-  os << endl ;
-
-  cout<<"CxxExecutor: User code filled from standard input into "
-      <<mUserCodeFn<<endl;
-  
-  rc = CrFile();   if(rc) return(1);
-  rc = Compile();  if(rc) return(1);
-  rc = Link();     if(rc) return(1);
-  rc = Call();     if(rc) return(1);
-  return(rc);
-}
-
-/* --Methode-- */
 int CxxExecutor::CrFile(string cfilename,string func)
 {
+if(cfilename.size()<1) cfilename = mDefTmp + mDefRoot + ".cc";
+if(func.size()<1) func = mDefFunc;
+
 ofstream os(cfilename.c_str(),ios::out);
 if(!os)
@@ -240,4 +214,11 @@
 PutIncludeUser(os);
 os<<endl;
+
+os<<"//-------------------------------------------------//"<<endl;
+os<<"//------------- Fonctions utilisateur -------------//"<<endl;
+os<<"//-------------------------------------------------//"<<endl;
+if(mUserFctFn.size()>0) os<<"#include \""<<mUserFctFn<<"\""<<endl;
+os<<endl;
+
 
 os<<"extern \"C\" {"<<endl;
@@ -378,19 +359,35 @@
 
 /* --Methode-- */
-int CxxExecutor::FillUserCode(vector<string>& usercode,uint_4 first)
-// - first is the first position in the vector<> where the code starts
-// User code is read from input. It is put into file "cxx_spiapp.h".
+int CxxExecutor::FillUserCode(string& usercode,uint_4 first)
+// - first is the first position in the "string" where the code starts
+// User code is read from input. It is put into file "TmpDir/cxx_spiapp.h".
 {
 mUserCodeFn = "";
-uint_4 nus = usercode.size();
-if(nus<=first) {cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
-                return 1;}
-mUserCodeFn = "cxx_spiapp.h";
+mUserFctFn  = "";
+
+// get the string part which is after word "first"
+string code = usercode;
+if(code.size()<=0) {cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
+                    return 1;}
+size_t q;
+for(uint_4 i=0;i<=first;i++) {
+  q = code.find_first_not_of(" \t");
+  if(q>=code.size()) {code=""; break;}
+  code = code.substr(q);
+  if(i==first) break;
+  q = code.find_first_of(" \t");
+  if(q>=code.size()) {code=""; break;}
+  code = code.substr(q);
+}
+if(code.size()<=0)
+  {cout<<"CxxExecutor::FillUserCode: no user code after "<<first<<endl;
+   return 1;}
+
+// Fill the file with user code
+mUserCodeFn = mDefTmp + mDefRoot + ".h";
 ofstream os(mUserCodeFn.c_str(),ios::out);
 if(!os) {cout<<"CxxExecutor::FillUserCode: unable to open "
              <<mUserCodeFn<<endl;  mUserCodeFn = ""; return 1;}
-// On ajoute un blanc pour les chaines de caracteres contenant des blancs
-for(uint_4 i=first;i<nus;i++) os<<" "<<usercode[i];
-os<<endl;
+os<<" "<<code;
 cout<<"User code filled from standard input into "<<mUserCodeFn<<endl;
 return 0;
@@ -398,8 +395,9 @@
 
 /* --Methode-- */
-int CxxExecutor::FillUserCode(string filename)
-// User code is read from "filename".
+int CxxExecutor::FillUserCode(string filename,string filefctname)
+// User code is read from "filename" an optionally from filefctname.
 {
 mUserCodeFn = filename;
+mUserFctFn  = filefctname;
 cout<<"User code filled from file "<<filename<<endl;
 return 0;
@@ -409,15 +407,15 @@
 int CxxExecutor::Compile(string rootfilename)
 {
-string fc = rootfilename + ".cc";
-string fl = rootfilename + ".so";
+if(rootfilename.size()<1) rootfilename = mDefRoot;
 cout<<"Compile: "<<rootfilename<<endl;
 int rc = 0;
 rc = CrMakefile();
 if(rc) return(1);
-string make  = "make -f cxx_spiapp_Makefile";
-       make += " CXXFLAGS=\"" + mCompOpt + "\"";
-       make += " LDFLAGS=\""  + mLinkOpt + "\"";
-       make += " MYLIBS=\""   + mMyLibs  + "\"";
-       make += " " + rootfilename;
+string make  = "";
+make += "make -f " + mDefRoot + "_Makefile";
+make += " CXXFLAGS=\"" + mCompOpt + "\"";
+make += " LDFLAGS=\""  + mLinkOpt + "\"";
+make += " MYLIBS=\""   + mMyLibs  + "\"";
+make += " " + rootfilename;
 rc = system(make.c_str());
 if(rc)
@@ -430,5 +428,6 @@
 int CxxExecutor::CrMakefile(void)
 {
-ofstream os("cxx_spiapp_Makefile",ios::out);
+string makename = mDefTmp + mDefRoot + "_Makefile";
+ofstream os(makename.c_str(),ios::out);
 if(!os)
   {cout<<"CxxExecutor::CrMakefile: unable to open file for Makefile"<<endl;
@@ -459,7 +458,7 @@
 os<<"\t"<<"$(LINK.cc) -shared -o $@ $< $(LIBS) $(MYLIBS)"<<endl;
 os<<"%.o:%.cc"<<endl;
-os<<"\t"<<"$(COMPILE.cc)  -o $@ $<"<<endl;
+os<<"\t"<<"$(COMPILE.cc) -o $@ $<"<<endl;
 os<<"%.o:%.c"<<endl;
-os<<"\t"<<"$(COMPILE.c) -c $(CFLAGS)   $(USERFLAGS) -o $@ $<"<<endl;
+os<<"\t"<<"$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $<"<<endl;
 //---------------------------------------------------------------------
 return 0;
@@ -469,9 +468,13 @@
 int CxxExecutor::Link(string libname,string func)
 {
+if(libname.size()<1) libname = mDefTmp + mDefRoot + ".so";
+if(func.size()<1) func = mDefFunc;
+
 NamedObjMgr omg;
 PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
 string key("link");
 vector<string> arg; arg.push_back(libname); arg.push_back(func);
-int rc = mpiac->ExecuteCommand(key,arg);
+string toks = libname + " " + func;
+int rc = mpiac->ExecuteCommand(key,arg,toks);
 cout<<"Link from "<<libname<<" for function "<<func
     <<" (rc="<<rc<<")"<<endl;
@@ -482,11 +485,14 @@
 int CxxExecutor::Call(string func)
 {
+if(func.size()<1) func = mDefFunc;
+
 NamedObjMgr omg;
 PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
 string key("call");
 vector<string> arg; arg.push_back(func);
+string toks = func;
 if(mCallArgs.size()>0)
   for(uint_4 i=0;i<mCallArgs.size();i++) arg.push_back(mCallArgs[i]);
-mpiac->ExecuteCommand(key,arg);
+mpiac->ExecuteCommand(key,arg,toks);
 return 0;
 }
@@ -589,63 +595,2 @@
 return mMyLibs;
 }
-
-
-
-
-/* --Methode--  DO NOT DELETE.... cmv property !!!
-int CxxExecutor::FillUserCode(vector<string>& usercode,uint_4 first)
-{
-mUserCodeFn = "";
-uint_4 nus = usercode.size();
-if(nus<=first) {
-  cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
-  return 1;
-}
-mUserCodeFn = "cxx_spiapp.h";
-ofstream os(mUserCodeFn.c_str(),ios::out);
-if(!os)
-  {cout<<"CxxExecutor::FillUserCode: unable to open "<<mUserCodeFn<<endl;
-   mUserCodeFn = ""; return 1;}
-// **** 1er probleme ****
-// - Pour la lisibilite et eviter les bugs avec les chaines de caracteres
-// contenant des blancs, on ne casse les lignes qu'apres un ";" a condition
-// qu'il ne soit pas dans une chaine de caracteres c'est a dire
-// entoure de "....;....".
-// - Attention aux " dans les chaines de caracteres:  "...\"..."
-// - Bugs non-gere pour les tortures: ".....\\" suivi par une autre
-//   chaine de caracteres qui contient un ';'
-//   ex: cout<<"aaa\\"; cout<<"blabla;blabla";
-// **** 2ieme probleme ****
-// - Le decodeur de ligne va couper les commentaires qui contiennent des blancs:
-// "salut ca va" --> 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<nus;i++) {
-  const char* str = usercode[i].c_str();
-  size_t lstr= strlen(str);
-  for(uint_4 j=0;j<lstr;j++) {
-    // debut de mot dans un commentaire -> 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)
-      {os<<dum<<endl; dum = "";}
-  }
-}
-cout<<"User code filled from standard input into "<<mUserCodeFn<<endl;
-return 0;
-}
-*/
