]> Creatis software - crea.git/blob - lib/creaDevManagerLib/modelCDMApplication.cpp
Feature #1711
[crea.git] / lib / creaDevManagerLib / modelCDMApplication.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  * modelCDMApplication.cpp
30  *
31  *  Created on: Nov 23, 2012
32  *      Author: Daniel Felipe Gonzalez Obando
33  */
34
35 #include "modelCDMApplication.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 modelCDMApplication::modelCDMApplication()
46 {
47   mainFile = NULL;
48 }
49
50 modelCDMApplication::modelCDMApplication(modelCDMIProjectTreeNode* parent, const std::string& path, const std::string& name, const int& level)
51 {
52   std::cout << "creating application: " + path + "\n";
53   this->parent = parent;
54   this->mainFile = NULL;
55   //folder name
56   this->name = name;
57   //path
58   this->path = CDMUtilities::fixPath(path);
59   //type
60   this->type = wxDIR_DIRS;
61   //level
62   this->level = level;
63   //open CMakeList
64   std::string pathMakeLists = path + CDMUtilities::SLASH + "CMakeLists.txt";
65
66   std::ifstream confFile;
67   confFile.open((pathMakeLists).c_str());
68
69   std::string word;
70   while(confFile.is_open() && !confFile.eof())
71     {
72       //get sets
73       std::getline(confFile,word,'(');
74       std::vector<std::string> wordBits;
75       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
76
77       if(wordBits[wordBits.size()-1] == "SET")
78         {
79           //get library name
80           std::getline(confFile,word,')');
81           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
82           if(wordBits[0] == "EXE_NAME")
83             {
84               word = wordBits[1];
85               for (int i = 2; i < (int)(wordBits.size()); i++)
86                 {
87                   word += " " + wordBits[i];
88                 }
89
90               this->executableName = word;
91             }
92         }
93     }
94   confFile.close();
95
96   //add library contents
97
98   this->children.clear();
99   wxDir dir(crea::std2wx((this->path).c_str()));
100   if (dir.IsOpened())
101     {
102       wxString fileName;
103       //folders
104       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
105       while (cont)
106         {
107           std::string stdfileName = crea::wx2std(fileName);
108
109           modelCDMFolder* folder = new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
110           this->folders.push_back(folder);
111           this->children.push_back(folder);
112
113           cont = dir.GetNext(&fileName);
114         }
115       //files
116       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
117       while (cont)
118         {
119           std::string stdfileName = crea::wx2std(fileName);
120
121           //if CMakeLists, create CMakeLists
122           if(stdfileName == "CMakeLists.txt")
123             {
124               this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
125               this->children.push_back(this->CMakeLists);
126             }
127           //if is an unknown file, create file
128           else
129             {
130               modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
131               std::string extension = stdfileName.substr(stdfileName.size()-4);
132               if (mainFile == NULL && (extension == ".cxx" || extension == ".cpp"))
133                 {
134                   std::ifstream fileStream;
135                   std::string word;
136                   fileStream.open((this->path + CDMUtilities::SLASH + stdfileName).c_str());
137                   while (fileStream.is_open() && !fileStream.eof())
138                     {
139                       //get sets
140                       std::getline(fileStream,word,'(');
141                       std::vector<std::string> wordBits;
142                       CDMUtilities::splitter::split(wordBits,word," \n",CDMUtilities::splitter::no_empties);
143                       if (wordBits[wordBits.size() - 1] == "main")
144                         {
145                           this->mainFile = file;
146                         }
147                     }
148                   fileStream.close();
149                 }
150               this->children.push_back(file);
151             }
152
153           cont = dir.GetNext(&fileName);
154         }
155     }
156   this->SortChildren();
157   std::sort(this->folders.begin(), this->folders.end(), CompareNodeItem);
158 }
159
160 modelCDMApplication::~modelCDMApplication()
161 {
162 }
163
164 const std::string& modelCDMApplication::GetExecutableName() const
165 {
166   return this->executableName;
167 }
168
169 modelCDMFile* modelCDMApplication::GetMainFile() const
170 {
171   return this->mainFile;
172 }
173
174 bool modelCDMApplication::SetExecutableName(const std::string& fileName, std::string*& result)
175 {
176   std::vector<std::string> words;
177   CDMUtilities::splitter::split(words, fileName, ", /\\\"", CDMUtilities::splitter::no_empties);
178   std::string fileNameReal = words[0];
179   for (int i = 1; i < (int)(words.size()); i++)
180     {
181       fileNameReal += "-" + words[i];
182     }
183
184   std::string line;
185   //opening original cmakelists
186   std::ifstream in((this->path + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
187   if( !in.is_open())
188     {
189       result = new std::string("CMakeLists.txt file failed to open.");
190       return false;
191     }
192   //opening temporal cmakelists
193   std::ofstream out((this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
194   if( !out.is_open())
195     {
196       result = new std::string("CMakeLists.txt.tmp file failed to open.");
197       return false;
198     }
199   //copying contents from original to temporal and making changes
200   while (getline(in, line))
201     {
202       if(line.find("SET ( EXE_NAME") != std::string::npos)
203         line = "SET ( EXE_NAME  " + fileNameReal + "  )";
204       out << line << std::endl;
205     }
206   in.close();
207   out.close();
208   //delete old file and rename new file
209   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
210   if(system(renameCommand.c_str()))
211     {
212       result = new std::string("An error occurred while running '" + renameCommand + "'.");
213       return false;
214     }
215
216   this->executableName = fileNameReal;
217   return true;
218 }
219
220 modelCDMFolder* modelCDMApplication::CreateFolder(const std::string& name, std::string*& result)
221 {
222   //TODO:: mkdir depending on OS
223   std::string command = "mkdir " + path + CDMUtilities::SLASH + name;
224   if(system(command.c_str()))
225     {
226       result = new std::string("Error executing: " + command + ".");
227       return NULL;
228     }
229   modelCDMFolder* folder = new modelCDMFolder(this, path + CDMUtilities::SLASH + name, name, level + 1);
230   this->folders.push_back(folder);
231   this->children.push_back(folder);
232
233   return folder;
234 }
235
236 const bool modelCDMApplication::Refresh(std::string*& result)
237 {
238   this->mainFile = NULL;
239   std::cout << "refreshing application: " << this->executableName << std::endl;
240   //set attributes
241   this->type = wxDIR_DIRS;
242
243   //open CMakeList
244   std::string pathMakeLists = path + CDMUtilities::SLASH + "CMakeLists.txt";
245
246   std::ifstream confFile;
247   confFile.open((pathMakeLists).c_str());
248
249   std::string word;
250   while(confFile.is_open() && !confFile.eof())
251     {
252       //get sets
253       std::getline(confFile,word,'(');
254       std::vector<std::string> wordBits;
255       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
256
257       if(wordBits[wordBits.size()-1] == "SET")
258         {
259           //get app name
260           std::getline(confFile,word,')');
261           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
262           if(wordBits[0] == "EXE_NAME")
263             {
264               word = wordBits[1];
265               for (int i = 2; i < (int)(wordBits.size()); i++)
266                 {
267                   word += " " + wordBits[i];
268                 }
269
270               this->executableName = word;
271             }
272         }
273     }
274
275   confFile.close();
276
277   //check children
278   std::vector<bool> checked(this->children.size(), false);
279   std::vector<bool> checkedFolders(this->folders.size(), false);
280
281   //check all folders
282   wxDir dir(crea::std2wx((this->path).c_str()));
283   if (dir.IsOpened())
284     {
285       wxString fileName;
286       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
287       while (cont)
288         {
289           std::string stdfileName = crea::wx2std(fileName);
290           std::string applicationName = stdfileName;
291           //check if they already exist
292           bool found = false;
293           for (int i = 0; !found && i < (int)(this->folders.size()); i++)
294             {
295               if (this->folders[i]->GetName() == applicationName)
296                 {
297                   found = true;
298                   int pos = std::find(this->children.begin(), this->children.end(), this->folders[i]) - this->children.begin();
299                   checked[pos] = true;
300                   checkedFolders[i] = true;
301                   if(!this->folders[i]->Refresh(result))
302                     return false;
303                 }
304             }
305           if(!found)
306             {
307               modelCDMFolder* folder = new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
308               this->folders.push_back(folder);
309               this->children.push_back(folder);
310             }
311           cont = dir.GetNext(&fileName);
312         }
313
314       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
315       while (cont)
316         {
317           std::string stdfileName = crea::wx2std(fileName);
318
319           //if CMakeLists, create CMakeLists
320           if(stdfileName == "CMakeLists.txt")
321             {
322               if (this->CMakeLists == NULL)
323                 {
324                   this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
325                   this->children.push_back(this->CMakeLists);
326                 }
327               else
328                 {
329                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
330                   checked[pos] = true;
331                   if(!this->CMakeLists->Refresh(result))
332                     return false;
333                 }
334             }
335           //if is an unknown file, create file
336           else
337             {
338               bool found = false;
339               for (int i = 0; !found && i < (int)(this->children.size()); i++)
340                 {
341                   if (this->children[i]->GetName() == stdfileName)
342                     {
343                       found = true;
344                       checked[i] = true;
345
346                       if(!this->children[i]->Refresh(result))
347                         return false;
348
349                       std::string extension = stdfileName.substr(stdfileName.size()-4);
350                       if (mainFile == NULL && (extension == ".cxx" || extension == ".cpp"))
351                         {
352                           std::ifstream fileStream;
353                           std::string word;
354                           fileStream.open((this->path + CDMUtilities::SLASH + stdfileName).c_str());
355                           while (fileStream.is_open() && !fileStream.eof())
356                             {
357                               //get sets
358                               std::getline(fileStream,word,'(');
359                               std::vector<std::string> wordBits;
360                               CDMUtilities::splitter::split(wordBits,word," \n",CDMUtilities::splitter::no_empties);
361                               if (wordBits[wordBits.size() - 1] == "main")
362                                 {
363                                   this->mainFile = dynamic_cast<modelCDMFile*>(children[i]);
364                                 }
365                             }
366                           fileStream.close();
367                         }
368                     }
369                 }
370
371               if(!found)
372                 {
373                   modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
374
375                   std::string extension = stdfileName.substr(stdfileName.size()-4);
376                   if (mainFile == NULL && (extension == ".cxx" || extension == ".cpp"))
377                     {
378                       std::ifstream fileStream;
379                       std::string word;
380                       fileStream.open((this->path + CDMUtilities::SLASH + stdfileName).c_str());
381                       while (fileStream.is_open() && !fileStream.eof())
382                         {
383                           //get sets
384                           std::getline(fileStream,word,'(');
385                           std::vector<std::string> wordBits;
386                           CDMUtilities::splitter::split(wordBits,word," \n",CDMUtilities::splitter::no_empties);
387                           if (wordBits[wordBits.size() - 1] == "main")
388                             {
389                               this->mainFile = file;
390                             }
391                         }
392                       fileStream.close();
393                     }
394
395                   this->children.push_back(file);
396                 }
397             }
398
399           cont = dir.GetNext(&fileName);
400         }
401     }
402
403   for (int i = 0; i < (int)(checkedFolders.size()); i++)
404     {
405       if(!checkedFolders[i])
406         {
407           this->folders.erase(this->folders.begin()+i);
408           checkedFolders.erase(checkedFolders.begin()+i);
409           i--;
410         }
411     }
412   for (int i = 0; i < (int)(checked.size()); i++)
413     {
414       if(!checked[i])
415         {
416           delete this->children[i];
417           this->children.erase(this->children.begin()+i);
418           checked.erase(checked.begin()+i);
419           i--;
420         }
421     }
422   this->SortChildren();
423   return true;
424 }
425
426 void modelCDMApplication::CheckStructure(std::map<std::string, bool>& properties)
427 {
428   //check cmake exist
429   if(this->CMakeLists != NULL)
430     {
431       //set default properties
432       properties["application " + this->name + " lib ${crea_LIBRARIES}"] = false;
433       properties["application " + this->name + " lib ${WXWIDGETS_LIBRARIES}"] = false;
434       properties["application " + this->name + " lib ${KWWidgets_LIBRARIES}"] = false;
435       properties["application " + this->name + " lib ${VTK_LIBRARIES}"] = false;
436       properties["application " + this->name + " lib ${ITK_LIBRARIES}"] = false;
437       properties["application " + this->name + " lib ${GDCM_LIBRARIES}"] = false;
438       properties["application " + this->name + " lib ${BOOST_LIBRARIES}"] = false;
439
440       //open cmakelists
441       std::ifstream confFile;
442       confFile.open((this->CMakeLists->GetPath()).c_str());
443
444       //take everything that is not commented
445       std::string fileContent;
446
447       std::string word;
448       std::vector<std::string> words;
449       while(confFile.is_open() && !confFile.eof())
450         {
451           std::getline(confFile,word, '\n');
452           if(word[0] != '#')
453             {
454               CDMUtilities::splitter::split(words, word, "#", CDMUtilities::splitter::empties_ok);
455               if (words.size() > 0)
456                 {
457                   word = words[0];
458                   CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::empties_ok);
459                   for (int i = 0; i < (int)(words.size()); i++)
460                     {
461                       if(words[i].substr(0,2) == "//")
462                         break;
463                       fileContent += words[i] + " ";
464                     }
465                 }
466             }
467         }
468
469       //check every instruction
470       std::stringstream ss(fileContent);
471       while(!ss.eof())
472         {
473           std::getline(ss,word, '(');
474
475           //check instruction name
476           CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
477
478           //set instructions
479           if (words.size() > 0 && words[words.size()-1] == "SET")
480             {
481               std::getline(ss,word, ')');
482
483               CDMUtilities::splitter::split(words, word, " \t", CDMUtilities::splitter::no_empties);
484               if (words.size() > 1)
485                 {
486                   if (words[0] == "${EXE_NAME}_LINK_LIBRARIES")
487                     {
488                       for (int i = 1; i < (int)(words.size()); i++)
489                         {
490                           properties["application " + this->name + " lib " + words[i]] = true;
491                         }
492                     }
493                 }
494             }
495           else if (words.size() > 0 && words[words.size()-1] == "INCLUDE_DIRECTORIES")
496             {
497               std::getline(ss,word, ')');
498
499               CDMUtilities::splitter::split(words, word, " \t", CDMUtilities::splitter::no_empties);
500
501               for (int i = 0; i < (int)(words.size()); i++)
502                 {
503                   properties["application " + this->name + " dir " + words[i]] = true;
504                 }
505
506
507             }
508         }
509
510     }
511 }