]> 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" || wordBits[wordBits.size() - 1] == "IMPLEMENT_APP")
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 #ifdef _WIN32
210   std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
211 #else
212   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
213 #endif
214   
215   if(system(renameCommand.c_str()))
216     {
217       result = new std::string("An error occurred while running '" + renameCommand + "'.");
218       return false;
219     }
220
221   this->executableName = fileNameReal;
222   return true;
223 }
224
225 modelCDMFolder* modelCDMApplication::CreateFolder(const std::string& name, std::string*& result)
226 {
227   //TODO:: mkdir depending on OS
228   std::string command = "mkdir " + path + CDMUtilities::SLASH + name;
229   if(system(command.c_str()))
230     {
231       result = new std::string("Error executing: " + command + ".");
232       return NULL;
233     }
234   modelCDMFolder* folder = new modelCDMFolder(this, path + CDMUtilities::SLASH + name, name, level + 1);
235   this->folders.push_back(folder);
236   this->children.push_back(folder);
237
238   return folder;
239 }
240
241 const bool modelCDMApplication::Refresh(std::string*& result)
242 {
243   this->mainFile = NULL;
244   std::cout << "refreshing application: " << this->executableName << std::endl;
245   //set attributes
246   this->type = wxDIR_DIRS;
247
248   //open CMakeList
249   std::string pathMakeLists = path + CDMUtilities::SLASH + "CMakeLists.txt";
250
251   std::ifstream confFile;
252   confFile.open((pathMakeLists).c_str());
253
254   std::string word;
255   while(confFile.is_open() && !confFile.eof())
256     {
257       //get sets
258       std::getline(confFile,word,'(');
259       std::vector<std::string> wordBits;
260       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
261
262       if(wordBits[wordBits.size()-1] == "SET")
263         {
264           //get app name
265           std::getline(confFile,word,')');
266           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
267           if(wordBits[0] == "EXE_NAME")
268             {
269               word = wordBits[1];
270               for (int i = 2; i < (int)(wordBits.size()); i++)
271                 {
272                   word += " " + wordBits[i];
273                 }
274
275               this->executableName = word;
276             }
277         }
278     }
279
280   confFile.close();
281
282   //check children
283   std::vector<bool> checked(this->children.size(), false);
284   std::vector<bool> checkedFolders(this->folders.size(), false);
285
286   //check all folders
287   wxDir dir(crea::std2wx((this->path).c_str()));
288   if (dir.IsOpened())
289     {
290       wxString fileName;
291       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
292       while (cont)
293         {
294           std::string stdfileName = crea::wx2std(fileName);
295           std::string applicationName = stdfileName;
296           //check if they already exist
297           bool found = false;
298           for (int i = 0; !found && i < (int)(this->folders.size()); i++)
299             {
300               if (this->folders[i]->GetName() == applicationName)
301                 {
302                   found = true;
303                   int pos = std::find(this->children.begin(), this->children.end(), this->folders[i]) - this->children.begin();
304                   checked[pos] = true;
305                   checkedFolders[i] = true;
306                   if(!this->folders[i]->Refresh(result))
307                     return false;
308                 }
309             }
310           if(!found)
311             {
312               modelCDMFolder* folder = new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
313               this->folders.push_back(folder);
314               this->children.push_back(folder);
315             }
316           cont = dir.GetNext(&fileName);
317         }
318
319       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
320       while (cont)
321         {
322           std::string stdfileName = crea::wx2std(fileName);
323
324           //if CMakeLists, create CMakeLists
325           if(stdfileName == "CMakeLists.txt")
326             {
327               if (this->CMakeLists == NULL)
328                 {
329                   this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
330                   this->children.push_back(this->CMakeLists);
331                 }
332               else
333                 {
334                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
335                   checked[pos] = true;
336                   if(!this->CMakeLists->Refresh(result))
337                     return false;
338                 }
339             }
340           //if is an unknown file, create file
341           else
342             {
343               bool found = false;
344               for (int i = 0; !found && i < (int)(this->children.size()); i++)
345                 {
346                   if (this->children[i]->GetName() == stdfileName)
347                     {
348                       found = true;
349                       checked[i] = true;
350
351                       if(!this->children[i]->Refresh(result))
352                         return false;
353
354                       std::string extension = stdfileName.substr(stdfileName.size()-4);
355                       if (mainFile == NULL && (extension == ".cxx" || extension == ".cpp"))
356                         {
357                           std::ifstream fileStream;
358                           std::string word;
359                           fileStream.open((this->path + CDMUtilities::SLASH + stdfileName).c_str());
360                           while (fileStream.is_open() && !fileStream.eof())
361                             {
362                               //get sets
363                               std::getline(fileStream,word,'(');
364                               std::vector<std::string> wordBits;
365                               CDMUtilities::splitter::split(wordBits,word," \n",CDMUtilities::splitter::no_empties);
366                               if (wordBits[wordBits.size() - 1] == "main" || wordBits[wordBits.size() - 1] == "IMPLEMENT_APP")
367                                 {
368                                   this->mainFile = dynamic_cast<modelCDMFile*>(children[i]);
369                                 }
370                             }
371                           fileStream.close();
372                         }
373                     }
374                 }
375
376               if(!found)
377                 {
378                   modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
379
380                   std::string extension = stdfileName.substr(stdfileName.size()-4);
381                   if (mainFile == NULL && (extension == ".cxx" || extension == ".cpp"))
382                     {
383                       std::ifstream fileStream;
384                       std::string word;
385                       fileStream.open((this->path + CDMUtilities::SLASH + stdfileName).c_str());
386                       while (fileStream.is_open() && !fileStream.eof())
387                         {
388                           //get sets
389                           std::getline(fileStream,word,'(');
390                           std::vector<std::string> wordBits;
391                           CDMUtilities::splitter::split(wordBits,word," \n",CDMUtilities::splitter::no_empties);
392                           if (wordBits[wordBits.size() - 1] == "main" || wordBits[wordBits.size() - 1] == "IMPLEMENT_APP")
393                             {
394                               this->mainFile = file;
395                             }
396                         }
397                       fileStream.close();
398                     }
399
400                   this->children.push_back(file);
401                 }
402             }
403
404           cont = dir.GetNext(&fileName);
405         }
406     }
407
408   for (int i = 0; i < (int)(checkedFolders.size()); i++)
409     {
410       if(!checkedFolders[i])
411         {
412           this->folders.erase(this->folders.begin()+i);
413           checkedFolders.erase(checkedFolders.begin()+i);
414           i--;
415         }
416     }
417   for (int i = 0; i < (int)(checked.size()); i++)
418     {
419       if(!checked[i])
420         {
421           delete this->children[i];
422           this->children.erase(this->children.begin()+i);
423           checked.erase(checked.begin()+i);
424           i--;
425         }
426     }
427   this->SortChildren();
428   return true;
429 }
430
431 void modelCDMApplication::CheckStructure(std::map<std::string, bool>& properties)
432 {
433   //check cmake exist
434   if(this->CMakeLists != NULL)
435     {
436       //set default properties
437       properties["application " + this->name + " lib ${crea_LIBRARIES}"] = false;
438       properties["application " + this->name + " lib ${WXWIDGETS_LIBRARIES}"] = false;
439       properties["application " + this->name + " lib ${KWWidgets_LIBRARIES}"] = false;
440       properties["application " + this->name + " lib ${VTK_LIBRARIES}"] = false;
441       properties["application " + this->name + " lib ${ITK_LIBRARIES}"] = false;
442       properties["application " + this->name + " lib ${GDCM_LIBRARIES}"] = false;
443       properties["application " + this->name + " lib ${BOOST_LIBRARIES}"] = false;
444
445       //open cmakelists
446       std::ifstream confFile;
447       confFile.open((this->CMakeLists->GetPath()).c_str());
448
449       //take everything that is not commented
450       std::string fileContent;
451
452       std::string word;
453       std::vector<std::string> words;
454       while(confFile.is_open() && !confFile.eof())
455         {
456           std::getline(confFile,word, '\n');
457           if(word[0] != '#')
458             {
459               CDMUtilities::splitter::split(words, word, "#", CDMUtilities::splitter::empties_ok);
460               if (words.size() > 0)
461                 {
462                   word = words[0];
463                   CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::empties_ok);
464                   for (int i = 0; i < (int)(words.size()); i++)
465                     {
466                       if(words[i].substr(0,2) == "//")
467                         break;
468                       fileContent += words[i] + " ";
469                     }
470                 }
471             }
472         }
473
474       //check every instruction
475       std::stringstream ss(fileContent);
476       while(!ss.eof())
477         {
478           std::getline(ss,word, '(');
479
480           //check instruction name
481           CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
482
483           //set instructions
484           if (words.size() > 0 && words[words.size()-1] == "SET")
485             {
486               std::getline(ss,word, ')');
487
488               CDMUtilities::splitter::split(words, word, " \t", CDMUtilities::splitter::no_empties);
489               if (words.size() > 1)
490                 {
491                   if (words[0] == "${EXE_NAME}_LINK_LIBRARIES")
492                     {
493                       for (int i = 1; i < (int)(words.size()); i++)
494                         {
495                           properties["application " + this->name + " lib " + words[i]] = true;
496                         }
497                     }
498                 }
499             }
500           else if (words.size() > 0 && words[words.size()-1] == "INCLUDE_DIRECTORIES")
501             {
502               std::getline(ss,word, ')');
503
504               CDMUtilities::splitter::split(words, word, " \t", CDMUtilities::splitter::no_empties);
505
506               for (int i = 0; i < (int)(words.size()); i++)
507                 {
508                   properties["application " + this->name + " dir " + words[i]] = true;
509                 }
510
511
512             }
513         }
514
515     }
516 }