]> Creatis software - crea.git/blob - lib/creaDevManagerLib/modelCDMPackage.cpp
Feature #1711 CreaDevManager application implementation
[crea.git] / lib / creaDevManagerLib / modelCDMPackage.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  * modelCDMPackage.cpp
30  *
31  *  Created on: Nov 23, 2012
32  *      Author: Daniel Felipe Gonzalez Obando
33  */
34
35 #include "modelCDMPackage.h"
36
37 #include "modelCDMProject.h"
38 #include "modelCDMLib.h"
39 #include "modelCDMLibrary.h"
40
41
42 #include <fstream>
43 #include <sstream>
44 #include <algorithm>
45 #include <boost/regex.hpp>
46
47 #include "creaWx.h"
48 #include "wx/dir.h"
49 #include "CDMUtilities.h"
50
51 modelCDMPackage::modelCDMPackage()
52 {
53   this->src = NULL;
54 }
55
56 modelCDMPackage::modelCDMPackage(modelCDMIProjectTreeNode* parent, const std::string& path, const std::string& name, const int& level)
57 {
58   std::cout << "creating package: " + path + "\n";
59   this->parent = parent;
60   this->type = wxDIR_DIRS;
61   this->name = name;
62   //Get Package Name
63
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 package name
80           std::getline(confFile,word,')');
81           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
82           if(wordBits[0] == "BBTK_PACKAGE_NAME")
83             {
84               word = wordBits[1];
85               for (int i = 2; i < (int)(wordBits.size()); i++)
86                 {
87                   word += " " + wordBits[i];
88                 }
89               wordBits.clear();
90               CDMUtilities::splitter::split(wordBits, word, "\"", CDMUtilities::splitter::no_empties);
91
92               this->namePackage = wordBits[0];
93             }
94           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_AUTHOR")
95             {
96               word = wordBits[1];
97               for (int i = 2; i < (int)(wordBits.size()); i++)
98                 {
99                   word += " " + wordBits[i];
100                 }
101               wordBits.clear();
102               CDMUtilities::splitter::split(wordBits, word, "\"", CDMUtilities::splitter::no_empties);
103
104               this->authors = wordBits[0];
105             }
106           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_DESCRIPTION")
107             {
108               word = wordBits[1];
109               for (int i = 2; i < (int)(wordBits.size()); i++)
110                 {
111                   word += " " + wordBits[i];
112                 }
113               wordBits.clear();
114               CDMUtilities::splitter::split(wordBits, word, "\"", CDMUtilities::splitter::no_empties);
115
116               this->description = wordBits[0];
117             }
118           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_MAJOR_VERSION")
119             {
120               this->version = wordBits[1];
121             }
122           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_MINOR_VERSION")
123             {
124               this->version += "." + wordBits[1];
125             }
126           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_BUILD_VERSION")
127             {
128               this->version += "." + wordBits[1];
129             }
130         }
131     }
132
133   this->level = level;
134   this->path = path;
135
136   //check all folders and files
137   wxDir dir(crea::std2wx((path).c_str()));
138   if (dir.IsOpened())
139     {
140       wxString fileName;
141
142       //folders
143       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
144       while (cont)
145         {
146           std::string stdfileName = crea::wx2std(fileName);
147           //if src, check for black boxes
148           if(stdfileName == "src")
149             {
150               this->src = new modelCDMPackageSrc(this, path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
151               this->children.push_back(this->src);
152             }
153           else
154             {
155               this->children.push_back(new modelCDMFolder(this, path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
156             }
157
158           cont = dir.GetNext(&fileName);
159         }
160
161       //files
162       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
163       while (cont)
164         {
165           std::string stdfileName = crea::wx2std(fileName);
166           std::size_t fileTypePos = stdfileName.find_last_of(".");
167           std::string fileType = stdfileName.substr(fileTypePos);
168
169           //if CMakeLists, create CMakeLists
170           if(stdfileName == "CMakeLists.txt")
171             {
172               this->CMakeLists = new modelCDMCMakeListsFile(this, path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
173               this->children.push_back(this->CMakeLists);
174             }
175           //if is a code file, create code file
176           else if(fileType == ".c" ||
177               fileType == ".cxx" ||
178               fileType == ".h" ||
179               fileType == ".cpp" ||
180               fileType == ".txx" ||
181               fileType == ".cmake" )
182             {
183               modelCDMCodeFile* file = new modelCDMCodeFile(this, path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
184               this->children.push_back(file);
185             }
186           //if is an unknown file, create file
187           else
188             {
189               this->children.push_back(new modelCDMFile(this, path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
190             }
191
192           cont = dir.GetNext(&fileName);
193         }
194     }
195   this->SortChildren();
196 }
197
198 modelCDMPackage::~modelCDMPackage()
199 {
200 }
201
202 const std::string& modelCDMPackage::GetNamePackage() const
203 {
204   return this->namePackage;
205 }
206
207 const std::string& modelCDMPackage::GetAuthors() const
208 {
209   return this->authors;
210 }
211
212 const std::string& modelCDMPackage::GetAuthorsEmail() const
213 {
214   return this->authorsEmail;
215 }
216
217 const std::string& modelCDMPackage::GetVersion() const
218 {
219   return this->version;
220 }
221
222 const std::string& modelCDMPackage::GetDescription() const
223 {
224   return this->description;
225 }
226
227 modelCDMPackageSrc* modelCDMPackage::GetSrc() const
228 {
229   return this->src;
230 }
231
232 bool modelCDMPackage::SetAuthors(const std::string& authors, std::string*& result)
233 {
234   std::vector<std::string> words;
235   CDMUtilities::splitter::split(words, authors, ",\n", CDMUtilities::splitter::no_empties);
236   std::string authorsReal = words[0];
237   for (int i = 1; i < (int)(words.size()); i++)
238     {
239       authorsReal += "/" + words[i];
240     }
241
242   std::string line;
243   //opening original cmakelists
244   std::ifstream in((this->path + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
245   if( !in.is_open())
246     {
247       result = new std::string("CMakeLists.txt file failed to open.");
248       return false;
249     }
250   //opening temporal cmakelists
251   std::ofstream out((this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
252   if( !out.is_open())
253     {
254       result = new std::string("CMakeLists.txt.tmp file failed to open.");
255       return false;
256     }
257   //copying contents from original to temporal and making changes
258   while (getline(in, line))
259     {
260       if(line.find("SET(${BBTK_PACKAGE_NAME}_AUTHOR") != std::string::npos)
261         line = "SET(${BBTK_PACKAGE_NAME}_AUTHOR \"" + authorsReal + "\")";
262       out << line << std::endl;
263     }
264   in.close();
265   out.close();
266   //delete old file and rename new file
267 #ifdef _WIN32
268   std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
269 #else
270   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
271 #endif
272   
273   if(system(renameCommand.c_str()))
274     {
275       result = new std::string("An error occurred while running '" + renameCommand + "'.");
276       return false;
277     }
278
279   this->authors = authorsReal;
280   return true;
281 }
282
283 bool modelCDMPackage::SetAuthorsEmail(const std::string& email, std::string*& result)
284 {
285   //TODO: implement method
286   return true;
287 }
288
289 bool modelCDMPackage::SetVersion(const std::string& version, std::string*& result)
290 {
291   std::vector<std::string> vers;
292   CDMUtilities::splitter::split(vers, version, " .", CDMUtilities::splitter::no_empties);
293
294
295   std::string line;
296   //opening original cmakelists
297   std::ifstream in((this->path + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
298   if( !in.is_open())
299     {
300       result = new std::string("CMakeLists.txt file failed to open.");
301       return false;
302     }
303   //opening temporal cmakelists
304   std::ofstream out((this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
305   if( !out.is_open())
306     {
307       result = new std::string("CMakeLists.txt.tmp file failed to open.");
308       return false;
309     }
310   //copying contents from original to temporal and making changes
311   while (getline(in, line))
312     {
313       if(line.find("SET(${BBTK_PACKAGE_NAME}_MAJOR_VERSION") != std::string::npos)
314         line = "SET(${BBTK_PACKAGE_NAME}_MAJOR_VERSION " + vers[0] + ")";
315       else if(line.find("SET(${BBTK_PACKAGE_NAME}_VERSION") != std::string::npos)
316         line = "SET(${BBTK_PACKAGE_NAME}_MINOR_VERSION " + vers[1] + ")";
317       else if(line.find("SET(${BBTK_PACKAGE_NAME}_BUILD_VERSION") != std::string::npos)
318         line = "SET(${BBTK_PACKAGE_NAME}_BUILD_VERSION " + vers[2] + ")";
319       out << line << std::endl;
320     }
321   in.close();
322   out.close();
323   //delete old file and rename new file
324 #ifdef _WIN32
325   std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
326 #else
327   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
328 #endif
329   
330   if(system(renameCommand.c_str()))
331     {
332       result = new std::string("An error occurred while running '" + renameCommand + "'.");
333       return false;
334     }
335
336   this->version = vers[0] + "." + vers[1] + "." + vers[2];
337   return true;
338 }
339
340 bool modelCDMPackage::SetDescription(const std::string& description, std::string*& result)
341 {
342   std::vector<std::string> words;
343   CDMUtilities::splitter::split(words, description, " \n", CDMUtilities::splitter::no_empties);
344   std::string descriptionReal = words[0];
345   for (int i = 1; i < (int)(words.size()); i++)
346     {
347       descriptionReal += " " + words[i];
348     }
349
350   std::string line;
351   //opening original cmakelists
352   std::ifstream in((this->path + CDMUtilities::SLASH + "CMakeLists.txt").c_str());
353   if( !in.is_open())
354     {
355       result = new std::string("CMakeLists.txt file failed to open.");
356       return false;
357     }
358   //opening temporal cmakelists
359   std::ofstream out((this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp").c_str());
360   if( !out.is_open())
361     {
362       result = new std::string("CMakeLists.txt.tmp file failed to open.");
363       return false;
364     }
365   //copying contents from original to temporal and making changes
366   while (getline(in, line))
367     {
368       if(line.find("SET(${BBTK_PACKAGE_NAME}_DESCRIPTION") != std::string::npos)
369         line = "SET(${BBTK_PACKAGE_NAME}_DESCRIPTION \"" + descriptionReal + "\")";
370       out << line << std::endl;
371     }
372   in.close();
373   out.close();
374   //delete old file and rename new file
375 #ifdef _WIN32
376   std::string renameCommand = "move /Y \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
377 #else
378   std::string renameCommand = "mv \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt.tmp\" \"" + this->path + CDMUtilities::SLASH + "CMakeLists.txt\"";
379 #endif
380   
381   if(system(renameCommand.c_str()))
382     {
383       result = new std::string("An error occurred while running '" + renameCommand + "'.");
384       return false;
385     }
386
387   this->description = descriptionReal;
388   return true;
389 }
390
391 modelCDMBlackBox* modelCDMPackage::CreateBlackBox(
392     std::string*& result,
393     const std::string& name,
394     const std::string& type,
395     const std::string& format,
396     const std::string& categories,
397     const std::string& authors,
398     const std::string& authorsEmail,
399     const std::string& description
400 )
401 {
402   return this->src->CreateBlackBox(result,name, this->namePackage, type,format,categories,authors,authorsEmail,description);
403 }
404
405 const bool modelCDMPackage::Refresh(std::string*& result)
406 {
407   std::cout << "refreshing package " << this->namePackage << std::endl;
408   this->type = wxDIR_DIRS;
409
410   //Get Package Name
411
412   std::string pathMakeLists = path + CDMUtilities::SLASH + "CMakeLists.txt";
413
414   std::ifstream confFile;
415   confFile.open((pathMakeLists).c_str());
416
417   std::string word;
418   while(confFile.is_open() && !confFile.eof())
419     {
420       //get sets
421       std::getline(confFile,word,'(');
422       std::vector<std::string> wordBits;
423       CDMUtilities::splitter::split(wordBits,word," (\n",CDMUtilities::splitter::no_empties);
424
425       if(wordBits[wordBits.size()-1] == "SET")
426         {
427           //get package name
428           std::getline(confFile,word,')');
429           CDMUtilities::splitter::split(wordBits, word, " ", CDMUtilities::splitter::no_empties);
430           if(wordBits[0] == "BBTK_PACKAGE_NAME")
431             {
432               word = wordBits[1];
433               for (int i = 2; i < (int)(wordBits.size()); i++)
434                 {
435                   word += " " + wordBits[i];
436                 }
437               wordBits.clear();
438               CDMUtilities::splitter::split(wordBits, word, "\"", CDMUtilities::splitter::no_empties);
439
440               this->namePackage = wordBits[0];
441             }
442           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_AUTHOR")
443             {
444               word = wordBits[1];
445               for (int i = 2; i < (int)(wordBits.size()); i++)
446                 {
447                   word += " " + wordBits[i];
448                 }
449               wordBits.clear();
450               CDMUtilities::splitter::split(wordBits, word, "\"", CDMUtilities::splitter::no_empties);
451
452               this->authors = wordBits[0];
453             }
454           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_DESCRIPTION")
455             {
456               word = wordBits[1];
457               for (int i = 2; i < (int)(wordBits.size()); i++)
458                 {
459                   word += " " + wordBits[i];
460                 }
461               wordBits.clear();
462               CDMUtilities::splitter::split(wordBits, word, "\"", CDMUtilities::splitter::no_empties);
463
464               this->description = wordBits[0];
465             }
466           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_MAJOR_VERSION")
467             {
468               this->version = wordBits[1];
469             }
470           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_MINOR_VERSION")
471             {
472               this->version += "." + wordBits[1];
473             }
474           else if(wordBits[0] == "${BBTK_PACKAGE_NAME}_BUILD_VERSION")
475             {
476               this->version += "." + wordBits[1];
477             }
478         }
479     }
480
481
482
483   std::vector<bool> checked(this->children.size(), false);
484   bool checkedSrc = false;
485
486   //check all folders
487   wxDir dir(crea::std2wx((this->path).c_str()));
488   if (dir.IsOpened())
489     {
490       wxString fileName;
491       bool cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_DIRS);
492       while (cont)
493         {
494
495           std::string stdfileName = crea::wx2std(fileName);
496
497           //detect black boxes in src
498           if(stdfileName == "src")
499             {
500               //check if box already exist
501               bool found = false;
502               if (this->src != NULL)
503                 {
504                   found = true;
505                   int pos = std::find(this->children.begin(), this->children.end(), this->src) - this->children.begin();
506                   checked[pos] = true;
507                   checkedSrc = true;
508                   if(!this->src->Refresh(result))
509                     return false;
510                 }
511               else
512                 {
513                   this->src = new modelCDMPackageSrc(this, path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level +1);
514                   this->children.push_back(this->src);
515                 }
516             }
517           else
518             {
519
520               //check if folder already exist
521               bool found = false;
522               for (int i = 0; !found && i < (int)(this->children.size()); i++)
523                 {
524                   if (this->children[i]->GetName() == stdfileName)
525                     {
526                       found = true;
527                       checked[i] = true;
528                       if(!this->children[i]->Refresh(result))
529                         return false;
530                     }
531                 }
532               if(!found)
533                 {
534                   modelCDMFolder* folder = new modelCDMFolder(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
535                   this->children.push_back(folder);
536                 }
537             }
538           cont = dir.GetNext(&fileName);
539
540         }
541
542       cont = dir.GetFirst(&fileName, wxEmptyString, wxDIR_FILES);
543       while (cont)
544         {
545           std::string stdfileName = crea::wx2std(fileName);
546           std::size_t fileTypePos = stdfileName.find_last_of(".");
547           std::string fileType = stdfileName.substr(fileTypePos);
548
549           //if CMakeLists, create CMakeLists
550           if(stdfileName == "CMakeLists.txt")
551             {
552               if (this->CMakeLists == NULL)
553                 {
554                   this->CMakeLists = new modelCDMCMakeListsFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
555                   this->children.push_back(this->CMakeLists);
556                 }
557               else
558                 {
559                   int pos = std::find(this->children.begin(), this->children.end(), this->CMakeLists) - this->children.begin();
560                   checked[pos] = true;
561                   if(!this->CMakeLists->Refresh(result))
562                     return false;
563                 }
564             }
565           //if is an unknown file, create file
566           else
567             {
568               bool found = false;
569               for (int i = 0; !found && i < (int)(this->children.size()); i++)
570                 {
571                   if (this->children[i]->GetName() == stdfileName)
572                     {
573                       found = true;
574                       checked[i] = true;
575                       if(!this->children[i]->Refresh(result))
576                         return false;
577                     }
578                 }
579
580               if(!found)
581                 {
582                   //if is a code file, create modelCDMCodeFile
583                   if(
584                       fileType == ".c" ||
585                       fileType == ".cxx" ||
586                       fileType == ".h" ||
587                       fileType == ".cpp" ||
588                       fileType == ".txx" ||
589                       fileType == ".cmake" )
590                     {
591                       this->children.push_back(new modelCDMCodeFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1));
592                     }
593                   else
594                     {
595                       modelCDMFile* file = new modelCDMFile(this, this->path + CDMUtilities::SLASH + stdfileName, stdfileName, this->level + 1);
596                       this->children.push_back(file);
597                     }
598                 }
599             }
600
601           cont = dir.GetNext(&fileName);
602         }
603     }
604
605   if(!checkedSrc)
606     {
607       this->src = NULL;
608     }
609
610   for (int i = 0; i < (int)(checked.size()); i++)
611     {
612       if(!checked[i])
613         {
614           delete this->children[i];
615           this->children.erase(this->children.begin()+i);
616           checked.erase(checked.begin()+i);
617           i--;
618         }
619     }
620   this->SortChildren();
621   return true;
622 }
623
624 void modelCDMPackage::CheckStructure(std::map<std::string, bool>& properties)
625 {
626   //check cmake exist
627   if(this->CMakeLists != NULL)
628     {
629       //open cmakelists
630       std::ifstream confFile;
631       confFile.open((this->CMakeLists->GetPath()).c_str());
632
633       //take everything that is not commented
634       std::string fileContent;
635
636       std::string word;
637       std::vector<std::string> words;
638       while(confFile.is_open() && !confFile.eof())
639         {
640           std::getline(confFile,word, '\n');
641           if(word[0] != '#')
642             {
643               CDMUtilities::splitter::split(words, word, "#", CDMUtilities::splitter::empties_ok);
644               if (words.size() > 0)
645                 {
646                   word = words[0];
647                   CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::empties_ok);
648                   for (int i = 0; i < (int)(words.size()); i++)
649                     {
650                       if(words[i].substr(0,2) == "//")
651                         break;
652                       fileContent += words[i] + " ";
653                     }
654                 }
655             }
656         }
657
658       //check every instruction
659       std::stringstream ss(fileContent);
660       while(!ss.eof())
661         {
662           std::getline(ss,word, '(');
663
664           //check instruction name
665           CDMUtilities::splitter::split(words, word, " ", CDMUtilities::splitter::no_empties);
666
667           //set instructions
668           if (words.size() > 0 && words[words.size()-1] == "SET")
669             {
670               std::getline(ss,word, ')');
671
672               CDMUtilities::splitter::split(words, word, " \t", CDMUtilities::splitter::no_empties);
673               if (words.size() > 1)
674                 {
675                   if (words[0] == "${BBTK_PACKAGE_NAME}_USE_VTK" && words[1] == "ON")
676                     {
677                       properties["package " + this->name + " set USE_VTK"] = true;
678                     }
679                   else if (words[0] == "${BBTK_PACKAGE_NAME}_USE_ITK" && words[1] == "ON")
680                     {
681                       properties["package " + this->name + " set USE_ITK"] = true;
682                     }
683                   else if (words[0] == "${BBTK_PACKAGE_NAME}_USE_GDCM" && words[1] == "ON")
684                     {
685                       properties["package " + this->name + " set USE_GDCM"] = true;
686                     }
687                   else if (words[0] == "${BBTK_PACKAGE_NAME}_USE_GDCM_VTK" && words[1] == "ON")
688                     {
689                       properties["package " + this->name + " set USE_GDCM_VTK"] = true;
690                     }
691                   else if (words[0] == "${BBTK_PACKAGE_NAME}_USE_GSMIS" && words[1] == "ON")
692                     {
693                       properties["package " + this->name + " set USE_GSMIS"] = true;
694                     }
695                   else if (words[0] == "${BBTK_PACKAGE_NAME}_USE_WXWIDGETS" && words[1] == "ON")
696                     {
697                       properties["package " + this->name + " set USE_WXWIDGETS"] = true;
698                     }
699                   else if (words[0] == "${BBTK_PACKAGE_NAME}_USE_KWWIDGETS" && words[1] == "ON")
700                     {
701                       properties["package " + this->name + " set USE_KWWIDGETS"] = true;
702                     }
703                   else if (words[0] == "USE_BOOST" && words[1] == "ON")
704                     {
705                       properties["package " + this->name + " set USE_BOOST"] = true;
706                     }
707                   else if (words[0] == "${BBTK_PACKAGE_NAME}_INCLUDE_DIRS")
708                     {
709                       for (int i = 1; i < (int)(words.size()); i++)
710                         {
711                           if(words[i].substr(0,2) == "${" || words[i].substr(0,2) == "..")
712                           properties["package " + this->name + " dir " + words[i]] = true;
713                         }
714                     }
715                   else if (words[0] == "${BBTK_PACKAGE_NAME}_LIBS")
716                     {
717                       for (int i = 1; i < (int)(words.size()); i++)
718                         {
719                           properties["package " + this->name + " lib " + words[i]] = true;
720                         }
721                     }
722                 }
723             }
724         }
725
726     }
727 }
728
729 std::map<std::string, bool> modelCDMPackage::Get3rdPartyLibraries()
730 {
731   std::map<std::string, std::string> correspondence;
732   correspondence["${BBTK_PACKAGE_NAME}_USE_VTK"] = "VTK";
733   correspondence["${BBTK_PACKAGE_NAME}_USE_ITK"] = "ITK";
734   correspondence["${BBTK_PACKAGE_NAME}_USE_GDCM"] = "GDCM";
735   correspondence["${BBTK_PACKAGE_NAME}_USE_GDCM_VTK"] = "GDCM_VTK";
736   correspondence["${BBTK_PACKAGE_NAME}_USE_GSMIS"] = "GSMIS";
737   correspondence["${BBTK_PACKAGE_NAME}_USE_WXWIDGETS"] = "WxWidgets";
738   correspondence["${BBTK_PACKAGE_NAME}_USE_KWWIDGETS"] = "KWWidgets";
739   std::map<std::string, bool> res;
740   res["VTK"] = false;
741   res["ITK"] = false;
742   res["GDCM"] = false;
743   res["GDCM_VTK"] = false;
744   res["GSMIS"] = false;
745   res["WxWidgets"] = false;
746   res["KWWidgets"] = false;
747
748   if (this->HasCMakeLists())
749     {
750       std::string CMfile = CDMUtilities::readFile(this->CMakeLists->GetPath().c_str());
751
752       boost::regex expression("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_USE_\\w+\\s+ON");
753       std::string::const_iterator start, end;
754       start = CMfile.begin();
755       end = CMfile.end();
756       boost::match_results<std::string::const_iterator> what;
757       boost::match_flag_type flags = boost::match_default;
758       while(boost::regex_search(start, end, what, expression, flags))
759         {
760           //std::cout << what[0].str() << std::endl;
761           boost::regex expression1 = boost::regex("\\$\\{BBTK_PACKAGE_NAME\\}_USE_\\w+");
762           std::string::const_iterator start1, end1;
763           start1 = what[0].first;
764           end1 = what[0].second;
765           boost::match_results<std::string::const_iterator> what1;
766           if(boost::regex_search(start1, end1, what1, expression1, flags))
767             {
768               std::string dete = what1.str();
769               CDMUtilities::normalizeStr(dete);
770               //std::cout << dete << std::endl;
771               if(correspondence.find(dete) != correspondence.end())
772                 res[correspondence[dete]] = true;
773             }
774           start = what[0].second;
775         }
776     }
777   return res;
778 }
779
780 bool modelCDMPackage::Set3rdPartyLibrary(const std::string& library_name,
781     const bool& toInclude)
782 {
783   std::map<std::string, std::string> correspondence;
784
785   correspondence["VTK"] = "_USE_VTK";
786   correspondence["ITK"] = "_USE_ITK";
787   correspondence["GDCM"] = "_USE_GDCM";
788   correspondence["GDCM_VTK"] = "_USE_GDCM_VTK";
789   correspondence["GSMIS"] = "_USE_GSMIS";
790   correspondence["WxWidgets"] = "_USE_WXWIDGETS";
791   correspondence["KWWidgets"] = "_USE_KWWIDGETS";
792
793   if (correspondence.find(library_name) != correspondence.end())
794     {
795       std::string library_command = correspondence[library_name];
796       if (this->HasCMakeLists())
797         {
798           std::string CMfile = CDMUtilities::readFile(this->CMakeLists->GetPath().c_str());
799           std::string resCMfile = "";
800           bool found = false;
801
802           try {
803             boost::regex expression("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}"+library_command+"([\\s]|#[^\\n]*\\n)+ON([\\s]|#[^\\n]*\\n)*\\)");
804
805             std::string::const_iterator start, end;
806             start = CMfile.begin();
807             end = CMfile.end();
808             boost::match_results<std::string::const_iterator> what;
809             boost::match_flag_type flags = boost::match_default;
810             if(boost::regex_search(start, end, what, expression, flags))
811               {
812                 found = true;
813                 resCMfile += what.prefix().str();
814                 if (toInclude)
815                   resCMfile += what.str();
816                 else
817                   resCMfile += "#" + what.str();
818                 resCMfile += what.suffix().str();
819
820                 return CDMUtilities::writeFile(this->CMakeLists->GetPath().c_str(), resCMfile);
821               }
822             else
823               {
824                 boost::regex expression("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}"+library_command+"([\\s]|#[^\\n]*\\n)+OFF([\\s]|#[^\\n]*\\n)*\\)");
825
826                 start = CMfile.begin();
827                 end = CMfile.end();
828                 if(boost::regex_search(start, end, what, expression, flags))
829                   {
830                     found = true;
831                     resCMfile += what.prefix().str();
832                     if (toInclude)
833                       {
834                         std::string dete = what.str();
835                         int pos = dete.rfind("OFF");
836                         dete.replace(pos, 3, "ON");
837                         resCMfile += dete;
838                       }
839                     else
840                       resCMfile += what.str();
841                     resCMfile += what.suffix().str();
842
843                     return CDMUtilities::writeFile(this->CMakeLists->GetPath().c_str(), resCMfile);
844                   }
845                 else
846                   {
847                     boost::regex expression("^\\h*#\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}"+library_command+"([\\s]|#[^\\n]*\\n)+ON([\\s]|#[^\\n]*\\n)*\\)");
848                     if(boost::regex_search(start, end, what, expression, flags))
849                       {
850                         found = true;
851                         resCMfile += what.prefix().str();
852                         if(toInclude)
853                           {
854                             std::string dete = what[0].str();
855                             for (int i = 0; i < dete.size(); ++i) {
856                               if (dete[i] != '#')
857                                 resCMfile.push_back(dete[i]);
858                               if (dete[i] == 'S')
859                                 {
860                                   resCMfile += dete.substr(i+1);
861                                   break;
862                                 }
863                             }
864                           }
865                         else
866                           resCMfile += what.str();
867
868                         resCMfile += what.suffix().str();
869                         return CDMUtilities::writeFile(this->CMakeLists->GetPath().c_str(), resCMfile);
870                       }
871                     else
872                       {
873                         boost::regex expression("^\\h*#\\h*UNCOMMENT EACH LIBRARY NEEDED \\(WILL BE FOUND AND USED AUTOMATICALLY\\)[^\\n]*\\n");
874                         if(boost::regex_search(start, end, what, expression, flags))
875                           {
876                             found = true;
877                             resCMfile += what.prefix().str();
878                             resCMfile += what.str();
879                             if(toInclude)
880                               {
881                                 resCMfile += "SET(${BBTK_PACKAGE_NAME}"+ library_command +"  ON)\n";
882                               }
883                             resCMfile += what.suffix().str();
884                             return CDMUtilities::writeFile(this->CMakeLists->GetPath().c_str(), resCMfile);
885                           }
886                       }
887                   }
888               }
889           } catch (boost::bad_expression& e) {
890             std::cout << "bad regex: " << e.what() << std::endl;
891             std::cout.flush();
892           }
893         }
894     }
895   return false;
896 }
897
898 std::map<std::string, bool> modelCDMPackage::GetCustomLibraries()
899 {
900   std::map<std::string, bool> res;
901   std::map<std::string, bool> res1;
902
903   std::map<std::string, std::string> correspondence;
904   std::vector<modelCDMLibrary*> libraries;
905   modelCDMIProjectTreeNode* p = this;
906   while(p != NULL && dynamic_cast<modelCDMProject*>(p) == NULL)
907     p = p->GetParent();
908
909   if(p != NULL && dynamic_cast<modelCDMProject*>(p)->GetLib() != NULL)
910     libraries = dynamic_cast<modelCDMProject*>(p)->GetLib()->GetLibraries();
911
912   for (int i = 0; i < libraries.size(); ++i)
913     {
914       correspondence[libraries[i]->GetName()] = libraries[i]->GetNameLibrary();
915       res[libraries[i]->GetNameLibrary()] = false;
916       res1[libraries[i]->GetNameLibrary()] = false;
917     }
918
919   if (this->HasCMakeLists())
920     {
921       std::string CMfile = CDMUtilities::readFile(this->CMakeLists->GetPath().c_str());
922
923       //find included libraries
924       boost::regex expression("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_LIBS(([\\s]|#[^\\n]*\\n)+([\\$\\{\\}\\w\\d]+|\"(?:[^\"\\\\]|\\\\.)*\"))*([\\s]|#[^\\n]*\\n)*\\)");
925       std::string::const_iterator start, end;
926       start = CMfile.begin();
927       end = CMfile.end();
928       boost::match_results<std::string::const_iterator> what;
929       boost::match_flag_type flags = boost::match_default;
930       if(boost::regex_search(start, end, what, expression, flags))
931         {
932
933           expression = boost::regex("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_LIBS");
934           std::string::const_iterator start1, end1;
935           start1 = what[0].first;
936           end1 = what[0].second;
937           boost::match_results<std::string::const_iterator> what1;
938           if(boost::regex_search(start1, end1, what1, expression, flags))
939             {
940               expression = boost::regex("^\\h*[\\w\\d]+");
941               std::string::const_iterator start2, end2;
942               start2 = what1[0].second;
943               end2 = what[0].second;
944               boost::match_results<std::string::const_iterator> what2;
945               while(boost::regex_search(start2, end2, what2, expression, flags))
946                 {
947                   std::string dete = what2.str();
948                   CDMUtilities::normalizeStr(dete);
949                   //std::cout << "detectado lib: " << dete << std::endl;
950                   if(res1.find(dete) != res1.end())
951                     res1[dete] = true;
952
953                   start2 = what2[0].second;
954                 }
955             }
956         }
957
958       //find included folders
959       //std::cout << "searching..." << std::endl;
960       expression = boost::regex("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_INCLUDE_DIRS(([\\s]|#[^\\n]*\\n|////[^\\n]*\\n)+([\\.\\/\\$\\{\\}\\w\\d]+|\"(?:[^\"\\\\]|\\\\.)*\"))*([\\s]|#[^\\n]*\\n)*\\)");
961       start = CMfile.begin();
962       end = CMfile.end();
963       if(boost::regex_search(start, end, what, expression, flags))
964         {
965           //std::cout << what.str() << std::endl;
966           expression = boost::regex("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_INCLUDE_DIRS");
967           std::string::const_iterator start1, end1;
968           start1 = what[0].first;
969           end1 = what[0].second;
970           boost::match_results<std::string::const_iterator> what1;
971           if(boost::regex_search(start1, end1, what1, expression, flags))
972             {
973               //std::cout << what1.str() << std::endl;
974               expression = boost::regex("^\\h*\\.\\.\\/lib\\/([\\w\\d])+");
975               std::string::const_iterator start2, end2;
976               start2 = what1[0].second;
977               end2 = what[0].second;
978               boost::match_results<std::string::const_iterator> what2;
979               while(boost::regex_search(start2, end2, what2, expression, flags))
980                 {
981                   std::string dete = what2.str();
982                   CDMUtilities::normalizeStr(dete);
983                   //std::cout << "detectado dir: " << dete.substr(7) << std::endl;
984                   if(correspondence.find(dete.substr(7)) != correspondence.end())
985                     res[correspondence[dete.substr(7)]] = res1[correspondence[dete.substr(7)]];
986
987                   start2 = what2[0].second;
988                 }
989             }
990         }
991     }
992
993   return res;
994 }
995
996 bool modelCDMPackage::SetCustomLibrary(const std::string& library_name,
997     const bool& toInclude)
998 {
999   std::map<std::string, std::string> correspondence;
1000
1001     std::vector<modelCDMLibrary*> libraries;
1002     modelCDMIProjectTreeNode* p = this;
1003     while(p != NULL && dynamic_cast<modelCDMProject*>(p) == NULL)
1004       p = p->GetParent();
1005
1006     if(p != NULL && dynamic_cast<modelCDMProject*>(p)->GetLib() != NULL)
1007       libraries = dynamic_cast<modelCDMProject*>(p)->GetLib()->GetLibraries();
1008
1009     for (int i = 0; i < libraries.size(); ++i)
1010       {
1011         correspondence[libraries[i]->GetNameLibrary()] = libraries[i]->GetName();
1012       }
1013
1014     if (correspondence.find(library_name) != correspondence.end())
1015       {
1016         if (this->HasCMakeLists())
1017           {
1018             std::string resCMfile = "";
1019             std::string CMfile = CDMUtilities::readFile(this->CMakeLists->GetPath().c_str());
1020             bool found = false;
1021
1022             //find included libraries
1023             //std::cout << "searching..." << CMfile << std::endl;
1024             boost::regex expression("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_LIBS(([\\s]|#[^\\n]*\\n)+([\\$\\{\\}\\w\\d]+|\"(?:[^\"\\\\]|\\\\.)*\"))*([\\s]|#[^\\n]*\\n)*\\)");
1025             std::string::const_iterator start, end;
1026             start = CMfile.begin();
1027             end = CMfile.end();
1028             boost::match_results<std::string::const_iterator> what;
1029             boost::match_flag_type flags = boost::match_default;
1030             if(boost::regex_search(start, end, what, expression, flags))
1031               {
1032                 //std::cout << what.str() << std::endl;
1033                 resCMfile += what.prefix().str();
1034                 expression = boost::regex("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_LIBS");
1035                 std::string::const_iterator start1, end1;
1036                 start1 = what[0].first;
1037                 end1 = what[0].second;
1038                 boost::match_results<std::string::const_iterator> what1;
1039                 if(boost::regex_search(start1, end1, what1, expression, flags))
1040                   {
1041                     resCMfile += what1.prefix().str() + what1.str();
1042                     //check if already exists
1043                     expression = boost::regex("^\\h*"+library_name);
1044                     std::string::const_iterator start2, end2;
1045                     start2 = what1[0].second;
1046                     end2 = what[0].second;
1047                     boost::match_results<std::string::const_iterator> what2, temp2;
1048                     while(boost::regex_search(start2, end2, what2, expression, flags))
1049                       {
1050                         resCMfile += what2.prefix().str();
1051                         found = true;
1052                         if (!toInclude)
1053                           {
1054                             resCMfile += "#";
1055                           }
1056                         resCMfile += what2.str();
1057                         temp2 = what2;
1058                         start2 = what2[0].second;
1059                       }
1060                     if(found)
1061                       resCMfile += temp2.suffix().str();
1062                     //check if is commented
1063                     else
1064                       {
1065                         expression = boost::regex("^\\h*#+\\h*"+library_name);
1066                         start2 = what1[0].second;
1067                         end2 = what[0].second;
1068                         while(boost::regex_search(start2, end2, what2, expression, flags))
1069                           {
1070                             found = true;
1071                             resCMfile += what2.prefix().str();
1072                             if(toInclude)
1073                               {
1074                                 std::string dete = what2[0].str();
1075                                 for (int i = 0; i < dete.size(); ++i) {
1076                                   if (dete[i] != '#')
1077                                     resCMfile.push_back(dete[i]);
1078                                 }
1079                               }
1080                             temp2 = what2;
1081                             start2 = what2[0].second;
1082                           }
1083                         if(found)
1084                           resCMfile += temp2.suffix().str();
1085                         //add at the beggining of instruction
1086                         else
1087                           {
1088                             if(toInclude)
1089                               resCMfile += "\n" + library_name;
1090                             resCMfile += what1.suffix().str();
1091                           }
1092                       }
1093                   }
1094                 resCMfile += what.suffix().str();
1095               }
1096             else
1097               return false;
1098
1099             //find included folders
1100             CMfile = resCMfile;
1101             resCMfile = "";
1102
1103
1104             found = false;
1105             //std::cout << "searching..." << CMfile << std::endl;
1106             expression = boost::regex("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_INCLUDE_DIRS(([\\s]|#[^\\n]*\\n)+([\\.\\/\\$\\{\\}\\w\\d]+|\"(?:[^\"\\\\]|\\\\.)*\"))*([\\s]|#[^\\n]*\\n)*\\)");
1107             start = CMfile.begin();
1108             end = CMfile.end();
1109             if(boost::regex_search(start, end, what, expression, flags))
1110               {
1111                 resCMfile += what.prefix().str();
1112                 //std::cout << what.str() << std::endl;
1113                 expression = boost::regex("^\\h*SET([\\s]|#[^\\n]*\\n)*\\(([\\s]|#[^\\n]*\\n)*\\$\\{BBTK_PACKAGE_NAME\\}_INCLUDE_DIRS");
1114                 std::string::const_iterator start1, end1;
1115                 start1 = what[0].first;
1116                 end1 = what[0].second;
1117                 boost::match_results<std::string::const_iterator> what1;
1118                 if(boost::regex_search(start1, end1, what1, expression, flags))
1119                   {
1120                     resCMfile += what1.prefix().str() + what1.str();
1121                     //std::cout << what1.str() << std::endl;
1122                     //search if dir is already included
1123                     expression = boost::regex("^\\h*\\.\\.\\/lib\\/"+correspondence[library_name]);
1124                     std::string::const_iterator start2, end2;
1125                     start2 = what1[0].second;
1126                     end2 = what[0].second;
1127                     boost::match_results<std::string::const_iterator> what2, temp2;
1128                     while(boost::regex_search(start2, end2, what2, expression, flags))
1129                       {
1130                         found = true;
1131                         resCMfile += what2.prefix().str();
1132                         if(!toInclude)
1133                           resCMfile += "#";
1134                         resCMfile += what2.str();
1135                         temp2 = what2;
1136                         start2 = what2[0].second;
1137                       }
1138                     if(found)
1139                       resCMfile += temp2.suffix().str();
1140                     //search if dir is commented
1141                     else
1142                       {
1143                         expression = boost::regex("^\\h*#+\\h*\\.\\.\\/lib\\/"+correspondence[library_name]);
1144                         start2 = what1[0].second;
1145                         end2 = what[0].second;
1146                         while(boost::regex_search(start2, end2, what2, expression, flags))
1147                           {
1148                             found = true;
1149                             resCMfile += what2.prefix().str();
1150                             if(toInclude)
1151                               {
1152                                 std::string dete = what2[0].str();
1153                                 for (int i = 0; i < dete.size(); ++i) {
1154                                   if (dete[i] != '#')
1155                                     resCMfile.push_back(dete[i]);
1156                                 }
1157                               }
1158                             temp2 = what2;
1159                             start2 = what2[0].second;
1160                           }
1161                         if(found)
1162                           resCMfile += temp2.suffix().str();
1163                         //add at the beggining of instruction
1164                         else
1165                           {
1166                             if(toInclude)
1167                               resCMfile += "\n../lib/" + correspondence[library_name];
1168                             resCMfile += what1.suffix().str();
1169                           }
1170                       }
1171                   }
1172                 resCMfile += what.suffix().str();
1173               }
1174             else
1175               return false;
1176
1177             return CDMUtilities::writeFile(this->CMakeLists->GetPath().c_str(), resCMfile);
1178           }
1179       }
1180
1181     return false;
1182 }