]> Creatis software - crea.git/blob - lib/creaDevManagerLib/modelCDMLib.cpp
69bfcff7d3f92a023c8c8590bdf341b39ecf7ccc
[crea.git] / lib / creaDevManagerLib / modelCDMLib.cpp
1 /*
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image
5 #                        pour la Sant�)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 # Previous Authors : Laurent Guigues, Jean-Pierre Roux
8 # CreaTools website : www.creatis.insa-lyon.fr/site/fr/creatools_accueil
9 #
10 #  This software is governed by the CeCILL-B license under French law and
11 #  abiding by the rules of distribution of free software. You can  use,
12 #  modify and/ or redistribute the software under the terms of the CeCILL-B
13 #  license as circulated by CEA, CNRS and INRIA at the following URL
14 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
15 #  or in the file LICENSE.txt.
16 #
17 #  As a counterpart to the access to the source code and  rights to copy,
18 #  modify and redistribute granted by the license, users are provided only
19 #  with a limited warranty  and the software's author,  the holder of the
20 #  economic rights,  and the successive licensors  have only  limited
21 #  liability.
22 #
23 #  The fact that you are presently reading this means that you have had
24 #  knowledge of the CeCILL-B license and that you accept its terms.
25 # ------------------------------------------------------------------------
26  */
27
28 /*
29  * modelCDMLib.cpp
30  *
31  *  Created on: Nov 23, 2012
32  *      Author: Daniel Felipe Gonzalez Obando
33  */
34
35 #include "modelCDMLib.h"
36
37 #include <fstream>
38 #include <sstream>
39 #include <algorithm>
40
41 #include "CDMUtilities.h"
42 #include "creaWx.h"
43 #include "wx/dir.h"
44
45 modelCDMLib::modelCDMLib()
46 {
47 }
48
49 modelCDMLib::modelCDMLib(modelCDMIProjectTreeNode* parent, const std::string& path, const std::string& name, const int& level)
50 {
51   std::cout << "creating lib\n";
52   this->parent = parent;
53   this->type = wxDIR_DIRS;
54   this->name = name;
55   this->level = level;
56   this->path = path;
57
58
59
60   this->path = CDMUtilities::fixPath(path);
61   //open makelists file
62   std::string pathFixed(CDMUtilities::fixPath(path));
63
64   this->libraries.clear();
65   wxDir dir(crea::std2wx((pathFixed).c_str()));
66   if (dir.IsOpened())
67     {
68       wxString fileName;
69       //folders
70       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
71       while (cont)
72         {
73           std::string stdfileName = crea::wx2std(fileName);
74
75           if(stdfileName != "template_lib")
76             {
77               modelCDMLibrary* library = new modelCDMLibrary(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
78               this->libraries.push_back(library);
79               this->children.push_back(library);
80             }
81           else
82             {
83               modelCDMFolder* folder = new modelCDMFolder(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
84               this->children.push_back(folder);
85             }
86
87           cont = dir.GetNext(&fileName);
88         }
89       //files
90       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
91       while (cont)
92         {
93           std::string stdfileName = crea::wx2std(fileName);
94
95           //if CMakeLists, create CMakeLists
96           if(stdfileName == "CMakeLists.txt")
97             {
98               this->CMakeLists = new modelCDMCMakeListsFile(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
99               this->children.push_back(this->CMakeLists);
100             }
101           //if is an unknown file, create file
102           else
103             {
104               this->children.push_back(new modelCDMFile(this, pathFixed + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
105             }
106
107           cont = dir.GetNext(&fileName);
108         }
109     }
110   this->SortChildren();
111   std::sort(this->libraries.begin(), this->libraries.end(), CompareNodeItem);
112 }
113
114 modelCDMLib::~modelCDMLib()
115 {
116 }
117
118 const std::vector<modelCDMLibrary*>& modelCDMLib::GetLibraries() const
119 {
120   return this->libraries;
121 }
122
123 modelCDMLibrary* modelCDMLib::CreateLibrary(
124     const std::string& namein,
125     std::string*& result
126 )
127 {
128   std::vector<std::string> words;
129   CDMUtilities::splitter::split(words,namein," '/\\*\"%",CDMUtilities::splitter::no_empties);
130   std::string name;
131   for (int i = 0; i < (int)(words.size()); i++)
132     {
133           name += words[i];
134     }
135   if (name == "")
136     {
137       result = new std::string("The given name is not valid:  '/\\*\"% are forbidden.");
138           return NULL;
139     }
140   //copy template library folder with new name
141 #ifdef _WIN32
142         std::string copyCommand = "xcopy \"" + this->path + CDMUtilities::SLASH + "template_lib\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "\" /Y";
143 #else
144   std::string copyCommand = "cp -r \"" + this->path + CDMUtilities::SLASH + "template_lib\" \"" + this->path + CDMUtilities::SLASH + name + "\"";
145 #endif
146   if(system(copyCommand.c_str()))
147     {
148       result = new std::string("An error occurred while running '" + copyCommand + "'.");
149       return NULL;
150     }
151   //set name of library in CMakeLists inside copied folder
152   std::string line;
153   std::ifstream in((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
154   if( !in.is_open())
155     {
156       result = new std::string("CMakeLists.txt file failed to open.");
157       return NULL;
158     }
159   std::ofstream out((this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
160   while (getline(in, line))
161     {
162       if(line == "SET ( LIBRARY_NAME   MyLib  )")
163         line = "SET ( LIBRARY_NAME   " + name + "  )";
164       out << line << std::endl;
165     }
166   in.close();
167   out.close();
168   //delete old file and rename new file
169 #ifdef _WIN32
170   std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
171 #else
172   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + name + CDMUtilities::SLASH + "CMakeLists.txt\"";
173 #endif
174   if(system(renameCommand.c_str()))
175     {
176       result = new std::string("An error occurred while running '" + renameCommand + "'.");
177       return NULL;
178     }
179
180   //add library to lib CMakeLists
181   std::fstream out1((this->path + CDMUtilities::SLASH + "CMakeLists.txt").c_str(), std::fstream::in | std::fstream::out | std::fstream::app);
182   if (out1.is_open())
183     {
184       out1 << "ADD_SUBDIRECTORY(" << name << ")" << std::endl;
185       out1.close();
186     }
187
188
189   //add library to model
190   modelCDMLibrary* library = new modelCDMLibrary(this, this->path + CDMUtilities::SLASH + name, name, this->level + 1);
191   this->libraries.push_back(library);
192   this->children.push_back(library);
193
194   this->SortChildren();
195
196   result = new std::string(this->path + CDMUtilities::SLASH + name);
197   return library;
198 }
199
200 const bool modelCDMLib::Refresh(std::string*& result)
201 {
202   std::cout << "refreshing lib" << std::endl;
203   this->type = wxDIR_DIRS;
204
205
206
207   std::vector<bool> checked(this->children.size(), false);
208   std::vector<bool> checkedLibraries(this->libraries.size(), false);
209
210   //check all folders
211   wxDir dir(crea::std2wx((this->path).c_str()));
212   if (dir.IsOpened())
213     {
214       wxString fileName;
215       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
216       while (cont)
217         {
218           std::string stdfileName = crea::wx2std(fileName);
219
220           if(stdfileName != "template_lib")
221             {
222               std::string libraryName = stdfileName;
223               //check if library already exist
224               bool found = false;
225               for (int i = 0; !found && i < (int)(this->libraries.size()); i++)
226                 {
227                   if (this->libraries[i]->GetName() == libraryName)
228                     {
229                       found = true;
230                       int pos = std::find(this->children.begin(), this->children.end(), this->libraries[i]) - this->children.begin();
231                       checked[pos] = true;
232                       checkedLibraries[i] = true;
233                       if(!this->libraries[i]->Refresh(result))
234                         return false;
235                     }
236                 }
237               if(!found)
238                 {
239                   modelCDMLibrary* library = new modelCDMLibrary(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
240                   this->libraries.push_back(library);
241                   this->children.push_back(library);
242                 }
243             }
244           else
245             {
246               //check if folder already exist
247               bool found = false;
248               for (int i = 0; !found && i < (int)(this->children.size()); i++)
249                 {
250                   if (this->children[i]->GetName() == stdfileName)
251                     {
252                       found = true;
253                       checked[i] = true;
254                       if(!this->children[i]->Refresh(result))
255                         return false;
256                     }
257                 }
258               if(!found)
259                 {
260                   modelCDMFolder* folder= new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
261                   this->children.push_back(folder);
262                 }
263             }
264           cont = dir.GetNext(&fileName);
265         }
266
267       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
268       while (cont)
269         {
270           std::string stdfileName = crea::wx2std(fileName);
271
272           //if CMakeLists, create CMakeLists
273           if(stdfileName == "CMakeLists.txt")
274             {
275               if (this->CMakeLists == NULL)
276                 {
277                   this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
278                   this->children.push_back(this->CMakeLists);
279                 }
280               else
281                 {
282                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
283                   checked[pos] = true;
284                   if(!this->CMakeLists->Refresh(result))
285                     return false;
286                 }
287             }
288           //if is an unknown file, create file
289           else
290             {
291               bool found = false;
292               for (int i = 0; !found && i < (int)(this->children.size()); i++)
293                 {
294                   if (this->children[i]->GetName() == stdfileName)
295                     {
296                       found = true;
297                       checked[i] = true;
298                       if(!this->children[i]->Refresh(result))
299                         return false;
300                     }
301                 }
302
303               if(!found)
304                 {
305                   modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
306                   this->children.push_back(file);
307                 }
308             }
309
310           cont = dir.GetNext(&fileName);
311         }
312     }
313
314   for (int i = 0; i < (int)(checkedLibraries.size()); i++)
315     {
316       if(!checkedLibraries[i])
317         {
318           this->libraries.erase(this->libraries.begin()+i);
319           checkedLibraries.erase(checkedLibraries.begin()+i);
320           i--;
321         }
322     }
323   for (int i = 0; i < (int)(checked.size()); i++)
324     {
325       if(!checked[i])
326         {
327           delete this->children[i];
328           this->children.erase(this->children.begin()+i);
329           checked.erase(checked.begin()+i);
330           i--;
331         }
332     }
333   this->SortChildren();
334   std::sort(this->libraries.begin(), this->libraries.end(), CompareNodeItem);
335   return true;
336 }
337
338 void modelCDMLib::CheckStructure(std::map<std::string, bool>& properties)
339 {
340   //check cmake exist
341   if(this->CMakeLists != NULL)
342     {
343       //set properties parameters based on model
344       for (int i = 0; i < (int)(this->libraries.size()); i++)
345         properties["lib add " + libraries[i]->GetName()] = false;
346
347       //open cmakelists
348       std::ifstream confFile;
349       confFile.open((this->CMakeLists->GetPath()).c_str());
350
351       //take everything that is not commented
352       std::string fileContent;
353
354       std::string word;
355       std::vector<std::string> words;
356       while(confFile.is_open() && !confFile.eof())
357         {
358           std::getline(confFile,word, '\n');
359           if(word[0] != '#')
360             {
361               CDMUtilities::splitter::split(words, word, "#", CDMUtilities::splitter::empties_ok);
362               if (words.size() > 0)
363                 {
364                   word = words[0];
365                   CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::empties_ok);
366                   for (int i = 0; i < (int)(words.size()); i++)
367                     {
368                       if(words[i].substr(0,2) == "//")
369                         break;
370                       fileContent += words[i] + " ";
371                     }
372                 }
373             }
374         }
375
376       //check every instruction
377       std::stringstream ss(fileContent);
378       while(!ss.eof())
379         {
380           std::getline(ss,word, '(');
381
382           //check instruction name
383           CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
384
385           //add instructions
386           if (words.size() > 0 && words[words.size()-1] == "ADD_SUBDIRECTORY")
387             {
388               std::getline(ss,word, ')');
389               //std::cout << word << std::endl;
390               CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
391
392               if (words.size() > 0)
393                 {
394                   {
395                     properties["lib add " + words[0]] = true;
396                   }
397                 }
398             }
399         }
400
401     }
402
403   //check libraries' structure
404   for (int i = 0; i < (int)(this->libraries.size()); i++)
405     {
406       properties["library " + this->libraries[i]->GetName()] = true;
407       this->libraries[i]->CheckStructure(properties);
408     }
409 }
410
411 bool modelCDMLib::IsLibraryIncluded(const std::string& library_name)
412 {
413   if(this->HasCMakeLists())
414     {
415       std::ifstream CMFile(this->CMakeLists->GetPath().c_str());
416       if (CMFile.is_open())
417         {
418           std::string line;
419           while(!CMFile.eof())
420             {
421               std::getline(CMFile, line);
422               while(line[0]==' ')
423                 line.erase(0);
424               if(line[0] != '#')
425                 {
426                   std::vector<std::string> lineSeg;
427                   CDMUtilities::splitter::split(lineSeg,line,"()",CDMUtilities::splitter::no_empties);
428                   if(lineSeg.size() > 0 && lineSeg[0] == "ADD_SUBDIRECTORY" && lineSeg[1] == library_name)
429                     {
430                       CMFile.close();
431                       return true;
432                     }
433                 }
434             }
435           CMFile.close();
436         }
437     }
438   return false;
439 }
440
441 bool modelCDMLib::SetLibraryInclude(const std::string& library_name, const bool& toInclude)
442 {
443   if (this->HasCMakeLists())
444     {
445       std::ifstream CMFile(this->CMakeLists->GetPath().c_str());
446       if (CMFile.is_open())
447         {
448           std::stringstream outs;
449           std::string line;
450           bool found = false;
451           while(!CMFile.eof())
452             {
453               std::getline(CMFile, line);
454               if(line != "")
455                 {
456                   std::vector<std::string> segs;
457                   CDMUtilities::splitter::split(segs, line, " ", CDMUtilities::splitter::no_empties);
458                   //is comment
459                   if(segs.size() > 0 && segs[0][0] == '#')
460                     {
461                       if(toInclude)
462                         {
463                           CDMUtilities::splitter::split(segs, line, " #()", CDMUtilities::splitter::no_empties);
464                           if (segs.size() > 1 && segs[0] == "ADD_SUBDIRECTORY" && segs[1] == library_name)
465                             {
466                               found = true;
467                               outs << "ADD_SUBDIRECTORY(" << library_name << ")\n";
468                             }
469                           else
470                             outs << line << "\n";
471                         }
472                       else
473                         {
474                           outs << line << "\n";
475                         }
476                     }
477                   //is not comment
478                   else
479                     {
480                       if (segs.size() > 0 && !toInclude)
481                         {
482                           CDMUtilities::splitter::split(segs, line, " ()", CDMUtilities::splitter::no_empties);
483                           if (segs.size() > 1 && segs[0] == "ADD_SUBDIRECTORY" && segs[1] == library_name)
484                             {
485                               outs << "#" << line << "\n";
486                             }
487                           else
488                             {
489                               outs << line << "\n";
490                             }
491                         }
492                       else
493                         {
494                           CDMUtilities::splitter::split(segs, line, " ()", CDMUtilities::splitter::no_empties);
495                           if (segs.size() > 1 && segs[0] == "ADD_SUBDIRECTORY" && segs[1] == library_name)
496                             {
497                               found = true;
498                             }
499                           outs << line << "\n";
500                         }
501                     }
502                 }
503               else
504                 {
505                   outs << "\n";
506                 }
507             }
508
509           CMFile.close();
510
511           if(!found && toInclude)
512             outs << "ADD_SUBDIRECTORY(" << library_name << ")\n";
513
514           std::ofstream CMFileOut(this->CMakeLists->GetPath().c_str());
515           if (CMFileOut.is_open())
516             {
517               CMFileOut << outs.rdbuf();
518               CMFileOut.close();
519               return true;
520             }
521         }
522     }
523   return false;
524 }