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

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

bug mineur cmv 12/10/00

  • Property svn:executable set to *
File size: 19.1 KB
RevLine 
[1224]1#include "cxxexecutor.h"
2
3#include <typeinfo>
4
5#include "dvlist.h"
6
7#include "nomgadapter.h"
8#include "pistdimgapp.h"
9
10
[1230]11void FillVStringFrString(string s,vector<string>& vs,char sep = ' ');
[1224]12
[1230]13
[1224]14/* --Methode-- */
15CxxExecutor::CxxExecutor(PIACmd *mpiac, PIStdImgApp* /* app */)
16 : mCompOpt(""), mLinkOpt(""), mMyLibs("")
17{
18mUserCode.resize(0);
19mIncList.resize(0);
20mCallArgs.resize(0);
21
22NamedObjMgr omg;
23
24// On enregistre les nouvelles commandes
25string hgrp = "CxxExecutorCmd";
26string usage,kw;
27
28kw = "c++exec";
29usage = "c++exec: Execute the following c++ user code\n";
30usage+= "Usage: c++exec c++ user code";
31mpiac->RegisterCommand(kw, usage, this, hgrp);
32
33kw = "c++execfrf";
34usage = "c++execfrf: Execute c++ user code contained in a file\n";
35usage+= "Usage: c++execfrf fileuser.cc";
36mpiac->RegisterCommand(kw, usage, this, hgrp);
37
38kw = "c++args";
39usage = "c++args: Define user function arguments\n";
[1230]40usage+= "Usage: c++args arg1 arg2 arg3 ...\n";
41usage+= " c++args -? : give current arguments\n";
42usage+= " c++args : reset current arguments";
[1224]43mpiac->RegisterCommand(kw, usage, this, hgrp);
44
45kw = "c++create";
46usage = "c++create: create a file to be used by spiapp\n";
47usage+= "Usage: c++create file.cc func c++ user code...\n";
48mpiac->RegisterCommand(kw, usage, this, hgrp);
49
50kw = "c++createfrf";
51usage = "c++createfrf: create a file \"file.cc\"to be used by spiapp\n";
52usage+= " with a user file \"fileuser.cc\"\n";
53usage+= "Usage: c++createfrf file.cc func fileuser.cc\n";
54mpiac->RegisterCommand(kw, usage, this, hgrp);
55
56kw = "c++compile";
57usage = "c++compile: compile a file (file.cc -> file.so)\n";
58usage+= "Usage: c++compile file\n";
59usage+= "Warning: give \"file\" or \"file.so\" to create \"file.so\" from \"file.cc\"\n";
60usage+= " : to be used before c++link";
61mpiac->RegisterCommand(kw, usage, this, hgrp);
62
63kw = "c++link";
64usage = "c++link: link function \"func\" in file.so to spiapp\n";
65usage+= "Usage: c++link file.so func";
66mpiac->RegisterCommand(kw, usage, this, hgrp);
67
68kw = "c++include";
69usage = "c++include: give personnal includes to be used\n";
70usage+= "Usage: c++include myinc1.h myinc2.h ...\n";
[1230]71usage+= " c++include -? : give current include files\n";
72usage+= " c++include : reset current include files\n";
[1224]73usage+= "Warning: to be used before c++create... c++exec...";
74mpiac->RegisterCommand(kw, usage, this, hgrp);
75
76kw = "c++compileopt";
77usage = "c++compileopt: give additionnal compile options\n";
78usage+= "Usage: c++compileopt -g -O5 -IMy_Inc_Dir ...\n";
[1230]79usage+= " c++compileopt -? : give current compile options\n";
80usage+= " c++compileopt : reset current compile options\n";
[1224]81usage+= "Warning: to be used before c++compile";
82mpiac->RegisterCommand(kw, usage, this, hgrp);
83
84kw = "c++linkopt";
85usage = "c++linkopt: give additionnal link options\n";
[1230]86usage+= "Usage: c++linkopt -g -O5 ...\n";
87usage+= " c++linkopt -? : give current link options\n";
88usage+= " c++linkopt : reset current link options\n";
[1224]89usage+= "Warning: to be used before c++compile";
90mpiac->RegisterCommand(kw, usage, this, hgrp);
91
92kw = "c++mylibs";
93usage = "c++mylibs: give additionnal libraries\n";
[1230]94usage+= "Usage: c++mylibs -LMy_Lib_Dir -lmylib1 -lmylib2 ...\n";
95usage+= " c++mylibs -? : give current additionnal libraries\n";
96usage+= " c++mylibs : reset current additionnal libraries\n";
[1224]97usage+= "Warning: to be used before c++compile";
98mpiac->RegisterCommand(kw, usage, this, hgrp);
99
[1230]100
101
[1224]102kw = "c++setvar";
103usage = "c++setvar: Setting test variable \n";
104usage+= "c++setvar varname varcontent ";
105mpiac->RegisterCommand(kw, usage, this, hgrp);
106
107kw = "c++getvar";
108usage = "c++getvar: Getting test variable content\n";
109usage+= "c++getvar varname ";
110mpiac->RegisterCommand(kw, usage, this, hgrp);
111
112kw = "c++varlist";
113usage = "c++getvar: Printing test variable list\n";
114usage+= "c++varlist ";
115mpiac->RegisterCommand(kw, usage, this, hgrp);
116
117}
118
119/* --Methode-- */
120CxxExecutor::~CxxExecutor()
121{
122}
123
124/* --Methode-- */
125int CxxExecutor::Execute(string& kw, vector<string>& tokens)
126{
127int rc=0;
128if(kw == "c++exec" || kw == "c++execfrf") {
129 if(tokens.size()<1) {
130 cout<<"Usage: c++exec c++ user code"<<endl;
131 cout<<"Usage: c++execfrf fileuser.cc"<<endl;
132 return(1);
133 }
134 if(kw == "c++exec") rc = FillUserCode(tokens,0);
135 if(kw == "c++execfrf") 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") {
[1233]143 if(tokens.size()==1) if(tokens[0]=="-?")
144 {cout<<"c++args "<<GetArgs()<<endl; return(0);}
[1230]145 FillArgs(tokens);
[1224]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(tokens,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"<<endl;
158 return(1);
159 }
160 rc = FillUserCode(tokens[2]); if(rc) return(1);
161 rc = CrFile(tokens[0],tokens[1]); if(rc) return(1);
162
163} else if(kw == "c++compile") {
164 if(tokens.size()>=1) rc = Compile(tokens[0]);
165 else rc = Compile();
166 if(rc) return(1);
167
168} else if(kw == "c++link") {
169 if(tokens.size()>=2) rc = Link(tokens[0],tokens[1]);
170 else if(tokens.size()>=1) rc = Link(tokens[0]);
171 else rc = Link();
172 if(rc) return(1);
173
174} else if(kw == "c++include") {
[1233]175 if(tokens.size()==1) if(tokens[0]=="-?")
176 {cout<<"c++include "<<GetInclude()<<endl; return(0);}
[1230]177 FillInclude(tokens);
[1224]178
179} else if(kw == "c++compileopt") {
[1233]180 if(tokens.size()==1) if(tokens[0]=="-?")
181 {cout<<"c++compileopt "<<GetCompileOpt()<<endl; return(0);}
[1230]182 FillCompileOpt(tokens);
[1224]183
184} else if(kw == "c++linkopt") {
[1233]185 if(tokens.size()==1) if(tokens[0]=="-?")
186 {cout<<"c++linkopt "<<GetLinkOpt()<<endl; return(0);}
[1230]187 FillLinkOpt(tokens);
[1224]188
189} else if(kw == "c++mylibs") {
[1233]190 if(tokens.size()==1) if(tokens[0]=="-?")
191 {cout<<"c++mylibs "<<GetLinkLibs()<<endl; return(0);}
[1230]192 FillLinkLibs(tokens);
[1224]193
[1230]194
195
[1224]196} else if(kw == "c++setvar") {
197 if(tokens.size()<2) {
[1230]198 cout<<" Usage: c++setvar varname varcontent "<<endl;
[1224]199 return(1);
200 }
201 string varcont = tokens[1];
202 if(tokens.size()>2)
203 for(uint_4 i=2;i<tokens.size();i++) varcont += " " + tokens[i] ;
204 NamedObjMgr omg;
205 omg.SetVar(tokens[0], varcont);
206} else if(kw == "c++getvar") {
207 if(tokens.size()<1) {
[1230]208 cout<<" Usage: c++getvar varname "<<endl;
[1224]209 return(1);
210 }
211 NamedObjMgr omg;
[1230]212 cout<<"c++getvar("<<tokens[0]<<")="<<omg.GetVar(tokens[0])<<endl;
[1224]213} else if(kw == "c++varlist") {
214 NamedObjMgr omg;
[1230]215 cout<<omg.GetVarList();
[1224]216}
217
218
219return(0);
220}
221
222/* --Methode-- */
223int CxxExecutor::CrFile(string cfilename,string func)
224{
225ofstream os(cfilename.c_str(),ios::out);
226if(!os) {
227 cout<<"CxxExecutor::CrFile: unable to open "<<cfilename<<endl;
228 return 1;
229}
230
231PutInclude(os);
232os<<endl;
233
234PutIncludeUser(os);
235os<<endl;
236
237os<<"extern \"C\" {"<<endl;
238os<<" int "<<func<<"( vector<string>& args );"<<endl;
239os<<"}"<<endl<<endl;
240os<<"int "<<func<<"( vector<string>& args )"<<endl;
241os<<"{"<<endl;
242os<<"// Some definitions to help using spiapp;"<<endl;
243os<<"NamedObjMgr omg;"<<endl;
244os<<"Services2NObjMgr& srvo = *omg.GetServiceObj();"<<endl;
245os<<"//omg.AddObj(OBJECT* object,string nom_object);"<<endl;
246os<<endl;
247
248PutObject(os);
249os<<endl;
250
251PutVar(os);
252os<<endl;
253
254PutUserCode(os);
255os<<endl;
256
257os<<endl;
258os<<"return 0;"<<endl;
259os<<"}"<<endl;
260
261cout<<"File "<<cfilename<<" for function "<<func<<" created"<<endl;
262return 0;
263}
264
265/* --Methode-- */
266void CxxExecutor::PutInclude(ofstream& os)
267{
268os<<"#include \"machdefs.h\""<<endl
269 <<endl
270
271 <<"//---- System et stdc++ include files"<<endl
272 <<"#include <stdio.h>"<<endl
273 <<"#include <stdlib.h>"<<endl
274 <<"#include <math.h>"<<endl
275 <<"#include <ctype.h>"<<endl
276 <<"#include <string.h>"<<endl
277 <<"#include <iostream.h>"<<endl
278 <<"#include <fstream.h>"<<endl
279 <<"#include <complex>"<<endl
280 <<endl
281
282 <<"#include <typeinfo>"<<endl
283 <<"#include <string>"<<endl
284 <<"#include <vector>"<<endl
285 <<"#include <map>"<<endl
286 <<"#include <functional>"<<endl
287 <<"#include <list>"<<endl
288 <<endl
289
290 <<"//---- Sophya include files"<<endl
291 <<"#include \"systools.h\""<<endl
292 <<"#include \"ntools.h\""<<endl
293 <<"#include \"array.h\""<<endl
294 <<"#include \"histats.h\""<<endl
295 <<endl
296
297 <<"//---- Spiapp include files"<<endl
298 <<"#include \"nobjmgr.h\""<<endl
299 <<"#include \"servnobjm.h\""<<endl
300 <<endl
301
302 <<"#define KeepObj(obj) ___nomobj = #obj; omg.AddObj(obj,___nomobj);"<<endl
303 <<"#define KeepVar(var) ___nomobj = #var; omg.GetVarList().Get(___nomobj) = var ;"<<endl
304 <<endl;
305
306return;
307}
308
309/* --Methode-- */
310void CxxExecutor::PutIncludeUser(ofstream& os)
311{
312if(mIncList.size()<1) return;
313for(uint_4 i=0;i<mIncList.size();i++)
314 os<<"#include \""<<mIncList[i]<<"\""<<endl;
315}
316
317/* --Methode-- */
318void CxxExecutor::PutObject(ofstream& os)
319{
320NamedObjMgr omg;
321NObjMgrAdapter* objmgrad;
322vector<string> objlist;
323string patt = "*";
324omg.GetObjList(patt,objlist);
325int nobjs = objlist.size();
326
327os<<"//-------------- Object List --------------"<<endl;
328os<<"//Number of objects = "<<nobjs<<endl;
329os<<"string ___nomobj;"<<endl<<endl;
330if(nobjs<=0) return;
331
332string dir,nobj,stmp,obtype;
333for(int i=0;i<nobjs;i++) {
334 objmgrad = omg.GetObjAdapter(objlist[i]);
335 omg.ParseObjectName(objlist[i],dir,nobj);
336 obtype = objmgrad->GetDataObjType();
337 stmp = "___" + nobj;
338
339 os<<"___nomobj = \""<<nobj<<"\";"<<endl;
340 os<<obtype<<"* "<<stmp
341 <<" = dynamic_cast< "<<obtype<<" * >(omg.GetObj(___nomobj));"<<endl;
342 os<<"if("<<stmp<<"==NULL) throw NullPtrError"
343 <<"(\"CxxExecutor::PutObject: Non existing object "<<nobj
344 <<"... please update file\");"<<endl;
345 os<<obtype<<"& "<<nobj<<" = (*"<<stmp<<");"<<endl<<endl;
346}
347
348return;
349}
350
351/* --Methode-- */
352void CxxExecutor::PutVar(ofstream& os)
353{
354os<<"//-------------- Variable List --------------"<<endl;
355NamedObjMgr omg;
356DVList& varlist = omg.GetVarList();
357// varlist.Show(); varlist.Print();
358DVList::ValList::const_iterator it;
359for(it=varlist.Begin(); it!=varlist.End(); it++) {
360 string key = (*it).first;
361 os<<"___nomobj = \""<<key<<"\";"<<endl;
362 os<<"MuTyV & "<<key<<" = omg.GetVarList().Get(___nomobj);"<<endl;
363}
364
365}
366
367/* --Methode-- */
368void CxxExecutor::PutUserCode(ofstream& os)
369{
370os<<"//--------------------------------------------//"<<endl;
371os<<"//------------- Code utilisateur -------------//"<<endl;
372os<<"//--------------------------------------------//"<<endl;
373os<<endl;
374if(mUserCode.size()<1) return;
375for(uint_4 i=0;i<mUserCode.size();i++) os<<mUserCode[i]<<endl;
376}
377
378/* --Methode-- */
379int CxxExecutor::FillUserCode(vector<string>& usercode,uint_4 first)
380// - first is the first position in the vector<> where the code starts
381{
382mUserCode.resize(0);
383uint_4 nus = usercode.size();
384if(nus<=first) {
385 cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
386 return 1;
387}
388string dum = "";
389// On ajoute un blanc pour les chaines de caracteres contenant des blancs
390for(uint_4 i=first;i<nus;i++) dum += " " + usercode[i];
391// Tout dans une seule ligne pour eviter les pbs (cf au bas du fichier)
392mUserCode.push_back(dum);
393cout<<"User code filled from standard input"<<endl;
394return 0;
395}
396
397/* --Methode-- */
398int CxxExecutor::FillUserCode(string filename)
399{
400mUserCode.resize(0);
401
402ifstream is(filename.c_str());
403if(!is) {
404 cout<<"CxxExecutor::FillUserCode: unable to open "<<filename<<endl;
405 return 1;
406}
407
408int nline = 4096; // Au plus 4096 characters par ligne!
409char *str = new char[nline+2];
410while(is)
411 {is.getline(str,nline); mUserCode.push_back((string) str);}
412delete [] str;
413if(mUserCode.size()<=0) {
414 return 2;
415 cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
416}
417
[1230]418cout<<"User code filled from file "<<filename<<endl;
[1224]419return 0;
420}
421
422/* --Methode-- */
423int CxxExecutor::Compile(string rootfilename)
424{
425string fc = rootfilename + ".cc";
426string fl = rootfilename + ".so";
427cout<<"Compile: "<<rootfilename<<endl;
428int rc = 0;
429rc = CrMakefile();
430if(rc) return(1);
431string make = "make -f cxx_spiapp_Makefile";
432 make += " CXXFLAGS=\"" + mCompOpt + "\"";
433 make += " LDFLAGS=\"" + mLinkOpt + "\"";
434 make += " MYLIBS=\"" + mMyLibs + "\"";
435 make += " " + rootfilename;
436rc = system(make.c_str());
437if(rc)
438 {cout<<"CxxExecutor::Compile : \n"<<make<<" Failed"<<endl;
439 return 1000+rc;}
440return 0;
441}
442
443/* --Methode-- */
444int CxxExecutor::CrMakefile(void)
445{
446ofstream os("cxx_spiapp_Makefile",ios::out);
447if(!os)
448 {cout<<"CxxExecutor::CrMakefile: unable to open file for Makefile"<<endl;
449 return 1;}
450//---------------------------------------------------------------------
451os<<"MODULEDECCXXFLAGS := -msg_quiet"<<endl;
452os<<"include $(DPCBASEREP)/Include/MakefileUser.h"<<endl;
453os<<"MYLIBS ="<<endl;
454os<<"LIBS = -L$(SLB) -lPI -lextsophya -lsophya -lm"<<endl;
455os<<"ifeq ($(MACHEROS),OSF1)"<<endl;
456os<<"LIBS := $(LIBS) -lfor"<<endl;
457os<<"endif"<<endl;
458os<<"ifeq ($(MACHEROS),Linux)"<<endl;
459os<<"LIBS := $(LIBS) -ldl -lf2c"<<endl;
460os<<"endif"<<endl;
461os<<"%.so:$(OBJ)%.o"<<endl;
462os<<"%:%.cc"<<endl;
463os<<"%:%.o"<<endl;
464os<<"%.o:%.cc"<<endl;
465os<<"%.o:%.c"<<endl;
466os<<"%:%.c"<<endl;
467os<<endl;
468os<<".PRECIOUS: %.so"<<endl;
469os<<endl;
470os<<"%:%.so"<<endl;
471os<<"\t"<<"echo $@ \" made (.so) \""<<endl;
472os<<"%.so:$(OBJ)%.o"<<endl;
473os<<"\t"<<"$(LINK.cc) -shared -o $@ $< $(LIBS) $(MYLIBS)"<<endl;
474os<<"$(OBJ)%.o:%.cc"<<endl;
475os<<"\t"<<"$(COMPILE.cc) -o $@ $<"<<endl;
476os<<"$(OBJ)%.o:%.c"<<endl;
477os<<"\t"<<"$(COMPILE.c) -c $(CFLAGS) $(USERFLAGS) -o $@ $<"<<endl;
478//---------------------------------------------------------------------
479return 0;
480}
481
482/* --Methode-- */
483int CxxExecutor::Link(string libname,string func)
484{
485NamedObjMgr omg;
486PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
487string key("link");
488vector<string> arg; arg.push_back(libname); arg.push_back(func);
489int rc = mpiac->ExecuteCommand(key,arg);
490cout<<"Link from "<<libname<<" for function "<<func
491 <<" (rc="<<rc<<")"<<endl;
492return 0;
493}
494
495/* --Methode-- */
496int CxxExecutor::Call(string func)
497{
498NamedObjMgr omg;
499PIACmd* mpiac = omg.GetImgApp()->CmdInterpreter();
500string key("call");
501vector<string> arg; arg.push_back(func);
502if(mCallArgs.size()>0)
503 for(int i=0;i<mCallArgs.size();i++) arg.push_back(mCallArgs[i]);
504mpiac->ExecuteCommand(key,arg);
505return 0;
506}
507
[1230]508/* --Methode-- */
509void CxxExecutor::FillArgs(vector<string>& args)
510{
511mCallArgs.resize(0);
512if(args.size()<1) return;
513for(uint_4 i=0;i<args.size();i++) mCallArgs.push_back(args[i]);
514}
515
516void CxxExecutor::FillArgs(string& args)
517{
518mCallArgs.resize(0);
519FillVStringFrString(args,mCallArgs,' ');
520}
521
522string CxxExecutor::GetArgs(void)
523{
524string dum = "";
525if(mCallArgs.size()<1) return dum;
526for(uint_4 i=0;i<mCallArgs.size();i++) dum += mCallArgs[i] + " ";
527return dum;
528}
529
530/* --Methode-- */
531void CxxExecutor::FillInclude(vector<string>& inc)
532{
533mIncList.resize(0);
534if(inc.size()<1) return;
535for(uint_4 i=0;i<inc.size();i++) mIncList.push_back(inc[i]);
536}
537
538void CxxExecutor::FillInclude(string& inc)
539{
540mIncList.resize(0);
541FillVStringFrString(inc,mIncList,' ');
542}
543
544string CxxExecutor::GetInclude(void)
545{
546string dum = "";
547if(mIncList.size()<1) return dum;
548for(uint_4 i=0;i<mIncList.size();i++) dum += mIncList[i] + " ";
549return dum;
550}
551
552/* --Methode-- */
553void CxxExecutor::FillCompileOpt(vector<string>& copt)
554{
555mCompOpt = "";
556if(copt.size()<1) return;
557for(uint_4 i=0;i<copt.size();i++) mCompOpt += copt[i] + " ";
558}
559
560void CxxExecutor::FillCompileOpt(string& copt)
561{
562mCompOpt = copt;
563}
564
565string CxxExecutor::GetCompileOpt(void)
566{
567return mCompOpt;
568}
569
570/* --Methode-- */
571void CxxExecutor::FillLinkOpt(vector<string>& lopt)
572{
573mLinkOpt = "";
574if(lopt.size()<1) return;
575for(uint_4 i=0;i<lopt.size();i++) mLinkOpt += lopt[i] + " ";
576}
577
578void CxxExecutor::FillLinkOpt(string& lopt)
579{
580mLinkOpt = lopt;
581}
582
583string CxxExecutor::GetLinkOpt(void)
584{
585return mLinkOpt;
586}
587
588/* --Methode-- */
589void CxxExecutor::FillLinkLibs(vector<string>& llibs)
590{
591mMyLibs = "";
592if(llibs.size()<1) return;
593for(uint_4 i=0;i<llibs.size();i++) mMyLibs += llibs[i] + " ";
594}
595
596void CxxExecutor::FillLinkLibs(string& llibs)
597{
598mMyLibs = llibs;
599}
600
601string CxxExecutor::GetLinkLibs(void)
602{
603return mMyLibs;
604}
605
606
607
608
[1224]609/* --Methode-- DO NOT DELETE.... cmv property !!!
610int CxxExecutor::FillUserCode(vector<string>& usercode,uint_4 first)
611// - first is the first position in the vector<> where the code starts
612{
613mUserCode.resize(0);
614uint_4 nus = usercode.size();
615if(nus<=first) {
616 cout<<"CxxExecutor::FillUserCode: no user code"<<endl;
617 return 1;
618}
619// **** 1er probleme ****
620// - Pour la lisibilite et eviter les bugs avec les chaines de caracteres
621// contenant des blancs, on ne casse les lignes qu'apres un ";" a condition
622// qu'il ne soit pas dans une chaine de caracteres c'est a dire
623// entoure de "....;....".
624// - Attention aux " dans les chaines de caracteres: "...\"..."
625// - Bugs non-gere pour les tortures: ".....\\" suivi par une autre
626// chaine de caracteres qui contient un ';'
627// ex: cout<<"aaa\\"; cout<<"blabla;blabla";
628// **** 2ieme probleme ****
629// - Le decodeur de ligne va couper les commentaires qui contiennent des blancs:
630// "salut ca va" --> tokens[0]="salut tokens[1]=ca tokens[2]=va" --> "salutcava"
631// - On contourne partiellement le pb en ajoutant un blanc en debut des tokens[]
632// identifies comme etant dans une chaine de caracteres (mais impossible de gerer
633// si il y a plusieurs blancs!): "salut ca va" -> "salut ca va"
634// **** Conclusion ****
635// Pour ecrire du code sophistique, le faire dans un fichier
636string dum = "";
637bool lastchar = false;
638bool comment = false;
639for(uint_4 i=first;i<nus;i++) {
640 const char* str = usercode[i].c_str();
641 size_t lstr= strlen(str);
642 for(uint_4 j=0;j<lstr;j++) {
643 // debut de mot dans un commentaire -> ajouter un blanc
644 if(j==0 && comment) dum += " ";
645 // on arrive sur un " : debut ou fin commentaire? inactif (\")?
646 if(str[j]=='"') {
647 if(j==0) comment = (comment) ? false: true;
648 else {if(str[j-1]!='\\') comment = (comment) ? false: true;}
649 }
650 dum += str[j];
651 if( i==nus-1 && j==lstr-1 ) lastchar = true;
652 // On charge la string "dum" si : 1-/ on a un ";"
653 // 2-/ c'est le dernier charactere
654 if((str[j]==';' && !comment) || lastchar)
655 {mUserCode.push_back(dum); dum = "";}
656 }
657}
658cout<<"User code filled from standard input"<<endl;
659return 0;
660}
661*/
662
[1230]663
664void FillVStringFrString(string s,vector<string>& vs,char sep)
665// Use string "s" to fill vector of strings "vs"
666// considering char "sep" as a separator.
667// Vector is filled from its end (no reset done).
668// Tp write a "sep" char, use \'sep'
669// Warning: separator "sep" could not be set to '\'
670// Ex: sep=' ': s="aaa bbb cc d " -> vs=(aaa,bbb,cc,d)
671// Ex: sep=';': s="aaa ;bbb; cc;d " -> vs=(aaa ,bbb, cc,d )
672// Ex: sep=';': s=";aaa\;bbb;;;ccc;ddd" -> vs=(aaa;bbb,ccc,ddd)
673// Ex: sep=';': s=";aaa\;bbb;;;ccc;ddd\" -> vs=(aaa;bbb,ccc,ddd\)
674{
675uint_4 ls = s.size();
676if(ls<=0 || sep=='\\') return;
677s += sep; // add a separator at the end
678const char* str = s.c_str();
679ls = strlen(str); // str[ls-1]==sep cf ci-dessus
680string dum = "";
681for(uint_4 i=0; i<ls; i++) {
682 if(i==0 && str[i]==sep) {
683 continue;
684 } else if(str[i]=='\\') {
685 if(str[i+1]!=sep || i==ls-2) dum += str[i];
686 } else if(str[i]!=sep) {
687 dum += str[i];
688 } else { // C'est un "sep" mais est-ce vraiment un separateur?
689 if(str[i-1]=='\\' && i!=ls-1) dum += str[i];
690 else { // C'est un separateur, ne delimite t-il pas d'autres separateurs?
691 if(dum.size()<=0) continue;
692 vs.push_back(dum);
693 dum = "";
694 }
695 }
696}
697}
Note: See TracBrowser for help on using the repository browser.