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