]> Creatis software - bbtk.git/blob - kernel/src/bbtkUtilities.cxx
#2536 BBTK Feature New Normal wt-version Package
[bbtk.git] / kernel / src / bbtkUtilities.cxx
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   Program:   bbtk
30   Module:    $RCSfile: bbtkUtilities.cxx,v $
31   Language:  C++
32   Date:      $Date: 2012/11/16 08:49:01 $
33   Version:   $Revision: 1.15 $
34 =========================================================================*/
35
36
37
38
39 #include "bbtkUtilities.h"
40 #include "bbtkMessageManager.h"
41
42 #if defined(MACOSX) // assume this is OSX 
43 # include <sys/param.h>
44 # include <mach-o/dyld.h> // _NSGetExecutablePath : must add -framework CoreFoundation to link line 
45 # include <string.h>
46 # ifndef PATH_MAX
47 #  define PATH_MAX MAXPATHLEN
48 # endif
49 #endif // MACOSX
50
51 #ifndef PATH_MAX // If not defined yet : do it 
52 #  define PATH_MAX 2048
53 #endif 
54
55 namespace bbtk
56 {
57
58
59
60             // ======================================================================
61     // See : http://www.techbytes.ca/techbyte103.html for more O.S.
62     bool Utilities::FileExists(std::string strFilename) 
63     {
64       struct stat stFileInfo;
65      bool blnReturn;
66      int intStat;
67      
68      // Attempt to get the file attributes
69      intStat = stat(strFilename.c_str(),&stFileInfo);
70      if(intStat == 0) 
71        {
72          // We were able to get the file attributes
73          // so the file obviously exists.
74          blnReturn = true;
75        } 
76      else 
77        {
78          // We were not able to get the file attributes.
79          // This may mean that we don't have permission to
80          // access the folder which contains this file. If you
81          // need to do that level of checking, lookup the
82          // return values of stat which will give you
83          // more details on why stat failed.
84          blnReturn = false;
85        }
86      
87      return(blnReturn);
88     }
89     
90     
91     // =====================================================================
92     
93     std::string Utilities::ExtractPackageName(const std::string  &name, 
94                                           std::string& path)
95     {
96       std::string pkgname;
97       path = "";
98       
99       std::string::size_type slash_position = name.find_last_of("/\\");
100       if (slash_position != std::string::npos) 
101         {
102           pkgname = name.substr(slash_position+1,std::string::npos);
103           path = name.substr(0,slash_position);
104           //    std::cout << "F:P='"<<path<<"'"<<std::endl;//+1,std::string::npos);
105         }
106       else 
107         {
108           pkgname = name;
109         }
110       
111       // remove {.so | dll} if any
112       std::string::size_type dot_position = pkgname.find_last_of('.');      
113       if (dot_position != std::string::npos){
114         pkgname = pkgname.substr(0,dot_position);
115       }      
116 #if defined(__GNUC__)
117       
118       // GCC mechanism
119       // shared lib name = libbb<name>.so
120       
121       // remove {libbb} if any
122       if (memcmp ( pkgname.c_str(), "libbb", 5) == 0) {
123         pkgname =  pkgname.substr(5, pkgname.length());
124       }
125       /*
126      /// \ \todo     what would happen if (stupid) user names his package 'libbb' ?!?
127       /// \ --> Should be forbidden!
128       */
129 #elif defined(_WIN32)
130       
131       // WIN 32 mechanism
132       // shared lib name = <name>.dll
133       
134       // EED Problem loading package call bbtkTools
135       //     // remove {bb} if any
136       if (memcmp (pkgname.c_str(), "bb", 2) == 0) {
137         pkgname =  pkgname.substr(2, pkgname.length());  
138       }
139       
140       /*
141      /// \ \todo     what would happen if (stupid) user names his package 'bb' ?!?
142      /// \ --> Should be forbidden!
143      */
144 #else
145       bbtkError("neither __GNUC__ nor _WIN32 ?!? How did you compile ?");
146 #endif      
147       return pkgname;
148     }
149     
150     //=====================================================================
151     std::string Utilities::ExtractScriptName(const std::string &name,
152                                          std::string& path)
153     {
154       std::string pkgname;
155       
156       std::string::size_type slash_position = name.find_last_of("/\\");
157       if (slash_position != std::string::npos) {
158         pkgname =name.substr(slash_position+1,std::string::npos);
159         path = name.substr(0,slash_position);      
160       } else {
161         pkgname = name;
162       }
163       // remove {.bbs } if any
164       std::string::size_type dot_position = pkgname.find_last_of('.');
165       if (dot_position != std::string::npos){
166         pkgname = pkgname.substr(0,dot_position);
167       }
168       return pkgname;
169     }
170     
171     // ========================================================================
172
173     std::string Utilities::ExpandLibName(const std::string &name, bool verbose)
174     {
175       // -----   Think of expanding path name ( ./ ../ ../../ )
176       
177       char buf[2048]; // for getcwd
178       char * currentDir = getcwd(buf, 2048);
179       std::string cwd(currentDir);
180       std::string libname(name);
181       std::string fileSeparator;
182       fileSeparator = ConfigurationFile::GetInstance().Get_file_separator();
183       // tooHigh : true is user supplies a library pathname with too many "../"
184       bool tooHigh = false;
185       
186       //std::cout << "------------------cwd ["  << cwd << "] name [" << name << "]" << std::endl;
187       
188       if ( name[0] == '/' ||  name[1] == ':' ) // Linux or Windows absolute name
189         {
190           return(libname);
191         }
192       else if  ( name =="." )
193         {
194           libname = cwd  + fileSeparator;
195           return(libname);
196         }
197       else if  (name[0] == '.' && (name[1] == '/' || name[1] == '\\') )
198         {
199           libname = cwd  + fileSeparator + name.substr(2, name.length());
200           return(libname);
201         }
202       else if ( name[0] == '.' &&  name[1] == '.' /*  && (name[2] == '/' || name[2] == '\\') */ ) 
203         {
204           if ( IsAtRoot(cwd) )  // hope it gets / (for Linux),  C: D: (for Windows)
205       {  
206      // if we are already at / or c: --> hopeless  
207          if (verbose)
208            std::cout << "   File path [" <<  name << "] doesn't exist" << std::endl;
209          tooHigh = true;
210       }
211       else
212       {
213          // iterate on ../ and go up from the current working dir!
214          std::string a(name); 
215          bool alreadyProcessRoot = false;
216
217           //if (a[a.size()-1] != fileSeparator[0])
218           //   a.append(fileSeparator);
219 //std::cout << "------------------a ["  << a << "]" << std::endl;
220
221          for(;;)  // wild loop !
222          {
223             std::string::size_type slash_position = cwd.find_last_of(fileSeparator);
224             if (slash_position != std::string::npos) {
225              if (slash_position == 0)
226                 slash_position = 1;
227               cwd = cwd.substr(0,slash_position/*+1*/);
228 //std::cout << "------------------cwd ["  << cwd << "]" << std::endl;
229             //  if (a == "..") {
230             //    a = "";
231             //    break;
232             //   }
233             //   else
234                  a = a.substr(3, /*name.length()*/ a.length());  // remove ../
235 //std::cout << "------------------a ["  << a << "]" << std::endl;  
236               if (a == "" || alreadyProcessRoot)
237               {
238                 if (verbose)
239                   std::cout << "   File path : [" <<  name << "] doesn't exist" << std::endl;
240                 tooHigh = true;
241                 break;
242               }
243              // std::string b = cwd + a;
244               libname =  cwd;
245               char c = cwd[cwd.size()-1];
246               if (c != '/' && c != '\\' )
247                 libname += fileSeparator;
248               libname += a;
249
250               if ( a[0] != '.' ) // if . (probabely ../), loop again
251                 break;
252
253               if (IsAtRoot(cwd))
254                 alreadyProcessRoot = true;
255             }
256          } // end iterating on ../
257       }
258 //std::cout << "------------------out of loop]" << std::endl;        
259       if (tooHigh)
260          libname="";
261       return (libname);
262
263     }  // -----   End of expanding path name   ( ./ ../ ../../ )
264
265     std::cout <<"* ERROR in ExpandLibName : should never get here!" << std::endl;
266     // To avoid warning
267     return(""); // Will never get here!
268   }
269
270 // ===================================================================================
271
272   std::string Utilities::MakeLibnameFromPath(std::string path, std::string pkgname)
273   {
274     std::string libname = path;
275         if(path.size()>0){
276                 char c = path[path.size()-1];    
277 #if defined(__GNUC__)
278        if (c != '/')
279           libname += "/libbb";
280        else
281           libname += "libbb";
282        libname += pkgname;
283 #if defined(MACOSX)
284           libname += ".dylib";
285 #else
286           libname += ".so";
287 #endif  
288           
289 #elif defined(_WIN32)
290        if (c != '\\') 
291           libname += "\\bb";
292        else
293           libname += "bb";
294        libname += pkgname;
295        libname += ".dll";
296 #endif
297         }
298     
299     return libname;    
300   }
301
302 // ===================================================================================
303
304   std::string Utilities::MakePkgnameFromPath(std::string path, std::string pkgname, bool addExt)
305   {
306     std::string libname = path;
307         if(path.size()>0){
308                 char c = path[path.size()-1];
309                 if (c != '/' && c != '\\')
310                 {
311                    libname +=  ConfigurationFile::GetInstance().Get_file_separator ();
312                 }
313                 libname += pkgname;
314                 if (addExt)
315                 {
316                    int l = libname.size();
317                    if (l>4)
318                    {
319                           if (libname.substr(l-4, 4) != ".bbs")
320                           {
321                                    libname = libname + ".bbs";
322                           }
323                    }
324                 }
325         }
326     
327     return libname;
328   }
329   // =======================================================================
330
331   // =======================================================================
332   /// Returns the user settings dir, e.g. /home/username/.bbtk
333   std::string Utilities::GetUserSettingsDir()
334   {
335     std::string str_Home=Utilities::GetEnvHome();
336     std::string fullname = str_Home + "/.bbtk";
337     MakeValidFileName(fullname);
338     return fullname;
339   }
340   
341
342   // =======================================================================
343   /// Builds the complete path to the file 'name' located 
344   /// in user settings dir, e.g. /home/username/.bbtk/
345   std::string Utilities::MakeUserSettingsFullFileName(const std::string& name)
346   {
347     std::string str_home=Utilities::GetEnvHome();
348     std::string fullname = str_home + "/.bbtk/" + name;
349     MakeValidFileName(fullname);
350     return fullname;
351   }
352   // =======================================================================
353   
354
355   // =======================================================================
356   void Utilities::CreateDirectoryIfNeeded( std::string const &dirName)
357   {
358     if (FileExists(dirName)) return;
359     std::string cmd("mkdir \"");
360     cmd += dirName;
361     cmd += "\"";
362     system(cmd.c_str());
363   }  
364   // =======================================================================
365   
366   
367   //========================================================================
368   bool Utilities::IsAtRoot(std::string cwd)
369   {
370     if ( cwd == "/"              // hope it gets /     (for Linux)
371          || (cwd.size() <= 3 && cwd[1] == ':') ) // hope it gets C: D: (for Windows)
372       return (true);
373     else
374       return(false);
375   }
376   // ======================================================================
377
378   // ======================================================================
379   bool Utilities::IsDirectory(std::string const &dirName)
380   {
381     struct stat fs;
382     
383     if ( stat(dirName.c_str(), &fs) == 0 )
384       {
385 #if _WIN32
386         return ((fs.st_mode & _S_IFDIR) != 0);
387 #else
388         return S_ISDIR(fs.st_mode);
389 #endif
390       }
391     else
392       {
393         return false;
394       }
395   }
396   // =======================================================================
397     
398   // =======================================================================
399   void Utilities::SplitAroundFirstDot( const std::string& in,
400                                        std::string& left,
401                                        std::string& right)
402   {
403     std::string delimiter = ".";
404     std::string::size_type pos = in.find_first_of(delimiter);
405     if (std::string::npos != pos) 
406       {
407         left = in.substr(0,pos);
408         right = in.substr(pos+1,in.size());
409         
410       }
411     else
412       {
413         left ="";
414         right = "";
415         bbtkGlobalError("Token '"<<in<<"' : expected 'a.b' format but no dot found");
416       }
417   }
418   //=======================================================================
419
420   //=======================================================================
421   void Utilities::SplitString ( const std::string& str, 
422                                 const std::string& delimiters, 
423                                 std::vector<std::string>& tokens)
424   {
425     // Skip delimiters at beginning.
426     std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
427     // Find first delimiter.
428     std::string::size_type pos     = str.find_first_of(delimiters, lastPos);
429     
430     while (std::string::npos != pos || std::string::npos != lastPos)
431       {
432         // Found a token, add it to the vector.
433         tokens.push_back(str.substr(lastPos, pos - lastPos));
434         // Skip delimiters.  Note the "not_of"
435         lastPos = str.find_first_not_of(delimiters, pos);
436         // Find next delimiter
437         pos = str.find_first_of(delimiters, lastPos);
438       }
439     
440   }
441   //=======================================================================
442   
443   
444   // ======================================================================
445   std::string Utilities::get_file_name(const std::string& s) 
446   { 
447     std::string::size_type slash_position = s.find_last_of("/\\");
448     if (slash_position != std::string::npos) 
449       {
450         return  s.substr(slash_position+1,std::string::npos);   
451       }
452     else 
453       {
454         return s;
455       }
456   }
457   //=======================================================================
458  
459
460   // ========================================================================
461   /**
462    * \brief   Explore a directory with possibility of recursion
463    *          return number of files read
464    * @param  dirpath   directory to explore
465    * @param  recursive whether we want recursion or not
466    */
467   int Utilities::Explore(std::string const &dirpath, bool recursive, std::vector<std::string> &Filenames)
468   {
469     int numberOfFiles = 0;
470     std::string fileName;
471       
472       std::string dirName = dirpath;
473       
474 #ifdef _MSC_VER
475       WIN32_FIND_DATA fileData;
476    HANDLE hFile = FindFirstFile((dirName+"\\*").c_str(), &fileData);
477
478    for(BOOL b = (hFile != INVALID_HANDLE_VALUE); b;
479        b = FindNextFile(hFile, &fileData))
480    {
481       fileName = fileData.cFileName;
482       if ( fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
483       {
484          // Need to check for . and .. to avoid infinite loop
485          if ( fileName != "." && fileName != ".." && recursive )
486          {
487             numberOfFiles += Explore(dirName+ "\\"+fileName,recursive,Filenames);
488          }
489       }
490       else
491       {
492          Filenames.push_back(dirName+"\\"+fileName);
493          numberOfFiles++;
494       }
495    }
496    DWORD dwError = GetLastError();
497    if (hFile != INVALID_HANDLE_VALUE) 
498       FindClose(hFile);
499    if (dwError != ERROR_NO_MORE_FILES) 
500    {
501       LPVOID lpMsgBuf;
502       FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
503                     FORMAT_MESSAGE_FROM_SYSTEM|
504                     FORMAT_MESSAGE_IGNORE_INSERTS,
505                     NULL,GetLastError(),
506                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
507                     (LPTSTR) &lpMsgBuf,0,NULL);
508
509      // ErrorMacro("FindNextFile error. Error is " << (char *)lpMsgBuf
510      //             <<" for the directory : "<<dirName);
511       
512       return 0;
513    }
514
515 #else
516   // Real POSIX implementation: scandir is a BSD extension only, and doesn't 
517   // work on debian for example
518 //std::cout <<"in Explor dirname[" << dirName << "]" << std::endl; 
519    DIR* dir = opendir(dirName.c_str());
520    if (!dir)
521    {
522       return 0;
523    }
524 //std::cout <<"Open OK" << std::endl; 
525    // According to POSIX, the dirent structure contains a field char d_name[]
526    // of unspecified size, with at most NAME_MAX characters preceeding the
527    // terminating null character. Use of other fields will harm the  porta-
528    // bility of your programs.
529
530    struct stat buf;
531    dirent *d;
532    for (d = readdir(dir); d; d = readdir(dir))
533    {
534       fileName = dirName + "/" + d->d_name;
535 //std::cout <<"in Explor filename[" << fileName << "]" << std::endl;      
536       if( stat(fileName.c_str(), &buf) != 0 )
537       {
538          //ErrorMacro( strerror(errno) );
539       }
540       if ( S_ISREG(buf.st_mode) )    //is it a regular file?
541       {
542          Filenames.push_back( fileName );
543          numberOfFiles++;
544       }
545       else if ( S_ISDIR(buf.st_mode) ) //directory?
546       {
547          if ( d->d_name[0] != '.' && recursive ) //we also skip hidden files
548          {
549             numberOfFiles += Explore( fileName, recursive, Filenames);
550          }
551       }
552       else
553       {
554          //ErrorMacro( "Unexpected error" );
555          return -1;
556       }
557    }
558    if( closedir(dir) != 0 )
559    {
560      // ErrorMacro( strerror(errno) );
561    }
562 #endif
563
564   return numberOfFiles;
565
566 }
567   //=======================================================================
568  
569
570     //=======================================================================
571     // Replaces substrings "\\n" by a real carriage return "\n"
572     void Utilities::SubsBackslashN ( std::string& s )
573     {
574       std::string ss("\\n");
575       std::string::size_type pos = 0;
576       pos = s.find(ss,0);
577       const char* cr = "\n";
578       while ( pos != std::string::npos )
579         {
580           s.replace(pos,2,cr,1);
581           pos = s.find(ss, pos-1);
582         }
583     }
584     //=======================================================================
585
586
587    //=======================================================================
588
589   bool Utilities::loosematch(std::string stdLine,std::string stdOptions) 
590   {
591     bool result=false;
592     std::vector<std::string> tokens;
593     SplitString ( stdOptions,"|", tokens);
594     int i,size=tokens.size();  
595     for (i=0; i<size; i++)
596       {           
597 #ifdef WIN32
598         if ( strcmpi(stdLine.c_str(),tokens[i].c_str())==0) 
599           { 
600             result=true; 
601           }               
602 #else
603         if ( strcasecmp(stdLine.c_str(),tokens[i].c_str())==0) 
604           { 
605             result=true; 
606           }               
607 #endif
608         
609       }
610     return result;
611   }
612   //=========================================================================  
613   
614   //=========================================================================  
615   // From http://www.fltk.org/newsgroups.php?gfltk.general+v:22083
616   //
617   int get_app_path (char *pname, size_t pathsize)
618   {
619 #ifdef LINUX
620     /* Oddly, the readlink(2) man page says no NULL is appended. */
621     /* So you have to do it yourself, based on the return value: */
622     pathsize --; /* Preserve a space to add the trailing NULL */
623     long result = readlink("/proc/self/exe", pname, pathsize);
624     if (result > 0)
625       {
626         pname[result] = 0; /* add the #@!%ing NULL */
627         
628         if ((access(pname, 0) == 0))
629           return 0; /* file exists, return OK */
630         /*else name doesn't seem to exist, return FAIL (falls
631           through) */
632       }
633 #endif /* LINUX */
634     
635 #ifdef WIN32
636     long result = GetModuleFileName(NULL, pname, pathsize);
637     if (result > 0)
638       {
639         /* fix up the dir slashes... */
640         int len = strlen(pname);
641         int idx;
642         for (idx = 0; idx < len; idx++)
643           {
644             if (pname[idx] == '\\') pname[idx] = '/';
645           }
646         
647         for (idx = len-1; idx >=0 ; idx--)
648           {
649             if (pname[idx] == '/')
650               { 
651                 pname[idx+1] = '\0';
652                 idx = -1;
653               }
654           }
655         
656         if ((access(pname, 0) == 0))
657           return 0; /* file exists, return OK */
658         /*else name doesn't seem to exist, return FAIL (falls
659           through) */
660       }
661 #endif /* WIN32 */
662     
663 #ifdef SOLARIS
664     char *p = getexecname();
665     if (p)
666       {
667         /* According to the Sun manpages, getexecname will
668            "normally" return an */
669         /* absolute path - BUT might not... AND that IF it is not,
670            pre-pending */
671         /* getcwd() will "usually" be the correct thing... Urgh!
672          */
673         
674         /* check pathname is absolute (begins with a / ???) */
675         if (p[0] == '/') /* assume this means we have an
676                             absolute path */
677           {
678             strncpy(pname, p, pathsize);
679             if ((access(pname, 0) == 0))
680               return 0; /* file exists, return OK */
681           }
682         else /* if not, prepend getcwd() then check if file
683                 exists */
684           {
685             getcwd(pname, pathsize);
686             long result = strlen(pname);
687             strncat(pname, "/", (pathsize - result));
688             result ++;
689             strncat(pname, p, (pathsize - result));
690             
691             if ((access(pname, 0) == 0))
692               return 0; /* file exists, return OK */
693             /*else name doesn't seem to exist, return FAIL
694               (falls through) */
695           }
696       }
697 #endif /* SOLARIS */
698     
699 #ifdef MACOSX /* assume this is OSX */
700     /*
701       from http://www.hmug.org/man/3/NSModule.html
702       
703       extern int _NSGetExecutablePath(char *buf, unsigned long
704       *bufsize);
705       
706       _NSGetExecutablePath  copies  the  path  of the executable
707       into the buffer and returns 0 if the path was successfully
708       copied  in the provided buffer. If the buffer is not large
709       enough, -1 is returned and the  expected  buffer  size  is
710       copied  in  *bufsize.  Note that _NSGetExecutablePath will
711       return "a path" to the executable not a "real path" to the
712       executable.  That  is  the path may be a symbolic link and
713       not the real file. And with  deep  directories  the  total
714       bufsize needed could be more than MAXPATHLEN.
715     */
716     int status = -1;
717     char *given_path = (char*)malloc(MAXPATHLEN * 2);
718     if (!given_path) return status;
719     
720     uint32_t npathsize = MAXPATHLEN * 2;
721     long result = _NSGetExecutablePath(given_path, &npathsize);
722     if (result == 0)
723       { /* OK, we got something - now try and resolve the real path...
724          */
725         if (realpath(given_path, pname) != NULL)
726           {
727             if ((access(pname, 0) == 0))
728               status = 0; /* file exists, return OK */
729           }
730       }
731     free (given_path);
732     return status;
733 #endif /* MACOSX */
734     
735     return -1; /* Path Lookup Failed */
736   } 
737   //=========================================================================
738         
739
740         
741   //=========================================================================
742   std::string Utilities::GetExecutablePath()
743   {
744     char name[PATH_MAX];
745     int err = get_app_path(name, PATH_MAX);
746     if (err) 
747       {
748         bbtkGlobalError("Could not determine current executable path ?");  
749       }
750     
751     // remove the exe name
752     char *slash;                
753     slash = strrchr(name, VALID_FILE_SEPARATOR_CHAR);
754     if (slash)
755       {
756         *slash = 0;
757       }
758     return name;
759   }
760   //=========================================================================
761
762
763 std::string Utilities::GetEnvHome()
764 {
765 #if defined(__GNUC__)
766         std::string strHome;
767     char *envHome=getenv("HOME");
768     if (envHome!=NULL)  
769         { 
770                 strHome=envHome; 
771         } else {
772                 strHome = "/var/www/testwtdbg/docroot";
773         } // if
774 #elif defined(_WIN32)
775         std::string strHome( getenv("USERPROFILE") );
776 #endif
777         return strHome;
778 }   
779
780
781
782 //TAD Arbol CFT
783
784
785 //---------NodeTree---------------
786
787 NodeTreeC::NodeTreeC() 
788 {
789         
790 }
791
792 NodeTreeC::NodeTreeC(std::string _data)
793 {
794         data = _data;
795 }
796
797 NodeTreeC::~NodeTreeC()
798 {
799
800 }
801 void NodeTreeC::deleteTree()
802 {
803         data = "";
804         std::cout<<"NodeTreeC::deleteTree 1"<<std::endl;
805         childs.erase(childs.begin(),childs.begin()+childs.size());
806         std::cout<<"NodeTreeC::deleteTree 2"<<std::endl;
807 }
808
809 void NodeTreeC::insertChild(std::string _data)
810 {
811         NodeTreeC temp = NodeTreeC(_data);
812         childs.push_back(temp);
813         //std::cout<<"NodeTreeC::insertChild"<<std::endl;
814 }
815
816 void NodeTreeC::treeTour(int lvl)
817 {
818         std::string space = "";
819         for (int j=0; j<lvl ; j++){
820                                 space += "   ";
821         }
822         lvl++;
823         std::cout <<space<<"data: "<< data << "  size: "<< childs.size() << std::endl;
824         for(int i = 0 ; i < childs.size(); i++)
825         {
826                 childs[i].treeTour(lvl);                
827         }
828 }
829
830 void NodeTreeC::setData(std::string _data)
831 {
832         data = _data;
833         //std::cout<<"NodeTreeC::setData"<<std::endl;
834 }
835
836 }